is only triggered when FOUC would really have occurred.
Reviewed by aroben
* css/cssstyleselector.cpp:
(WebCore::CSSStyleSelector::styleForElement):
* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::updateLayoutIgnorePendingStylesheets):
(WebCore::Document::updateStyleSelector):
* dom/Document.h:
(WebCore::Document::haveStylesheetsLoaded):
(WebCore::Document::):
(WebCore::Document::didLayoutWithPendingStylesheets):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::paintChildren):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::paintLayer):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@16191
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2006-09-01 David Hyatt <hyatt@apple.com>
+
+ Fix for 10682, refine the FOUC paint suppression logic so that it
+ is only triggered when FOUC would really have occurred.
+
+ Reviewed by aroben
+
+ * css/cssstyleselector.cpp:
+ (WebCore::CSSStyleSelector::styleForElement):
+ * dom/Document.cpp:
+ (WebCore::Document::Document):
+ (WebCore::Document::updateLayoutIgnorePendingStylesheets):
+ (WebCore::Document::updateStyleSelector):
+ * dom/Document.h:
+ (WebCore::Document::haveStylesheetsLoaded):
+ (WebCore::Document::):
+ (WebCore::Document::didLayoutWithPendingStylesheets):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::paintChildren):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::paintLayer):
+
2006-09-01 MorganL <morlmor@yahoo.com>
Reviewed by Darin. Updated/landed by Adam.
RenderStyle* CSSStyleSelector::styleForElement(Element* e, RenderStyle* defaultParent, bool allowSharing, bool resolveForRootDefault)
{
- if (allowSharing && !e->document()->haveStylesheetsLoaded()) {
+ // Once an element has a renderer, we don't try to destroy it, since otherwise the renderer
+ // will vanish if a style recalc happens during loading.
+ if (allowSharing && !e->document()->haveStylesheetsLoaded() && !e->renderer()) {
if (!styleNotYetAvailable) {
styleNotYetAvailable = ::new RenderStyle();
styleNotYetAvailable->setDisplay(NONE);
m_styleSelector = new CSSStyleSelector(this, m_usersheet, m_styleSheets.get(), !inCompatMode());
m_pendingStylesheets = 0;
m_ignorePendingStylesheets = false;
- m_didLayoutWithPendingStylesheets = false;
+ m_pendingSheetLayout = NoLayoutWithPendingSheets;
m_cssTarget = 0;
if (!haveStylesheetsLoaded()) {
m_ignorePendingStylesheets = true;
- m_didLayoutWithPendingStylesheets = true;
+ // FIXME: We are willing to attempt to suppress painting with outdated style info only once. Our assumption is that it would be
+ // dangerous to try to stop it a second time, after page content has already been loaded and displayed
+ // with accurate style information. (Our suppression involves blanking the whole page at the
+ // moment. If it were more refined, we might be able to do something better.)
+ // It's worth noting though that this entire method is a hack, since what we really want to do is
+ // suspend JS instead of doing a layout with inaccurate information.
+ if (m_pendingSheetLayout == NoLayoutWithPendingSheets)
+ m_pendingSheetLayout = DidLayoutWithPendingSheets;
updateStyleSelector();
}
if (!haveStylesheetsLoaded())
return;
- if (m_didLayoutWithPendingStylesheets) {
- m_didLayoutWithPendingStylesheets = false;
+ if (didLayoutWithPendingStylesheets() && m_pendingStylesheets <= 0) {
+ m_pendingSheetLayout = IgnoreLayoutWithPendingSheets;
if (renderer())
renderer()->repaint();
}
* This method returns true if all top-level stylesheets have loaded (including
* any @imports that they may be loading).
*/
- bool haveStylesheetsLoaded(bool checkIgnoreFlag = true) const { return m_pendingStylesheets <= 0 || (checkIgnoreFlag && m_ignorePendingStylesheets); }
+ bool haveStylesheetsLoaded() const { return m_pendingStylesheets <= 0 || m_ignorePendingStylesheets; }
/**
* Increments the number of pending sheets. The <link> elements
ExceptionCode& ec);
#endif // XPATH_SUPPORT
+ enum PendingSheetLayout { NoLayoutWithPendingSheets, DidLayoutWithPendingSheets, IgnoreLayoutWithPendingSheets };
+
+ bool didLayoutWithPendingStylesheets() const { return m_pendingSheetLayout == DidLayoutWithPendingSheets; }
+
protected:
CSSStyleSelector* m_styleSelector;
FrameView* m_view;
// If we do ignore the pending stylesheet count, then we need to add a boolean
// to track that this happened so that we can do a full repaint when the stylesheets
// do eventually load.
- bool m_didLayoutWithPendingStylesheets;
+ PendingSheetLayout m_pendingSheetLayout;
RefPtr<CSSStyleSheet> m_elemSheet;
// Avoid painting descendants of the root element when stylesheets haven't loaded. This eliminates FOUC.
// It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
// will do a full repaint().
- if (!document()->haveStylesheetsLoaded(false))
+ if (document()->didLayoutWithPendingStylesheets())
return;
PaintPhase newPhase = (i.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : i.phase;
// Avoid painting layers when stylesheets haven't loaded. This eliminates FOUC.
// It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
// will do a full repaint().
- if (!renderer()->document()->haveStylesheetsLoaded(false) && !renderer()->isRenderView() && !renderer()->isRoot())
+ if (renderer()->document()->didLayoutWithPendingStylesheets() && !renderer()->isRenderView() && !renderer()->isRoot())
return;
// Calculate the clip rects we should use.