Diff
Modified: trunk/LayoutTests/ChangeLog (214434 => 214435)
--- trunk/LayoutTests/ChangeLog 2017-03-27 22:22:40 UTC (rev 214434)
+++ trunk/LayoutTests/ChangeLog 2017-03-27 22:56:32 UTC (rev 214435)
@@ -1,3 +1,14 @@
+2017-03-27 Antti Koivisto <an...@apple.com>
+
+ Loading in-body stylesheets should not block rendering of elements before them
+ https://bugs.webkit.org/show_bug.cgi?id=169345
+
+ Reviewed by Simon Fraser.
+
+ * http/tests/incremental/resources/delayed-css.php: Added.
+ * http/tests/incremental/stylesheet-body-incremental-rendering-expected.html: Added.
+ * http/tests/incremental/stylesheet-body-incremental-rendering.html: Added.
+
2017-03-27 Myles C. Maxfield <mmaxfi...@apple.com>
Test variation font ranges in the CSS Font Loading API
Added: trunk/LayoutTests/http/tests/incremental/stylesheet-body-incremental-rendering-expected.html (0 => 214435)
--- trunk/LayoutTests/http/tests/incremental/stylesheet-body-incremental-rendering-expected.html (rev 0)
+++ trunk/LayoutTests/http/tests/incremental/stylesheet-body-incremental-rendering-expected.html 2017-03-27 22:56:32 UTC (rev 214435)
@@ -0,0 +1,6 @@
+<div style="width:100px; height:100px; background-color:green"></div>
+<div style="width:100px; height:100px; background-color:green"></div>
+<p>
+Before stylesheet load: (repaint rects (rect 8 8 100 100) )<br>
+After stylesheet load: (repaint rects (rect 8 108 100 100) )<br>
+</p>
Added: trunk/LayoutTests/http/tests/incremental/stylesheet-body-incremental-rendering.html (0 => 214435)
--- trunk/LayoutTests/http/tests/incremental/stylesheet-body-incremental-rendering.html (rev 0)
+++ trunk/LayoutTests/http/tests/incremental/stylesheet-body-incremental-rendering.html 2017-03-27 22:56:32 UTC (rev 214435)
@@ -0,0 +1,24 @@
+<body>
+<script>
+document.body.offsetWidth;
+
+internals.startTrackingRepaints();
+let initialRects;
+setTimeout(() => {
+ initialRects = internals.repaintRectsAsText();
+ internals.stopTrackingRepaints();
+ internals.startTrackingRepaints();
+}, 0);
+
+document.body._onload_ = () => {
+ let finalRects = internals.repaintRectsAsText();
+ internals.stopTrackingRepaints();
+ document.body.innerHTML += `<p>
+ Before stylesheet load: ${initialRects}<br>
+ After stylesheet load: ${finalRects}<br>
+ </p>`;
+};
+</script>
+<div style="width:100px; height:100px; background-color:green"></div>
+<link rel="stylesheet" href=""
+<div class=delayed style="width:100px; height:100px; background-color:red"></div>
Modified: trunk/Source/WebCore/ChangeLog (214434 => 214435)
--- trunk/Source/WebCore/ChangeLog 2017-03-27 22:22:40 UTC (rev 214434)
+++ trunk/Source/WebCore/ChangeLog 2017-03-27 22:56:32 UTC (rev 214435)
@@ -1,3 +1,96 @@
+2017-03-27 Antti Koivisto <an...@apple.com>
+
+ Allow the page to render before <link> stylesheet tags in body
+ https://bugs.webkit.org/show_bug.cgi?id=149157
+ <rdar://problem/24658830>
+
+ Reviewed by Simon Fraser.
+
+ Currently we block style and renderer building completely if document has any loading
+ stylesheets. In case a script queries something layout dependent we construct the render
+ tree with whatever style we have but block painting in it.
+
+ This patch changes behavior so that a loading stylesheet in body only blocks rendering for elements
+ that are after it. The expectation is that such stylesheets rarely affect elements before them
+ and the elements can be rendered without causing ugly visible styling changes.
+
+ The patch replaces the old flash-of-unstyled-content (FOUC) preventation mechanism with a more
+ fine-grained one. Paint blocking is now done on per-renderer basis with based on isNonFinal flag in
+ RenderStyle.
+
+ For stylesheets in head the behavior should be largely unchanged.
+
+ Test: http/tests/incremental/stylesheet-body-incremental-rendering.html
+
+ * css/StyleResolver.cpp:
+ (WebCore::StyleResolver::pseudoStyleRulesForElement):
+ * dom/Document.cpp:
+ (WebCore::Document::Document):
+ (WebCore::Document::resolveStyle):
+ (WebCore::Document::updateLayoutIgnorePendingStylesheets):
+
+ Remove the old FOUC preventation state tracking.
+
+ (WebCore::Document::shouldScheduleLayout):
+ (WebCore::Document::didRemoveAllPendingStylesheet):
+
+ Repaints will now get triggered by the normal style mechanism.
+
+ * dom/Document.h:
+ (WebCore::Document::hasNodesWithNonFinalStyle):
+ (WebCore::Document::setHasNodesWithNonFinalStyle):
+
+ Track if we need to recompute the style later because non-final or unstyled elements.
+
+ (WebCore::Document::didLayoutWithPendingStylesheets): Deleted.
+ (WebCore::Document::hasNodesWithPlaceholderStyle): Deleted.
+ (WebCore::Document::setHasNodesWithPlaceholderStyle): Deleted.
+ * html/HTMLFrameSetElement.cpp:
+ (WebCore::HTMLFrameSetElement::rendererIsNeeded):
+ * page/FrameView.cpp:
+ (WebCore::FrameView::qualifiesAsVisuallyNonEmpty):
+
+ Don't qualify as visually non-empty if we have loading stylesheets in head (even if there is
+ a fouc-prevented render tree).
+
+ (WebCore::FrameView::fireLayoutRelatedMilestonesIfNeeded):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::paintContents):
+
+ Instead of a global test, block painting if isNonFinal is set in the renderer's style.
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::shouldSuppressPaintingLayer):
+ * rendering/style/RenderStyle.cpp:
+ (WebCore::RenderStyle::changeRequiresRepaint):
+
+ The isNonFinal flag prevents painting so we need to trigger repaint when it gets cleared.
+
+ * rendering/style/RenderStyle.h:
+ (WebCore::RenderStyle::isNotFinal):
+ (WebCore::RenderStyle::setIsNotFinal):
+ (WebCore::RenderStyle::isPlaceholderStyle): Deleted.
+ (WebCore::RenderStyle::setIsPlaceholderStyle): Deleted.
+
+ There is no need for placeholder styles anymore. Reuse the bit for isNotFinal.
+
+ * rendering/style/StyleRareNonInheritedData.cpp:
+ (WebCore::StyleRareNonInheritedData::StyleRareNonInheritedData):
+ (WebCore::StyleRareNonInheritedData::operator==):
+ * rendering/style/StyleRareNonInheritedData.h:
+ * style/StyleScope.cpp:
+ (WebCore::Style::Scope::analyzeStyleSheetChange):
+ (WebCore::Style::Scope::updateActiveStyleSheets):
+ * style/StyleTreeResolver.cpp:
+ (WebCore::Style::TreeResolver::styleForElement):
+ (WebCore::Style::TreeResolver::resolveElement):
+
+ If we have seens a loading stylesheet and don't have a renderer yet don't style the element.
+ In case there is a renderer or we are ignoring pending sheets, resolve the style normally
+ but mark it as non-final.
+
+ (WebCore::Style::makePlaceholderStyle): Deleted.
+
2017-03-27 Myles C. Maxfield <mmaxfi...@apple.com>
Test variation font ranges in the CSS Font Loading API
Modified: trunk/Source/WebCore/css/StyleResolver.cpp (214434 => 214435)
--- trunk/Source/WebCore/css/StyleResolver.cpp 2017-03-27 22:22:40 UTC (rev 214434)
+++ trunk/Source/WebCore/css/StyleResolver.cpp 2017-03-27 22:56:32 UTC (rev 214435)
@@ -1123,8 +1123,8 @@
Vector<RefPtr<StyleRule>> StyleResolver::pseudoStyleRulesForElement(const Element* element, PseudoId pseudoId, unsigned rulesToInclude)
{
- if (!element || !element->document().haveStylesheetsLoaded())
- return Vector<RefPtr<StyleRule>>();
+ if (!element)
+ return { };
m_state = State(*element, nullptr);
Modified: trunk/Source/WebCore/dom/Document.cpp (214434 => 214435)
--- trunk/Source/WebCore/dom/Document.cpp 2017-03-27 22:22:40 UTC (rev 214434)
+++ trunk/Source/WebCore/dom/Document.cpp 2017-03-27 22:56:32 UTC (rev 214435)
@@ -1725,7 +1725,8 @@
if (type == ResolveStyleType::Rebuild) {
// This may get set again during style resolve.
- m_hasNodesWithPlaceholderStyle = false;
+ m_hasNodesWithNonFinalStyle = false;
+ m_hasNodesWithMissingStyle = false;
auto documentStyle = Style::resolveForDocument(*this);
@@ -1761,6 +1762,9 @@
}
updatedCompositingLayers = frameView.updateCompositingLayersAfterStyleChange();
+
+ if (m_renderView->needsLayout())
+ frameView.scheduleRelayout();
}
// If we wanted to call implicitClose() during recalcStyle, do so now that we're finished.
@@ -1854,12 +1858,6 @@
frameView->layout();
}
-// 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
-// stylesheets are loaded. Doing a layout ignoring the pending stylesheets
-// lets us get reasonable answers. The long term solution to this problem is
-// to instead suspend _javascript_ execution.
void Document::updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks runPostLayoutTasks)
{
bool oldIgnore = m_ignorePendingStylesheets;
@@ -1866,22 +1864,9 @@
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 = bodyOrFrameset();
- if (bodyElement && !bodyElement->renderer() && m_pendingSheetLayout == NoLayoutWithPendingSheets) {
- m_pendingSheetLayout = DidLayoutWithPendingSheets;
- styleScope().didChangeActiveStyleSheetCandidates();
- resolveStyle(ResolveStyleType::Rebuild);
- } 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.
- resolveStyle(ResolveStyleType::Rebuild);
+ // FIXME: This should just invalidate elements with missing styles.
+ if (m_hasNodesWithMissingStyle)
+ scheduleForcedStyleRecalc();
}
updateLayout();
@@ -2723,14 +2708,16 @@
bool Document::shouldScheduleLayout()
{
- // This function will only be called when FrameView thinks a layout is needed.
- // This enforces a couple extra rules.
- //
- // (a) Only schedule a layout once the stylesheets are loaded.
- // (b) Only schedule layout once we have a body element.
+ if (!documentElement())
+ return false;
+ if (!is<HTMLHtmlElement>(*documentElement()))
+ return true;
+ if (!bodyOrFrameset())
+ return false;
+ if (styleScope().hasPendingSheetsBeforeBody())
+ return false;
- return (haveStylesheetsLoaded() && bodyOrFrameset())
- || (documentElement() && !is<HTMLHtmlElement>(*documentElement()));
+ return true;
}
bool Document::isLayoutTimerActive()
@@ -3034,15 +3021,6 @@
void Document::didRemoveAllPendingStylesheet()
{
- if (m_pendingSheetLayout == DidLayoutWithPendingSheets) {
- // Painting is disabled when doing layouts with pending sheets to avoid FOUC.
- // We need to force paint when coming out from this state.
- // FIXME: This is not very elegant.
- m_pendingSheetLayout = IgnoreLayoutWithPendingSheets;
- if (renderView())
- renderView()->repaintViewAndCompositedLayers();
- }
-
if (auto* parser = scriptableDocumentParser())
parser->executeScriptsWaitingForStylesheetsSoon();
}
Modified: trunk/Source/WebCore/dom/Document.h (214434 => 214435)
--- trunk/Source/WebCore/dom/Document.h 2017-03-27 22:22:40 UTC (rev 214434)
+++ trunk/Source/WebCore/dom/Document.h 2017-03-27 22:56:32 UTC (rev 214435)
@@ -936,13 +936,11 @@
WEBCORE_EXPORT Ref<XPathNSResolver> createNSResolver(Node* nodeResolver);
WEBCORE_EXPORT ExceptionOr<Ref<XPathResult>> evaluate(const String& _expression_, Node* contextNode, RefPtr<XPathNSResolver>&&, unsigned short type, XPathResult*);
- enum PendingSheetLayout { NoLayoutWithPendingSheets, DidLayoutWithPendingSheets, IgnoreLayoutWithPendingSheets };
+ bool hasNodesWithNonFinalStyle() const { return m_hasNodesWithNonFinalStyle; }
+ void setHasNodesWithNonFinalStyle() { m_hasNodesWithNonFinalStyle = true; }
+ bool hasNodesWithMissingStyle() const { return m_hasNodesWithMissingStyle; }
+ void setHasNodesWithMissingStyle() { m_hasNodesWithMissingStyle = true; }
- bool didLayoutWithPendingStylesheets() const { return m_pendingSheetLayout == DidLayoutWithPendingSheets; }
-
- bool hasNodesWithPlaceholderStyle() const { return m_hasNodesWithPlaceholderStyle; }
- void setHasNodesWithPlaceholderStyle() { m_hasNodesWithPlaceholderStyle = true; }
-
void updateFocusAppearanceSoon(SelectionRestorationMode);
void cancelFocusAppearanceUpdate();
@@ -1678,16 +1676,12 @@
bool m_wellFormed { false };
bool m_createRenderers { true };
- bool m_hasNodesWithPlaceholderStyle { false };
+ bool m_hasNodesWithNonFinalStyle { false };
+ bool m_hasNodesWithMissingStyle { false };
// But sometimes you need to ignore pending stylesheet count to
// force an immediate layout when requested by JS.
bool m_ignorePendingStylesheets { false };
- // 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.
- PendingSheetLayout m_pendingSheetLayout { NoLayoutWithPendingSheets };
-
bool m_hasElementUsingStyleBasedEditability { false };
bool m_focusNavigationStartingNodeIsRemoved { false };
Modified: trunk/Source/WebCore/html/HTMLFrameSetElement.cpp (214434 => 214435)
--- trunk/Source/WebCore/html/HTMLFrameSetElement.cpp 2017-03-27 22:22:40 UTC (rev 214434)
+++ trunk/Source/WebCore/html/HTMLFrameSetElement.cpp 2017-03-27 22:56:32 UTC (rev 214435)
@@ -153,7 +153,7 @@
{
// For compatibility, frames render even when display: none is set.
// However, we delay creating a renderer until stylesheets have loaded.
- return !style.isPlaceholderStyle();
+ return !style.isNotFinal();
}
RenderPtr<RenderElement> HTMLFrameSetElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&)
Modified: trunk/Source/WebCore/page/FrameView.cpp (214434 => 214435)
--- trunk/Source/WebCore/page/FrameView.cpp 2017-03-27 22:22:40 UTC (rev 214434)
+++ trunk/Source/WebCore/page/FrameView.cpp 2017-03-27 22:56:32 UTC (rev 214435)
@@ -4586,6 +4586,10 @@
if (!frame().document()->parsing() && frame().loader().stateMachine().committedFirstRealDocumentLoad())
return true;
+ // FIXME: We should also ignore renderers with non-final style.
+ if (frame().document()->styleScope().hasPendingSheetsBeforeBody())
+ return false;
+
// Require the document to grow a bit.
// Using a value of 48 allows the header on Google's search page to render immediately before search results populate later.
static const int documentHeightThreshold = 48;
@@ -5128,7 +5132,7 @@
updateIsVisuallyNonEmpty();
// If the layout was done with pending sheets, we are not in fact visually non-empty yet.
- if (m_isVisuallyNonEmpty && !frame().document()->didLayoutWithPendingStylesheets() && m_firstVisuallyNonEmptyLayoutCallbackPending) {
+ if (m_isVisuallyNonEmpty &&m_firstVisuallyNonEmptyLayoutCallbackPending) {
m_firstVisuallyNonEmptyLayoutCallbackPending = false;
if (requestedMilestones & DidFirstVisuallyNonEmptyLayout)
milestonesAchieved |= DidFirstVisuallyNonEmptyLayout;
Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (214434 => 214435)
--- trunk/Source/WebCore/rendering/RenderBlock.cpp 2017-03-27 22:22:40 UTC (rev 214434)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp 2017-03-27 22:56:32 UTC (rev 214435)
@@ -1579,10 +1579,10 @@
void RenderBlock::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
- // 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, styleResolverChanged() on the Document
- // will do a full repaint.
- if (document().didLayoutWithPendingStylesheets() && !isRenderView())
+ // Style is non-final if the element has a pending stylesheet before it. We end up with renderers with such styles if a script
+ // forces renderer construction by querying something layout dependent.
+ // Avoid FOUC by not painting. Switching to final style triggers repaint.
+ if (style().isNotFinal())
return;
if (childrenInline())
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (214434 => 214435)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2017-03-27 22:22:40 UTC (rev 214434)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2017-03-27 22:56:32 UTC (rev 214435)
@@ -3939,10 +3939,7 @@
static inline bool shouldSuppressPaintingLayer(RenderLayer* layer)
{
- // Avoid painting descendants of the root layer 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 (layer->renderer().document().didLayoutWithPendingStylesheets() && !layer->isRootLayer() && !layer->renderer().isDocumentElementRenderer())
+ if (layer->renderer().style().isNotFinal() && !layer->isRootLayer() && !layer->renderer().isDocumentElementRenderer())
return true;
// Avoid painting all layers if the document is in a state where visual updates aren't allowed.
Modified: trunk/Source/WebCore/rendering/style/RenderStyle.cpp (214434 => 214435)
--- trunk/Source/WebCore/rendering/style/RenderStyle.cpp 2017-03-27 22:22:40 UTC (rev 214434)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.cpp 2017-03-27 22:56:32 UTC (rev 214435)
@@ -853,6 +853,9 @@
|| m_rareInheritedData->imageRendering != other.m_rareInheritedData->imageRendering)
return true;
+ if (m_rareNonInheritedData->isNotFinal != other.m_rareNonInheritedData->isNotFinal)
+ return true;
+
if (m_rareNonInheritedData->shapeOutside != other.m_rareNonInheritedData->shapeOutside)
return true;
Modified: trunk/Source/WebCore/rendering/style/RenderStyle.h (214434 => 214435)
--- trunk/Source/WebCore/rendering/style/RenderStyle.h 2017-03-27 22:22:40 UTC (rev 214434)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.h 2017-03-27 22:56:32 UTC (rev 214435)
@@ -1659,8 +1659,9 @@
static Isolation initialIsolation() { return IsolationAuto; }
#endif
- bool isPlaceholderStyle() const { return m_rareNonInheritedData->isPlaceholderStyle; }
- void setIsPlaceholderStyle() { SET_VAR(m_rareNonInheritedData, isPlaceholderStyle, true); }
+ // Indicates the style is likely to change due to a pending stylesheet load.
+ bool isNotFinal() const { return m_rareNonInheritedData->isNotFinal; }
+ void setIsNotFinal() { SET_VAR(m_rareNonInheritedData, isNotFinal, true); }
void setVisitedLinkColor(const Color&);
void setVisitedLinkBackgroundColor(const Color& v) { SET_VAR(m_rareNonInheritedData, visitedLinkBackgroundColor, v); }
Modified: trunk/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp (214434 => 214435)
--- trunk/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp 2017-03-27 22:22:40 UTC (rev 214434)
+++ trunk/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp 2017-03-27 22:56:32 UTC (rev 214435)
@@ -107,7 +107,7 @@
, breakInside(RenderStyle::initialBreakInside())
, resize(RenderStyle::initialResize())
, hasAttrContent(false)
- , isPlaceholderStyle(false)
+ , isNotFinal(false)
{
maskBoxImage.setMaskDefaults();
}
@@ -200,7 +200,7 @@
, breakInside(o.breakInside)
, resize(o.resize)
, hasAttrContent(o.hasAttrContent)
- , isPlaceholderStyle(o.isPlaceholderStyle)
+ , isNotFinal(o.isNotFinal)
{
}
@@ -304,7 +304,7 @@
&& breakInside == o.breakInside
&& resize == o.resize
&& hasAttrContent == o.hasAttrContent
- && isPlaceholderStyle == o.isPlaceholderStyle;
+ && isNotFinal == o.isNotFinal;
}
bool StyleRareNonInheritedData::contentDataEquivalent(const StyleRareNonInheritedData& other) const
Modified: trunk/Source/WebCore/rendering/style/StyleRareNonInheritedData.h (214434 => 214435)
--- trunk/Source/WebCore/rendering/style/StyleRareNonInheritedData.h 2017-03-27 22:22:40 UTC (rev 214434)
+++ trunk/Source/WebCore/rendering/style/StyleRareNonInheritedData.h 2017-03-27 22:56:32 UTC (rev 214435)
@@ -220,7 +220,7 @@
unsigned hasAttrContent : 1;
- unsigned isPlaceholderStyle : 1;
+ unsigned isNotFinal : 1;
private:
StyleRareNonInheritedData();
Modified: trunk/Source/WebCore/style/StyleScope.cpp (214434 => 214435)
--- trunk/Source/WebCore/style/StyleScope.cpp 2017-03-27 22:22:40 UTC (rev 214434)
+++ trunk/Source/WebCore/style/StyleScope.cpp 2017-03-27 22:56:32 UTC (rev 214435)
@@ -394,7 +394,7 @@
auto styleResolverUpdateType = hasInsertions ? Reset : Additive;
// If we are already parsing the body and so may have significant amount of elements, put some effort into trying to avoid style recalcs.
- if (!m_document.bodyOrFrameset() || m_document.hasNodesWithPlaceholderStyle())
+ if (!m_document.bodyOrFrameset() || m_document.hasNodesWithNonFinalStyle() || m_document.hasNodesWithMissingStyle())
return styleResolverUpdateType;
StyleInvalidationAnalysis invalidationAnalysis(addedSheets, styleResolver.mediaQueryEvaluator());
@@ -445,7 +445,7 @@
// Don't bother updating, since we haven't loaded all our style info yet
// and haven't calculated the style resolver for the first time.
- if (!m_shadowRoot && !m_didUpdateActiveStyleSheets && hasPendingSheets()) {
+ if (!m_shadowRoot && !m_didUpdateActiveStyleSheets && hasPendingSheetsBeforeBody()) {
clearResolver();
return;
}
Modified: trunk/Source/WebCore/style/StyleTreeResolver.cpp (214434 => 214435)
--- trunk/Source/WebCore/style/StyleTreeResolver.cpp 2017-03-27 22:22:40 UTC (rev 214434)
+++ trunk/Source/WebCore/style/StyleTreeResolver.cpp 2017-03-27 22:56:32 UTC (rev 214435)
@@ -51,24 +51,6 @@
namespace Style {
-static std::unique_ptr<RenderStyle> makePlaceholderStyle(Document& document)
-{
- auto placeholderStyle = RenderStyle::createPtr();
- placeholderStyle->setDisplay(NONE);
- placeholderStyle->setIsPlaceholderStyle();
-
- FontCascadeDescription fontDescription;
- fontDescription.setOneFamily(standardFamily);
- fontDescription.setKeywordSizeFromIdentifier(CSSValueMedium);
- float size = Style::fontSizeForKeyword(CSSValueMedium, false, document);
- fontDescription.setSpecifiedSize(size);
- fontDescription.setComputedSize(size);
- placeholderStyle->setFontDescription(fontDescription);
-
- placeholderStyle->fontCascade().update(&document.fontSelector());
- return placeholderStyle;
-}
-
TreeResolver::TreeResolver(Document& document)
: m_document(document)
{
@@ -126,11 +108,6 @@
std::unique_ptr<RenderStyle> TreeResolver::styleForElement(Element& element, const RenderStyle& inheritedStyle)
{
- if (m_didSeePendingStylesheet && !element.renderer() && !m_document.isIgnoringPendingStylesheets()) {
- m_document.setHasNodesWithPlaceholderStyle();
- return makePlaceholderStyle(m_document);
- }
-
if (element.hasCustomStyleResolveCallbacks()) {
RenderStyle* shadowHostStyle = scope().shadowRoot ? m_update->elementStyle(*scope().shadowRoot->host()) : nullptr;
if (auto customStyle = element.resolveCustomStyle(inheritedStyle, shadowHostStyle)) {
@@ -191,15 +168,25 @@
ElementUpdate TreeResolver::resolveElement(Element& element)
{
+ if (m_didSeePendingStylesheet && !element.renderer() && !m_document.isIgnoringPendingStylesheets()) {
+ m_document.setHasNodesWithMissingStyle();
+ return { };
+ }
+
auto newStyle = styleForElement(element, parent().style);
if (!affectsRenderedSubtree(element, *newStyle))
return { };
+ auto* existingStyle = element.renderStyle();
+
+ if (m_didSeePendingStylesheet && (!existingStyle || existingStyle->isNotFinal())) {
+ newStyle->setIsNotFinal();
+ m_document.setHasNodesWithNonFinalStyle();
+ }
+
auto update = createAnimatedElementUpdate(WTFMove(newStyle), element, parent().change);
- auto* existingStyle = element.renderStyle();
-
if (&element == m_document.documentElement()) {
m_documentElementStyle = RenderStyle::clonePtr(*update.style);
scope().styleResolver.setOverrideDocumentElementStyle(m_documentElementStyle.get());