Title: [295197] branches/safari-613-branch
Revision
295197
Author
alanc...@apple.com
Date
2022-06-02 23:46:08 -0700 (Thu, 02 Jun 2022)

Log Message

Cherry-pick d323be61003f. rdar://problem/14839536

    Breaking out of a quoted reply block by inserting a new paragraph should reset writing direction
    https://bugs.webkit.org/show_bug.cgi?id=240778
    rdar://14839536

    Reviewed by Devin Rousso.

    The process of breaking out of a `blockquote` via the "InsertNewlineInQuotedContent" editor command currently works by
    splitting the `blockquote` into two sibling elements underneath the same parent container, and then inserting a `br`
    element in between these sibling `blockquote` elements. The selection is then moved to the end of the newly created
    `br`, which inherits the writing direction (`dir`) of the element containing the `blockquote`. In the case of Mail, if
    the system language is right-to-left but the quoted content is left-to-right, this can lead to some unintuitive behavior
    when breaking out of quoted LTR content, since the newly created line break will inherit the right-to-left direction of
    its ancestor.

    To fix this, in the case where we're breaking out of a `blockquote` and the start of the selection is left-to-right but
    the element that contains the `blockquote` is right-to-left, we can wrap the `br` in another block-level container
    element with `dir=auto` to avoid inheriting the writing direction from the `blockquote`'s ancestor. This means that the
    writing direction of the newly inserted paragraph will automatically be determined by what the user types.

    Test: editing/execCommand/reset-direction-after-breaking-blockquote.html

    * LayoutTests/editing/execCommand/reset-direction-after-breaking-blockquote-expected.txt: Added.
    * LayoutTests/editing/execCommand/reset-direction-after-breaking-blockquote.html: Added.
    * Source/WebCore/editing/BreakBlockquoteCommand.cpp:
    (WebCore::BreakBlockquoteCommand::doApply):

    Canonical link: https://commits.webkit.org/250901@main
    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294714 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Added Paths

Diff

Added: branches/safari-613-branch/LayoutTests/editing/execCommand/reset-direction-after-breaking-blockquote-expected.txt (0 => 295197)


--- branches/safari-613-branch/LayoutTests/editing/execCommand/reset-direction-after-breaking-blockquote-expected.txt	                        (rev 0)
+++ branches/safari-613-branch/LayoutTests/editing/execCommand/reset-direction-after-breaking-blockquote-expected.txt	2022-06-03 06:46:08 UTC (rev 295197)
@@ -0,0 +1,23 @@
+| "\n    "
+| <p>
+|   "Start of right to left content"
+| "\n    "
+| <blockquote>
+|   type="cite"
+|   "\n        "
+|   <p>
+|     dir="ltr"
+|     id="target"
+|     "Some quoted content"
+| <div>
+|   dir="auto"
+|   <#selection-caret>
+|   <br>
+| <blockquote>
+|   type="cite"
+|   "\n        "
+|   <p>
+|     dir="ltr"
+|     "End of quoted content"
+|   "\n    "
+| "\n"

Added: branches/safari-613-branch/LayoutTests/editing/execCommand/reset-direction-after-breaking-blockquote.html (0 => 295197)


--- branches/safari-613-branch/LayoutTests/editing/execCommand/reset-direction-after-breaking-blockquote.html	                        (rev 0)
+++ branches/safari-613-branch/LayoutTests/editing/execCommand/reset-direction-after-breaking-blockquote.html	2022-06-03 06:46:08 UTC (rev 295197)
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<style>
+blockquote {
+    border-left: 2px solid lightblue;
+    padding-left: 1em;
+}
+</style>
+</head>
+<body>
+<p id="description">
+    This tests that the writing direction is reset to its natural value after breaking out of a blockquote in the case
+    where the writing direction at the previous selection differs from the writing direction of the newly inserted
+    paragraph.
+</p>
+<div contenteditable id="editor" dir="rtl">
+    <p>Start of right to left content</p>
+    <blockquote type="cite">
+        <p dir="ltr" id="target">Some quoted content</p>
+        <p dir="ltr">End of quoted content</p>
+    </blockquote>
+</div>
+<script>
+getSelection().setPosition(document.getElementById("target"), 1);
+document.execCommand("InsertNewlineInQuotedContent", true);
+Markup.dump("editor");
+</script>
+</body>
+</html>
\ No newline at end of file

Modified: branches/safari-613-branch/Source/WebCore/editing/BreakBlockquoteCommand.cpp (295196 => 295197)


--- branches/safari-613-branch/Source/WebCore/editing/BreakBlockquoteCommand.cpp	2022-06-03 06:46:05 UTC (rev 295196)
+++ branches/safari-613-branch/Source/WebCore/editing/BreakBlockquoteCommand.cpp	2022-06-03 06:46:08 UTC (rev 295197)
@@ -26,10 +26,13 @@
 #include "config.h"
 #include "BreakBlockquoteCommand.h"
 
+#include "CommonAtomStrings.h"
 #include "Editing.h"
 #include "ElementInlines.h"
 #include "HTMLBRElement.h"
+#include "HTMLDivElement.h"
 #include "HTMLNames.h"
+#include "NodeRenderStyle.h"
 #include "NodeTraversal.h"
 #include "RenderListItem.h"
 #include "Text.h"
@@ -67,17 +70,34 @@
     Position pos = endingSelection().start().downstream();
     
     // Find the top-most blockquote from the start.
-    Node* topBlockquote = highestEnclosingNodeOfType(pos, isMailBlockquote);
+    RefPtr topBlockquote = highestEnclosingNodeOfType(pos, isMailBlockquote);
     if (!topBlockquote || !topBlockquote->parentNode() || !topBlockquote->isElementNode())
         return;
-    
-    auto breakNode = HTMLBRElement::create(document());
 
-    bool isLastVisPosInNode = isLastVisiblePositionInNode(visiblePos, topBlockquote);
+    auto breakNode = [&]() -> Ref<HTMLElement> {
+        auto lineBreak = HTMLBRElement::create(document());
+        RefPtr containerNode = pos.containerNode();
+        if (!containerNode || !containerNode->renderStyle())
+            return lineBreak;
 
+        auto* parentStyle = topBlockquote->parentNode()->renderStyle();
+        if (!parentStyle)
+            return lineBreak;
+
+        if (parentStyle->direction() == containerNode->renderStyle()->direction())
+            return lineBreak;
+
+        auto container = HTMLDivElement::create(document());
+        container->setDir(autoAtom());
+        container->appendChild(lineBreak);
+        return container;
+    }();
+
+    bool isLastVisPosInNode = isLastVisiblePositionInNode(visiblePos, topBlockquote.get());
+
     // If the position is at the beginning of the top quoted content, we don't need to break the quote.
     // Instead, insert the break before the blockquote, unless the position is as the end of the quoted content.
-    if (isFirstVisiblePositionInNode(visiblePos, topBlockquote) && !isLastVisPosInNode) {
+    if (isFirstVisiblePositionInNode(visiblePos, topBlockquote.get()) && !isLastVisPosInNode) {
         insertNodeBefore(breakNode.copyRef(), *topBlockquote);
         setEndingSelection(VisibleSelection(positionBeforeNode(breakNode.ptr()), Affinity::Downstream, endingSelection().isDirectional()));
         rebalanceWhitespace();   
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to