| Index: Source/core/dom/Document.cpp
|
| diff --git a/Source/core/dom/Document.cpp b/Source/core/dom/Document.cpp
|
| index 90a353c3f97e1b6f91a1c2547df6d3355fdbf59d..a52399ed5245a404e8a3d22312e7633f3530e7e0 100644
|
| --- a/Source/core/dom/Document.cpp
|
| +++ b/Source/core/dom/Document.cpp
|
| @@ -156,6 +156,7 @@
|
| #include "core/platform/DateComponents.h"
|
| #include "core/platform/HistogramSupport.h"
|
| #include "core/platform/Language.h"
|
| +#include "core/platform/ScrollbarTheme.h"
|
| #include "core/platform/Timer.h"
|
| #include "core/platform/chromium/TraceEvent.h"
|
| #include "core/platform/network/HTTPParsers.h"
|
| @@ -1823,6 +1824,9 @@ void Document::updateLayout()
|
| if (frameView && renderer() && (frameView->layoutPending() || renderer()->needsLayout()))
|
| frameView->layout();
|
|
|
| + if (frameView)
|
| + frameView->partialLayout().reset();
|
| +
|
| setNeedsFocusedElementCheck();
|
| }
|
|
|
| @@ -1835,6 +1839,31 @@ void Document::setNeedsFocusedElementCheck()
|
| m_didPostCheckFocusedElementTask = true;
|
| }
|
|
|
| +void Document::recalcStyleForLayoutIgnoringPendingStylesheets()
|
| +{
|
| + TemporaryChange<bool> ignorePendingStylesheets(m_ignorePendingStylesheets, m_ignorePendingStylesheets);
|
| + if (!haveStylesheetsLoaded()) {
|
| + m_ignorePendingStylesheets = 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.
|
| + HTMLElement* bodyElement = body();
|
| + if (bodyElement && !bodyElement->renderer() && m_pendingSheetLayout == NoLayoutWithPendingSheets) {
|
| + m_pendingSheetLayout = DidLayoutWithPendingSheets;
|
| + styleResolverChanged(RecalcStyleImmediately);
|
| + } else if (m_hasNodesWithPlaceholderStyle) {
|
| + // If new nodes have been added or style recalc has been done with style sheets still
|
| + // pending, some nodes may not have had their real style calculated yet. Normally this
|
| + // gets cleaned when style sheets arrive but here we need up-to-date style immediately.
|
| + recalcStyle(Force);
|
| + }
|
| + }
|
| +}
|
| +
|
| // FIXME: This is a bad idea and needs to be removed eventually.
|
| // Other browsers load stylesheets before they continue parsing the web page.
|
| // Since we don't, we can run JavaScript code that needs answers before the
|
| @@ -1843,30 +1872,40 @@ void Document::setNeedsFocusedElementCheck()
|
| // to instead suspend JavaScript execution.
|
| void Document::updateLayoutIgnorePendingStylesheets()
|
| {
|
| - bool oldIgnore = m_ignorePendingStylesheets;
|
| + recalcStyleForLayoutIgnoringPendingStylesheets();
|
| + updateLayout();
|
| +}
|
| +
|
| +void Document::partialUpdateLayoutIgnorePendingStylesheets(Node* stopLayoutAtNode)
|
| +{
|
| + // Non-overlay scrollbars can cause a second layout that is dependent
|
| + // on a first layout. This is disabled for partial layout for now.
|
| + if (!RuntimeEnabledFeatures::partialLayoutEnabled() || !ScrollbarTheme::theme()->usesOverlayScrollbars()) {
|
| + updateLayoutIgnorePendingStylesheets();
|
| + return;
|
| + }
|
|
|
| - if (!haveStylesheetsLoaded()) {
|
| - m_ignorePendingStylesheets = 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.
|
| - HTMLElement* bodyElement = body();
|
| - if (bodyElement && !bodyElement->renderer() && m_pendingSheetLayout == NoLayoutWithPendingSheets) {
|
| - m_pendingSheetLayout = DidLayoutWithPendingSheets;
|
| - styleResolverChanged(RecalcStyleImmediately);
|
| - } else if (m_hasNodesWithPlaceholderStyle)
|
| - // If new nodes have been added or style recalc has been done with style sheets still pending, some nodes
|
| - // may not have had their real style calculated yet. Normally this gets cleaned when style sheets arrive
|
| - // but here we need up-to-date style immediately.
|
| - recalcStyle(Force);
|
| + TemporaryChange<bool> ignorePendingStylesheets(m_ignorePendingStylesheets, m_ignorePendingStylesheets);
|
| + recalcStyleForLayoutIgnoringPendingStylesheets();
|
| +
|
| + if (stopLayoutAtNode) {
|
| + RenderObject* renderer = stopLayoutAtNode->renderer();
|
| + bool canPartialLayout = renderer;
|
| + while (renderer) {
|
| + if (!renderer->supportsPartialLayout()) {
|
| + canPartialLayout = false;
|
| + break;
|
| + }
|
| + renderer = renderer->parent();
|
| + }
|
| + if (canPartialLayout && view())
|
| + view()->partialLayout().setStopAtRenderer(stopLayoutAtNode->renderer());
|
| }
|
|
|
| updateLayout();
|
|
|
| - m_ignorePendingStylesheets = oldIgnore;
|
| + if (view())
|
| + view()->partialLayout().reset();
|
| }
|
|
|
| PassRefPtr<RenderStyle> Document::styleForElementIgnoringPendingStylesheets(Element* element)
|
|
|