From 1598b5d14da63ab3345c23a74458e72d41d8460c Mon Sep 17 00:00:00 2001 From: Henri Sivonen Date: Tue, 5 Jan 2010 14:37:05 +0200 Subject: [PATCH] Bug 537683 - No longer break out of doc update batch upon nsIParser::Terminate() in the HTML5 parser. r=bnewman. --- parser/html/nsHtml5TreeOpExecutor.cpp | 18 +++++++++++------- parser/html/nsHtml5TreeOpExecutor.h | 21 ++++----------------- 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/parser/html/nsHtml5TreeOpExecutor.cpp b/parser/html/nsHtml5TreeOpExecutor.cpp index fb59e579ec43..bd9bbfabfacb 100644 --- a/parser/html/nsHtml5TreeOpExecutor.cpp +++ b/parser/html/nsHtml5TreeOpExecutor.cpp @@ -104,13 +104,16 @@ nsHtml5TreeOpExecutor::DidBuildModel(PRBool aTerminated) { NS_PRECONDITION(mStarted, "Bad life cycle."); - // Break out of update batch if we are in one - EndDocUpdate(); - - // If the above caused a call to nsIParser::Terminate(), let that call - // win. - if (!mParser) { - return NS_OK; + if (!aTerminated) { + // Break out of update batch if we are in one + // and aren't forcibly terminating + EndDocUpdate(); + + // If the above caused a call to nsIParser::Terminate(), let that call + // win. + if (!mParser) { + return NS_OK; + } } static_cast (mParser.get())->DropStreamParser(); @@ -270,6 +273,7 @@ void nsHtml5TreeOpExecutor::Flush() { if (!mParser) { + mOpQueue.Clear(); // clear in order to be able to assert in destructor return; } if (mFlushState != eNotFlushing) { diff --git a/parser/html/nsHtml5TreeOpExecutor.h b/parser/html/nsHtml5TreeOpExecutor.h index d0987c66c08d..3d7ca0cd3edc 100644 --- a/parser/html/nsHtml5TreeOpExecutor.h +++ b/parser/html/nsHtml5TreeOpExecutor.h @@ -228,13 +228,11 @@ class nsHtml5TreeOpExecutor : public nsContentSink, } inline void EndDocUpdate() { - if (mFlushState >= eInDocUpdate) { + NS_PRECONDITION(mFlushState != eNotifying, "mFlushState out of sync"); + if (mFlushState == eInDocUpdate) { FlushPendingAppendNotifications(); - if (NS_UNLIKELY(!mParser)) { - return; - } - mDocument->EndUpdate(UPDATE_CONTENT_MODEL); mFlushState = eInFlush; + mDocument->EndUpdate(UPDATE_CONTENT_MODEL); } } @@ -264,23 +262,11 @@ class nsHtml5TreeOpExecutor : public nsContentSink, } void FlushPendingAppendNotifications() { - if (NS_UNLIKELY(mFlushState == eNotifying)) { - // nsIParser::Terminate() was called in response to iter->Fire below - // earlier in the call stack. - return; - } NS_PRECONDITION(mFlushState == eInDocUpdate, "Notifications flushed outside update"); mFlushState = eNotifying; const nsHtml5PendingNotification* start = mPendingNotifications.Elements(); const nsHtml5PendingNotification* end = start + mPendingNotifications.Length(); for (nsHtml5PendingNotification* iter = (nsHtml5PendingNotification*)start; iter < end; ++iter) { - if (NS_UNLIKELY(!mParser)) { - // nsIParser::Terminate() was called in response to a notification - // this most likely means that the page is being navigated away from - // so just dropping the rest of the notifications on the floor - // instead of doing something fancy. - break; - } iter->Fire(); } mPendingNotifications.Clear(); @@ -290,6 +276,7 @@ class nsHtml5TreeOpExecutor : public nsContentSink, } #endif mElementsSeenInThisAppendBatch.Clear(); + NS_ASSERTION(mFlushState == eNotifying, "mFlushState out of sync"); mFlushState = eInDocUpdate; }