зеркало из https://github.com/mozilla/gecko-dev.git
Make sure to flush out the content model before processing restyles; otherwise
we can end up with odd content duplication. Bug 309986, r+sr=dbaron
This commit is contained in:
Родитель
04db0be1a4
Коммит
bdd0e13912
|
@ -3977,10 +3977,20 @@ HTMLContentSink::BeginUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType)
|
|||
// notification to occur. Since this could result in frame
|
||||
// creation, make sure we've flushed everything before we
|
||||
// continue.
|
||||
// Also increment mInNotification to make sure we don't flush again
|
||||
// until the end of this update, even if nested updates or
|
||||
|
||||
// Note that UPDATE_CONTENT_STATE notifications never cause
|
||||
// synchronous frame construction, so we never have to worry about
|
||||
// them here. The code that handles the async event these
|
||||
// notifications post will flush us out if it needs to.
|
||||
|
||||
// Also, if this is not an UPDATE_CONTENT_STATE notification,
|
||||
// increment mInNotification to make sure we don't flush again until
|
||||
// the end of this update, even if nested updates or
|
||||
// FlushPendingNotifications calls happen during it.
|
||||
if (!mInNotification++ && mCurrentContext) {
|
||||
NS_ASSERTION(aUpdateType && (aUpdateType & UPDATE_ALL) == aUpdateType,
|
||||
"Weird update type bitmask");
|
||||
if (aUpdateType != UPDATE_CONTENT_STATE && !mInNotification++ &&
|
||||
mCurrentContext) {
|
||||
mCurrentContext->FlushTags(PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
@ -3992,8 +4002,13 @@ HTMLContentSink::EndUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType)
|
|||
// something else in the script processing caused the
|
||||
// notification to occur. Update our notion of how much
|
||||
// has been flushed to include any new content if ending
|
||||
// this update leaves us not inside a notification.
|
||||
if (!--mInNotification) {
|
||||
// this update leaves us not inside a notification. Note that we
|
||||
// exclude UPDATE_CONTENT_STATE notifications here, since those
|
||||
// never affect the frame model directly while inside the
|
||||
// notification.
|
||||
NS_ASSERTION(aUpdateType && (aUpdateType & UPDATE_ALL) == aUpdateType,
|
||||
"Weird update type bitmask");
|
||||
if (aUpdateType != UPDATE_CONTENT_STATE && !--mInNotification) {
|
||||
UpdateAllContexts();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10425,16 +10425,19 @@ nsCSSFrameConstructor::DoContentStateChanged(nsIContent* aContent,
|
|||
NS_ASSERTION(styleSet, "couldn't get style set");
|
||||
|
||||
if (aContent) {
|
||||
nsChangeHint hint;
|
||||
if (aStateMask & (NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_USERDISABLED |
|
||||
NS_EVENT_STATE_SUPPRESSED)) {
|
||||
// Any change to a content state that affects which frames we
|
||||
// construct must lead to a frame reconstruct here
|
||||
hint = nsChangeHint_ReconstructFrame;
|
||||
} else {
|
||||
hint = NS_STYLE_HINT_NONE;
|
||||
nsIFrame* primaryFrame = mPresShell->GetPrimaryFrameFor(aContent);
|
||||
if (primaryFrame) {
|
||||
nsChangeHint hint = NS_STYLE_HINT_NONE;
|
||||
// Any change to a content state that affects which frames we construct
|
||||
// must lead to a frame reconstruct here if we already have a frame.
|
||||
// Note that we never decide through non-CSS means to not create frames
|
||||
// based on content states, so if we already don't have a frame we don't
|
||||
// need to force a reframe -- if it's needed, the HasStateDependentStyle
|
||||
// call will handle things.
|
||||
nsIFrame* primaryFrame = mPresShell->GetPrimaryFrameFor(aContent);
|
||||
if (primaryFrame) {
|
||||
if (aStateMask & (NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_USERDISABLED |
|
||||
NS_EVENT_STATE_SUPPRESSED)) {
|
||||
hint = nsChangeHint_ReconstructFrame;
|
||||
} else {
|
||||
PRUint8 app = primaryFrame->GetStyleDisplay()->mAppearance;
|
||||
if (app) {
|
||||
nsITheme *theme = presContext->GetTheme();
|
||||
|
@ -13253,7 +13256,16 @@ void nsCSSFrameConstructor::RestyleEvent::HandleEvent() {
|
|||
NS_ASSERTION(viewManager, "Must have view manager for update");
|
||||
|
||||
viewManager->BeginUpdateViewBatch();
|
||||
// Force flushing of any pending content notifications that might have queued
|
||||
// up while our event was pending. That will ensure that we don't construct
|
||||
// frames for content right now that's still waiting to be notified on,
|
||||
constructor->mPresShell->GetDocument()->
|
||||
FlushPendingNotifications(Flush_ContentAndNotify);
|
||||
|
||||
// Make sure that any restyles that happen from now on will go into
|
||||
// a new event.
|
||||
constructor->mRestyleEventQueue = nsnull;
|
||||
|
||||
constructor->ProcessPendingRestyles();
|
||||
viewManager->EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче