Changeset 243124 in webkit


Ignore:
Timestamp:
Mar 18, 2019 6:56:39 PM (5 years ago)
Author:
Megan Gardner
Message:

Smart Insert for paragraphs.
https://bugs.webkit.org/show_bug.cgi?id=194880

Reviewed by Ryosuke Niwa.

Source/WebCore:

Add additional newlines to maintain spacing around paragraphs.

Tests: editing/pasteboard/smart-paste-paragraph-001.html

editing/pasteboard/smart-paste-paragraph-002.html
editing/pasteboard/smart-paste-paragraph-003.html
editing/pasteboard/smart-paste-paragraph-004.html

  • dom/Document.cpp:

(WebCore::Document::editingBehavior const):

  • dom/Document.h:

Expose editing behaviour through document so that is can be access from the selection commands
and allow the editing behaviour to be used.

  • editing/CompositeEditCommand.h:
  • editing/EditingBehavior.h:

(WebCore::EditingBehavior::shouldSmartInsertDeleteParagraphs const):

Only have editing insert paragraphs on iOS and in editing elements that support multiple lines.

  • editing/ReplaceSelectionCommand.cpp:

(WebCore::ReplaceSelectionCommand::doApply):
(WebCore::ReplaceSelectionCommand::shouldPerformSmartParagraphReplace const):
(WebCore::ReplaceSelectionCommand::addNewLinesForSmartReplace):

  • editing/ReplaceSelectionCommand.h:

Add addititional newlines when pasting full paragraphs to maintian two newlines between paragraphs
if that is what the original document had. If there are not multiple lines between paragraphs, do not
add additional new lines.

LayoutTests:

List tests are covered by paste-list-00*.
Table tests are covered by paste-table-00* and paste-into-table-*.

  • editing/pasteboard/smart-paste-paragraph-001-expected.txt: Added.
  • editing/pasteboard/smart-paste-paragraph-001.html: Added.
  • editing/pasteboard/smart-paste-paragraph-002-expected.txt: Added.
  • editing/pasteboard/smart-paste-paragraph-002.html: Added.
  • editing/pasteboard/smart-paste-paragraph-003-expected.txt: Added.
  • editing/pasteboard/smart-paste-paragraph-003.html: Added.
  • editing/pasteboard/smart-paste-paragraph-004-expected.txt: Added.
  • editing/pasteboard/smart-paste-paragraph-004.html: Added.
  • platform/ios-wk2/editing/pasteboard/paste-text-016-expected.txt:

This needed to be rebaselined to match the new behaviour.

  • platform/ios/editing/pasteboard/smart-paste-paragraph-001-expected.txt: Added.
  • platform/ios/editing/pasteboard/smart-paste-paragraph-002-expected.txt: Added.
  • platform/ios/editing/pasteboard/smart-paste-paragraph-003-expected.txt: Added.
  • platform/ios/editing/pasteboard/smart-paste-paragraph-004-expected.txt: Added.
Location:
trunk
Files:
12 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r243109 r243124  
     12019-03-18  Megan Gardner  <megan_gardner@apple.com>
     2
     3        Smart Insert for paragraphs.
     4        https://bugs.webkit.org/show_bug.cgi?id=194880
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        List tests are covered by paste-list-00*.
     9        Table tests are covered by paste-table-00* and paste-into-table-*.
     10
     11        * editing/pasteboard/smart-paste-paragraph-001-expected.txt: Added.
     12        * editing/pasteboard/smart-paste-paragraph-001.html: Added.
     13        * editing/pasteboard/smart-paste-paragraph-002-expected.txt: Added.
     14        * editing/pasteboard/smart-paste-paragraph-002.html: Added.
     15        * editing/pasteboard/smart-paste-paragraph-003-expected.txt: Added.
     16        * editing/pasteboard/smart-paste-paragraph-003.html: Added.
     17        * editing/pasteboard/smart-paste-paragraph-004-expected.txt: Added.
     18        * editing/pasteboard/smart-paste-paragraph-004.html: Added.
     19        * platform/ios-wk2/editing/pasteboard/paste-text-016-expected.txt:
     20        This needed to be rebaselined to match the new behaviour.
     21        * platform/ios/editing/pasteboard/smart-paste-paragraph-001-expected.txt: Added.
     22        * platform/ios/editing/pasteboard/smart-paste-paragraph-002-expected.txt: Added.
     23        * platform/ios/editing/pasteboard/smart-paste-paragraph-003-expected.txt: Added.
     24        * platform/ios/editing/pasteboard/smart-paste-paragraph-004-expected.txt: Added.
     25
    1262019-03-18  Jer Noble  <jer.noble@apple.com>
    227
  • trunk/LayoutTests/platform/ios-wk2/editing/pasteboard/paste-text-016-expected.txt

    r222051 r243124  
    3939          text run at (0,20) width 384: "***TEST*** line should be second, following the first line."
    4040      RenderBlock {DIV} at (0,40) size 784x12
    41       RenderBlock {DIV} at (0,52) size 784x238
    42         RenderBlock {DIV} at (0,0) size 784x238 [border: (2px solid #FF0000)]
     41      RenderBlock {DIV} at (0,52) size 784x268
     42        RenderBlock {DIV} at (0,0) size 784x268 [border: (2px solid #FF0000)]
    4343          RenderBlock {P} at (14,14) size 756x30
    4444            RenderText {#text} at (0,1) size 316x28
     
    4646            RenderBR {BR} at (315,23) size 1x0
    4747          RenderBlock {P} at (14,44) size 756x30
     48            RenderBR {BR} at (0,1) size 0x28
     49          RenderBlock {P} at (14,74) size 756x30
    4850            RenderText {#text} at (0,1) size 130x28
    4951              text run at (0,1) width 130: "***TEST***"
    50           RenderBlock {DIV} at (14,74) size 756x30
     52          RenderBlock {DIV} at (14,104) size 756x30
    5153            RenderBR {BR} at (0,1) size 0x28
    52           RenderBlock {P} at (14,104) size 756x30
     54          RenderBlock {P} at (14,134) size 756x30
    5355            RenderText {#text} at (0,1) size 127x28
    5456              text run at (0,1) width 127: "Another line."
    55           RenderBlock {P} at (14,134) size 756x0
    56           RenderBlock (anonymous) at (14,134) size 756x30
    57             RenderText {#text} at (0,1) size 6x28
    58               text run at (0,1) width 6: " "
    5957          RenderBlock {P} at (14,164) size 756x0
    6058          RenderBlock (anonymous) at (14,164) size 756x30
    6159            RenderText {#text} at (0,1) size 6x28
    6260              text run at (0,1) width 6: " "
    63           RenderBlock {P} at (14,194) size 756x30
     61          RenderBlock {P} at (14,194) size 756x0
     62          RenderBlock (anonymous) at (14,194) size 756x30
     63            RenderText {#text} at (0,1) size 6x28
     64              text run at (0,1) width 6: " "
     65          RenderBlock {P} at (14,224) size 756x30
    6466            RenderBR {BR} at (0,1) size 0x28
    65 caret: position 0 of child 0 {BR} of child 2 {DIV} of child 1 {DIV} of child 7 {DIV} of body
     67caret: position 0 of child 0 {BR} of child 3 {DIV} of child 1 {DIV} of child 7 {DIV} of body
  • trunk/Source/WebCore/ChangeLog

    r243122 r243124  
     12019-03-18  Megan Gardner  <megan_gardner@apple.com>
     2
     3        Smart Insert for paragraphs.
     4        https://bugs.webkit.org/show_bug.cgi?id=194880
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        Add additional newlines to maintain spacing around paragraphs.
     9
     10        Tests: editing/pasteboard/smart-paste-paragraph-001.html
     11               editing/pasteboard/smart-paste-paragraph-002.html
     12               editing/pasteboard/smart-paste-paragraph-003.html
     13               editing/pasteboard/smart-paste-paragraph-004.html
     14
     15        * dom/Document.cpp:
     16        (WebCore::Document::editingBehavior const):
     17        * dom/Document.h:
     18
     19        Expose editing behaviour through document so that is can be access from the selection commands
     20        and allow the editing behaviour to be used.
     21
     22        * editing/CompositeEditCommand.h:
     23        * editing/EditingBehavior.h:
     24        (WebCore::EditingBehavior::shouldSmartInsertDeleteParagraphs const):
     25
     26        Only have editing insert paragraphs on iOS and in editing elements that support multiple lines.
     27
     28        * editing/ReplaceSelectionCommand.cpp:
     29        (WebCore::ReplaceSelectionCommand::doApply):
     30        (WebCore::ReplaceSelectionCommand::shouldPerformSmartParagraphReplace const):
     31        (WebCore::ReplaceSelectionCommand::addNewLinesForSmartReplace):
     32        * editing/ReplaceSelectionCommand.h:
     33
     34        Add addititional newlines when pasting full paragraphs to maintian two newlines between paragraphs
     35        if that is what the original document had. If there are not multiple lines between paragraphs, do not
     36        add additional new lines.
     37
    1382019-03-18  Ryosuke Niwa  <rniwa@webkit.org>
    239
  • trunk/Source/WebCore/dom/Document.cpp

    r243122 r243124  
    74317431    return fontSelector().fontFaceSet();
    74327432}
     7433   
     7434EditingBehavior Document::editingBehavior() const
     7435{
     7436    return EditingBehavior { settings().editingBehaviorType() };
     7437}
    74337438
    74347439float Document::deviceScaleFactor() const
  • trunk/Source/WebCore/dom/Document.h

    r243122 r243124  
    117117class DocumentTimeline;
    118118class DocumentType;
     119class EditingBehavior;
    119120class ExtensionStyleSheets;
    120121class FloatQuad;
     
    563564    const Settings& settings() const { return m_settings.get(); }
    564565    Settings& mutableSettings() { return m_settings.get(); }
     566    EditingBehavior editingBehavior() const;
    565567
    566568    const Quirks& quirks() const { return m_quirks; }
  • trunk/Source/WebCore/editing/CompositeEditCommand.h

    r240476 r243124  
    153153    void insertNodeAtTabSpanPosition(Ref<Node>&&, const Position&);
    154154    void insertNodeBefore(Ref<Node>&&, Node& refChild, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable);
     155    void insertParagraphSeparatorAtPosition(const Position&, bool useDefaultParagraphElement = false, bool pasteBlockqutoeIntoUnquotedArea = false);
    155156    void insertParagraphSeparator(bool useDefaultParagraphElement = false, bool pasteBlockqutoeIntoUnquotedArea = false);
    156157    void insertLineBreak();
  • trunk/Source/WebCore/editing/EditingBehavior.h

    r241719 r243124  
    9999    // On iOS, when smart delete is on, it is always on, and should do not additional checks (i.e. WordGranularity).
    100100    bool shouldAlwaysSmartDelete() const { return m_type == EditingIOSBehavior; }
     101   
     102    // On iOS, we should turn on smart insert and delete and newlines around paragraphs to match UIKit behaviour.
     103    bool shouldSmartInsertDeleteParagraphs() const { return m_type == EditingIOSBehavior; }
    101104
    102105private:
  • trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp

    r241932 r243124  
    778778    return true;
    779779}
     780   
     781static bool isBlankLine(VisiblePosition& position)
     782{
     783    return isStartOfLine(position) && startOfLine(position.next()) != startOfLine(position);
     784}
    780785
    781786// At copy time, WebKit wraps copied content in a span that contains the source document's
     
    924929    m_documentFragmentHTMLMarkup = serializeFragment(*m_documentFragment, SerializedNodes::SubtreeIncludingNode);
    925930    return CompositeEditCommand::willApplyCommand();
     931}
     932   
     933static bool hasBlankLineBetweenParagraphs(Position& position)
     934{
     935    bool reachedBoundaryStart = false;
     936    bool reachedBoundaryEnd = false;
     937    VisiblePosition visiblePosition(position);
     938    VisiblePosition previousPosition = visiblePosition.previous(CannotCrossEditingBoundary, &reachedBoundaryStart);
     939    VisiblePosition nextPosition = visiblePosition.next(CannotCrossEditingBoundary, &reachedBoundaryStart);
     940    bool hasLineBeforePosition = isEndOfLine(previousPosition);
     941   
     942    return !reachedBoundaryStart && !reachedBoundaryEnd && isBlankLine(visiblePosition) && hasLineBeforePosition && isStartOfLine(nextPosition);
    926943}
    927944
     
    10701087    insertionPos = positionOutsideTabSpan(insertionPos);
    10711088
     1089    bool hasBlankLinesBetweenParagraphs = hasBlankLineBetweenParagraphs(insertionPos);
     1090   
    10721091    bool handledStyleSpans = handleStyleSpansBeforeInsertion(fragment, insertionPos);
    10731092
     
    11211140
    11221141    Node* blockStart = enclosingBlock(insertionPos.deprecatedNode());
    1123     if ((isListHTMLElement(refNode.get()) || (isLegacyAppleStyleSpan(refNode.get()) && isListHTMLElement(refNode->firstChild())))
    1124         && blockStart && blockStart->renderer()->isListItem())
     1142    bool isInsertingIntoList = (isListHTMLElement(refNode.get()) || (isLegacyAppleStyleSpan(refNode.get()) && isListHTMLElement(refNode->firstChild())))
     1143    && blockStart && blockStart->renderer()->isListItem();
     1144    if (isInsertingIntoList)
    11251145        refNode = insertAsListItems(downcast<HTMLElement>(*refNode), blockStart, insertionPos, insertedNodes);
    11261146    else {
     
    12711291        addSpacesForSmartReplace();
    12721292
     1293    if (!isInsertingIntoList && hasBlankLinesBetweenParagraphs && shouldPerformSmartParagraphReplace())
     1294        addNewLinesForSmartReplace();
     1295
    12731296    // If we are dealing with a fragment created from plain text
    12741297    // no style matching is necessary.
     
    13261349    return true;
    13271350}
     1351   
     1352bool ReplaceSelectionCommand::shouldPerformSmartParagraphReplace() const
     1353{
     1354    if (!m_smartReplace)
     1355        return false;
     1356
     1357    if (!document().editingBehavior().shouldSmartInsertDeleteParagraphs())
     1358        return false;
     1359
     1360    return true;
     1361}
    13281362
    13291363static bool isCharacterSmartReplaceExemptConsideringNonBreakingSpace(UChar32 character, bool previousCharacter)
    13301364{
    13311365    return isCharacterSmartReplaceExempt(character == noBreakSpace ? ' ' : character, previousCharacter);
     1366}
     1367
     1368void ReplaceSelectionCommand::addNewLinesForSmartReplace()
     1369{
     1370    VisiblePosition startOfInsertedContent = positionAtStartOfInsertedContent();
     1371    VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent();
     1372
     1373    bool isPastedContentEntireParagraphs = isStartOfParagraph(startOfInsertedContent) && isEndOfParagraph(endOfInsertedContent);
     1374
     1375    // If we aren't pasting a paragraph, no need to attempt to insert newlines.
     1376    if (!isPastedContentEntireParagraphs)
     1377        return;
     1378
     1379    bool reachedBoundaryStart = false;
     1380    bool reachedBoundaryEnd = false;
     1381    VisiblePosition positionBeforeStart = startOfInsertedContent.previous(CannotCrossEditingBoundary, &reachedBoundaryStart);
     1382    VisiblePosition positionAfterEnd = endOfInsertedContent.next(CannotCrossEditingBoundary, &reachedBoundaryEnd);
     1383
     1384    if (!reachedBoundaryStart && !reachedBoundaryEnd) {
     1385        if (!isBlankLine(positionBeforeStart) && !isBlankLine(startOfInsertedContent) && isEndOfLine(positionBeforeStart) && !isEndOfEditableOrNonEditableContent(positionAfterEnd) && !isEndOfEditableOrNonEditableContent(endOfInsertedContent)) {
     1386            setEndingSelection(startOfInsertedContent);
     1387            insertParagraphSeparator();
     1388            auto newStart = endingSelection().visibleStart().previous(CannotCrossEditingBoundary, &reachedBoundaryStart);
     1389            if (!reachedBoundaryStart)
     1390                m_startOfInsertedContent = newStart.deepEquivalent();
     1391        }
     1392    }
     1393
     1394    reachedBoundaryStart = false;
     1395    reachedBoundaryEnd = false;
     1396    positionAfterEnd = endOfInsertedContent.next(CannotCrossEditingBoundary, &reachedBoundaryEnd);
     1397    positionBeforeStart = startOfInsertedContent.previous(CannotCrossEditingBoundary, &reachedBoundaryStart);
     1398
     1399    if (!reachedBoundaryEnd && !reachedBoundaryStart) {
     1400        if (!isBlankLine(positionAfterEnd) && !isBlankLine(endOfInsertedContent) && isStartOfLine(positionAfterEnd) && !isEndOfLine(positionAfterEnd) && !isEndOfEditableOrNonEditableContent(positionAfterEnd)) {
     1401            setEndingSelection(endOfInsertedContent);
     1402            insertParagraphSeparator();
     1403            m_endOfInsertedContent = endingSelection().start();
     1404        }
     1405    }
    13321406}
    13331407
  • trunk/Source/WebCore/editing/ReplaceSelectionCommand.h

    r235775 r243124  
    109109
    110110    bool shouldPerformSmartReplace() const;
     111    bool shouldPerformSmartParagraphReplace() const;
    111112    void addSpacesForSmartReplace();
     113    void addNewLinesForSmartReplace();
    112114    void completeHTMLReplacement(const Position& lastPositionToSelect);
    113115    void mergeTextNodesAroundPosition(Position&, Position& positionOnlyToBeUpdated);
Note: See TracChangeset for help on using the changeset viewer.