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

Changeset 243296 in webkit


Ignore:
Timestamp:
Mar 21, 2019, 10:03:17 AM (7 years ago)
Author:
Megan Gardner
Message:

Smart delete for paragraphs.
https://bugs.webkit.org/show_bug.cgi?id=195837

Reviewed by Ryosuke Niwa.

Remove additional newlines to maintain spacing around paragraphs.

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

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

  • editing/DeleteSelectionCommand.cpp:

(WebCore::isBlankLine):
(WebCore::DeleteSelectionCommand::initializePositionData):

Location:
trunk
Files:
13 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r243290 r243296  
     12019-03-21  Megan Gardner  <megan_gardner@apple.com>
     2
     3        Smart delete for paragraphs.
     4        https://bugs.webkit.org/show_bug.cgi?id=195837
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        Remove additional newlines to maintain spacing around paragraphs.
     9
     10        Tests: editing/pasteboard/smart-delete-paragraph-001.html
     11               editing/pasteboard/smart-delete-paragraph-002.html
     12               editing/pasteboard/smart-delete-paragraph-003.html
     13               editing/pasteboard/smart-delete-paragraph-004.html
     14
     15        * editing/DeleteSelectionCommand.cpp:
     16        (WebCore::isBlankLine):
     17        (WebCore::DeleteSelectionCommand::initializePositionData):
     18
    1192019-03-21  Cathie Chen  <cathiechen@igalia.com>
    220
  • trunk/Source/WebCore/editing/DeleteSelectionCommand.cpp

    r239535 r243296  
    173173}
    174174   
     175bool DeleteSelectionCommand::shouldSmartDeleteParagraphSpacers()
     176{
     177    return document().editingBehavior().shouldSmartInsertDeleteParagraphs();
     178}
     179   
     180void DeleteSelectionCommand::smartDeleteParagraphSpacers()
     181{
     182    VisiblePosition visibleStart { m_upstreamStart };
     183    VisiblePosition visibleEnd { m_downstreamEnd };
     184    bool selectionEndsInParagraphSeperator = isEndOfParagraph(visibleEnd);
     185    bool selectionEndIsEndOfContent = endOfEditableContent(visibleEnd) == visibleEnd;
     186    bool startAndEndInSameUnsplittableElement = unsplittableElementForPosition(visibleStart.deepEquivalent()) == unsplittableElementForPosition(visibleEnd.deepEquivalent());
     187    visibleStart = visibleStart.previous(CannotCrossEditingBoundary);
     188    visibleEnd = visibleEnd.next(CannotCrossEditingBoundary);
     189    bool previousPositionIsBlankParagraph = isBlankParagraph(visibleStart);
     190    bool endPositonIsBlankParagraph = isBlankParagraph(visibleEnd);
     191    bool hasBlankParagraphAfterEndOrIsEndOfContent = !selectionEndIsEndOfContent && (endPositonIsBlankParagraph || selectionEndsInParagraphSeperator);
     192    if (startAndEndInSameUnsplittableElement && previousPositionIsBlankParagraph && hasBlankParagraphAfterEndOrIsEndOfContent) {
     193        m_needPlaceholder = false;
     194        Position position;
     195        if (endPositonIsBlankParagraph)
     196            position = startOfNextParagraph(startOfNextParagraph(m_downstreamEnd)).deepEquivalent();
     197        else
     198            position = VisiblePosition(m_downstreamEnd).next().deepEquivalent();
     199        m_upstreamEnd = position.upstream();
     200        m_downstreamEnd = position.downstream();
     201        m_trailingWhitespace = m_downstreamEnd.trailingWhitespacePosition(VP_DEFAULT_AFFINITY);
     202        setStartingSelectionOnSmartDelete(m_upstreamStart, m_downstreamEnd);
     203    }
     204    if (startAndEndInSameUnsplittableElement && selectionEndIsEndOfContent && previousPositionIsBlankParagraph && selectionEndsInParagraphSeperator) {
     205        m_needPlaceholder = false;
     206        VisiblePosition endOfParagraphBeforeStart = endOfParagraph(VisiblePosition { m_upstreamStart }.previous().previous());
     207        Position position = endOfParagraphBeforeStart.deepEquivalent();
     208        m_upstreamStart = position.upstream();
     209        m_downstreamStart = position.downstream();
     210        m_leadingWhitespace = m_upstreamStart.leadingWhitespacePosition(DOWNSTREAM);
     211        setStartingSelectionOnSmartDelete(m_upstreamStart, m_upstreamEnd);
     212    }
     213}
     214   
    175215bool DeleteSelectionCommand::initializePositionData()
    176216{
     
    266306            setStartingSelectionOnSmartDelete(m_downstreamStart, m_downstreamEnd);
    267307        }
     308   
     309        if (shouldSmartDeleteParagraphSpacers())
     310            smartDeleteParagraphSpacers();
    268311    }
    269312   
  • trunk/Source/WebCore/editing/DeleteSelectionCommand.h

    r235775 r243296  
    7070    void deleteTextFromNode(Text&, unsigned, unsigned) override;
    7171    void removeRedundantBlocks();
     72    bool shouldSmartDeleteParagraphSpacers();
     73    void smartDeleteParagraphSpacers();
    7274
    7375    // This function provides access to original string after the correction has been deleted.
  • trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp

    r243124 r243296  
    778778    return true;
    779779}
    780    
    781 static bool isBlankLine(VisiblePosition& position)
    782 {
    783     return isStartOfLine(position) && startOfLine(position.next()) != startOfLine(position);
    784 }
    785780
    786781// At copy time, WebKit wraps copied content in a span that contains the source document's
     
    940935    bool hasLineBeforePosition = isEndOfLine(previousPosition);
    941936   
    942     return !reachedBoundaryStart && !reachedBoundaryEnd && isBlankLine(visiblePosition) && hasLineBeforePosition && isStartOfLine(nextPosition);
     937    return !reachedBoundaryStart && !reachedBoundaryEnd && isBlankParagraph(visiblePosition) && hasLineBeforePosition && isStartOfLine(nextPosition);
    943938}
    944939
     
    13831378
    13841379    if (!reachedBoundaryStart && !reachedBoundaryEnd) {
    1385         if (!isBlankLine(positionBeforeStart) && !isBlankLine(startOfInsertedContent) && isEndOfLine(positionBeforeStart) && !isEndOfEditableOrNonEditableContent(positionAfterEnd) && !isEndOfEditableOrNonEditableContent(endOfInsertedContent)) {
     1380        if (!isBlankParagraph(positionBeforeStart) && !isBlankParagraph(startOfInsertedContent) && isEndOfLine(positionBeforeStart) && !isEndOfEditableOrNonEditableContent(positionAfterEnd) && !isEndOfEditableOrNonEditableContent(endOfInsertedContent)) {
    13861381            setEndingSelection(startOfInsertedContent);
    13871382            insertParagraphSeparator();
     
    13981393
    13991394    if (!reachedBoundaryEnd && !reachedBoundaryStart) {
    1400         if (!isBlankLine(positionAfterEnd) && !isBlankLine(endOfInsertedContent) && isStartOfLine(positionAfterEnd) && !isEndOfLine(positionAfterEnd) && !isEndOfEditableOrNonEditableContent(positionAfterEnd)) {
     1395        if (!isBlankParagraph(positionAfterEnd) && !isBlankParagraph(endOfInsertedContent) && isStartOfLine(positionAfterEnd) && !isEndOfLine(positionAfterEnd) && !isEndOfEditableOrNonEditableContent(positionAfterEnd)) {
    14011396            setEndingSelection(endOfInsertedContent);
    14021397            insertParagraphSeparator();
  • trunk/Source/WebCore/editing/VisibleUnits.cpp

    r239535 r243296  
    13781378    return pos.isNotNull() && pos == endOfParagraph(pos, boundaryCrossingRule);
    13791379}
     1380   
     1381bool isBlankParagraph(const VisiblePosition& position)
     1382{
     1383    return isStartOfParagraph(position) && startOfParagraph(position.next()) != startOfParagraph(position);
     1384}
    13801385
    13811386VisiblePosition previousParagraphPosition(const VisiblePosition& p, int x)
  • trunk/Source/WebCore/editing/VisibleUnits.h

    r218748 r243296  
    7676WEBCORE_EXPORT bool isEndOfParagraph(const VisiblePosition &, EditingBoundaryCrossingRule = CannotCrossEditingBoundary);
    7777bool inSameParagraph(const VisiblePosition &, const VisiblePosition &, EditingBoundaryCrossingRule = CannotCrossEditingBoundary);
     78bool isBlankParagraph(const VisiblePosition &);
    7879
    7980// blocks (true paragraphs; line break elements don't break blocks)
Note: See TracChangeset for help on using the changeset viewer.