⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 294714 in webkit


Ignore:
Timestamp:
May 23, 2022, 7:06:58 PM (4 years ago)
Author:
Wenson Hsieh
Message:

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

Location:
trunk
Files:
2 added
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/editing/BreakBlockquoteCommand.cpp

    r285920 r294714  
    2727#include "BreakBlockquoteCommand.h"
    2828
     29#include "CommonAtomStrings.h"
    2930#include "Editing.h"
    3031#include "ElementInlines.h"
    3132#include "HTMLBRElement.h"
     33#include "HTMLDivElement.h"
    3234#include "HTMLNames.h"
     35#include "NodeRenderStyle.h"
    3336#include "NodeTraversal.h"
    3437#include "RenderListItem.h"
     
    6871   
    6972    // Find the top-most blockquote from the start.
    70     Node* topBlockquote = highestEnclosingNodeOfType(pos, isMailBlockquote);
     73    RefPtr topBlockquote = highestEnclosingNodeOfType(pos, isMailBlockquote);
    7174    if (!topBlockquote || !topBlockquote->parentNode() || !topBlockquote->isElementNode())
    7275        return;
    73    
    74     auto breakNode = HTMLBRElement::create(document());
    75 
    76     bool isLastVisPosInNode = isLastVisiblePositionInNode(visiblePos, topBlockquote);
     76
     77    auto breakNode = [&]() -> Ref<HTMLElement> {
     78        auto lineBreak = HTMLBRElement::create(document());
     79        RefPtr containerNode = pos.containerNode();
     80        if (!containerNode || !containerNode->renderStyle())
     81            return lineBreak;
     82
     83        auto* parentStyle = topBlockquote->parentNode()->renderStyle();
     84        if (!parentStyle)
     85            return lineBreak;
     86
     87        if (parentStyle->direction() == containerNode->renderStyle()->direction())
     88            return lineBreak;
     89
     90        auto container = HTMLDivElement::create(document());
     91        container->setDir(autoAtom());
     92        container->appendChild(lineBreak);
     93        return container;
     94    }();
     95
     96    bool isLastVisPosInNode = isLastVisiblePositionInNode(visiblePos, topBlockquote.get());
    7797
    7898    // If the position is at the beginning of the top quoted content, we don't need to break the quote.
    7999    // Instead, insert the break before the blockquote, unless the position is as the end of the quoted content.
    80     if (isFirstVisiblePositionInNode(visiblePos, topBlockquote) && !isLastVisPosInNode) {
     100    if (isFirstVisiblePositionInNode(visiblePos, topBlockquote.get()) && !isLastVisPosInNode) {
    81101        insertNodeBefore(breakNode.copyRef(), *topBlockquote);
    82102        setEndingSelection(VisibleSelection(positionBeforeNode(breakNode.ptr()), Affinity::Downstream, endingSelection().isDirectional()));
Note: See TracChangeset for help on using the changeset viewer.