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:
Родитель
70565eed68
Коммит
26caa52944
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче