Source/WebCore:
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Dec 2016 16:08:04 +0000 (16:08 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Dec 2016 16:08:04 +0000 (16:08 +0000)
REGRESSION (r198990): Cannot edit content inside <details> in wysiwyg editor
https://bugs.webkit.org/show_bug.cgi?id=165757

Reviewed by Andreas Kling.

Test: fast/html/details-edit.html

-webkit-user-modify is reset on shadow boundary so it doesn't go through <details> shadow tree.

* css/StyleResolver.cpp:
(WebCore::StyleResolver::styleForElement):
(WebCore::StyleResolver::pseudoStyleForElement):
(WebCore::StyleResolver::styleForPage):
(WebCore::StyleResolver::applyMatchedProperties):
* dom/Node.cpp:
(WebCore::computeEditabilityFromComputedStyle):
(WebCore::Node::computeEditability):

    Make -webkit-user-modify (which we would want to get rid of completely eventually) have no effect in shadow trees.
    Check for contenteditable directly instead.

* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::createInnerTextStyle):
* html/HTMLTextAreaElement.cpp:
(WebCore::HTMLTextAreaElement::createInnerTextStyle):
* html/shadow/TextControlInnerElements.cpp:
* rendering/RenderFlowThread.cpp:
(WebCore::RenderFlowThread::createFlowThreadStyle):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::calculateClipRects):
* rendering/RenderListItem.cpp:
(WebCore::RenderListItem::styleDidChange):
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::createAnonymousStyleWithDisplay):
(WebCore::RenderStyle::createStyleInheritingFromPseudoStyle):
(WebCore::RenderStyle::inheritFrom):

    Let -webkit-user-modify inherit through shadow boundary as normal.

* rendering/style/RenderStyle.h:

LayoutTests:
REGRESSION (r198990): Safari - Cannot edit content inside <details> in wysiwyg editor
https://bugs.webkit.org/show_bug.cgi?id=165757

Reviewed by Andreas Kling.

* editing/execCommand/justify-right-then-indent-with-problematic-body-expected.txt:
* fast/html/details-edit-expected.txt: Added.
* fast/html/details-edit.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@209756 268f45cc-cd09-0410-ab3c-d52691b4dbfc

15 files changed:
LayoutTests/ChangeLog
LayoutTests/editing/execCommand/justify-right-then-indent-with-problematic-body-expected.txt
LayoutTests/fast/html/details-edit-expected.txt [new file with mode: 0644]
LayoutTests/fast/html/details-edit.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/css/StyleResolver.cpp
Source/WebCore/dom/Node.cpp
Source/WebCore/html/HTMLInputElement.cpp
Source/WebCore/html/HTMLTextAreaElement.cpp
Source/WebCore/html/shadow/TextControlInnerElements.cpp
Source/WebCore/rendering/RenderFlowThread.cpp
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderListItem.cpp
Source/WebCore/rendering/style/RenderStyle.cpp
Source/WebCore/rendering/style/RenderStyle.h

index cd487f2..ef07cbc 100644 (file)
@@ -1,3 +1,14 @@
+2016-12-13  Antti Koivisto  <antti@apple.com>
+
+        REGRESSION (r198990): Safari - Cannot edit content inside <details> in wysiwyg editor
+        https://bugs.webkit.org/show_bug.cgi?id=165757
+
+        Reviewed by Andreas Kling.
+
+        * editing/execCommand/justify-right-then-indent-with-problematic-body-expected.txt:
+        * fast/html/details-edit-expected.txt: Added.
+        * fast/html/details-edit.html: Added.
+
 2016-12-13  Per Arne Vollan  <pvollan@apple.com>
 
         Unreviewed test gardening.
