Bug 537683 - No longer break out of doc update batch upon nsIParser::Terminate() in the HTML5 parser. r=bnewman.

This commit is contained in:
Henri Sivonen 2010-01-05 14:37:05 +02:00
Родитель 3ea6664b1d
Коммит 1598b5d14d
2 изменённых файлов: 15 добавлений и 24 удалений

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

@ -104,13 +104,16 @@ nsHtml5TreeOpExecutor::DidBuildModel(PRBool aTerminated)
{ {
NS_PRECONDITION(mStarted, "Bad life cycle."); NS_PRECONDITION(mStarted, "Bad life cycle.");
// Break out of update batch if we are in one if (!aTerminated) {
EndDocUpdate(); // Break out of update batch if we are in one
// and aren't forcibly terminating
// If the above caused a call to nsIParser::Terminate(), let that call EndDocUpdate();
// win.
if (!mParser) { // If the above caused a call to nsIParser::Terminate(), let that call
return NS_OK; // win.
if (!mParser) {
return NS_OK;
}
} }
static_cast<nsHtml5Parser*> (mParser.get())->DropStreamParser(); static_cast<nsHtml5Parser*> (mParser.get())->DropStreamParser();
@ -270,6 +273,7 @@ void
nsHtml5TreeOpExecutor::Flush() nsHtml5TreeOpExecutor::Flush()
{ {
if (!mParser) { if (!mParser) {
mOpQueue.Clear(); // clear in order to be able to assert in destructor
return; return;
} }
if (mFlushState != eNotFlushing) { if (mFlushState != eNotFlushing) {

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

@ -228,13 +228,11 @@ class nsHtml5TreeOpExecutor : public nsContentSink,
} }
inline void EndDocUpdate() { inline void EndDocUpdate() {
if (mFlushState >= eInDocUpdate) { NS_PRECONDITION(mFlushState != eNotifying, "mFlushState out of sync");
if (mFlushState == eInDocUpdate) {
FlushPendingAppendNotifications(); FlushPendingAppendNotifications();
if (NS_UNLIKELY(!mParser)) {
return;
}
mDocument->EndUpdate(UPDATE_CONTENT_MODEL);
mFlushState = eInFlush; mFlushState = eInFlush;
mDocument->EndUpdate(UPDATE_CONTENT_MODEL);
} }
} }
@ -264,23 +262,11 @@ class nsHtml5TreeOpExecutor : public nsContentSink,
} }
void FlushPendingAppendNotifications() { 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"); NS_PRECONDITION(mFlushState == eInDocUpdate, "Notifications flushed outside update");
mFlushState = eNotifying; mFlushState = eNotifying;
const nsHtml5PendingNotification* start = mPendingNotifications.Elements(); const nsHtml5PendingNotification* start = mPendingNotifications.Elements();
const nsHtml5PendingNotification* end = start + mPendingNotifications.Length(); const nsHtml5PendingNotification* end = start + mPendingNotifications.Length();
for (nsHtml5PendingNotification* iter = (nsHtml5PendingNotification*)start; iter < end; ++iter) { 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(); iter->Fire();
} }
mPendingNotifications.Clear(); mPendingNotifications.Clear();
@ -290,6 +276,7 @@ class nsHtml5TreeOpExecutor : public nsContentSink,
} }
#endif #endif
mElementsSeenInThisAppendBatch.Clear(); mElementsSeenInThisAppendBatch.Clear();
NS_ASSERTION(mFlushState == eNotifying, "mFlushState out of sync");
mFlushState = eInDocUpdate; mFlushState = eInDocUpdate;
} }