Enabled asynchronous loading of SCRIPT SRC=, STYLE SRC= and LINK elements for style sheets. Changed nsIScriptContext to not be dependent on JavaScript.

This commit is contained in:
vidur%netscape.com 1998-12-15 06:10:59 +00:00
Родитель ba1f9dee86
Коммит fd093d0d82
21 изменённых файлов: 908 добавлений и 353 удалений

Просмотреть файл

@ -21,6 +21,7 @@
#include "nsIUnicharInputStream.h"
#include "nsIHTMLContent.h"
#include "nsIURL.h"
#include "nsIURLGroup.h"
#include "nsIHttpUrl.h"
#include "nsHTMLDocument.h"
#include "nsIPresShell.h"
@ -73,6 +74,7 @@ static NS_DEFINE_IID(kIHTMLContentSinkIID, NS_IHTML_CONTENT_SINK_IID);
static NS_DEFINE_IID(kIHTTPUrlIID, NS_IHTTPURL_IID);
static NS_DEFINE_IID(kIScrollableViewIID, NS_ISCROLLABLEVIEW_IID);
static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID);
static NS_DEFINE_IID(kIStreamListenerIID, NS_ISTREAMLISTENER_IID);
//----------------------------------------------------------------------
@ -226,6 +228,11 @@ public:
nsresult ProcessMETATag(const nsIParserNode& aNode);
nsresult ProcessSCRIPTTag(const nsIParserNode& aNode);
nsresult ProcessSTYLETag(const nsIParserNode& aNode);
// Script processing related routines
nsresult ResumeParsing();
nsresult EvaluateScript(nsString& aScript,
PRInt32 aLineNo);
};
class SinkContext {
@ -276,6 +283,38 @@ public:
};
class nsAccumulatingURLLoader;
typedef void (*nsAccumulationDoneFunc)(nsAccumulatingURLLoader* aLoader,
nsString& aData,
void* aRef,
nsresult aStatus);
class nsAccumulatingURLLoader : public nsIStreamListener {
public:
nsAccumulatingURLLoader(nsIURL* aURL,
nsAccumulationDoneFunc aFunc,
void* aRef);
~nsAccumulatingURLLoader();
NS_DECL_ISUPPORTS
NS_IMETHOD OnStartBinding(nsIURL* aURL, const char *aContentType);
NS_IMETHOD OnProgress(nsIURL* aURL, PRInt32 aProgress, PRInt32 aProgressMax);
NS_IMETHOD OnStatus(nsIURL* aURL, const nsString &aMsg);
NS_IMETHOD OnStopBinding(nsIURL* aURL, PRInt32 aStatus, const nsString &aMsg);
NS_IMETHOD GetBindInfo(nsIURL* aURL);
NS_IMETHOD OnDataAvailable(nsIURL* aURL, nsIInputStream *aIStream,
PRInt32 aLength);
protected:
nsIURL* mURL;
nsAccumulationDoneFunc mFunc;
void* mRef;
nsString* mData;
};
//----------------------------------------------------------------------
static void
@ -2057,6 +2096,48 @@ HTMLContentSink::ProcessBASETag(const nsIParserNode& aNode)
return NS_OK;
}
typedef struct {
nsString mTitle;
nsString mMedia;
PRBool mIsActive;
nsIURL* mURL;
nsIHTMLContent* mElement;
HTMLContentSink* mSink;
} nsAsyncStyleProcessingData;
static void
nsDoneLoadingStyle(nsAccumulatingURLLoader* aLoader,
nsString& aData,
void* aRef,
nsresult aStatus)
{
nsresult rv = NS_OK;
nsAsyncStyleProcessingData* d = (nsAsyncStyleProcessingData*)aRef;
nsIUnicharInputStream* uin = nsnull;
if ((NS_OK == aStatus) && (0 < aData.Length())) {
// wrap the string with the CSS data up in a unicode
// input stream.
rv = NS_NewStringUnicharInputStream(&uin, new nsString(aData));
if (NS_OK == rv) {
// XXX We have no way of indicating failure. Silently fail?
rv = d->mSink->LoadStyleSheet(d->mURL, uin, d->mIsActive,
d->mTitle, d->mMedia, d->mElement);
}
}
d->mSink->ResumeParsing();
NS_RELEASE(d->mURL);
NS_IF_RELEASE(d->mElement);
NS_RELEASE(d->mSink);
delete d;
// We added a reference when the loader was created. This
// release should destroy it.
NS_RELEASE(aLoader);
}
nsresult
HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
{
@ -2118,38 +2199,47 @@ HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
if (rel.EqualsIgnoreCase("stylesheet") || rel.EqualsIgnoreCase("alternate stylesheet")) {
if ((0 == type.Length()) || type.EqualsIgnoreCase("text/css")) {
nsIURL* url = nsnull;
nsIUnicharInputStream* uin = nsnull;
nsAutoString absURL;
nsIURL* docURL = mDocument->GetDocumentURL();
result = NS_MakeAbsoluteURL(docURL, mBaseHREF, href, absURL);
nsIURLGroup* urlGroup = mDocumentURL->GetURLGroup();
result = NS_MakeAbsoluteURL(mDocumentURL, mBaseHREF, href, absURL);
if (NS_OK != result) {
return result;
}
NS_RELEASE(docURL);
result = NS_NewURL(&url, nsnull, absURL);
if (NS_OK != result) {
return result;
if (urlGroup) {
result = urlGroup->CreateURL(&url, nsnull, absURL, nsnull);
NS_RELEASE(urlGroup);
}
PRInt32 ec;
nsIInputStream* iin = url->Open(&ec);
if (nsnull == iin) {
NS_RELEASE(url);
return (nsresult) ec;/* XXX fix url->Open */
else {
result = NS_NewURL(&url, nsnull, absURL);
}
result = NS_NewConverterStream(&uin, nsnull, iin);
NS_RELEASE(iin);
if (NS_OK != result) {
NS_RELEASE(url);
return result;
}
result = LoadStyleSheet(url, uin, rel.EqualsIgnoreCase("stylesheet"),
title, media, element);
NS_RELEASE(uin);
nsAsyncStyleProcessingData* d = new nsAsyncStyleProcessingData;
if (nsnull == d) {
return NS_ERROR_OUT_OF_MEMORY;
}
d->mTitle.SetString(title);
d->mMedia.SetString(media);
d->mIsActive = rel.EqualsIgnoreCase("stylesheet");
d->mURL = url;
NS_ADDREF(url);
d->mElement = element;
NS_ADDREF(element);
d->mSink = this;
NS_ADDREF(this);
nsAccumulatingURLLoader* loader =
new nsAccumulatingURLLoader(url,
(nsAccumulationDoneFunc)nsDoneLoadingStyle,
(void *)d);
NS_RELEASE(url);
result = NS_ERROR_HTMLPARSER_BLOCK;
}
}
NS_RELEASE(element);
return result;
}
@ -2214,8 +2304,6 @@ HTMLContentSink::ProcessMETATag(const nsIParserNode& aNode)
return NS_OK;
}
#define SCRIPT_BUF_SIZE 1024
// Returns PR_TRUE if the language name is a version of JavaScript and
// PR_FALSE otherwise
static PRBool
@ -2243,6 +2331,78 @@ IsJavaScriptLanguage(const nsString& aName)
}
}
nsresult
HTMLContentSink::ResumeParsing()
{
if (nsnull != mParser) {
mParser->EnableParser(PR_TRUE);
}
return NS_OK;
}
nsresult
HTMLContentSink::EvaluateScript(nsString& aScript,
PRInt32 aLineNo)
{
nsresult rv = NS_OK;
if (aScript.Length() > 0) {
nsIScriptContextOwner *owner;
nsIScriptContext *context;
owner = mDocument->GetScriptContextOwner();
if (nsnull != owner) {
rv = owner->GetScriptContext(&context);
if (rv != NS_OK) {
NS_RELEASE(owner);
return rv;
}
nsAutoString ret;
nsIURL* docURL = mDocument->GetDocumentURL();
const char* url;
if (docURL) {
url = docURL->GetSpec();
}
PRBool isUndefined;
PRBool result = context->EvaluateString(aScript, url, aLineNo,
ret, &isUndefined);
NS_IF_RELEASE(docURL);
NS_RELEASE(context);
NS_RELEASE(owner);
}
}
return rv;
}
static void
nsDoneLoadingScript(nsAccumulatingURLLoader* aLoader,
nsString& aData,
void* aRef,
nsresult aStatus)
{
HTMLContentSink* sink = (HTMLContentSink*)aRef;
if (NS_OK == aStatus) {
// XXX We have no way of indicating failure. Silently fail?
sink->EvaluateScript(aData, 0);
}
sink->ResumeParsing();
// The url loader held a reference to the sink
NS_RELEASE(sink);
// We added a reference when the loader was created. This
// release should destroy it.
NS_RELEASE(aLoader);
}
nsresult
HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
{
@ -2255,8 +2415,7 @@ HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
for (i = 0; i < ac; i++) {
const nsString& key = aNode.GetKeyAt(i);
if (key.EqualsIgnoreCase("src")) {
src = aNode.GetValueAt(i);
src.Trim("\"", PR_TRUE, PR_TRUE);
GetAttributeValueAt(aNode, i, src, nsnull);
}
else if (key.EqualsIgnoreCase("type")) {
nsAutoString type;
@ -2277,88 +2436,54 @@ HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
if (isJavaScript) {
nsAutoString script;
// If there is a SRC attribute, (for now) read from the
// stream synchronously and hold the data in a string.
if (src != "") {
// Use the SRC attribute value to open a blocking stream
mCurrentContext->FlushTags();
// If there is a SRC attribute...
if (src.Length() > 0) {
// Use the SRC attribute value to open an accumulating stream
nsIURL* url = nsnull;
nsAutoString absURL;
nsIURL* docURL = mDocument->GetDocumentURL();
rv = NS_MakeAbsoluteURL(docURL, mBaseHREF, src, absURL);
nsIURLGroup* urlGroup = mDocumentURL->GetURLGroup();
rv = NS_MakeAbsoluteURL(mDocumentURL, mBaseHREF, src, absURL);
if (NS_OK != rv) {
return rv;
}
NS_RELEASE(docURL);
rv = NS_NewURL(&url, nsnull, absURL);
if (urlGroup) {
rv = urlGroup->CreateURL(&url, nsnull, absURL, nsnull);
NS_RELEASE(urlGroup);
}
else {
rv = NS_NewURL(&url, nsnull, absURL);
}
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
PRInt32 nb;
nsresult err;
do {
char buf[SCRIPT_BUF_SIZE];
err = iin->Read(buf, 0, SCRIPT_BUF_SIZE, &nb);
if (NS_OK == err) {
script.Append((const char *)buf, nb);
}
} while (err == NS_OK);
if (NS_BASE_STREAM_EOF != err) {
rv = NS_ERROR_FAILURE;
}
NS_RELEASE(iin);
// Add a reference to this since the url loader is holding
// onto it as opaque data.
NS_ADDREF(this);
nsAccumulatingURLLoader* loader =
new nsAccumulatingURLLoader(url,
(nsAccumulationDoneFunc)nsDoneLoadingScript,
(void *)this);
NS_RELEASE(url);
rv = NS_ERROR_HTMLPARSER_BLOCK;
}
else {
// Otherwise, get the text content of the script tag
script = aNode.GetSkippedContent();
}
mCurrentContext->FlushTags();
PRUint32 lineNo = (PRUint32)aNode.GetSourceLineNumber();
if (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;
nsIURL* mDocURL = mDocument->GetDocumentURL();
const char* mURL;
if (mDocURL) {
mURL = mDocURL->GetSpec();
}
PRUint32 mLineNo = (PRUint32)aNode.GetSourceLineNumber();
PRBool result = context->EvaluateString(script, mURL, mLineNo, &val);
NS_IF_RELEASE(mDocURL);
NS_RELEASE(context);
NS_RELEASE(owner);
}
EvaluateScript(script, lineNo);
}
}
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?
// XXX This code and ProcessSCRIPTTag share alot in common; clean that up!
@ -2440,40 +2565,56 @@ HTMLContentSink::ProcessSTYLETag(const nsIParserNode& aNode)
url = mDocumentURL;
NS_IF_ADDREF(url);
}
// Now that we have a url and a unicode input stream, parse the
// style sheet.
rv = LoadStyleSheet(url, uin, PR_TRUE, title, media, element);
NS_RELEASE(url);
NS_RELEASE(uin);
} else {
// src with immediate style data doesn't add up
// XXX what does nav do?
// Use the SRC attribute value to open an accumulating stream
nsAutoString absURL;
nsIURL* docURL = mDocument->GetDocumentURL();
rv = NS_MakeAbsoluteURL(docURL, mBaseHREF, src, absURL);
nsIURLGroup* urlGroup = mDocumentURL->GetURLGroup();
rv = NS_MakeAbsoluteURL(mDocumentURL, mBaseHREF, src, absURL);
if (NS_OK != rv) {
return rv;
}
NS_RELEASE(docURL);
rv = NS_NewURL(&url, nsnull, absURL);
if (urlGroup) {
rv = urlGroup->CreateURL(&url, nsnull, absURL, nsnull);
NS_RELEASE(urlGroup);
}
else {
rv = NS_NewURL(&url, nsnull, absURL);
}
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 */
}
rv = NS_NewConverterStream(&uin, nsnull, iin);
NS_RELEASE(iin);
if (NS_OK != rv) {
NS_RELEASE(url);
return rv;
nsAsyncStyleProcessingData* d = new nsAsyncStyleProcessingData;
if (nsnull == d) {
return NS_ERROR_OUT_OF_MEMORY;
}
d->mTitle.SetString(title);
d->mMedia.SetString(media);
d->mIsActive = PR_TRUE;
d->mURL = url;
NS_ADDREF(url);
d->mElement = element;
NS_ADDREF(element);
d->mSink = this;
NS_ADDREF(this);
nsAccumulatingURLLoader* loader =
new nsAccumulatingURLLoader(url,
(nsAccumulationDoneFunc)nsDoneLoadingStyle,
(void *)d);
NS_RELEASE(url);
rv = NS_ERROR_HTMLPARSER_BLOCK;
}
// Now that we have a url and a unicode input stream, parse the
// style sheet.
rv = LoadStyleSheet(url, uin, PR_TRUE, title, media, element);
NS_RELEASE(element);
NS_RELEASE(uin);
NS_RELEASE(url);
return rv;
}
@ -2601,3 +2742,103 @@ HTMLContentSink::NotifyError(nsresult aErrorResult)
PR_ASSERT(0);
return NS_OK;
}
//----------------------------------------------------------------------
nsAccumulatingURLLoader::nsAccumulatingURLLoader(nsIURL* aURL,
nsAccumulationDoneFunc aFunc,
void* aRef)
{
mFunc = aFunc;
mRef = aRef;
mData = new nsString();
nsresult rv;
if (aURL) {
rv = aURL->Open(this);
if ((NS_OK != rv) && (nsnull != mFunc)) {
(*mFunc)(this, *mData, mRef, rv);
}
}
}
nsAccumulatingURLLoader::~nsAccumulatingURLLoader()
{
if (nsnull != mData) {
delete mData;
}
}
NS_IMPL_ISUPPORTS(nsAccumulatingURLLoader, kIStreamListenerIID)
NS_IMETHODIMP
nsAccumulatingURLLoader::OnStartBinding(nsIURL* aURL,
const char *aContentType)
{
// XXX Should check content type?
return NS_OK;
}
NS_IMETHODIMP
nsAccumulatingURLLoader::OnProgress(nsIURL* aURL,
PRInt32 aProgress,
PRInt32 aProgressMax)
{
return NS_OK;
}
NS_IMETHODIMP
nsAccumulatingURLLoader::OnStatus(nsIURL* aURL, const nsString &aMsg)
{
return NS_OK;
}
NS_IMETHODIMP
nsAccumulatingURLLoader::OnStopBinding(nsIURL* aURL,
PRInt32 aStatus,
const nsString &aMsg)
{
(*mFunc)(this, *mData, mRef, aStatus);
return NS_OK;
}
NS_IMETHODIMP
nsAccumulatingURLLoader::GetBindInfo(nsIURL* aURL)
{
return NS_OK;
}
#define BUF_SIZE 1024
NS_IMETHODIMP
nsAccumulatingURLLoader::OnDataAvailable(nsIURL* aURL,
nsIInputStream *aIStream,
PRInt32 aLength)
{
nsresult rv = NS_OK;
char buffer[BUF_SIZE];
PRInt32 len, lenRead;
aIStream->GetLength(&len);
while (len > 0) {
if (len < BUF_SIZE) {
lenRead = len;
}
else {
lenRead = BUF_SIZE;
}
rv = aIStream->Read(buffer, 0, lenRead, &lenRead);
if (NS_OK != rv) {
return rv;
}
mData->Append(buffer, lenRead);
len -= lenRead;
}
return rv;
}

Просмотреть файл

@ -1126,14 +1126,17 @@ nsXMLContentSink::EvaluateScript(nsString& aScript, PRUint32 aLineNo)
return rv;
}
jsval val;
nsIURL* mDocURL = mDocument->GetDocumentURL();
const char* mURL;
if (mDocURL) {
mURL = mDocURL->GetSpec();
}
PRBool result = context->EvaluateString(aScript, mURL, aLineNo, &val);
nsAutoString val;
PRBool isUndefined;
PRBool result = context->EvaluateString(aScript, mURL, aLineNo,
val, &isUndefined);
NS_IF_RELEASE(mDocURL);

Просмотреть файл

@ -22,7 +22,6 @@
#include "nscore.h"
#include "nsString.h"
#include "nsISupports.h"
#include "jsapi.h"
class nsIScriptGlobalObject;
class nsIScriptSecurityManager;
@ -51,10 +50,11 @@ public:
* @return true if the script was valid and got executed
*
**/
virtual PRBool EvaluateString(nsString& aScript,
virtual PRBool EvaluateString(const nsString& aScript,
const char *aURL,
PRUint32 aLineNo,
jsval *aRetValue) = 0;
nsString& aRetValue,
PRBool* aIsUndefined) = 0;
/**
* Return the global object.

Просмотреть файл

@ -63,19 +63,33 @@ nsJSContext::~nsJSContext()
NS_IMPL_ISUPPORTS(nsJSContext, kIScriptContextIID);
PRBool nsJSContext::EvaluateString(nsString& aScript,
const char *aURL,
PRUint32 aLineNo,
jsval *aRetValue)
PRBool nsJSContext::EvaluateString(const nsString& aScript,
const char *aURL,
PRUint32 aLineNo,
nsString& aRetValue,
PRBool* aIsUndefined)
{
return ::JS_EvaluateUCScriptForPrincipals(mContext,
JS_GetGlobalObject(mContext),
nsnull,
(jschar*)aScript.GetUnicode(),
aScript.Length(),
aURL,
aLineNo,
aRetValue);
jsval val;
PRBool ret = ::JS_EvaluateUCScriptForPrincipals(mContext,
JS_GetGlobalObject(mContext),
nsnull,
(jschar*)aScript.GetUnicode(),
aScript.Length(),
aURL,
aLineNo,
&val);
if (ret) {
*aIsUndefined = JSVAL_IS_VOID(val);
JSString* jsstring = JS_ValueToString(mContext, val);
aRetValue.SetString(JS_GetStringChars(jsstring));
}
else {
aRetValue.Truncate();
}
return ret;
}
nsIScriptGlobalObject* nsJSContext::GetGlobalObject()

Просмотреть файл

@ -19,6 +19,8 @@
#define nsJSEnvironment_h___
#include "nsIScriptContext.h"
#include "jsapi.h"
class nsIScriptSecurityManager;
class nsJSContext : public nsIScriptContext {
@ -31,10 +33,11 @@ public:
NS_DECL_ISUPPORTS
virtual PRBool EvaluateString(nsString& aScript,
virtual PRBool EvaluateString(const nsString& aScript,
const char *aURL,
PRUint32 aLineNo,
jsval *aRetValue);
nsString& aRetValue,
PRBool* aIsUndefined);
virtual nsIScriptGlobalObject* GetGlobalObject();
virtual void* GetNativeContext();
virtual nsresult InitClasses();

Просмотреть файл

@ -156,18 +156,19 @@ evaluate_script(URL_Struct* urls, const char *what, JSConData *con_data)
if (context_owner) {
context_owner->GetScriptContext(&script_context);
if (script_context) {
jsval ret;
nsAutoString ret;
PRBool isUndefined;
if (script_context->EvaluateString(nsString(what),
nsnull, 0,
&ret)) {
ret,
&isUndefined)) {
JSContext *cx = (JSContext *)script_context->GetNativeContext();
// Find out if it can be converted into a string
if ((ret != JSVAL_VOID) &&
JS_ConvertValue(cx, ret, JSTYPE_STRING, &ret)) {
con_data->len = JS_GetStringLength(JSVAL_TO_STRING(ret));
if (!isUndefined) {
con_data->len = ret.Length();
con_data->str = (char *)PR_MALLOC(con_data->len + 1);
PL_strcpy(con_data->str, JS_GetStringBytes(JSVAL_TO_STRING(ret)));
ret.ToCString(con_data->str, con_data->len);
}
else {
con_data->str = nsnull;

Просмотреть файл

@ -866,7 +866,7 @@ nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsI
* 2) close the top container, and add this to
* whatever container ends up on top.
*
* @update gess 3/25/98
* @update vidur 11/14/98
* @param aToken -- next (start) token to be handled
* @param aNode -- CParserNode representing this start token
* @return PR_TRUE if all went well; PR_FALSE if error occured
@ -915,8 +915,19 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
CollectSkippedContent(attrNode,theCount);
if(NS_OK==result) {
result=AddLeaf(attrNode);
if(NS_OK==result)
result=CloseHead(attrNode);
// XXX If the return value tells us to block, go
// ahead and close the tag out anyway, since its
// contents will be consumed.
if (NS_SUCCEEDED(result)) {
nsresult rv = CloseHead(attrNode);
// XXX Only send along a failure. If the close
// succeeded we still may need to indicate that the
// parser has blocked (i.e. return the result of
// the AddLeaf.
if (rv != NS_OK) {
result = rv;
}
}
}
}
}
@ -2948,7 +2959,7 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode& aNode){
* Call this method ONLY when you want to write a leaf
* into the head container.
*
* @update gess4/6/98
* @update vidur 11/14/98
* @param aNode -- next node to be added to model
* @return error code; 0 means OK
*/
@ -2966,8 +2977,18 @@ nsresult CNavDTD::AddHeadLeaf(const nsIParserNode& aNode){
nsresult result=OpenHead(aNode);
if(NS_OK==result) {
result=AddLeaf(aNode);
if(NS_OK==result) {
result=CloseHead(aNode);
// XXX If the return value tells us to block, go
// ahead and close the tag out anyway, since its
// contents will be consumed.
if (NS_SUCCEEDED(result)) {
nsresult rv = CloseHead(aNode);
// XXX Only send along a failure. If the close
// succeeded we still may need to indicate that the
// parser has blocked (i.e. return the result of
// the AddLeaf.
if (rv != NS_OK) {
result = rv;
}
}
}
return result;

Просмотреть файл

@ -40,6 +40,7 @@ class nsIParser;
#define NS_ICONTENT_SINK_IID \
{ 0xa6cf9052, 0x15b3, 0x11d2,{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
class nsIContentSink : public nsISupports {
public:
/**

Просмотреть файл

@ -43,6 +43,8 @@
/**
* Return codes for parsing routines.
* @update vidur 12/11/98
*
* NS_ERROR_HTMLPARSER_BLOCK indicates that the parser should
* block further parsing until it gets a Unblock() method call.
* NS_ERROR_HTMLPARSER_CONTINUE indicates that the parser should

Просмотреть файл

@ -182,7 +182,7 @@ MakeConversionTable()
/**
* default constructor
*
* @update gess 3/25/98
* @update vidur 12/11/98
* @param
* @return
*/
@ -569,20 +569,42 @@ CParserContext* nsParser::PopContext() {
* and tokenize input (TRUE), or whether it just caches input to be
* parsed later (FALSE).
*
* @update gess 9/1/98
* @update vidur 12/11/98
* @param aState determines whether we parse/tokenize or just cache.
* @return current state
*/
PRBool nsParser::EnableParser(PRBool aState){
nsIParser* me = nsnull;
// If the stream has already finished, there's a good chance
// that we might start closing things down when the parser
// is reenabled. To make sure that we're not deleted across
// the reenabling process, hold a reference to ourselves.
if (eOnStop == mStreamListenerState) {
me = this;
NS_ADDREF(me);
}
// If we're reenabling the parser
if ((PR_FALSE == mParserEnabled) && aState) {
mParserEnabled = PR_TRUE;
ResumeParse();
if (eOnStop == mStreamListenerState) {
// If the stream has already closed, finish out the parsing
// process. Note if the parser was disabled when we resumed
// parsing, then we have to wait till its reenabled before
// finishing.
if ((eOnStop == mStreamListenerState) && mParserEnabled) {
DidBuildModel(mStreamStatus);
}
}
mParserEnabled=aState;
return mParserEnabled;
else {
mParserEnabled=aState;
}
// Release reference if we added one at the top of this routine
NS_IF_RELEASE(me);
return aState;
}
@ -615,7 +637,7 @@ PRInt32 nsParser::Parse(nsIURL* aURL,nsIStreamObserver* aListener,PRBool aVerify
/**
* Cause parser to parse input from given stream
* @update gess5/11/98
* @update vidur 12/11/98
* @param aStream is the i/o source
* @return error code -- 0 if ok, non-zero if error.
*/
@ -698,12 +720,12 @@ PRInt32 nsParser::ResumeParse() {
buildResult=BuildModel();
if(kInterrupted==result)
mParserContext->mDTD->WillInterruptParse();
// If we're told to block the parser, we disable
// all further parsing (and cache any data coming
// in) until the parser is enabled.
if(NS_ERROR_HTMLPARSER_BLOCK==buildResult) {
mParserEnabled=PR_FALSE;
}
// If we're told to block the parser, we disable
// all further parsing (and cache any data coming
// in) until the parser is enabled.
if(NS_ERROR_HTMLPARSER_BLOCK==buildResult) {
EnableParser(PR_FALSE);
}
}
return result;
}
@ -881,7 +903,7 @@ nsresult nsParser::OnStartBinding(nsIURL* aURL, const char *aSourceType){
/**
*
*
* @update gess 5/12/98
* @update vidur 12/11/98
* @param pIStream contains the input chars
* @param length is the number of bytes waiting input
* @return error code (usually 0)
@ -953,7 +975,7 @@ nsresult nsParser::OnDataAvailable(nsIURL* aURL, nsIInputStream *pIStream, PRInt
/**
*
*
* @update gess 5/12/98
* @update vidur 12/11/98
* @param
* @return
*/

Просмотреть файл

@ -21,6 +21,7 @@
#include "nsIUnicharInputStream.h"
#include "nsIHTMLContent.h"
#include "nsIURL.h"
#include "nsIURLGroup.h"
#include "nsIHttpUrl.h"
#include "nsHTMLDocument.h"
#include "nsIPresShell.h"
@ -73,6 +74,7 @@ static NS_DEFINE_IID(kIHTMLContentSinkIID, NS_IHTML_CONTENT_SINK_IID);
static NS_DEFINE_IID(kIHTTPUrlIID, NS_IHTTPURL_IID);
static NS_DEFINE_IID(kIScrollableViewIID, NS_ISCROLLABLEVIEW_IID);
static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID);
static NS_DEFINE_IID(kIStreamListenerIID, NS_ISTREAMLISTENER_IID);
//----------------------------------------------------------------------
@ -226,6 +228,11 @@ public:
nsresult ProcessMETATag(const nsIParserNode& aNode);
nsresult ProcessSCRIPTTag(const nsIParserNode& aNode);
nsresult ProcessSTYLETag(const nsIParserNode& aNode);
// Script processing related routines
nsresult ResumeParsing();
nsresult EvaluateScript(nsString& aScript,
PRInt32 aLineNo);
};
class SinkContext {
@ -276,6 +283,38 @@ public:
};
class nsAccumulatingURLLoader;
typedef void (*nsAccumulationDoneFunc)(nsAccumulatingURLLoader* aLoader,
nsString& aData,
void* aRef,
nsresult aStatus);
class nsAccumulatingURLLoader : public nsIStreamListener {
public:
nsAccumulatingURLLoader(nsIURL* aURL,
nsAccumulationDoneFunc aFunc,
void* aRef);
~nsAccumulatingURLLoader();
NS_DECL_ISUPPORTS
NS_IMETHOD OnStartBinding(nsIURL* aURL, const char *aContentType);
NS_IMETHOD OnProgress(nsIURL* aURL, PRInt32 aProgress, PRInt32 aProgressMax);
NS_IMETHOD OnStatus(nsIURL* aURL, const nsString &aMsg);
NS_IMETHOD OnStopBinding(nsIURL* aURL, PRInt32 aStatus, const nsString &aMsg);
NS_IMETHOD GetBindInfo(nsIURL* aURL);
NS_IMETHOD OnDataAvailable(nsIURL* aURL, nsIInputStream *aIStream,
PRInt32 aLength);
protected:
nsIURL* mURL;
nsAccumulationDoneFunc mFunc;
void* mRef;
nsString* mData;
};
//----------------------------------------------------------------------
static void
@ -2057,6 +2096,48 @@ HTMLContentSink::ProcessBASETag(const nsIParserNode& aNode)
return NS_OK;
}
typedef struct {
nsString mTitle;
nsString mMedia;
PRBool mIsActive;
nsIURL* mURL;
nsIHTMLContent* mElement;
HTMLContentSink* mSink;
} nsAsyncStyleProcessingData;
static void
nsDoneLoadingStyle(nsAccumulatingURLLoader* aLoader,
nsString& aData,
void* aRef,
nsresult aStatus)
{
nsresult rv = NS_OK;
nsAsyncStyleProcessingData* d = (nsAsyncStyleProcessingData*)aRef;
nsIUnicharInputStream* uin = nsnull;
if ((NS_OK == aStatus) && (0 < aData.Length())) {
// wrap the string with the CSS data up in a unicode
// input stream.
rv = NS_NewStringUnicharInputStream(&uin, new nsString(aData));
if (NS_OK == rv) {
// XXX We have no way of indicating failure. Silently fail?
rv = d->mSink->LoadStyleSheet(d->mURL, uin, d->mIsActive,
d->mTitle, d->mMedia, d->mElement);
}
}
d->mSink->ResumeParsing();
NS_RELEASE(d->mURL);
NS_IF_RELEASE(d->mElement);
NS_RELEASE(d->mSink);
delete d;
// We added a reference when the loader was created. This
// release should destroy it.
NS_RELEASE(aLoader);
}
nsresult
HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
{
@ -2118,38 +2199,47 @@ HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
if (rel.EqualsIgnoreCase("stylesheet") || rel.EqualsIgnoreCase("alternate stylesheet")) {
if ((0 == type.Length()) || type.EqualsIgnoreCase("text/css")) {
nsIURL* url = nsnull;
nsIUnicharInputStream* uin = nsnull;
nsAutoString absURL;
nsIURL* docURL = mDocument->GetDocumentURL();
result = NS_MakeAbsoluteURL(docURL, mBaseHREF, href, absURL);
nsIURLGroup* urlGroup = mDocumentURL->GetURLGroup();
result = NS_MakeAbsoluteURL(mDocumentURL, mBaseHREF, href, absURL);
if (NS_OK != result) {
return result;
}
NS_RELEASE(docURL);
result = NS_NewURL(&url, nsnull, absURL);
if (NS_OK != result) {
return result;
if (urlGroup) {
result = urlGroup->CreateURL(&url, nsnull, absURL, nsnull);
NS_RELEASE(urlGroup);
}
PRInt32 ec;
nsIInputStream* iin = url->Open(&ec);
if (nsnull == iin) {
NS_RELEASE(url);
return (nsresult) ec;/* XXX fix url->Open */
else {
result = NS_NewURL(&url, nsnull, absURL);
}
result = NS_NewConverterStream(&uin, nsnull, iin);
NS_RELEASE(iin);
if (NS_OK != result) {
NS_RELEASE(url);
return result;
}
result = LoadStyleSheet(url, uin, rel.EqualsIgnoreCase("stylesheet"),
title, media, element);
NS_RELEASE(uin);
nsAsyncStyleProcessingData* d = new nsAsyncStyleProcessingData;
if (nsnull == d) {
return NS_ERROR_OUT_OF_MEMORY;
}
d->mTitle.SetString(title);
d->mMedia.SetString(media);
d->mIsActive = rel.EqualsIgnoreCase("stylesheet");
d->mURL = url;
NS_ADDREF(url);
d->mElement = element;
NS_ADDREF(element);
d->mSink = this;
NS_ADDREF(this);
nsAccumulatingURLLoader* loader =
new nsAccumulatingURLLoader(url,
(nsAccumulationDoneFunc)nsDoneLoadingStyle,
(void *)d);
NS_RELEASE(url);
result = NS_ERROR_HTMLPARSER_BLOCK;
}
}
NS_RELEASE(element);
return result;
}
@ -2214,8 +2304,6 @@ HTMLContentSink::ProcessMETATag(const nsIParserNode& aNode)
return NS_OK;
}
#define SCRIPT_BUF_SIZE 1024
// Returns PR_TRUE if the language name is a version of JavaScript and
// PR_FALSE otherwise
static PRBool
@ -2243,6 +2331,78 @@ IsJavaScriptLanguage(const nsString& aName)
}
}
nsresult
HTMLContentSink::ResumeParsing()
{
if (nsnull != mParser) {
mParser->EnableParser(PR_TRUE);
}
return NS_OK;
}
nsresult
HTMLContentSink::EvaluateScript(nsString& aScript,
PRInt32 aLineNo)
{
nsresult rv = NS_OK;
if (aScript.Length() > 0) {
nsIScriptContextOwner *owner;
nsIScriptContext *context;
owner = mDocument->GetScriptContextOwner();
if (nsnull != owner) {
rv = owner->GetScriptContext(&context);
if (rv != NS_OK) {
NS_RELEASE(owner);
return rv;
}
nsAutoString ret;
nsIURL* docURL = mDocument->GetDocumentURL();
const char* url;
if (docURL) {
url = docURL->GetSpec();
}
PRBool isUndefined;
PRBool result = context->EvaluateString(aScript, url, aLineNo,
ret, &isUndefined);
NS_IF_RELEASE(docURL);
NS_RELEASE(context);
NS_RELEASE(owner);
}
}
return rv;
}
static void
nsDoneLoadingScript(nsAccumulatingURLLoader* aLoader,
nsString& aData,
void* aRef,
nsresult aStatus)
{
HTMLContentSink* sink = (HTMLContentSink*)aRef;
if (NS_OK == aStatus) {
// XXX We have no way of indicating failure. Silently fail?
sink->EvaluateScript(aData, 0);
}
sink->ResumeParsing();
// The url loader held a reference to the sink
NS_RELEASE(sink);
// We added a reference when the loader was created. This
// release should destroy it.
NS_RELEASE(aLoader);
}
nsresult
HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
{
@ -2255,8 +2415,7 @@ HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
for (i = 0; i < ac; i++) {
const nsString& key = aNode.GetKeyAt(i);
if (key.EqualsIgnoreCase("src")) {
src = aNode.GetValueAt(i);
src.Trim("\"", PR_TRUE, PR_TRUE);
GetAttributeValueAt(aNode, i, src, nsnull);
}
else if (key.EqualsIgnoreCase("type")) {
nsAutoString type;
@ -2277,88 +2436,54 @@ HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
if (isJavaScript) {
nsAutoString script;
// If there is a SRC attribute, (for now) read from the
// stream synchronously and hold the data in a string.
if (src != "") {
// Use the SRC attribute value to open a blocking stream
mCurrentContext->FlushTags();
// If there is a SRC attribute...
if (src.Length() > 0) {
// Use the SRC attribute value to open an accumulating stream
nsIURL* url = nsnull;
nsAutoString absURL;
nsIURL* docURL = mDocument->GetDocumentURL();
rv = NS_MakeAbsoluteURL(docURL, mBaseHREF, src, absURL);
nsIURLGroup* urlGroup = mDocumentURL->GetURLGroup();
rv = NS_MakeAbsoluteURL(mDocumentURL, mBaseHREF, src, absURL);
if (NS_OK != rv) {
return rv;
}
NS_RELEASE(docURL);
rv = NS_NewURL(&url, nsnull, absURL);
if (urlGroup) {
rv = urlGroup->CreateURL(&url, nsnull, absURL, nsnull);
NS_RELEASE(urlGroup);
}
else {
rv = NS_NewURL(&url, nsnull, absURL);
}
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
PRInt32 nb;
nsresult err;
do {
char buf[SCRIPT_BUF_SIZE];
err = iin->Read(buf, 0, SCRIPT_BUF_SIZE, &nb);
if (NS_OK == err) {
script.Append((const char *)buf, nb);
}
} while (err == NS_OK);
if (NS_BASE_STREAM_EOF != err) {
rv = NS_ERROR_FAILURE;
}
NS_RELEASE(iin);
// Add a reference to this since the url loader is holding
// onto it as opaque data.
NS_ADDREF(this);
nsAccumulatingURLLoader* loader =
new nsAccumulatingURLLoader(url,
(nsAccumulationDoneFunc)nsDoneLoadingScript,
(void *)this);
NS_RELEASE(url);
rv = NS_ERROR_HTMLPARSER_BLOCK;
}
else {
// Otherwise, get the text content of the script tag
script = aNode.GetSkippedContent();
}
mCurrentContext->FlushTags();
PRUint32 lineNo = (PRUint32)aNode.GetSourceLineNumber();
if (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;
nsIURL* mDocURL = mDocument->GetDocumentURL();
const char* mURL;
if (mDocURL) {
mURL = mDocURL->GetSpec();
}
PRUint32 mLineNo = (PRUint32)aNode.GetSourceLineNumber();
PRBool result = context->EvaluateString(script, mURL, mLineNo, &val);
NS_IF_RELEASE(mDocURL);
NS_RELEASE(context);
NS_RELEASE(owner);
}
EvaluateScript(script, lineNo);
}
}
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?
// XXX This code and ProcessSCRIPTTag share alot in common; clean that up!
@ -2440,40 +2565,56 @@ HTMLContentSink::ProcessSTYLETag(const nsIParserNode& aNode)
url = mDocumentURL;
NS_IF_ADDREF(url);
}
// Now that we have a url and a unicode input stream, parse the
// style sheet.
rv = LoadStyleSheet(url, uin, PR_TRUE, title, media, element);
NS_RELEASE(url);
NS_RELEASE(uin);
} else {
// src with immediate style data doesn't add up
// XXX what does nav do?
// Use the SRC attribute value to open an accumulating stream
nsAutoString absURL;
nsIURL* docURL = mDocument->GetDocumentURL();
rv = NS_MakeAbsoluteURL(docURL, mBaseHREF, src, absURL);
nsIURLGroup* urlGroup = mDocumentURL->GetURLGroup();
rv = NS_MakeAbsoluteURL(mDocumentURL, mBaseHREF, src, absURL);
if (NS_OK != rv) {
return rv;
}
NS_RELEASE(docURL);
rv = NS_NewURL(&url, nsnull, absURL);
if (urlGroup) {
rv = urlGroup->CreateURL(&url, nsnull, absURL, nsnull);
NS_RELEASE(urlGroup);
}
else {
rv = NS_NewURL(&url, nsnull, absURL);
}
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 */
}
rv = NS_NewConverterStream(&uin, nsnull, iin);
NS_RELEASE(iin);
if (NS_OK != rv) {
NS_RELEASE(url);
return rv;
nsAsyncStyleProcessingData* d = new nsAsyncStyleProcessingData;
if (nsnull == d) {
return NS_ERROR_OUT_OF_MEMORY;
}
d->mTitle.SetString(title);
d->mMedia.SetString(media);
d->mIsActive = PR_TRUE;
d->mURL = url;
NS_ADDREF(url);
d->mElement = element;
NS_ADDREF(element);
d->mSink = this;
NS_ADDREF(this);
nsAccumulatingURLLoader* loader =
new nsAccumulatingURLLoader(url,
(nsAccumulationDoneFunc)nsDoneLoadingStyle,
(void *)d);
NS_RELEASE(url);
rv = NS_ERROR_HTMLPARSER_BLOCK;
}
// Now that we have a url and a unicode input stream, parse the
// style sheet.
rv = LoadStyleSheet(url, uin, PR_TRUE, title, media, element);
NS_RELEASE(element);
NS_RELEASE(uin);
NS_RELEASE(url);
return rv;
}
@ -2601,3 +2742,103 @@ HTMLContentSink::NotifyError(nsresult aErrorResult)
PR_ASSERT(0);
return NS_OK;
}
//----------------------------------------------------------------------
nsAccumulatingURLLoader::nsAccumulatingURLLoader(nsIURL* aURL,
nsAccumulationDoneFunc aFunc,
void* aRef)
{
mFunc = aFunc;
mRef = aRef;
mData = new nsString();
nsresult rv;
if (aURL) {
rv = aURL->Open(this);
if ((NS_OK != rv) && (nsnull != mFunc)) {
(*mFunc)(this, *mData, mRef, rv);
}
}
}
nsAccumulatingURLLoader::~nsAccumulatingURLLoader()
{
if (nsnull != mData) {
delete mData;
}
}
NS_IMPL_ISUPPORTS(nsAccumulatingURLLoader, kIStreamListenerIID)
NS_IMETHODIMP
nsAccumulatingURLLoader::OnStartBinding(nsIURL* aURL,
const char *aContentType)
{
// XXX Should check content type?
return NS_OK;
}
NS_IMETHODIMP
nsAccumulatingURLLoader::OnProgress(nsIURL* aURL,
PRInt32 aProgress,
PRInt32 aProgressMax)
{
return NS_OK;
}
NS_IMETHODIMP
nsAccumulatingURLLoader::OnStatus(nsIURL* aURL, const nsString &aMsg)
{
return NS_OK;
}
NS_IMETHODIMP
nsAccumulatingURLLoader::OnStopBinding(nsIURL* aURL,
PRInt32 aStatus,
const nsString &aMsg)
{
(*mFunc)(this, *mData, mRef, aStatus);
return NS_OK;
}
NS_IMETHODIMP
nsAccumulatingURLLoader::GetBindInfo(nsIURL* aURL)
{
return NS_OK;
}
#define BUF_SIZE 1024
NS_IMETHODIMP
nsAccumulatingURLLoader::OnDataAvailable(nsIURL* aURL,
nsIInputStream *aIStream,
PRInt32 aLength)
{
nsresult rv = NS_OK;
char buffer[BUF_SIZE];
PRInt32 len, lenRead;
aIStream->GetLength(&len);
while (len > 0) {
if (len < BUF_SIZE) {
lenRead = len;
}
else {
lenRead = BUF_SIZE;
}
rv = aIStream->Read(buffer, 0, lenRead, &lenRead);
if (NS_OK != rv) {
return rv;
}
mData->Append(buffer, lenRead);
len -= lenRead;
}
return rv;
}

Просмотреть файл

@ -1126,14 +1126,17 @@ nsXMLContentSink::EvaluateScript(nsString& aScript, PRUint32 aLineNo)
return rv;
}
jsval val;
nsIURL* mDocURL = mDocument->GetDocumentURL();
const char* mURL;
if (mDocURL) {
mURL = mDocURL->GetSpec();
}
PRBool result = context->EvaluateString(aScript, mURL, aLineNo, &val);
nsAutoString val;
PRBool isUndefined;
PRBool result = context->EvaluateString(aScript, mURL, aLineNo,
val, &isUndefined);
NS_IF_RELEASE(mDocURL);

Просмотреть файл

@ -866,7 +866,7 @@ nsresult CNavDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsI
* 2) close the top container, and add this to
* whatever container ends up on top.
*
* @update gess 3/25/98
* @update vidur 11/14/98
* @param aToken -- next (start) token to be handled
* @param aNode -- CParserNode representing this start token
* @return PR_TRUE if all went well; PR_FALSE if error occured
@ -915,8 +915,19 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
CollectSkippedContent(attrNode,theCount);
if(NS_OK==result) {
result=AddLeaf(attrNode);
if(NS_OK==result)
result=CloseHead(attrNode);
// XXX If the return value tells us to block, go
// ahead and close the tag out anyway, since its
// contents will be consumed.
if (NS_SUCCEEDED(result)) {
nsresult rv = CloseHead(attrNode);
// XXX Only send along a failure. If the close
// succeeded we still may need to indicate that the
// parser has blocked (i.e. return the result of
// the AddLeaf.
if (rv != NS_OK) {
result = rv;
}
}
}
}
}
@ -2948,7 +2959,7 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode& aNode){
* Call this method ONLY when you want to write a leaf
* into the head container.
*
* @update gess4/6/98
* @update vidur 11/14/98
* @param aNode -- next node to be added to model
* @return error code; 0 means OK
*/
@ -2966,8 +2977,18 @@ nsresult CNavDTD::AddHeadLeaf(const nsIParserNode& aNode){
nsresult result=OpenHead(aNode);
if(NS_OK==result) {
result=AddLeaf(aNode);
if(NS_OK==result) {
result=CloseHead(aNode);
// XXX If the return value tells us to block, go
// ahead and close the tag out anyway, since its
// contents will be consumed.
if (NS_SUCCEEDED(result)) {
nsresult rv = CloseHead(aNode);
// XXX Only send along a failure. If the close
// succeeded we still may need to indicate that the
// parser has blocked (i.e. return the result of
// the AddLeaf.
if (rv != NS_OK) {
result = rv;
}
}
}
return result;

Просмотреть файл

@ -40,6 +40,7 @@ class nsIParser;
#define NS_ICONTENT_SINK_IID \
{ 0xa6cf9052, 0x15b3, 0x11d2,{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
class nsIContentSink : public nsISupports {
public:
/**

Просмотреть файл

@ -43,6 +43,8 @@
/**
* Return codes for parsing routines.
* @update vidur 12/11/98
*
* NS_ERROR_HTMLPARSER_BLOCK indicates that the parser should
* block further parsing until it gets a Unblock() method call.
* NS_ERROR_HTMLPARSER_CONTINUE indicates that the parser should

Просмотреть файл

@ -182,7 +182,7 @@ MakeConversionTable()
/**
* default constructor
*
* @update gess 3/25/98
* @update vidur 12/11/98
* @param
* @return
*/
@ -569,20 +569,42 @@ CParserContext* nsParser::PopContext() {
* and tokenize input (TRUE), or whether it just caches input to be
* parsed later (FALSE).
*
* @update gess 9/1/98
* @update vidur 12/11/98
* @param aState determines whether we parse/tokenize or just cache.
* @return current state
*/
PRBool nsParser::EnableParser(PRBool aState){
nsIParser* me = nsnull;
// If the stream has already finished, there's a good chance
// that we might start closing things down when the parser
// is reenabled. To make sure that we're not deleted across
// the reenabling process, hold a reference to ourselves.
if (eOnStop == mStreamListenerState) {
me = this;
NS_ADDREF(me);
}
// If we're reenabling the parser
if ((PR_FALSE == mParserEnabled) && aState) {
mParserEnabled = PR_TRUE;
ResumeParse();
if (eOnStop == mStreamListenerState) {
// If the stream has already closed, finish out the parsing
// process. Note if the parser was disabled when we resumed
// parsing, then we have to wait till its reenabled before
// finishing.
if ((eOnStop == mStreamListenerState) && mParserEnabled) {
DidBuildModel(mStreamStatus);
}
}
mParserEnabled=aState;
return mParserEnabled;
else {
mParserEnabled=aState;
}
// Release reference if we added one at the top of this routine
NS_IF_RELEASE(me);
return aState;
}
@ -615,7 +637,7 @@ PRInt32 nsParser::Parse(nsIURL* aURL,nsIStreamObserver* aListener,PRBool aVerify
/**
* Cause parser to parse input from given stream
* @update gess5/11/98
* @update vidur 12/11/98
* @param aStream is the i/o source
* @return error code -- 0 if ok, non-zero if error.
*/
@ -698,12 +720,12 @@ PRInt32 nsParser::ResumeParse() {
buildResult=BuildModel();
if(kInterrupted==result)
mParserContext->mDTD->WillInterruptParse();
// If we're told to block the parser, we disable
// all further parsing (and cache any data coming
// in) until the parser is enabled.
if(NS_ERROR_HTMLPARSER_BLOCK==buildResult) {
mParserEnabled=PR_FALSE;
}
// If we're told to block the parser, we disable
// all further parsing (and cache any data coming
// in) until the parser is enabled.
if(NS_ERROR_HTMLPARSER_BLOCK==buildResult) {
EnableParser(PR_FALSE);
}
}
return result;
}
@ -881,7 +903,7 @@ nsresult nsParser::OnStartBinding(nsIURL* aURL, const char *aSourceType){
/**
*
*
* @update gess 5/12/98
* @update vidur 12/11/98
* @param pIStream contains the input chars
* @param length is the number of bytes waiting input
* @return error code (usually 0)
@ -953,7 +975,7 @@ nsresult nsParser::OnDataAvailable(nsIURL* aURL, nsIInputStream *pIStream, PRInt
/**
*
*
* @update gess 5/12/98
* @update vidur 12/11/98
* @param
* @return
*/

Просмотреть файл

@ -881,48 +881,26 @@ void JSConsole::EvaluateText(UINT aStartSel, UINT aEndSel)
LPSTR cleanBuffer = ::NormalizeBuffer(buffer);
// evaluate the string
jsval returnValue;
nsAutoString returnValue;
PRBool isUndefined;
if (mContext->EvaluateString(nsString(cleanBuffer),
nsnull,
0,
&returnValue)) {
returnValue,
&isUndefined)) {
// output the result on the console and on the edit area
CHAR result[128];
LPSTR res = result;
int bDelete = 0;
JSContext *cx = (JSContext *)mContext->GetNativeContext();
JSString *jsstring = JS_ValueToString(cx, returnValue);
char *str = JS_GetStringBytes(jsstring);
char *str = returnValue.ToNewCString();
::printf("The return value is ");
if (JSVAL_IS_OBJECT(returnValue)) {
::printf("an object\n");
}
else if (JSVAL_IS_INT(returnValue)) {
::printf("an int [%d]\n", JSVAL_TO_INT(returnValue));
}
else if (JSVAL_IS_DOUBLE(returnValue)) {
::printf("a double [%f]\n", *JSVAL_TO_DOUBLE(returnValue));
}
else if (JSVAL_IS_STRING(returnValue)) {
::printf("a string [%s]\n", JS_GetStringBytes(JSVAL_TO_STRING(returnValue)));
}
else if (JSVAL_IS_BOOLEAN(returnValue)) {
::printf("a boolean [%d]\n", JSVAL_TO_BOOLEAN(returnValue));
}
else if (JSVAL_IS_NULL(returnValue)) {
printf("null\n");
}
else if (JSVAL_IS_VOID(returnValue)) {
printf("void\n");
}
else {
printf("error: unknow return type!\n");
}
::printf("The return value is %s\n", str);
// make a string with 0xA changed to 0xD0xA
res = PrepareForTextArea(str, JS_GetStringLength(jsstring));
res = PrepareForTextArea(str, returnValue.Length());
if (res != str) {
bDelete = 1; // if the buffer was new'ed
}
@ -938,6 +916,7 @@ void JSConsole::EvaluateText(UINT aStartSel, UINT aEndSel)
if (bDelete > 0) {
delete[] res;
}
delete[] str;
// clean up a bit
JS_GC((JSContext *)mContext->GetNativeContext());

Просмотреть файл

@ -52,14 +52,14 @@ typedef PRUint32 nsresult;
* each module.
*/
#define NS_ERROR_MODULE_XPCOM 1
#define NS_ERROR_MODULE_BASE 2
#define NS_ERROR_MODULE_GFX 3
#define NS_ERROR_MODULE_WIDGET 4
#define NS_ERROR_MODULE_CALENDAR 5
#define NS_ERROR_MODULE_NETWORK 6
#define NS_ERROR_MODULE_PLUGINS 7
#define NS_ERROR_MODULE_LAYOUT 8
#define NS_ERROR_MODULE_XPCOM 1
#define NS_ERROR_MODULE_BASE 2
#define NS_ERROR_MODULE_GFX 3
#define NS_ERROR_MODULE_WIDGET 4
#define NS_ERROR_MODULE_CALENDAR 5
#define NS_ERROR_MODULE_NETWORK 6
#define NS_ERROR_MODULE_PLUGINS 7
#define NS_ERROR_MODULE_LAYOUT 8
#define NS_ERROR_MODULE_HTMLPARSER 9
/**

Просмотреть файл

@ -52,14 +52,14 @@ typedef PRUint32 nsresult;
* each module.
*/
#define NS_ERROR_MODULE_XPCOM 1
#define NS_ERROR_MODULE_BASE 2
#define NS_ERROR_MODULE_GFX 3
#define NS_ERROR_MODULE_WIDGET 4
#define NS_ERROR_MODULE_CALENDAR 5
#define NS_ERROR_MODULE_NETWORK 6
#define NS_ERROR_MODULE_PLUGINS 7
#define NS_ERROR_MODULE_LAYOUT 8
#define NS_ERROR_MODULE_XPCOM 1
#define NS_ERROR_MODULE_BASE 2
#define NS_ERROR_MODULE_GFX 3
#define NS_ERROR_MODULE_WIDGET 4
#define NS_ERROR_MODULE_CALENDAR 5
#define NS_ERROR_MODULE_NETWORK 6
#define NS_ERROR_MODULE_PLUGINS 7
#define NS_ERROR_MODULE_LAYOUT 8
#define NS_ERROR_MODULE_HTMLPARSER 9
/**

Просмотреть файл

@ -886,44 +886,20 @@ void JSConsole::EvaluateText(UINT aStartSel, UINT aEndSel)
if (mContext->EvaluateString(nsString(cleanBuffer),
nsnull,
0,
&returnValue)) {
returnValue,
&isUndefined)) {
// output the result on the console and on the edit area
CHAR result[128];
LPSTR res = result;
int bDelete = 0;
JSContext *cx = (JSContext *)mContext->GetNativeContext();
JSString *jsstring = JS_ValueToString(cx, returnValue);
char *str = JS_GetStringBytes(jsstring);
char *str = returnValue.ToNewCString();
::printf("The return value is ");
if (JSVAL_IS_OBJECT(returnValue)) {
::printf("an object\n");
}
else if (JSVAL_IS_INT(returnValue)) {
::printf("an int [%d]\n", JSVAL_TO_INT(returnValue));
}
else if (JSVAL_IS_DOUBLE(returnValue)) {
::printf("a double [%f]\n", *JSVAL_TO_DOUBLE(returnValue));
}
else if (JSVAL_IS_STRING(returnValue)) {
::printf("a string [%s]\n", JS_GetStringBytes(JSVAL_TO_STRING(returnValue)));
}
else if (JSVAL_IS_BOOLEAN(returnValue)) {
::printf("a boolean [%d]\n", JSVAL_TO_BOOLEAN(returnValue));
}
else if (JSVAL_IS_NULL(returnValue)) {
printf("null\n");
}
else if (JSVAL_IS_VOID(returnValue)) {
printf("void\n");
}
else {
printf("error: unknow return type!\n");
}
::printf("The return value is %s\n", str);
// make a string with 0xA changed to 0xD0xA
res = PrepareForTextArea(str, JS_GetStringLength(jsstring));
res = PrepareForTextArea(str, returnValue.Length());
if (res != str) {
bDelete = 1; // if the buffer was new'ed
}
@ -939,6 +915,7 @@ void JSConsole::EvaluateText(UINT aStartSel, UINT aEndSel)
if (bDelete > 0) {
delete[] res;
}
delete[] str;
// clean up a bit
JS_GC((JSContext *)mContext->GetNativeContext());

Просмотреть файл

@ -417,7 +417,8 @@ HandleBrowserEvent(nsGUIEvent *aEvent)
void nsBrowserWindow::ExecuteJavaScriptString(nsIWebShell* aWebShell, nsString& aJavaScript)
{
jsval retval;
nsAutoString retval;
PRBool isUndefined;
NS_ASSERTION(nsnull != aWebShell, "null webshell passed to EvaluateJavaScriptString");
// NS_ASSERTION(nsnull != aJavaScript, "null javascript string passed to EvaluateJavaScriptString");
@ -433,7 +434,7 @@ void nsBrowserWindow::ExecuteJavaScriptString(nsIWebShell* aWebShell, nsString&
if (NS_OK == res) {
// Ask the script context to evalute the javascript string
scriptContext->EvaluateString(aJavaScript,
url, 0, &retval);
url, 0, retval, &isUndefined);
NS_RELEASE(scriptContext);
}