diff --git a/LayoutTests/fast/html/details-edit-expected.txt b/LayoutTests/fast/html/details-edit-expected.txt
new file mode 100644 (file)
index 0000000..7ef22e9
--- /dev/null
@@ -0,0 +1 @@
+PASS
diff --git a/LayoutTests/fast/html/details-edit.html b/LayoutTests/fast/html/details-edit.html
new file mode 100644 (file)
index 0000000..361c730
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+</script>
+<body contenteditable>
+<details open>
+<p>FAIL</p>
+</details>
+<script>
+var p = document.querySelector("p");
+var selection = window.getSelection();
+selection.selectAllChildren(p);
+document.execCommand("InsertText", false, "PASS");
+</script>
index a34dc6d..a55f3e0 100644 (file)
@@ -1,3 +1,46 @@
+2016-12-13  Antti Koivisto  <antti@apple.com>
+
+        REGRESSION (r198990): Cannot edit content inside <details> in wysiwyg editor
+        https://bugs.webkit.org/show_bug.cgi?id=165757
+
+        Reviewed by Andreas Kling.
+
+        Test: fast/html/details-edit.html
+
+        -webkit-user-modify is reset on shadow boundary so it doesn't go through <details> shadow tree.
+
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::styleForElement):
+        (WebCore::StyleResolver::pseudoStyleForElement):
+        (WebCore::StyleResolver::styleForPage):
+        (WebCore::StyleResolver::applyMatchedProperties):
+        * dom/Node.cpp:
+        (WebCore::computeEditabilityFromComputedStyle):
+        (WebCore::Node::computeEditability):
+
+            Make -webkit-user-modify (which we would want to get rid of completely eventually) have no effect in shadow trees.
+            Check for contenteditable directly instead.
+
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::createInnerTextStyle):
+        * html/HTMLTextAreaElement.cpp:
+        (WebCore::HTMLTextAreaElement::createInnerTextStyle):
+        * html/shadow/TextControlInnerElements.cpp:
+        * rendering/RenderFlowThread.cpp:
+        (WebCore::RenderFlowThread::createFlowThreadStyle):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::calculateClipRects):
+        * rendering/RenderListItem.cpp:
+        (WebCore::RenderListItem::styleDidChange):
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::createAnonymousStyleWithDisplay):
+        (WebCore::RenderStyle::createStyleInheritingFromPseudoStyle):
+        (WebCore::RenderStyle::inheritFrom):
+
+            Let -webkit-user-modify inherit through shadow boundary as normal.
+
+        * rendering/style/RenderStyle.h:
+
 2016-12-12  Darin Adler  <darin@apple.com>
 
         Remove bindings generation support for legacy WebCore::Dictionary
index cc04c88..ea21e9b 100644 (file)
@@ -393,7 +393,7 @@ ElementStyle StyleResolver::styleForElement(const Element& element, const Render
 
     if (state.parentStyle()) {
         state.setStyle(RenderStyle::createPtr());
-        state.style()->inheritFrom(state.parentStyle(), isAtShadowBoundary(element) ? RenderStyle::AtShadowBoundary : RenderStyle::NotAtShadowBoundary);
+        state.style()->inheritFrom(*state.parentStyle());
     } else {
         state.setStyle(defaultStyleForElement());
         state.setParentStyle(RenderStyle::clonePtr(*state.style()));
@@ -605,7 +605,7 @@ std::unique_ptr<RenderStyle> StyleResolver::pseudoStyleForElement(const Element&
 
     if (m_state.parentStyle()) {
         state.setStyle(RenderStyle::createPtr());
-        state.style()->inheritFrom(m_state.parentStyle());
+        state.style()->inheritFrom(*m_state.parentStyle());
     } else {
         state.setStyle(defaultStyleForElement());
         state.setParentStyle(RenderStyle::clonePtr(*state.style()));
@@ -655,7 +655,7 @@ std::unique_ptr<RenderStyle> StyleResolver::styleForPage(int pageIndex)
     m_state = State(*documentElement, m_document.renderStyle());
 
     m_state.setStyle(RenderStyle::createPtr());
-    m_state.style()->inheritFrom(m_state.rootElementStyle());
+    m_state.style()->inheritFrom(*m_state.rootElementStyle());
 
     PageRuleCollector collector(m_state, m_ruleSets);
     collector.matchAllPageRules(pageIndex);
@@ -1338,7 +1338,7 @@ void StyleResolver::applyMatchedProperties(const MatchResult& matchResult, const
             EInsideLink linkStatus = state.style()->insideLink();
             // If the cache item parent style has identical inherited properties to the current parent style then the
             // resulting style will be identical too. We copy the inherited properties over from the cache and are done.
-            state.style()->inheritFrom(cacheItem->renderStyle.get());
+            state.style()->inheritFrom(*cacheItem->renderStyle);
 
             // Unfortunately the link status is treated like an inherited property. We need to explicitly restore it.
             state.style()->setInsideLink(linkStatus);
index ebf8200..e4fbc5d 100644 (file)
@@ -701,7 +701,10 @@ Node::Editability Node::computeEditability(UserSelectAllTreatment treatment, Sho
     if (!document().hasLivingRenderTree() || isPseudoElement())
         return Editability::ReadOnly;
 
-    if (document().frame() && document().frame()->page() && document().frame()->page()->isEditable() && !containingShadowRoot())
+    if (isInShadowTree())
+        return HTMLElement::editabilityFromContentEditableAttr(*this);
+
+    if (document().frame() && document().frame()->page() && document().frame()->page()->isEditable())
         return Editability::CanEditRichly;
 
     if (shouldUpdateStyle == ShouldUpdateStyle::Update && document().needsStyleRecalc()) {
index cd3a612..6c1d8b3 100644 (file)
@@ -1948,7 +1948,7 @@ bool HTMLInputElement::shouldTruncateText(const RenderStyle& style) const
 RenderStyle HTMLInputElement::createInnerTextStyle(const RenderStyle& style) const
 {
     auto textBlockStyle = RenderStyle::create();
-    textBlockStyle.inheritFrom(&style);
+    textBlockStyle.inheritFrom(style);
     adjustInnerTextStyle(style, textBlockStyle);
 
     textBlockStyle.setWhiteSpace(PRE);
index 99fa8d7..c41bc8f 100644 (file)
@@ -569,7 +569,7 @@ bool HTMLTextAreaElement::willRespondToMouseClickEvents()
 RenderStyle HTMLTextAreaElement::createInnerTextStyle(const RenderStyle& style) const
 {
     auto textBlockStyle = RenderStyle::create();
-    textBlockStyle.inheritFrom(&style);
+    textBlockStyle.inheritFrom(style);
     adjustInnerTextStyle(style, textBlockStyle);
     textBlockStyle.setDisplay(BLOCK);
 
index 7901c6a..584da68 100644 (file)
@@ -78,7 +78,7 @@ Ref<TextControlInnerElement> TextControlInnerElement::create(Document& document)
 std::optional<ElementStyle> TextControlInnerElement::resolveCustomStyle(const RenderStyle&, const RenderStyle* shadowHostStyle)
 {
     auto innerContainerStyle = RenderStyle::createPtr();
-    innerContainerStyle->inheritFrom(shadowHostStyle);
+    innerContainerStyle->inheritFrom(*shadowHostStyle);
 
     innerContainerStyle->setFlexGrow(1);
     // min-width: 0; is needed for correct shrinking.
index 8967ab9..480da5f 100644 (file)
@@ -71,7 +71,7 @@ RenderFlowThread::RenderFlowThread(Document& document, RenderStyle&& style)
 RenderStyle RenderFlowThread::createFlowThreadStyle(const RenderStyle* parentStyle)
 {
     auto newStyle = RenderStyle::create();
-    newStyle.inheritFrom(parentStyle);
+    newStyle.inheritFrom(*parentStyle);
     newStyle.setDisplay(BLOCK);
     newStyle.setPosition(AbsolutePosition);
     newStyle.setZIndex(0);
index 4d1d72c..530d7ba 100644 (file)
@@ -6935,7 +6935,7 @@ void RenderLayer::removeReflection()
 RenderStyle RenderLayer::createReflectionStyle()
 {
     auto newStyle = RenderStyle::create();
-    newStyle.inheritFrom(&renderer().style());
+    newStyle.inheritFrom(renderer().style());
     
     // Map in our transform.
     TransformOperations transform;
index ab841a0..440bd2d 100644 (file)
@@ -79,7 +79,7 @@ void RenderListItem::styleDidChange(StyleDifference diff, const RenderStyle* old
     auto newStyle = RenderStyle::create();
     // The marker always inherits from the list item, regardless of where it might end
     // up (e.g., in some deeply nested line box). See CSS3 spec.
-    newStyle.inheritFrom(&style());
+    newStyle.inheritFrom(style());
     if (!m_marker) {
         m_marker = createRenderer<RenderListMarker>(*this, WTFMove(newStyle)).leakPtr();
         m_marker->initializeStyle();
index b628d58..d18551e 100644 (file)
@@ -112,7 +112,7 @@ std::unique_ptr<RenderStyle> RenderStyle::clonePtr(const RenderStyle& style)
 RenderStyle RenderStyle::createAnonymousStyleWithDisplay(const RenderStyle& parentStyle, EDisplay display)
 {
     auto newStyle = create();
-    newStyle.inheritFrom(&parentStyle);
+    newStyle.inheritFrom(parentStyle);
     newStyle.inheritUnicodeBidiFrom(&parentStyle);
     newStyle.setDisplay(display);
     return newStyle;
@@ -123,7 +123,7 @@ RenderStyle RenderStyle::createStyleInheritingFromPseudoStyle(const RenderStyle&
     ASSERT(pseudoStyle.styleType() == BEFORE || pseudoStyle.styleType() == AFTER);
 
     auto style = create();
-    style.inheritFrom(&pseudoStyle);
+    style.inheritFrom(pseudoStyle);
     return style;
 }
 
@@ -267,20 +267,14 @@ ContentDistributionType RenderStyle::resolvedAlignContentDistribution(const Styl
     return resolvedContentAlignmentDistribution(alignContent(), normalValueBehavior);
 }
 
-void RenderStyle::inheritFrom(const RenderStyle* inheritParent, IsAtShadowBoundary isAtShadowBoundary)
+void RenderStyle::inheritFrom(const RenderStyle& inheritParent)
 {
-    if (isAtShadowBoundary == AtShadowBoundary) {
-        // Even if surrounding content is user-editable, shadow DOM should act as a single unit, and not necessarily be editable
-        EUserModify currentUserModify = userModify();
-        rareInheritedData = inheritParent->rareInheritedData;
-        setUserModify(currentUserModify);
-    } else
-        rareInheritedData = inheritParent->rareInheritedData;
-    inherited = inheritParent->inherited;
-    inherited_flags = inheritParent->inherited_flags;
+    rareInheritedData = inheritParent.rareInheritedData;
+    inherited = inheritParent.inherited;
+    inherited_flags = inheritParent.inherited_flags;
 
-    if (m_svgStyle != inheritParent->m_svgStyle)
-        m_svgStyle.access()->inheritFrom(inheritParent->m_svgStyle.get());
+    if (m_svgStyle != inheritParent.m_svgStyle)
+        m_svgStyle.access()->inheritFrom(inheritParent.m_svgStyle.get());
 }
 
 void RenderStyle::copyNonInheritedFrom(const RenderStyle* other)
index d7bc5ae..a4f0a03 100644 (file)
@@ -510,12 +510,7 @@ public:
     StyleSelfAlignmentData resolvedJustifyItems(ItemPosition normalValueBehaviour) const;
     StyleSelfAlignmentData resolvedJustifySelf(const RenderStyle& parentStyle, ItemPosition normalValueBehaviour) const;
 
-    enum IsAtShadowBoundary {
-        AtShadowBoundary,
-        NotAtShadowBoundary,
-    };
-
-    void inheritFrom(const RenderStyle* inheritParent, IsAtShadowBoundary = NotAtShadowBoundary);
+    void inheritFrom(const RenderStyle& inheritParent);
     void copyNonInheritedFrom(const RenderStyle*);
 
     PseudoId styleType() const { return noninherited_flags.styleType(); }