Changeset 148597 in webkit


Ignore:
Timestamp:
Apr 17, 2013 3:29:24 AM (11 years ago)
Author:
Claudio Saavedra
Message:

execCommand("RemoveFormat") might remove format after the selection
https://bugs.webkit.org/show_bug.cgi?id=112240

Reviewed by Ryosuke Niwa.

Source/WebCore:

Tests: editing/execCommand/remove-format-multiple-elements-mac.html

This bug is hit when ApplyStyleCommand is used to change the
style and the current selection ends in the beginning of a new node.
The bug is actually a two-fold thing:

  1. There was no check as to whether the end node is really

selected or not, and format was always removed from it with
pushDownInlineStyleAroundNode(). An equivalent check for the start
node was already in place, so fix it analogously.

  1. Previous stage might change the dom tree, resulting in a render

tree that is not up-to-date. Position::upstream() is later used
and, in order to be able to find a visually equivalent position in
a text node, this method needs the render tree to be up-to-date,
therefore, a call to updateLayoutIgnorePendingStylesheets() is
necessary.

  • editing/ApplyStyleCommand.cpp:

(WebCore::ApplyStyleCommand::removeInlineStyle): Make sure that no
format is removed from the end node if it's not fully selected.
(WebCore::ApplyStyleCommand::nodeFullySelected): Call updateLayoutIgnorePendingStylesheets()

LayoutTests:

  • editing/execCommand/remove-format-multiple-elements-mac-expected.txt: Updated.
  • editing/execCommand/script-tests/remove-format-multiple-elements-mac.js:

