Bug 483818: Remove the currently-running-script counter from the parser since it's hard to keep it correct when we're creating a new parser due to document.write etc. r/sr=mrbkap

This commit is contained in:
Jonas Sicking 2009-04-15 15:34:50 -07:00
Родитель 70565eed68
Коммит 26caa52944
11 изменённых файлов: 59 добавлений и 57 удалений

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

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<script>
function appendScript(doc) {
var s = doc.createElement("script");
s.textContent = "document.write('executed'); document.close()";
doc.body.appendChild(s);
}
</script>
</head>
<body onload="appendScript(window.document)">
</body>
</html>

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

@ -40,3 +40,4 @@ load 426987-1.html
skip load 458637-1.html # sporadically fails -- see bug 473680
load 472593-1.html
load 474041-1.svg
load 483818-1.html

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

@ -350,10 +350,6 @@ nsContentSink::ScriptAvailable(nsresult aResult,
PRInt32 aLineNo)
{
PRUint32 count = mScriptElements.Count();
if (mParser && NS_SUCCEEDED(aResult)) {
// Only notify the parser about scripts that are actually going to run.
mParser->ScriptExecuting();
}
// aElement will not be in mScriptElements if a <script> was added
// using the DOM during loading, or if the script was inline and thus
@ -407,10 +403,6 @@ nsContentSink::ScriptEvaluated(nsresult aResult,
nsIScriptElement *aElement,
PRBool aIsInline)
{
if (mParser) {
mParser->ScriptDidExecute();
}
// Check if this is the element we were waiting for
PRInt32 count = mScriptElements.Count();
if (count == 0 || aElement != mScriptElements[count - 1]) {
@ -1736,6 +1728,12 @@ nsContentSink::DropParserAndPerfHint(void)
}
}
PRBool
nsContentSink::IsScriptExecutingImpl()
{
return !!mScriptLoader->GetCurrentScript();
}
nsresult
nsContentSink::WillParseImpl(void)
{

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

@ -136,6 +136,7 @@ class nsContentSink : public nsICSSLoaderObserver,
NS_HIDDEN_(void) DidBuildModelImpl(void);
NS_HIDDEN_(PRBool) ReadyToCallDidBuildModelImpl(PRBool aTerminated);
NS_HIDDEN_(void) DropParserAndPerfHint(void);
PRBool IsScriptExecutingImpl();
void NotifyAppend(nsIContent* aContent, PRUint32 aStartIndex);

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

@ -191,6 +191,7 @@ public:
virtual void FlushPendingNotifications(mozFlushType aType);
NS_IMETHOD SetDocumentCharset(nsACString& aCharset);
virtual nsISupports *GetTarget();
virtual PRBool IsScriptExecuting();
// nsIHTMLContentSink
NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
@ -3272,6 +3273,12 @@ HTMLContentSink::GetTarget()
return mDocument;
}
PRBool
HTMLContentSink::IsScriptExecuting()
{
return IsScriptExecutingImpl();
}
#ifdef DEBUG
/**
* This will dump content model into the output file.

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

@ -843,6 +843,12 @@ nsXMLContentSink::GetTarget()
return mDocument;
}
PRBool
nsXMLContentSink::IsScriptExecuting()
{
return IsScriptExecutingImpl();
}
nsresult
nsXMLContentSink::FlushText(PRBool aReleaseTextNode)
{

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

@ -100,6 +100,7 @@ public:
virtual void FlushPendingNotifications(mozFlushType aType);
NS_IMETHOD SetDocumentCharset(nsACString& aCharset);
virtual nsISupports *GetTarget();
virtual PRBool IsScriptExecuting();
// nsITransformObserver
NS_IMETHOD OnDocumentCreated(nsIDocument *aResultDocument);

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

@ -56,8 +56,8 @@
class nsIParser;
#define NS_ICONTENT_SINK_IID \
{ 0xcfa3643b, 0xee60, 0x4bf0, \
{ 0xbc, 0x83, 0x49, 0x95, 0xdb, 0xbc, 0xda, 0x75 } }
{ 0x6fd3c94f, 0xaf81, 0x4792, \
{ 0xa3, 0xe4, 0x1f, 0xb9, 0x40, 0xb6, 0x9c, 0x3a } }
class nsIContentSink : public nsISupports {
public:
@ -144,6 +144,16 @@ public:
* (IOW, may return null).
*/
virtual nsISupports *GetTarget()=0;
/**
* Returns true if there's currently script executing that we need to hold
* parsing for.
*/
virtual PRBool IsScriptExecuting()
{
return PR_FALSE;
}
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentSink, NS_ICONTENT_SINK_IID)

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

