Diff
Modified: trunk/Source/WebCore/CMakeLists.txt (220955 => 220956)
--- trunk/Source/WebCore/CMakeLists.txt 2017-08-20 02:11:33 UTC (rev 220955)
+++ trunk/Source/WebCore/CMakeLists.txt 2017-08-20 09:42:09 UTC (rev 220956)
@@ -2789,6 +2789,7 @@
style/RenderTreePosition.cpp
style/RenderTreeUpdater.cpp
style/RenderTreeUpdaterFirstLetter.cpp
+ style/RenderTreeUpdaterGeneratedContent.cpp
style/RenderTreeUpdaterListItem.cpp
style/StyleChange.cpp
style/StyleFontSizeFunctions.cpp
Modified: trunk/Source/WebCore/ChangeLog (220955 => 220956)
--- trunk/Source/WebCore/ChangeLog 2017-08-20 02:11:33 UTC (rev 220955)
+++ trunk/Source/WebCore/ChangeLog 2017-08-20 09:42:09 UTC (rev 220956)
@@ -1,3 +1,55 @@
+2017-08-20 Antti Koivisto <[email protected]>
+
+ Factor :before/:after render tree mutations into a RenderTreeUpdater helper class
+ https://bugs.webkit.org/show_bug.cgi?id=175752
+
+ Reviewed by Andreas Kling.
+
+ Move code that constructs generated content renderers out from PseudoElement.
+ Also refactor the related code from RenderTreeUpdater main class into
+ RenderTreeUpdater::GeneratedContent helper class.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * dom/PseudoElement.cpp:
+ (WebCore::PseudoElement::resolveCustomStyle): Deleted.
+
+ Not needed anymore.
+
+ (WebCore::PseudoElement::didAttachRenderers): Deleted.
+
+ Moves to createContentRenderers in GeneratedContent.
+
+ (WebCore::PseudoElement::didRecalcStyle): Deleted.
+
+ Moves to updateStyleForContentRenderers in GeneratedContent.
+
+ * dom/PseudoElement.h:
+ * style/RenderTreeUpdater.cpp:
+ (WebCore::RenderTreeUpdater::RenderTreeUpdater):
+ (WebCore::RenderTreeUpdater::~RenderTreeUpdater):
+ (WebCore::RenderTreeUpdater::commit):
+ (WebCore::RenderTreeUpdater::updateBeforeDescendants):
+ (WebCore::RenderTreeUpdater::updateAfterDescendants):
+ (WebCore::needsPseudoElement): Deleted.
+ (WebCore::RenderTreeUpdater::updateBeforeOrAfterPseudoElement): Deleted.
+ (WebCore::RenderTreeUpdater::updateQuotesUpTo): Deleted.
+
+ Quotes and other :before/:after support moves to GeneratedContent helpwe.
+
+ * style/RenderTreeUpdater.h:
+ (WebCore::RenderTreeUpdater::generatedContent):
+ * style/RenderTreeUpdaterGeneratedContent.cpp: Added.
+ (WebCore::RenderTreeUpdater::GeneratedContent::GeneratedContent):
+ (WebCore::RenderTreeUpdater::GeneratedContent::updateBeforePseudoElement):
+ (WebCore::RenderTreeUpdater::GeneratedContent::updateAfterPseudoElement):
+ (WebCore::RenderTreeUpdater::GeneratedContent::updateRemainingQuotes):
+ (WebCore::RenderTreeUpdater::GeneratedContent::updateQuotesUpTo):
+ (WebCore::createContentRenderers):
+ (WebCore::updateStyleForContentRenderers):
+ (WebCore::RenderTreeUpdater::GeneratedContent::updatePseudoElement):
+ (WebCore::RenderTreeUpdater::GeneratedContent::needsPseudoElement):
+ * style/RenderTreeUpdaterGeneratedContent.h: Added.
+
2017-08-19 Andy Estes <[email protected]>
[Payment Request] Add interface stubs
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (220955 => 220956)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-08-20 02:11:33 UTC (rev 220955)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-08-20 09:42:09 UTC (rev 220956)
@@ -6824,6 +6824,8 @@
E48E332C1F47037C00BAB0EF /* RenderTreeUpdaterFirstLetter.h in Headers */ = {isa = PBXBuildFile; fileRef = E48284091F44595600863AC3 /* RenderTreeUpdaterFirstLetter.h */; };
E48E332D1F47038000BAB0EF /* RenderTreeUpdaterListItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E48E332A1F46C98000BAB0EF /* RenderTreeUpdaterListItem.cpp */; };
E48E332E1F47038000BAB0EF /* RenderTreeUpdaterListItem.h in Headers */ = {isa = PBXBuildFile; fileRef = E48E33281F46C97F00BAB0EF /* RenderTreeUpdaterListItem.h */; };
+ E48E33311F47437000BAB0EF /* RenderTreeUpdaterGeneratedContent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E48E332F1F47436500BAB0EF /* RenderTreeUpdaterGeneratedContent.cpp */; };
+ E48E33321F47437300BAB0EF /* RenderTreeUpdaterGeneratedContent.h in Headers */ = {isa = PBXBuildFile; fileRef = E48E33301F47436700BAB0EF /* RenderTreeUpdaterGeneratedContent.h */; };
E4916FF7195DF6A0005AB349 /* LayerFlushThrottleState.h in Headers */ = {isa = PBXBuildFile; fileRef = E4916FF6195DF6A0005AB349 /* LayerFlushThrottleState.h */; settings = {ATTRIBUTES = (Private, ); }; };
E4946EAE156E64DD00D3297F /* StyleRuleImport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4946EAC156E64DD00D3297F /* StyleRuleImport.cpp */; };
E4946EAF156E64DD00D3297F /* StyleRuleImport.h in Headers */ = {isa = PBXBuildFile; fileRef = E4946EAD156E64DD00D3297F /* StyleRuleImport.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -15483,6 +15485,8 @@
E48944A1180B57D800F165D8 /* SimpleLineLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleLineLayout.h; sourceTree = "<group>"; };
E48E33281F46C97F00BAB0EF /* RenderTreeUpdaterListItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTreeUpdaterListItem.h; sourceTree = "<group>"; };
E48E332A1F46C98000BAB0EF /* RenderTreeUpdaterListItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeUpdaterListItem.cpp; sourceTree = "<group>"; };
+ E48E332F1F47436500BAB0EF /* RenderTreeUpdaterGeneratedContent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeUpdaterGeneratedContent.cpp; sourceTree = "<group>"; };
+ E48E33301F47436700BAB0EF /* RenderTreeUpdaterGeneratedContent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTreeUpdaterGeneratedContent.h; sourceTree = "<group>"; };
E4916FF6195DF6A0005AB349 /* LayerFlushThrottleState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LayerFlushThrottleState.h; sourceTree = "<group>"; };
E4946EAC156E64DD00D3297F /* StyleRuleImport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleRuleImport.cpp; sourceTree = "<group>"; };
E4946EAD156E64DD00D3297F /* StyleRuleImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleRuleImport.h; sourceTree = "<group>"; };
@@ -25063,6 +25067,8 @@
E46180281C8A06CD0026C02C /* RenderTreeUpdater.h */,
E48284061F44594B00863AC3 /* RenderTreeUpdaterFirstLetter.cpp */,
E48284091F44595600863AC3 /* RenderTreeUpdaterFirstLetter.h */,
+ E48E332F1F47436500BAB0EF /* RenderTreeUpdaterGeneratedContent.cpp */,
+ E48E33301F47436700BAB0EF /* RenderTreeUpdaterGeneratedContent.h */,
E48E332A1F46C98000BAB0EF /* RenderTreeUpdaterListItem.cpp */,
E48E33281F46C97F00BAB0EF /* RenderTreeUpdaterListItem.h */,
E401E0A51C3C0CF700F34D10 /* StyleChange.cpp */,
@@ -29620,6 +29626,7 @@
FD45A94F175D3F3E00C21EC8 /* Shape.h in Headers */,
FD45A95B175D41EE00C21EC8 /* ShapeInterval.h in Headers */,
FD45A952175D3F3E00C21EC8 /* ShapeOutsideInfo.h in Headers */,
+ E48E33321F47437300BAB0EF /* RenderTreeUpdaterGeneratedContent.h in Headers */,
FD1AF1501656F15100C6D4F7 /* ShapeValue.h in Headers */,
1A4A954E0B4EDCCB002D8C3C /* SharedBuffer.h in Headers */,
93309EA3099EB78C0056E581 /* SharedTimer.h in Headers */,
@@ -31268,6 +31275,7 @@
9BD4E91A1C462CFC005065BC /* CustomElementRegistry.cpp in Sources */,
62CD32591157E57C0063B0A7 /* CustomEvent.cpp in Sources */,
97BC6A201505F081001B74AC /* Database.cpp in Sources */,
+ E48E33311F47437000BAB0EF /* RenderTreeUpdaterGeneratedContent.cpp in Sources */,
97BC6A231505F081001B74AC /* DatabaseAuthorizer.cpp in Sources */,
97BC6A271505F081001B74AC /* DatabaseContext.cpp in Sources */,
FE456F181677D74E005EDDF9 /* DatabaseManager.cpp in Sources */,
Modified: trunk/Source/WebCore/dom/PseudoElement.cpp (220955 => 220956)
--- trunk/Source/WebCore/dom/PseudoElement.cpp 2017-08-20 02:11:33 UTC (rev 220955)
+++ trunk/Source/WebCore/dom/PseudoElement.cpp 2017-08-20 09:42:09 UTC (rev 220956)
@@ -78,50 +78,9 @@
m_hostElement = nullptr;
}
-std::optional<ElementStyle> PseudoElement::resolveCustomStyle(const RenderStyle& parentStyle, const RenderStyle*)
-{
- auto* style = m_hostElement->renderer()->getCachedPseudoStyle(m_pseudoId, &parentStyle);
- if (!style)
- return std::nullopt;
- return ElementStyle(RenderStyle::clonePtr(*style));
-}
-
-void PseudoElement::didAttachRenderers()
-{
- RenderElement* renderer = this->renderer();
- if (!renderer || renderer->style().hasFlowFrom())
- return;
-
- const RenderStyle& style = renderer->style();
- ASSERT(style.contentData());
-
- for (const ContentData* content = style.contentData(); content; content = content->next()) {
- auto child = content->createContentRenderer(document(), style);
- if (renderer->isChildAllowed(*child, style))
- renderer->addChild(child.leakPtr());
- }
-}
-
bool PseudoElement::rendererIsNeeded(const RenderStyle& style)
{
return pseudoElementRendererIsNeeded(&style);
}
-void PseudoElement::didRecalcStyle(Style::Change)
-{
- if (!renderer())
- return;
-
- // The renderers inside pseudo elements are anonymous so they don't get notified of recalcStyle and must have
- // the style propagated downward manually similar to RenderObject::propagateStyleToAnonymousChildren.
- RenderElement& renderer = *this->renderer();
- for (RenderObject* child = renderer.nextInPreOrder(&renderer); child; child = child->nextInPreOrder(&renderer)) {
- // We only manage the style for the generated content which must be images or text.
- if (!is<RenderImage>(*child) && !is<RenderQuote>(*child))
- continue;
- auto createdStyle = RenderStyle::createStyleInheritingFromPseudoStyle(renderer.style());
- downcast<RenderElement>(*child).setStyle(WTFMove(createdStyle));
- }
-}
-
} // namespace
Modified: trunk/Source/WebCore/dom/PseudoElement.h (220955 => 220956)
--- trunk/Source/WebCore/dom/PseudoElement.h 2017-08-20 02:11:33 UTC (rev 220955)
+++ trunk/Source/WebCore/dom/PseudoElement.h 2017-08-20 09:42:09 UTC (rev 220956)
@@ -42,9 +42,6 @@
Element* hostElement() const { return m_hostElement; }
void clearHostElement();
- std::optional<ElementStyle> resolveCustomStyle(const RenderStyle& parentStyle, const RenderStyle* shadowHostStyle) override;
- void didAttachRenderers() override;
- void didRecalcStyle(Style::Change) override;
bool rendererIsNeeded(const RenderStyle&) override;
// As per http://dev.w3.org/csswg/css3-regions/#flow-into, pseudo-elements such as ::first-line, ::first-letter, ::before or ::after
Modified: trunk/Source/WebCore/style/RenderTreeUpdater.cpp (220955 => 220956)
--- trunk/Source/WebCore/style/RenderTreeUpdater.cpp 2017-08-20 02:11:33 UTC (rev 220955)
+++ trunk/Source/WebCore/style/RenderTreeUpdater.cpp 2017-08-20 09:42:09 UTC (rev 220956)
@@ -41,8 +41,8 @@
#include "RenderFullScreen.h"
#include "RenderListItem.h"
#include "RenderNamedFlowThread.h"
-#include "RenderQuote.h"
#include "RenderTreeUpdaterFirstLetter.h"
+#include "RenderTreeUpdaterGeneratedContent.h"
#include "RenderTreeUpdaterListItem.h"
#include "StyleResolver.h"
#include "StyleTreeResolver.h"
@@ -82,12 +82,16 @@
{
}
-
RenderTreeUpdater::RenderTreeUpdater(Document& document)
: m_document(document)
+ , m_generatedContent(std::make_unique<GeneratedContent>(*this))
{
}
+RenderTreeUpdater::~RenderTreeUpdater()
+{
+}
+
static ContainerNode* findRenderingRoot(ContainerNode& node)
{
if (node.renderer())
@@ -129,11 +133,7 @@
for (auto* root : findRenderingRoots(*m_styleUpdate))
updateRenderTree(*root);
- if (m_document.renderView()->hasQuotesNeedingUpdate()) {
- updateQuotesUpTo(nullptr);
- m_previousUpdatedQuote = nullptr;
- m_document.renderView()->setHasQuotesNeedingUpdate(false);
- }
+ generatedContent().updateRemainingQuotes();
m_styleUpdate = nullptr;
}
@@ -247,12 +247,12 @@
void RenderTreeUpdater::updateBeforeDescendants(Element& element)
{
- updateBeforeOrAfterPseudoElement(element, BEFORE);
+ generatedContent().updateBeforePseudoElement(element);
}
void RenderTreeUpdater::updateAfterDescendants(Element& element, Style::Change styleChange)
{
- updateBeforeOrAfterPseudoElement(element, AFTER);
+ generatedContent().updateAfterPseudoElement(element);
auto* renderer = element.renderer();
if (!renderer)
@@ -347,7 +347,7 @@
{
if (!element.shouldMoveToFlowThread(style))
return;
- FlowThreadController& flowThreadController = element.document().renderView()->flowThreadController();
+ FlowThreadController& flowThreadController = renderView().flowThreadController();
flowThreadController.registerNamedFlowContentElement(element, flowThreadController.ensureRenderFlowThreadWithName(style.flowThread()));
}
#endif
@@ -518,75 +518,6 @@
}
}
-static bool needsPseudoElement(Element& current, PseudoId pseudoId)
-{
- if (!current.renderer() || !current.renderer()->canHaveGeneratedChildren())
- return false;
- if (current.isPseudoElement())
- return false;
- if (!pseudoElementRendererIsNeeded(current.renderer()->getCachedPseudoStyle(pseudoId)))
- return false;
- return true;
-}
-
-void RenderTreeUpdater::updateBeforeOrAfterPseudoElement(Element& current, PseudoId pseudoId)
-{
- PseudoElement* pseudoElement = pseudoId == BEFORE ? current.beforePseudoElement() : current.afterPseudoElement();
-
- if (auto* renderer = pseudoElement ? pseudoElement->renderer() : nullptr)
- renderTreePosition().invalidateNextSibling(*renderer);
-
- bool needsPseudoElement = WebCore::needsPseudoElement(current, pseudoId);
- if (!needsPseudoElement) {
- if (pseudoElement) {
- if (pseudoId == BEFORE)
- current.clearBeforePseudoElement();
- else
- current.clearAfterPseudoElement();
- }
- return;
- }
-
- RefPtr<PseudoElement> newPseudoElement;
- if (!pseudoElement) {
- newPseudoElement = PseudoElement::create(current, pseudoId);
- pseudoElement = newPseudoElement.get();
- }
-
- auto newStyle = RenderStyle::clonePtr(*current.renderer()->getCachedPseudoStyle(pseudoId, ¤t.renderer()->style()));
-
- auto elementUpdate = Style::TreeResolver::createAnimatedElementUpdate(WTFMove(newStyle), *pseudoElement, Style::NoChange);
-
- if (elementUpdate.change == Style::NoChange)
- return;
-
- if (newPseudoElement) {
- InspectorInstrumentation::pseudoElementCreated(m_document.page(), *newPseudoElement);
- if (pseudoId == BEFORE)
- current.setBeforePseudoElement(newPseudoElement.releaseNonNull());
- else
- current.setAfterPseudoElement(newPseudoElement.releaseNonNull());
- }
-
- updateElementRenderer(*pseudoElement, elementUpdate);
-
- auto* pseudoRenderer = pseudoElement->renderer();
- if (!pseudoRenderer)
- return;
-
- if (elementUpdate.change == Style::Detach)
- pseudoElement->didAttachRenderers();
- else
- pseudoElement->didRecalcStyle(elementUpdate.change);
-
- if (m_document.renderView()->hasQuotesNeedingUpdate()) {
- for (auto& child : descendantsOfType<RenderQuote>(*pseudoRenderer))
- updateQuotesUpTo(&child);
- }
- if (is<RenderListItem>(*pseudoRenderer))
- ListItem::updateMarker(downcast<RenderListItem>(*pseudoRenderer));
-}
-
void RenderTreeUpdater::tearDownRenderers(Element& root, TeardownType teardownType)
{
WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
@@ -642,20 +573,9 @@
text.setRenderer(nullptr);
}
-void RenderTreeUpdater::updateQuotesUpTo(RenderQuote* lastQuote)
+RenderView& RenderTreeUpdater::renderView()
{
- auto quoteRenderers = descendantsOfType<RenderQuote>(*m_document.renderView());
- auto it = m_previousUpdatedQuote ? ++quoteRenderers.at(*m_previousUpdatedQuote) : quoteRenderers.begin();
- auto end = quoteRenderers.end();
- for (; it != end; ++it) {
- auto& quote = *it;
- // Quote character depends on quote depth so we chain the updates.
- quote.updateRenderer(m_previousUpdatedQuote);
- m_previousUpdatedQuote = "e;
- if ("e == lastQuote)
- return;
- }
- ASSERT(!lastQuote);
+ return *m_document.renderView();
}
#if PLATFORM(IOS)
Modified: trunk/Source/WebCore/style/RenderTreeUpdater.h (220955 => 220956)
--- trunk/Source/WebCore/style/RenderTreeUpdater.h 2017-08-20 02:11:33 UTC (rev 220955)
+++ trunk/Source/WebCore/style/RenderTreeUpdater.h 2017-08-20 09:42:09 UTC (rev 220956)
@@ -37,7 +37,6 @@
class Document;
class Element;
class Node;
-class RenderQuote;
class RenderStyle;
class Text;
@@ -44,6 +43,7 @@
class RenderTreeUpdater {
public:
RenderTreeUpdater(Document&);
+ ~RenderTreeUpdater();
void commit(std::unique_ptr<const Style::Update>);
@@ -55,6 +55,8 @@
class ListItem;
private:
+ class GeneratedContent;
+
void updateRenderTree(ContainerNode& root);
void updateTextRenderer(Text&, const Style::TextUpdate*);
void updateElementRenderer(Element&, const Style::ElementUpdate&);
@@ -62,7 +64,6 @@
void invalidateWhitespaceOnlyTextSiblingsAfterAttachIfNeeded(Node&);
void updateBeforeDescendants(Element&);
void updateAfterDescendants(Element&, Style::Change);
- void updateBeforeOrAfterPseudoElement(Element&, PseudoId);
struct Parent {
Element* element { nullptr };
@@ -75,11 +76,13 @@
Parent& parent() { return m_parentStack.last(); }
RenderTreePosition& renderTreePosition();
+ GeneratedContent& generatedContent() { return *m_generatedContent; }
+
void pushParent(Element&, Style::Change);
void popParent();
void popParentsToDepth(unsigned depth);
- void updateQuotesUpTo(RenderQuote*);
+ RenderView& renderView();
Document& m_document;
std::unique_ptr<const Style::Update> m_styleUpdate;
@@ -87,7 +90,8 @@
Vector<Parent> m_parentStack;
HashSet<Text*> m_invalidatedWhitespaceOnlyTextSiblings;
- RenderQuote* m_previousUpdatedQuote { nullptr };
+
+ std::unique_ptr<GeneratedContent> m_generatedContent;
};
} // namespace WebCore
Added: trunk/Source/WebCore/style/RenderTreeUpdaterGeneratedContent.cpp (0 => 220956)
--- trunk/Source/WebCore/style/RenderTreeUpdaterGeneratedContent.cpp (rev 0)
+++ trunk/Source/WebCore/style/RenderTreeUpdaterGeneratedContent.cpp 2017-08-20 09:42:09 UTC (rev 220956)
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RenderTreeUpdaterGeneratedContent.h"
+
+#include "ContentData.h"
+#include "InspectorInstrumentation.h"
+#include "PseudoElement.h"
+#include "RenderDescendantIterator.h"
+#include "RenderElement.h"
+#include "RenderImage.h"
+#include "RenderQuote.h"
+#include "RenderTreeUpdater.h"
+#include "RenderTreeUpdaterListItem.h"
+#include "StyleTreeResolver.h"
+
+namespace WebCore {
+
+RenderTreeUpdater::GeneratedContent::GeneratedContent(RenderTreeUpdater& updater)
+ : m_updater(updater)
+{
+}
+
+void RenderTreeUpdater::GeneratedContent::updateBeforePseudoElement(Element& element)
+{
+ updatePseudoElement(element, BEFORE);
+}
+
+void RenderTreeUpdater::GeneratedContent::updateAfterPseudoElement(Element& element)
+{
+ updatePseudoElement(element, AFTER);
+}
+
+void RenderTreeUpdater::GeneratedContent::updateRemainingQuotes()
+{
+ if (!m_updater.renderView().hasQuotesNeedingUpdate())
+ return;
+ updateQuotesUpTo(nullptr);
+ m_previousUpdatedQuote = nullptr;
+ m_updater.renderView().setHasQuotesNeedingUpdate(false);
+}
+
+void RenderTreeUpdater::GeneratedContent::updateQuotesUpTo(RenderQuote* lastQuote)
+{
+ auto quoteRenderers = descendantsOfType<RenderQuote>(m_updater.renderView());
+ auto it = m_previousUpdatedQuote ? ++quoteRenderers.at(*m_previousUpdatedQuote) : quoteRenderers.begin();
+ auto end = quoteRenderers.end();
+ for (; it != end; ++it) {
+ auto& quote = *it;
+ // Quote character depends on quote depth so we chain the updates.
+ quote.updateRenderer(m_previousUpdatedQuote);
+ m_previousUpdatedQuote = "e;
+ if ("e == lastQuote)
+ return;
+ }
+ ASSERT(!lastQuote);
+}
+
+static void createContentRenderers(RenderElement& renderer)
+{
+ auto& style = renderer.style();
+ if (style.hasFlowFrom())
+ return;
+
+ ASSERT(style.contentData());
+
+ for (const ContentData* content = style.contentData(); content; content = content->next()) {
+ auto child = content->createContentRenderer(renderer.document(), style);
+ if (renderer.isChildAllowed(*child, style))
+ renderer.addChild(child.leakPtr());
+ }
+}
+
+static void updateStyleForContentRenderers(RenderElement& renderer)
+{
+ for (auto* child = renderer.nextInPreOrder(&renderer); child; child = child->nextInPreOrder(&renderer)) {
+ // We only manage the style for the generated content which must be images or text.
+ if (!is<RenderImage>(*child) && !is<RenderQuote>(*child))
+ continue;
+ auto createdStyle = RenderStyle::createStyleInheritingFromPseudoStyle(renderer.style());
+ downcast<RenderElement>(*child).setStyle(WTFMove(createdStyle));
+ }
+}
+
+void RenderTreeUpdater::GeneratedContent::updatePseudoElement(Element& current, PseudoId pseudoId)
+{
+ PseudoElement* pseudoElement = pseudoId == BEFORE ? current.beforePseudoElement() : current.afterPseudoElement();
+
+ if (auto* renderer = pseudoElement ? pseudoElement->renderer() : nullptr)
+ m_updater.renderTreePosition().invalidateNextSibling(*renderer);
+
+ if (!needsPseudoElement(current, pseudoId)) {
+ if (pseudoElement) {
+ if (pseudoId == BEFORE)
+ current.clearBeforePseudoElement();
+ else
+ current.clearAfterPseudoElement();
+ }
+ return;
+ }
+
+ RefPtr<PseudoElement> newPseudoElement;
+ if (!pseudoElement) {
+ newPseudoElement = PseudoElement::create(current, pseudoId);
+ pseudoElement = newPseudoElement.get();
+ }
+
+ auto newStyle = RenderStyle::clonePtr(*current.renderer()->getCachedPseudoStyle(pseudoId, ¤t.renderer()->style()));
+
+ auto elementUpdate = Style::TreeResolver::createAnimatedElementUpdate(WTFMove(newStyle), *pseudoElement, Style::NoChange);
+
+ if (elementUpdate.change == Style::NoChange)
+ return;
+
+ if (newPseudoElement) {
+ InspectorInstrumentation::pseudoElementCreated(m_updater.m_document.page(), *newPseudoElement);
+ if (pseudoId == BEFORE)
+ current.setBeforePseudoElement(newPseudoElement.releaseNonNull());
+ else
+ current.setAfterPseudoElement(newPseudoElement.releaseNonNull());
+ }
+
+ m_updater.updateElementRenderer(*pseudoElement, elementUpdate);
+
+ auto* pseudoRenderer = pseudoElement->renderer();
+ if (!pseudoRenderer)
+ return;
+
+ if (elementUpdate.change == Style::Detach)
+ createContentRenderers(*pseudoRenderer);
+ else
+ updateStyleForContentRenderers(*pseudoRenderer);
+
+ if (m_updater.renderView().hasQuotesNeedingUpdate()) {
+ for (auto& child : descendantsOfType<RenderQuote>(*pseudoRenderer))
+ updateQuotesUpTo(&child);
+ }
+ if (is<RenderListItem>(*pseudoRenderer))
+ ListItem::updateMarker(downcast<RenderListItem>(*pseudoRenderer));
+}
+
+bool RenderTreeUpdater::GeneratedContent::needsPseudoElement(Element& current, PseudoId pseudoId)
+{
+ if (!current.renderer() || !current.renderer()->canHaveGeneratedChildren())
+ return false;
+ if (current.isPseudoElement())
+ return false;
+ if (!pseudoElementRendererIsNeeded(current.renderer()->getCachedPseudoStyle(pseudoId)))
+ return false;
+ return true;
+}
+
+}
Added: trunk/Source/WebCore/style/RenderTreeUpdaterGeneratedContent.h (0 => 220956)
--- trunk/Source/WebCore/style/RenderTreeUpdaterGeneratedContent.h (rev 0)
+++ trunk/Source/WebCore/style/RenderTreeUpdaterGeneratedContent.h 2017-08-20 09:42:09 UTC (rev 220956)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "RenderStyleConstants.h"
+#include "RenderTreeUpdater.h"
+
+namespace WebCore {
+
+class Element;
+class RenderQuote;
+
+class RenderTreeUpdater::GeneratedContent {
+public:
+ GeneratedContent(RenderTreeUpdater&);
+
+ void updateBeforePseudoElement(Element&);
+ void updateAfterPseudoElement(Element&);
+ void updateRemainingQuotes();
+
+private:
+ void updatePseudoElement(Element&, PseudoId);
+ void updateQuotesUpTo(RenderQuote*);
+
+ static bool needsPseudoElement(Element&, PseudoId);
+
+ RenderTreeUpdater& m_updater;
+ RenderQuote* m_previousUpdatedQuote { nullptr };
+};
+
+}