[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

morrita at google.com morrita at google.com
Wed Dec 22 16:09:57 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit f792e715396d7302ded032ebe14bdf5542077cc5
Author: morrita at google.com <morrita at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Nov 19 06:25:28 2010 +0000

    2010-11-01  MORITA Hajime  <morrita at google.com>
    
            Reviewed by David Hyatt.
    
            Navigating dark background websites results in blinding white flashes between pages.
            https://bugs.webkit.org/show_bug.cgi?id=45640
    
            This FOUC is caused by an early layout request before the <body> is ready,
            and the page's background style given for <body>, instead of <html>.
            So many sites have such stylesheets that we should care them.
    
            - Some DOM operation such as 'element.offsetLeft' causes page layout.
            - The page layout results page repaint
            - The page page repaint makes a white screen. because there is nothing to paint
              before <body> is available.
    
            This change:
            - extracted existing FOUC check on RenderBlock and RenderLayer to
              Document::mayCauseFlashOfUnstyledContent(),
            - checked non-<head> element availability on mayCauseFlashOfUnstyledContent(), and
            - added FOUC guards before requesting reapint on FrameView.
    
            Note that non-<head> document root children are typically <body>, but possibly
            some other type of elements in the case of non-HTML documents.
    
            No new tests. The data loading speed matters and it cannot be
            captured by DRT.
    
            * dom/Document.cpp:
            (hasHeadSibling): Added.
            (WebCore::Document::mayCauseFlashOfUnstyledContent): Added.
            * dom/Document.h:
            * page/FrameView.cpp:
            (WebCore::FrameView::invalidateRect): Added a guard.
            (WebCore::FrameView::repaintContentRectangle): Added a guard.
            (WebCore::FrameView::doDeferredRepaints): Added a guard.
            (WebCore::FrameView::shouldUpdate): Added.
            * page/FrameView.h:
            * rendering/RenderBlock.cpp:
            (WebCore::RenderBlock::paintContents): Replaced FOUC check to use mayCauseFlashOfUnstyledContent
            * rendering/RenderLayer.cpp:
            (WebCore::RenderLayer::paintLayer): Replaced FOUC check to use mayCauseFlashOfUnstyledContent
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@72367 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 125e756..9aef4ce 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,46 @@
+2010-11-01  MORITA Hajime  <morrita at google.com>
+
+        Reviewed by David Hyatt.
+
+        Navigating dark background websites results in blinding white flashes between pages. 
+        https://bugs.webkit.org/show_bug.cgi?id=45640
+
+        This FOUC is caused by an early layout request before the <body> is ready, 
+        and the page's background style given for <body>, instead of <html>.
+        So many sites have such stylesheets that we should care them.
+        
+        - Some DOM operation such as 'element.offsetLeft' causes page layout.
+        - The page layout results page repaint
+        - The page page repaint makes a white screen. because there is nothing to paint
+          before <body> is available.
+        
+        This change:
+        - extracted existing FOUC check on RenderBlock and RenderLayer to 
+          Document::mayCauseFlashOfUnstyledContent(),
+        - checked non-<head> element availability on mayCauseFlashOfUnstyledContent(), and
+        - added FOUC guards before requesting reapint on FrameView.
+        
+        Note that non-<head> document root children are typically <body>, but possibly
+        some other type of elements in the case of non-HTML documents.
+        
+        No new tests. The data loading speed matters and it cannot be
+        captured by DRT.
+
+        * dom/Document.cpp:
+        (hasHeadSibling): Added.
+        (WebCore::Document::mayCauseFlashOfUnstyledContent): Added.
+        * dom/Document.h:
+        * page/FrameView.cpp:
+        (WebCore::FrameView::invalidateRect): Added a guard.
+        (WebCore::FrameView::repaintContentRectangle): Added a guard.
+        (WebCore::FrameView::doDeferredRepaints): Added a guard.
+        (WebCore::FrameView::shouldUpdate): Added.
+        * page/FrameView.h:
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::paintContents): Replaced FOUC check to use mayCauseFlashOfUnstyledContent
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::paintLayer): Replaced FOUC check to use mayCauseFlashOfUnstyledContent
+
 2010-11-18  Kent Tamura  <tkent at chromium.org>
 
         Reviewed by Tony Chang.
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index 9ad956f..40f078f 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -4868,4 +4868,34 @@ PassRefPtr<TouchList> Document::createTouchList(ExceptionCode&) const
 }
 #endif
 
