Skip to content

Instantly share code, notes, and snippets.

@emilio
Created May 30, 2017 01:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emilio/9faec4ab5c6dd16ad6ccba4e098999ac to your computer and use it in GitHub Desktop.
Save emilio/9faec4ab5c6dd16ad6ccba4e098999ac to your computer and use it in GitHub Desktop.
From 2e1a9e798f07734f49b6aa6b1aa008189c7b32a6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <ecobos@igalia.com>
Date: Mon, 29 May 2017 13:41:51 +0200
Subject: [PATCH] Implement the updated semantics for display: contents on
replaced elements.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Emilio Cobos Álvarez <ecobos@igalia.com>
---
LayoutTests/TestExpectations | 2 --
Source/WebCore/dom/Element.cpp | 13 +++++++++----
Source/WebCore/dom/Element.h | 9 ++++++++-
Source/WebCore/dom/ElementRareData.h | 8 ++++----
Source/WebCore/html/HTMLAppletElement.h | 1 +
Source/WebCore/html/HTMLAudioElement.h | 1 +
Source/WebCore/html/HTMLBRElement.h | 1 +
Source/WebCore/html/HTMLCanvasElement.h | 1 +
Source/WebCore/html/HTMLEmbedElement.h | 1 +
Source/WebCore/html/HTMLFrameElement.h | 1 +
Source/WebCore/html/HTMLFrameSetElement.h | 1 +
Source/WebCore/html/HTMLIFrameElement.h | 1 +
Source/WebCore/html/HTMLImageElement.h | 1 +
Source/WebCore/html/HTMLInputElement.h | 2 ++
Source/WebCore/html/HTMLMeterElement.h | 1 +
Source/WebCore/html/HTMLObjectElement.h | 1 +
Source/WebCore/html/HTMLSelectElement.h | 1 +
Source/WebCore/html/HTMLTextAreaElement.h | 1 +
Source/WebCore/html/HTMLVideoElement.h | 1 +
Source/WebCore/html/HTMLWBRElement.h | 1 +
Source/WebCore/style/RenderTreeUpdater.cpp | 8 ++++----
Source/WebCore/svg/SVGElement.h | 2 ++
22 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/LayoutTests/TestExpectations b/LayoutTests/TestExpectations
index cf472442262..516912d7db4 100644
--- a/LayoutTests/TestExpectations
+++ b/LayoutTests/TestExpectations
@@ -1178,8 +1178,6 @@ webkit.org/b/157477 imported/w3c/web-platform-tests/css/css-display-3/display-co
webkit.org/b/157477 imported/w3c/web-platform-tests/css/css-display-3/display-contents-dynamic-list-001-inline.html [ ImageOnlyFailure ]
webkit.org/b/157477 imported/w3c/web-platform-tests/css/css-display-3/display-contents-dynamic-list-001-none.html [ ImageOnlyFailure ]
-webkit.org/b/172596 imported/w3c/web-platform-tests/css/css-display-3/display-contents-replaced-001.html [ Skip ]
-
### END OF display: contents failures
########################################
diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp
index c87a6d68e11..a09b9f93295 100644
--- a/Source/WebCore/dom/Element.cpp
+++ b/Source/WebCore/dom/Element.cpp
@@ -1467,14 +1467,19 @@ WebAnimationVector Element::getAnimations()
bool Element::hasDisplayContents() const
{
- return hasRareData() && elementRareData()->hasDisplayContents();
+ return hasSpecifiedDisplayContents() && !hasImplicitDisplayNoneForDisplayContents();
}
-void Element::setHasDisplayContents(bool value)
+bool Element::hasSpecifiedDisplayContents() const
{
- if (hasDisplayContents() == value)
+ return hasRareData() && elementRareData()->hasSpecifiedDisplayContents();
+}
+
+void Element::setHasSpecifiedDisplayContents(bool value)
+{
+ if (hasSpecifiedDisplayContents() == value)
return;
- ensureElementRareData().setHasDisplayContents(value);
+ ensureElementRareData().setHasSpecifiedDisplayContents(value);
}
// Returns true is the given attribute is an event handler.
diff --git a/Source/WebCore/dom/Element.h b/Source/WebCore/dom/Element.h
index 941469b5171..699f1bbc03a 100644
--- a/Source/WebCore/dom/Element.h
+++ b/Source/WebCore/dom/Element.h
@@ -543,7 +543,8 @@ public:
void invalidateStyleAndRenderersForSubtree();
bool hasDisplayContents() const;
- void setHasDisplayContents(bool);
+ bool hasSpecifiedDisplayContents() const;
+ void setHasSpecifiedDisplayContents(bool);
using ContainerNode::setAttributeEventListener;
void setAttributeEventListener(const AtomicString& eventType, const QualifiedName& attributeName, const AtomicString& value);
@@ -591,6 +592,12 @@ private:
virtual void didAddUserAgentShadowRoot(ShadowRoot*) { }
virtual bool alwaysCreateUserAgentShadowRoot() const { return false; }
+ // Returns whether this element should behave as display: none when
+ // display: contents is specified on it.
+ //
+ // See: https://drafts.csswg.org/css-display/#unbox
+ virtual bool hasImplicitDisplayNoneForDisplayContents() const { return false; }
+
// FIXME: Remove the need for Attr to call willModifyAttribute/didModifyAttribute.
friend class Attr;
diff --git a/Source/WebCore/dom/ElementRareData.h b/Source/WebCore/dom/ElementRareData.h
index ce3abd6361f..b0dab6fd329 100644
--- a/Source/WebCore/dom/ElementRareData.h
+++ b/Source/WebCore/dom/ElementRareData.h
@@ -118,8 +118,8 @@ public:
bool hasPendingResources() const { return m_hasPendingResources; }
void setHasPendingResources(bool has) { m_hasPendingResources = has; }
- bool hasDisplayContents() const { return m_hasDisplayContents; }
- void setHasDisplayContents(bool value) { m_hasDisplayContents = value; }
+ bool hasSpecifiedDisplayContents() const { return m_hasSpecifiedDisplayContents; }
+ void setHasSpecifiedDisplayContents(bool value) { m_hasSpecifiedDisplayContents = value; }
private:
int m_tabIndex;
@@ -141,7 +141,7 @@ private:
unsigned m_childrenAffectedByLastChildRules : 1;
unsigned m_childrenAffectedByBackwardPositionalRules : 1;
unsigned m_childrenAffectedByPropertyBasedBackwardPositionalRules : 1;
- unsigned m_hasDisplayContents : 1;
+ unsigned m_hasSpecifiedDisplayContents : 1;
unsigned m_isNamedFlowContentElement : 1;
RegionOversetState m_regionOversetState;
@@ -185,7 +185,7 @@ inline ElementRareData::ElementRareData(RenderElement* renderer)
, m_childrenAffectedByLastChildRules(false)
, m_childrenAffectedByBackwardPositionalRules(false)
, m_childrenAffectedByPropertyBasedBackwardPositionalRules(false)
- , m_hasDisplayContents(false)
+ , m_hasSpecifiedDisplayContents(false)
, m_isNamedFlowContentElement(false)
, m_regionOversetState(RegionUndefined)
, m_minimumSizeForResizing(defaultMinimumSizeForResizing())
diff --git a/Source/WebCore/html/HTMLAppletElement.h b/Source/WebCore/html/HTMLAppletElement.h
index 4d5d324a53c..6b5435ad5f0 100644
--- a/Source/WebCore/html/HTMLAppletElement.h
+++ b/Source/WebCore/html/HTMLAppletElement.h
@@ -33,6 +33,7 @@ public:
private:
HTMLAppletElement(const QualifiedName&, Document&, bool createdByParser);
+ bool hasImplicitDisplayNoneForDisplayContents() const final { return true; }
void parseAttribute(const QualifiedName&, const AtomicString&) final;
bool isURLAttribute(const Attribute&) const final;
diff --git a/Source/WebCore/html/HTMLAudioElement.h b/Source/WebCore/html/HTMLAudioElement.h
index 6ec7494d1de..83110822d36 100644
--- a/Source/WebCore/html/HTMLAudioElement.h
+++ b/Source/WebCore/html/HTMLAudioElement.h
@@ -42,6 +42,7 @@ public:
private:
HTMLAudioElement(const QualifiedName&, Document&, bool);
+ bool hasImplicitDisplayNoneForDisplayContents() const final { return true; }
PlatformMediaSession::MediaType presentationType() const final { return PlatformMediaSession::Audio; }
};
diff --git a/Source/WebCore/html/HTMLBRElement.h b/Source/WebCore/html/HTMLBRElement.h
index bf446311d5a..b59fb49f5a0 100644
--- a/Source/WebCore/html/HTMLBRElement.h
+++ b/Source/WebCore/html/HTMLBRElement.h
@@ -37,6 +37,7 @@ public:
private:
HTMLBRElement(const QualifiedName&, Document&);
+ bool hasImplicitDisplayNoneForDisplayContents() const final { return true; }
bool isPresentationAttribute(const QualifiedName&) const final;
void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) final;
diff --git a/Source/WebCore/html/HTMLCanvasElement.h b/Source/WebCore/html/HTMLCanvasElement.h
index 0fac4a1018d..5bfd130ef39 100644
--- a/Source/WebCore/html/HTMLCanvasElement.h
+++ b/Source/WebCore/html/HTMLCanvasElement.h
@@ -160,6 +160,7 @@ public:
private:
HTMLCanvasElement(const QualifiedName&, Document&);
+ bool hasImplicitDisplayNoneForDisplayContents() const final { return true; }
void parseAttribute(const QualifiedName&, const AtomicString&) final;
RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final;
diff --git a/Source/WebCore/html/HTMLEmbedElement.h b/Source/WebCore/html/HTMLEmbedElement.h
index ffa5a7ed487..d8a6bfa1e8c 100644
--- a/Source/WebCore/html/HTMLEmbedElement.h
+++ b/Source/WebCore/html/HTMLEmbedElement.h
@@ -34,6 +34,7 @@ public:
private:
HTMLEmbedElement(const QualifiedName&, Document&, bool createdByParser);
+ bool hasImplicitDisplayNoneForDisplayContents() const final { return true; }
void parseAttribute(const QualifiedName&, const AtomicString&) final;
bool isPresentationAttribute(const QualifiedName&) const final;
void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) final;
diff --git a/Source/WebCore/html/HTMLFrameElement.h b/Source/WebCore/html/HTMLFrameElement.h
index 4f08ab04612..7c12a3d1b3c 100644
--- a/Source/WebCore/html/HTMLFrameElement.h
+++ b/Source/WebCore/html/HTMLFrameElement.h
@@ -41,6 +41,7 @@ public:
private:
HTMLFrameElement(const QualifiedName&, Document&);
+ bool hasImplicitDisplayNoneForDisplayContents() const final { return true; }
void didAttachRenderers() final;
bool rendererIsNeeded(const RenderStyle&) final;
RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final;
diff --git a/Source/WebCore/html/HTMLFrameSetElement.h b/Source/WebCore/html/HTMLFrameSetElement.h
index 6dc1ad669f6..0ab76255c72 100644
--- a/Source/WebCore/html/HTMLFrameSetElement.h
+++ b/Source/WebCore/html/HTMLFrameSetElement.h
@@ -49,6 +49,7 @@ public:
private:
HTMLFrameSetElement(const QualifiedName&, Document&);
+ bool hasImplicitDisplayNoneForDisplayContents() const final { return true; }
void parseAttribute(const QualifiedName&, const AtomicString&) final;
bool isPresentationAttribute(const QualifiedName&) const final;
void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) final;
diff --git a/Source/WebCore/html/HTMLIFrameElement.h b/Source/WebCore/html/HTMLIFrameElement.h
index 1626e0b9820..c76639a7634 100644
--- a/Source/WebCore/html/HTMLIFrameElement.h
+++ b/Source/WebCore/html/HTMLIFrameElement.h
@@ -41,6 +41,7 @@ public:
private:
HTMLIFrameElement(const QualifiedName&, Document&);
+ bool hasImplicitDisplayNoneForDisplayContents() const final { return true; }
#if PLATFORM(IOS)
bool isKeyboardFocusable(KeyboardEvent&) const final { return false; }
#endif
diff --git a/Source/WebCore/html/HTMLImageElement.h b/Source/WebCore/html/HTMLImageElement.h
index cd2e5e76355..a1fecf77482 100644
--- a/Source/WebCore/html/HTMLImageElement.h
+++ b/Source/WebCore/html/HTMLImageElement.h
@@ -100,6 +100,7 @@ protected:
void didMoveToNewDocument(Document& oldDocument) override;
private:
+ bool hasImplicitDisplayNoneForDisplayContents() const final { return true; }
void parseAttribute(const QualifiedName&, const AtomicString&) override;
bool isPresentationAttribute(const QualifiedName&) const override;
void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override;
diff --git a/Source/WebCore/html/HTMLInputElement.h b/Source/WebCore/html/HTMLInputElement.h
index b49ccc2d2c6..c12d2225544 100644
--- a/Source/WebCore/html/HTMLInputElement.h
+++ b/Source/WebCore/html/HTMLInputElement.h
@@ -341,6 +341,8 @@ protected:
private:
enum AutoCompleteSetting { Uninitialized, On, Off };
+ bool hasImplicitDisplayNoneForDisplayContents() const final { return true; }
+
void didAddUserAgentShadowRoot(ShadowRoot*) final;
void willChangeForm() final;
diff --git a/Source/WebCore/html/HTMLMeterElement.h b/Source/WebCore/html/HTMLMeterElement.h
index 604a65a9e3a..15e6534d79c 100644
--- a/Source/WebCore/html/HTMLMeterElement.h
+++ b/Source/WebCore/html/HTMLMeterElement.h
@@ -66,6 +66,7 @@ private:
HTMLMeterElement(const QualifiedName&, Document&);
virtual ~HTMLMeterElement();
+ bool hasImplicitDisplayNoneForDisplayContents() const final { return true; }
RenderMeter* renderMeter() const;
bool supportLabels() const final { return true; }
diff --git a/Source/WebCore/html/HTMLObjectElement.h b/Source/WebCore/html/HTMLObjectElement.h
index 9ea893b01d4..7f3cdcbc1b3 100644
--- a/Source/WebCore/html/HTMLObjectElement.h
+++ b/Source/WebCore/html/HTMLObjectElement.h
@@ -59,6 +59,7 @@ public:
private:
HTMLObjectElement(const QualifiedName&, Document&, HTMLFormElement*, bool createdByParser);
+ bool hasImplicitDisplayNoneForDisplayContents() const final { return true; }
void parseAttribute(const QualifiedName&, const AtomicString&) final;
bool isPresentationAttribute(const QualifiedName&) const final;
void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) final;
diff --git a/Source/WebCore/html/HTMLSelectElement.h b/Source/WebCore/html/HTMLSelectElement.h
index 6f91d57f55b..bf14fd20acf 100644
--- a/Source/WebCore/html/HTMLSelectElement.h
+++ b/Source/WebCore/html/HTMLSelectElement.h
@@ -109,6 +109,7 @@ protected:
HTMLSelectElement(const QualifiedName&, Document&, HTMLFormElement*);
private:
+ bool hasImplicitDisplayNoneForDisplayContents() const final { return true; }
const AtomicString& formControlType() const final;
bool isKeyboardFocusable(KeyboardEvent&) const final;
diff --git a/Source/WebCore/html/HTMLTextAreaElement.h b/Source/WebCore/html/HTMLTextAreaElement.h
index b9a3224c750..a1aa285d478 100644
--- a/Source/WebCore/html/HTMLTextAreaElement.h
+++ b/Source/WebCore/html/HTMLTextAreaElement.h
@@ -72,6 +72,7 @@ private:
enum WrapMethod { NoWrap, SoftWrap, HardWrap };
void didAddUserAgentShadowRoot(ShadowRoot*) final;
+ bool hasImplicitDisplayNoneForDisplayContents() const final { return true; }
void maxLengthAttributeChanged(const AtomicString& newValue);
void minLengthAttributeChanged(const AtomicString& newValue);
diff --git a/Source/WebCore/html/HTMLVideoElement.h b/Source/WebCore/html/HTMLVideoElement.h
index b3ef13deeaa..6602bc0b797 100644
--- a/Source/WebCore/html/HTMLVideoElement.h
+++ b/Source/WebCore/html/HTMLVideoElement.h
@@ -92,6 +92,7 @@ public:
private:
HTMLVideoElement(const QualifiedName&, Document&, bool createdByParser);
+ bool hasImplicitDisplayNoneForDisplayContents() const final { return true; }
void scheduleResizeEvent() final;
void scheduleResizeEventIfSizeChanged() final;
bool rendererIsNeeded(const RenderStyle&) final;
diff --git a/Source/WebCore/html/HTMLWBRElement.h b/Source/WebCore/html/HTMLWBRElement.h
index da815f4f7e4..b157399b357 100644
--- a/Source/WebCore/html/HTMLWBRElement.h
+++ b/Source/WebCore/html/HTMLWBRElement.h
@@ -40,6 +40,7 @@ public:
private:
HTMLWBRElement(const QualifiedName&, Document&);
+ bool hasImplicitDisplayNoneForDisplayContents() const final { return true; }
RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final;
};
diff --git a/Source/WebCore/style/RenderTreeUpdater.cpp b/Source/WebCore/style/RenderTreeUpdater.cpp
index df4b80101ec..247e2385e27 100644
--- a/Source/WebCore/style/RenderTreeUpdater.cpp
+++ b/Source/WebCore/style/RenderTreeUpdater.cpp
@@ -267,14 +267,14 @@ void RenderTreeUpdater::updateElementRenderer(Element& element, const Style::Ele
tearDownRenderers(element, TeardownType::KeepHoverAndActive);
}
- bool hasDisplayContents = update.style->display() == CONTENTS;
- if (hasDisplayContents != element.hasDisplayContents()) {
- element.setHasDisplayContents(hasDisplayContents);
+ bool hasSpecifiedDisplayContents = update.style->display() == CONTENTS;
+ if (hasSpecifiedDisplayContents != element.hasSpecifiedDisplayContents()) {
+ element.setHasSpecifiedDisplayContents(hasSpecifiedDisplayContents);
// Render tree position needs to be recomputed as rendering siblings may be found from the display:contents subtree.
renderTreePosition().invalidateNextSibling();
}
- bool shouldCreateNewRenderer = !element.renderer() && !hasDisplayContents;
+ bool shouldCreateNewRenderer = !element.renderer() && !hasSpecifiedDisplayContents;
if (shouldCreateNewRenderer) {
if (element.hasCustomStyleResolveCallbacks())
element.willAttachRenderers();
diff --git a/Source/WebCore/svg/SVGElement.h b/Source/WebCore/svg/SVGElement.h
index 283e6c89654..3dde3503d32 100644
--- a/Source/WebCore/svg/SVGElement.h
+++ b/Source/WebCore/svg/SVGElement.h
@@ -177,6 +177,8 @@ protected:
private:
const RenderStyle* computedStyle(PseudoId = NOPSEUDO) final;
+ bool hasImplicitDisplayNoneForDisplayContents() const final { return true; }
+
virtual void clearTarget() { }
void buildPendingResourcesIfNeeded();
--
2.13.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment