diff --git a/mozilla/content/base/public/mozFlushType.h b/mozilla/content/base/public/mozFlushType.h new file mode 100644 index 00000000000..6dd9207f815 --- /dev/null +++ b/mozilla/content/base/public/mozFlushType.h @@ -0,0 +1,61 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Boris Zbarsky. + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#ifndef mozFlushType_h___ +#define mozFlushType_h___ + +/** + * This is the enum used by nsIDocument::FlushPendingNotifications to + * decide what to flush. + */ +enum mozFlushType { + Flush_Content = 0x1, /* flush the content model construction */ + Flush_SinkNotifications = 0x2, /* flush the frame model construction */ + Flush_StyleReresolves = 0x4, /* flush style reresolution */ + Flush_OnlyReflow = 0x8, /* flush reflows */ + Flush_OnlyPaint = 0x10, /* flush painting */ + Flush_Frames = (Flush_Content | Flush_SinkNotifications), + Flush_ContentAndNotify = (Flush_Content | Flush_SinkNotifications), + Flush_Style = (Flush_Content | Flush_SinkNotifications | + Flush_StyleReresolves), + Flush_Layout = (Flush_Content | Flush_SinkNotifications | + Flush_StyleReresolves | Flush_OnlyReflow), + Flush_Display = (Flush_Content | Flush_SinkNotifications | + Flush_StyleReresolves | Flush_OnlyReflow | + Flush_OnlyPaint) +}; + +#endif /* mozFlushType_h___ */ diff --git a/mozilla/content/base/public/nsIDocument.h b/mozilla/content/base/public/nsIDocument.h index a74be3a851c..0f465ec2ba8 100644 --- a/mozilla/content/base/public/nsIDocument.h +++ b/mozilla/content/base/public/nsIDocument.h @@ -52,6 +52,7 @@ #include "nsILoadGroup.h" #include "nsReadableUtils.h" #include "nsCRT.h" +#include "mozFlushType.h" class nsIAtom; class nsIContent; @@ -510,8 +511,11 @@ public: PRUint32 aFlags, nsEventStatus* aEventStatus) = 0; - virtual void FlushPendingNotifications(PRBool aFlushReflows=PR_TRUE, - PRBool aUpdateViews=PR_FALSE) = 0; + /** + * Flush notifications for this document and its parent documents + * (since those may affect the layout of this one). + */ + virtual void FlushPendingNotifications(mozFlushType aType) = 0; PRInt32 GetAndIncrementContentID() { diff --git a/mozilla/content/base/src/mozSanitizingSerializer.h b/mozilla/content/base/src/mozSanitizingSerializer.h index ef90a276518..b1fea54cf7e 100644 --- a/mozilla/content/base/src/mozSanitizingSerializer.h +++ b/mozilla/content/base/src/mozSanitizingSerializer.h @@ -105,7 +105,7 @@ public: NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode) { return NS_OK; } NS_IMETHOD AddDocTypeDecl(const nsIParserNode& aNode); - NS_IMETHOD FlushPendingNotifications() { return NS_OK; } + virtual void FlushContent(PRBool aNotify) { } NS_IMETHOD SetDocumentCharset(nsACString& aCharset); NS_IMETHOD NotifyTagObservers(nsIParserNode* aNode) { return NS_OK; } diff --git a/mozilla/content/base/src/nsContentList.cpp b/mozilla/content/base/src/nsContentList.cpp index 861e38b3d5a..667e85c9118 100644 --- a/mozilla/content/base/src/nsContentList.cpp +++ b/mozilla/content/base/src/nsContentList.cpp @@ -429,8 +429,8 @@ nsContentList::Item(PRUint32 aIndex, PRBool aDoFlush) CheckDocumentExistence(); if (mDocument && aDoFlush) { - // Flush pending content changes Bug 4891 - mDocument->FlushPendingNotifications(PR_FALSE); + // Flush pending content changes Bug 4891. + mDocument->FlushPendingNotifications(Flush_ContentAndNotify); } if (mState != LIST_UP_TO_DATE) @@ -963,7 +963,8 @@ void nsContentList::BringSelfUpToDate(PRBool aDoFlush) { if (mDocument && aDoFlush) { - mDocument->FlushPendingNotifications(PR_FALSE); // Flush pending content changes Bug 4891 + // Flush pending content changes Bug 4891. + mDocument->FlushPendingNotifications(Flush_ContentAndNotify); } if (mState != LIST_UP_TO_DATE) diff --git a/mozilla/content/base/src/nsContentSink.cpp b/mozilla/content/base/src/nsContentSink.cpp index f26de3e29a1..74672ef89d4 100644 --- a/mozilla/content/base/src/nsContentSink.cpp +++ b/mozilla/content/base/src/nsContentSink.cpp @@ -863,7 +863,7 @@ nsContentSink::ScrollToRef(PRBool aReallyScroll) if (shell) { // Scroll to the anchor if (aReallyScroll) { - shell->FlushPendingNotifications(PR_FALSE); + shell->FlushPendingNotifications(Flush_Layout); } // Check an empty string which might be caused by the UTF-8 conversion diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index 4191ab54dd5..b80abdd4556 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -3906,10 +3906,11 @@ nsDocument::CreateEventGroup(nsIDOMEventGroup **aInstancePtrResult) } void -nsDocument::FlushPendingNotifications(PRBool aFlushReflows, - PRBool aUpdateViews) +nsDocument::FlushPendingNotifications(mozFlushType aType) { - if (!aFlushReflows || !mScriptGlobalObject) { + if (aType == (aType & (Flush_Content | Flush_SinkNotifications)) || + !mScriptGlobalObject) { + // Nothing to do here return; } @@ -3935,8 +3936,7 @@ nsDocument::FlushPendingNotifications(PRBool aFlushReflows, if (doc) { // If we have a parent we must flush the parent too to ensure // that our container is reflown if its size was changed. - - doc->FlushPendingNotifications(aFlushReflows, aUpdateViews); + doc->FlushPendingNotifications(aType); } } } @@ -3948,7 +3948,7 @@ nsDocument::FlushPendingNotifications(PRBool aFlushReflows, NS_STATIC_CAST(nsIPresShell*, mPresShells[i]); if (shell) { - shell->FlushPendingNotifications(aUpdateViews); + shell->FlushPendingNotifications(aType); } } } diff --git a/mozilla/content/base/src/nsDocument.h b/mozilla/content/base/src/nsDocument.h index f666ed24ef4..fc9404d6b09 100644 --- a/mozilla/content/base/src/nsDocument.h +++ b/mozilla/content/base/src/nsDocument.h @@ -397,8 +397,7 @@ public: virtual void StyleRuleRemoved(nsIStyleSheet* aStyleSheet, nsIStyleRule* aStyleRule); - virtual void FlushPendingNotifications(PRBool aFlushReflows = PR_TRUE, - PRBool aUpdateViews = PR_FALSE); + virtual void FlushPendingNotifications(mozFlushType aType); virtual void AddReference(void *aKey, nsISupports *aReference); virtual already_AddRefed RemoveReference(void *aKey); virtual nsIScriptEventManager* GetScriptEventManager(); diff --git a/mozilla/content/base/src/nsDocumentViewer.cpp b/mozilla/content/base/src/nsDocumentViewer.cpp index 87f65f34d8f..049045aaed6 100644 --- a/mozilla/content/base/src/nsDocumentViewer.cpp +++ b/mozilla/content/base/src/nsDocumentViewer.cpp @@ -656,7 +656,7 @@ DocumentViewerImpl::InitPresentationStuff(PRBool aDoInitialReflow) // Note that we are flushing before we add mPresShell as an observer // to avoid bogus notifications. - mDocument->FlushPendingNotifications(PR_FALSE); + mDocument->FlushPendingNotifications(Flush_ContentAndNotify); } mPresShell->BeginObservingDocument(); @@ -935,9 +935,7 @@ DocumentViewerImpl::LoadComplete(nsresult aStatus) static PRBool forcePaint = PR_GetEnv("MOZ_FORCE_PAINT_AFTER_ONLOAD") != nsnull; if (forcePaint) { - if (mPresShell) { - mPresShell->FlushPendingNotifications(PR_TRUE); - } + mDocument->FlushPendingNotifications(Flush_Display); nsIURI *uri = mDocument->GetDocumentURI(); nsCAutoString spec; if (uri) { diff --git a/mozilla/content/base/src/nsPlainTextSerializer.h b/mozilla/content/base/src/nsPlainTextSerializer.h index bfb35500ad9..e30aff43770 100644 --- a/mozilla/content/base/src/nsPlainTextSerializer.h +++ b/mozilla/content/base/src/nsPlainTextSerializer.h @@ -101,7 +101,7 @@ public: NS_IMETHOD AddComment(const nsIParserNode& aNode) { return NS_OK; } NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode) { return NS_OK; } NS_IMETHOD AddDocTypeDecl(const nsIParserNode& aNode) { return NS_OK; } - NS_IMETHOD FlushPendingNotifications() { return NS_OK; } + virtual void FlushContent(PRBool aNotify) { } NS_IMETHOD SetDocumentCharset(nsACString& aCharset) { return NS_OK; } NS_IMETHOD NotifyTagObservers(nsIParserNode* aNode) { return NS_OK; } diff --git a/mozilla/content/events/src/nsEventStateManager.cpp b/mozilla/content/events/src/nsEventStateManager.cpp index 18033be5b17..1cb5df6b981 100644 --- a/mozilla/content/events/src/nsEventStateManager.cpp +++ b/mozilla/content/events/src/nsEventStateManager.cpp @@ -503,6 +503,7 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext, GenerateMouseEnterExit(aPresContext, (nsGUIEvent*)aEvent); // Flush reflows and invalidates to eliminate flicker when both a reflow // and visual change occur in an event callback. See bug #36849 + // XXXbz eeeew. Why not fix viewmanager to flush reflows before painting?? FlushPendingEvents(aPresContext); break; case NS_MOUSE_EXIT: @@ -4641,7 +4642,8 @@ nsEventStateManager::FlushPendingEvents(nsIPresContext* aPresContext) NS_PRECONDITION(nsnull != aPresContext, "nsnull ptr"); nsIPresShell *shell = aPresContext->GetPresShell(); if (shell) { - shell->FlushPendingNotifications(PR_FALSE); + // This is not flushing _Display because of the mess that is bug 36849 + shell->FlushPendingNotifications(Flush_Layout); nsIViewManager* viewManager = shell->GetViewManager(); if (viewManager) { viewManager->FlushPendingInvalidates(); diff --git a/mozilla/content/html/content/src/nsGenericHTMLElement.cpp b/mozilla/content/html/content/src/nsGenericHTMLElement.cpp index 0219d9b4c69..f80511f583b 100644 --- a/mozilla/content/html/content/src/nsGenericHTMLElement.cpp +++ b/mozilla/content/html/content/src/nsGenericHTMLElement.cpp @@ -582,7 +582,7 @@ nsGenericHTMLElement::GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent) } // Flush all pending notifications so that our frames are uptodate - mDocument->FlushPendingNotifications(); + mDocument->FlushPendingNotifications(Flush_Layout); // Get the Frame for our content nsIFrame* frame = nsnull; @@ -933,7 +933,7 @@ nsGenericHTMLElement::GetScrollInfo(nsIScrollableView **aScrollableView, return; } - mDocument->FlushPendingNotifications(PR_TRUE, PR_FALSE); + mDocument->FlushPendingNotifications(Flush_Layout); // Get the presentation shell nsIPresShell *presShell = mDocument->GetShellAt(0); @@ -1239,7 +1239,7 @@ nsGenericHTMLElement::ScrollIntoView(PRBool aTop) } // Now flush to make sure things are up to date - presShell->FlushPendingNotifications(PR_FALSE); + mDocument->FlushPendingNotifications(Flush_Layout); // Get the primary frame for this element nsIFrame *frame = nsnull; @@ -2176,7 +2176,7 @@ nsGenericHTMLElement::GetPrimaryFrameFor(nsIContent* aContent, if (aFlushContent) { // Cause a flush of content, so we get up-to-date frame // information - aDocument->FlushPendingNotifications(PR_FALSE); + aDocument->FlushPendingNotifications(Flush_Frames); } // Get presentation shell 0 diff --git a/mozilla/content/html/content/src/nsHTMLAnchorElement.cpp b/mozilla/content/html/content/src/nsHTMLAnchorElement.cpp index 3937748531a..2e3bb0c56d6 100644 --- a/mozilla/content/html/content/src/nsHTMLAnchorElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLAnchorElement.cpp @@ -221,7 +221,7 @@ nsHTMLAnchorElement::SetFocus(nsIPresContext* aPresContext) // Make sure the presentation is up-to-date if (mDocument) { - mDocument->FlushPendingNotifications(); + mDocument->FlushPendingNotifications(Flush_Layout); } nsIPresShell *presShell = aPresContext->GetPresShell(); diff --git a/mozilla/content/html/content/src/nsHTMLAreaElement.cpp b/mozilla/content/html/content/src/nsHTMLAreaElement.cpp index a6c5d8dcd60..fc54a24d26b 100644 --- a/mozilla/content/html/content/src/nsHTMLAreaElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLAreaElement.cpp @@ -202,7 +202,7 @@ nsHTMLAreaElement::SetFocus(nsIPresContext* aPresContext) // Make sure the presentation is up-to-date if (mDocument) { - mDocument->FlushPendingNotifications(); + mDocument->FlushPendingNotifications(Flush_Layout); } nsIPresShell *presShell = aPresContext->GetPresShell(); diff --git a/mozilla/content/html/content/src/nsHTMLBodyElement.cpp b/mozilla/content/html/content/src/nsHTMLBodyElement.cpp index 7a195cc1845..607dce95b6d 100644 --- a/mozilla/content/html/content/src/nsHTMLBodyElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLBodyElement.cpp @@ -373,20 +373,12 @@ nsHTMLBodyElement::GetBgColor(nsAString& aBgColor) // If we don't have an attribute, find the actual color used for // (generally from the user agent style sheet) for compatibility if (rv == NS_CONTENT_ATTR_NOT_THERE) { - // XXX This should just use nsGenericHTMLElement::GetPrimaryFrame() if (mDocument) { - // Make sure the presentation is up-to-date - mDocument->FlushPendingNotifications(); - } - - nsCOMPtr context; - GetPresContext(this, getter_AddRefs(context)); - - if (context) { - nsIFrame* frame; - rv = context->PresShell()->GetPrimaryFrameFor(this, &frame); - NS_ENSURE_SUCCESS(rv, rv); + // Make sure the style is up-to-date, since we need it + mDocument->FlushPendingNotifications(Flush_Style); + nsIFrame* frame = GetPrimaryFrameFor(this, mDocument, PR_FALSE); + if (frame) { bgcolor = frame->GetStyleBackground()->mBackgroundColor; NS_RGBToHex(bgcolor, aBgColor); diff --git a/mozilla/content/html/content/src/nsHTMLFormElement.cpp b/mozilla/content/html/content/src/nsHTMLFormElement.cpp index d18903e7fcc..f0dca4903ff 100644 --- a/mozilla/content/html/content/src/nsHTMLFormElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLFormElement.cpp @@ -765,7 +765,7 @@ nsHTMLFormElement::DoSubmitOrReset(nsIPresContext* aPresContext, // Make sure the presentation is up-to-date if (mDocument) { - mDocument->FlushPendingNotifications(); + mDocument->FlushPendingNotifications(Flush_ContentAndNotify); } // JBK Don't get form frames anymore - bug 34297 diff --git a/mozilla/content/html/content/src/nsHTMLImageElement.cpp b/mozilla/content/html/content/src/nsHTMLImageElement.cpp index e9737827697..0b4e28af67c 100644 --- a/mozilla/content/html/content/src/nsHTMLImageElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLImageElement.cpp @@ -285,8 +285,8 @@ nsHTMLImageElement::GetXY() return point; } - // Flush all pending notifications so that our frames are uptodate - mDocument->FlushPendingNotifications(); + // Flush all pending notifications so that our frames are laid out correctly + mDocument->FlushPendingNotifications(Flush_Layout); // Get the Frame for this image nsIFrame* frame = nsnull; @@ -339,7 +339,7 @@ nsHTMLImageElement::GetWidthHeight() // Flush all pending notifications so that our frames are up to date. // If we're not in a document, we don't have a frame anyway, so we // don't care. - mDocument->FlushPendingNotifications(); + mDocument->FlushPendingNotifications(Flush_Layout); } nsIImageFrame* imageFrame; diff --git a/mozilla/content/html/document/src/nsHTMLContentSink.cpp b/mozilla/content/html/document/src/nsHTMLContentSink.cpp index 2c588a89067..06c3804d6ab 100644 --- a/mozilla/content/html/document/src/nsHTMLContentSink.cpp +++ b/mozilla/content/html/document/src/nsHTMLContentSink.cpp @@ -230,7 +230,7 @@ public: NS_IMETHOD WillInterrupt(void); NS_IMETHOD WillResume(void); NS_IMETHOD SetParser(nsIParser* aParser); - NS_IMETHOD FlushPendingNotifications(); + NS_IMETHOD_(void) FlushContent(PRBool aNotify); NS_IMETHOD SetDocumentCharset(nsACString& aCharset); // nsIHTMLContentSink @@ -727,7 +727,7 @@ public: return FlushText(aDidFlush, PR_TRUE); } - nsresult FlushTags(PRBool aNotify = PR_TRUE); + nsresult FlushTags(PRBool aNotify); PRBool IsCurrentContainer(nsHTMLTag mType); PRBool IsAncestorContainer(nsHTMLTag mType); @@ -4419,22 +4419,14 @@ HTMLContentSink::ProcessSTYLETag(const nsIParserNode& aNode) return rv; } -NS_IMETHODIMP -HTMLContentSink::FlushPendingNotifications() +void +HTMLContentSink::FlushContent(PRBool aNotify) { - nsresult result = NS_OK; // Only flush tags if we're not doing the notification ourselves - // (since we aren't reentrant) and if we're in a script (since we - // only care to flush if this is done via script). - // - // Bug 4891: Also flush outside of