+static bool hasHeadSibling(const Document* document)
+{
+    Node* de = document->documentElement();
+    if (!de)
+        return false;
+
+    for (Node* i = de->firstChild(); i; i = i->nextSibling()) {
+        // A child of the document element which is rather than <head> is
+        // typically visible and FOUC safe. So we return true here.
+        if (!i->hasTagName(headTag))
+            return true;
+    }
+
+    return false;
+}
+
+bool Document::mayCauseFlashOfUnstyledContent() const
+{
+    // Some kind of FOUC is caused by a repaint request before page's <body> arrival
+    // because page authors often give background styles to <body>, not to <html>.
+    // (And these styles are unavailable before <style> or <link> is given.)
+    // This functions is used for checking such possibility of FOUCs.
+    // Note that the implementation considers only empty or <head> only contents as a FOUC cause
+    // rather than missing <body>, because non-HTML document like SVG and arbitrary XML from foreign namespace 
+    // should be painted even if there is no <body>.
+    if (didLayoutWithPendingStylesheets())
+        return true;
+    return !hasHeadSibling(this);
+}
+
 } // namespace WebCore
diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h
index 83445e0..1e89820 100644
--- a/WebCore/dom/Document.h
+++ b/WebCore/dom/Document.h
@@ -1055,6 +1055,8 @@ public:
 
     const DocumentTiming* timing() const { return &m_documentTiming; }
 
+    bool mayCauseFlashOfUnstyledContent() const;
+
 protected:
     Document(Frame*, const KURL& url, bool isXHTML, bool isHTML, const KURL& baseURL = KURL());
 
diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp
index fe0be6a..13cbefb 100644
--- a/WebCore/page/FrameView.cpp
+++ b/WebCore/page/FrameView.cpp
@@ -303,7 +303,7 @@ bool FrameView::didFirstLayout() const
 void FrameView::invalidateRect(const IntRect& rect)
 {
     if (!parent()) {
-        if (hostWindow())
+        if (hostWindow() && shouldUpdate())
             hostWindow()->invalidateContentsAndWindow(rect, false /*immediate*/);
         return;
     }
@@ -1322,7 +1322,7 @@ void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
         return;
     }
     
-    if (!immediate && isOffscreen() && !shouldUpdateWhileOffscreen())
+    if (!shouldUpdate(immediate))
         return;
 
 #if ENABLE(TILED_BACKING_STORE)
@@ -1396,7 +1396,7 @@ void FrameView::checkStopDelayingDeferredRepaints()
 void FrameView::doDeferredRepaints()
 {
     ASSERT(!m_deferringRepaints);
-    if (isOffscreen() && !shouldUpdateWhileOffscreen()) {
+    if (!shouldUpdate()) {
         m_repaintRects.clear();
         m_repaintCount = 0;
         return;
@@ -1635,6 +1635,15 @@ void FrameView::setShouldUpdateWhileOffscreen(bool shouldUpdateWhileOffscreen)
     m_shouldUpdateWhileOffscreen = shouldUpdateWhileOffscreen;
 }
 
+bool FrameView::shouldUpdate(bool immediateRequested) const
+{
+    if (!immediateRequested && isOffscreen() && !shouldUpdateWhileOffscreen())
+        return false;
+    if (!m_frame || !m_frame->document() || m_frame->document()->mayCauseFlashOfUnstyledContent())
+        return false;
+    return true;
+}
+
 void FrameView::scheduleEvent(PassRefPtr<Event> event, PassRefPtr<Node> eventTarget)
 {
     if (!m_enqueueEvents) {
diff --git a/WebCore/page/FrameView.h b/WebCore/page/FrameView.h
index 8a1a071..bde1b79 100644
--- a/WebCore/page/FrameView.h
+++ b/WebCore/page/FrameView.h
@@ -137,6 +137,7 @@ public:
 
     bool shouldUpdateWhileOffscreen() const;
     void setShouldUpdateWhileOffscreen(bool);
+    bool shouldUpdate(bool = false) const;
 
     void adjustViewSize();
     
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index cc40465..d3ea2e0 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -2216,7 +2216,7 @@ void RenderBlock::paintContents(PaintInfo& paintInfo, int tx, int ty)
     // 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()->didLayoutWithPendingStylesheets() && !isRenderView())
+    if (document()->mayCauseFlashOfUnstyledContent() && !isRenderView())
         return;
 
     if (childrenInline())
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index 7b9000c..5af951c 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -2356,7 +2356,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
     // 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()->didLayoutWithPendingStylesheets() && !renderer()->isRenderView() && !renderer()->isRoot())
+    if (renderer()->document()->mayCauseFlashOfUnstyledContent() && !renderer()->isRenderView() && !renderer()->isRoot())
         return;
     
     // If this layer is totally invisible then there is nothing to paint.

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list