@ -53,10 +53,11 @@
#include "nsStringGlue.h"
#include "nsTArray.h"
// 3007e9c0-4d3e-4c80-8cae-fbb4723d88f2
// 506527cc-d832-420b-ba3a-80c05aa105f4
#define NS_IPARSER_IID \
{ 0x3007e9c0, 0x4d3e, 0x4c80, \
{ 0x8c, 0xae, 0xfb, 0xb4, 0x72, 0x3d, 0x88, 0xf2 } }
{ 0x506527cc, 0xd832, 0x420b, \
{ 0xba, 0x3a, 0x80, 0xc0, 0x5a, 0xa1, 0x05, 0xf4 } }
// {41421C60-310A-11d4-816F-000064657374}
#define NS_IDEBUG_DUMP_CONTENT_IID \
@ -287,19 +288,6 @@ class nsIParser : public nsISupports {
NS_IMETHOD CancelParsingEvents() = 0;
virtual void Reset() = 0;
/**
* Tells the parser that a script is now executing. The only data we
* should resume parsing for is document.written data. We'll deal with any
* data that comes in over the network later.
*/
virtual void ScriptExecuting() = 0;
/**
* Tells the parser that the script is done executing. We should now
* continue the regular parsing process.
*/
virtual void ScriptDidExecute() = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIParser, NS_IPARSER_IID)

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

@ -817,7 +817,6 @@ nsParser::Initialize(PRBool aConstructor)
mFlags = NS_PARSER_FLAG_OBSERVERS_ENABLED |
NS_PARSER_FLAG_PARSER_ENABLED |
NS_PARSER_FLAG_CAN_TOKENIZE;
mScriptsExecuting = 0;
MOZ_TIMER_DEBUGLOG(("Reset: Parse Time: nsParser::nsParser(), this=%p\n", this));
MOZ_TIMER_RESET(mParseTime);
@ -1720,7 +1719,7 @@ nsParser::ContinueInterruptedParsing()
// If there are scripts executing, then the content sink is jumping the gun
// (probably due to a synchronous XMLHttpRequest) and will re-enable us
// later, see bug 460706.
if (mScriptsExecuting) {
if (IsScriptExecuting()) {
return NS_OK;
}
@ -1814,23 +1813,10 @@ void nsParser::HandleParserContinueEvent(nsParserContinueEvent *ev)
mFlags &= ~NS_PARSER_FLAG_PENDING_CONTINUE_EVENT;
mContinueEvent = nsnull;
NS_ASSERTION(mScriptsExecuting == 0, "Interrupted in the middle of a script?");
NS_ASSERTION(!IsScriptExecuting(), "Interrupted in the middle of a script?");
ContinueInterruptedParsing();
}
void
nsParser::ScriptExecuting()
{
++mScriptsExecuting;
}
void
nsParser::ScriptDidExecute()
{
NS_ASSERTION(mScriptsExecuting > 0, "Too many calls to ScriptDidExecute");
--mScriptsExecuting;
}
nsresult
nsParser::DataAdded(const nsSubstring& aData, nsIRequest *aRequest)
{
@ -2896,7 +2882,7 @@ nsParser::OnDataAvailable(nsIRequest *request, nsISupports* aContext,
// Don't bother to start parsing until we've seen some
// non-whitespace data
if (mScriptsExecuting == 0 &&
if (!IsScriptExecuting() &&
theContext->mScanner->FirstNonWhitespacePosition() >= 0) {
if (mSink) {
mSink->WillParse();
@ -2940,7 +2926,7 @@ nsParser::OnStopRequest(nsIRequest *request, nsISupports* aContext,
if (mParserFilter)
mParserFilter->Finish();
if (mScriptsExecuting == 0 && NS_SUCCEEDED(rv)) {
if (!IsScriptExecuting() && NS_SUCCEEDED(rv)) {
if (mSink) {
mSink->WillParse();
}

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

@ -389,18 +389,9 @@ class nsParser : public nsIParser,
return sSpeculativeThreadPool;
}
/**
* Tells the parser that a script is now executing. The only data we
* should resume parsing for is document.written data. We'll deal with any
* data that comes in over the network later.
*/
virtual void ScriptExecuting();
/**
* Tells the parser that the script is done executing. We should now
* continue the regular parsing process.
*/
virtual void ScriptDidExecute();
PRBool IsScriptExecuting() {
return mSink && mSink->IsScriptExecuting();
}
protected:
@ -486,7 +477,6 @@ protected:
PRInt32 mCharsetSource;
PRUint16 mFlags;
PRUint32 mScriptsExecuting;
nsString mUnusedInput;
nsCString mCharset;