(selectFirstLine): Add this method to check that RemoveFormat works when
a whole line is selected.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r148596 r148597  
     12013-04-17  Claudio Saavedra  <csaavedra@igalia.com>
     2
     3        execCommand("RemoveFormat") might remove format after the selection
     4        https://bugs.webkit.org/show_bug.cgi?id=112240
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        * editing/execCommand/remove-format-multiple-elements-mac-expected.txt: Updated.
     9        * editing/execCommand/script-tests/remove-format-multiple-elements-mac.js:
     10        (selectFirstLine): Add this method to check that RemoveFormat works when
     11        a whole line is selected.
     12
    1132013-04-17  Zoltan Arvai  <zarvai@inf.u-szeged.hu>
    214
  • trunk/LayoutTests/editing/execCommand/remove-format-multiple-elements-mac-expected.txt

    r147035 r148597  
    1717PASS RemoveFormat on last two words of "<q><b><div>hello world</div></b>WebKit</q>" yields "<div><q><b>hello </b></q>world</div>WebKit"
    1818PASS RemoveFormat on second word of "<q><b><div>hello world</div></b>WebKit</q>" yields "<div><q><b>hello </b></q>world</div><q>WebKit</q>"
     19PASS RemoveFormat on first line of "<b><div>hello</div>webkit</b>" yields "<div>hello</div><b>webkit</b>"
    1920PASS RemoveFormat on all of "<i style="font-weight:bold;">hello</i> <u>world</u>" yields "hello world"
    2021PASS RemoveFormat on second word of "<font color="red"><b style="font-size: large;"><u>hello</u> world</b> WebKit</font>" yields "<font color="red"><b style="font-size: large;"><u>hello</u> </b></font>world<font color="red"> WebKit</font>"
  • trunk/LayoutTests/editing/execCommand/script-tests/remove-format-multiple-elements-mac.js

    r147035 r148597  
    5252}
    5353
     54function selectFirstLine(container) {
     55    window.getSelection().setPosition(container, 0);
     56    window.getSelection().modify('extend', 'forward', 'line');
     57    return 'first line';
     58}
     59
    5460testRemoveFormat('hello', selectAll, 'hello');
    5561testRemoveFormat('<i>hello</i> <u>world</u>', selectAll, 'hello world');
     
    6773testRemoveFormat('<q><b><div>hello world</div></b>WebKit</q>', selectLastTwoWords, '<div><q><b>hello </b></q>world</div>WebKit');
    6874testRemoveFormat('<q><b><div>hello world</div></b>WebKit</q>', selectSecondWord, '<div><q><b>hello </b></q>world</div><q>WebKit</q>');
     75testRemoveFormat('<b><div>hello</div>webkit</b>', selectFirstLine, '<div>hello</div><b>webkit</b>');
    6976
    7077testRemoveFormat('<i style="font-weight:bold;">hello</i> <u>world</u>', selectAll, 'hello world');
  • trunk/Source/WebCore/ChangeLog

    r148595 r148597  
     12013-04-17  Claudio Saavedra  <csaavedra@igalia.com>
     2
     3        execCommand("RemoveFormat") might remove format after the selection
     4        https://bugs.webkit.org/show_bug.cgi?id=112240
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        Tests: editing/execCommand/remove-format-multiple-elements-mac.html
     9
     10        This bug is hit when ApplyStyleCommand is used to change the
     11        style and the current selection ends in the beginning of a new node.
     12        The bug is actually a two-fold thing:
     13
     14        1. There was no check as to whether the end node is really
     15        selected or not, and format was always removed from it with
     16        pushDownInlineStyleAroundNode(). An equivalent check for the start
     17        node was already in place, so fix it analogously.
     18
     19        2. Previous stage might change the dom tree, resulting in a render
     20        tree that is not up-to-date. Position::upstream() is later used
     21        and, in order to be able to find a visually equivalent position in
     22        a text node, this method needs the render tree to be up-to-date,
     23        therefore, a call to updateLayoutIgnorePendingStylesheets() is
     24        necessary.
     25
     26        * editing/ApplyStyleCommand.cpp:
     27        (WebCore::ApplyStyleCommand::removeInlineStyle): Make sure that no
     28        format is removed from the end node if it's not fully selected.
     29        (WebCore::ApplyStyleCommand::nodeFullySelected): Call updateLayoutIgnorePendingStylesheets()
     30
    1312013-04-17  Alberto Garcia  <agarcia@igalia.com>
    232
  • trunk/Source/WebCore/editing/ApplyStyleCommand.cpp

    r148497 r148597  
    10771077    ASSERT(end.anchorNode()->inDocument());
    10781078    ASSERT(comparePositions(start, end) <= 0);
     1079    // FIXME: We should assert that start/end are not in the middle of a text node.
    10791080
    10801081    Position pushDownStart = start.downstream();
     
    10861087        && pushDownStart.computeOffsetInContainerNode() == pushDownStartContainer->maxCharacterOffset())
    10871088        pushDownStart = nextVisuallyDistinctCandidate(pushDownStart);
     1089    // If pushDownEnd is at the start of a text node, then this node is not fully selected.
     1090    // Move it to the previous deep equivalent position to avoid removing the style from this node.
    10881091    Position pushDownEnd = end.upstream();
     1092    Node* pushDownEndContainer = pushDownEnd.containerNode();
     1093    if (pushDownEndContainer && pushDownEndContainer->isTextNode() && !pushDownEnd.computeOffsetInContainerNode())
     1094        pushDownEnd = previousVisuallyDistinctCandidate(pushDownEnd);
    10891095
    10901096    pushDownInlineStyleAroundNode(style, pushDownStart.deprecatedNode());
     
    11531159    ASSERT(node->isElementNode());
    11541160
     1161    // The tree may have changed and Position::upstream() relies on an up-to-date layout.
     1162    node->document()->updateLayoutIgnorePendingStylesheets();
     1163
    11551164    return comparePositions(firstPositionInOrBeforeNode(node), start) >= 0
    11561165        && comparePositions(lastPositionInOrAfterNode(node).upstream(), end) <= 0;
Note: See TracChangeset for help on using the changeset viewer.