New issue
Advanced search Search tips

Issue 639184 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Closed: Aug 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 2
Type: Bug



Sign in to add a comment

Text insertion/removal makes irrelevant Range ignore previous DOM updates

Project Member Reported by xiaoche...@chromium.org, Aug 19 2016

Issue description

|Range::boundaryTextInserted/Removed()| are currently calling |boundary.markValid()| at their beginning without any condition. This makes previous DOM changes ignored, and may make the Range end up in an inconsistent state.
 
This is a regression bug introduced by r397987.

The current implementation (54.0.2833.0) is failing the following two unit tests:

// Regression test for  crbug.com/639184 
TEST_F(RangeTest, NotMarkedValidByIrrelevantTextInsert)
{
    document().body()->setInnerHTML("<div><span id=span1>foo</span>bar<span id=span2>baz</span></div>", ASSERT_NO_EXCEPTION);

    Element* div = document().querySelector("div");
    Element* span1 = document().getElementById("span1");
    Element* span2 = document().getElementById("span2");
    Text* text = toText(div->childNodes()->item(1));

    Range* range = Range::create(document(), span2, 0, div, 3);

    div->removeChild(span1, ASSERT_NO_EXCEPTION);
    text->insertData(0, "bar", ASSERT_NO_EXCEPTION);

    EXPECT_TRUE(range->boundaryPointsValid());
    EXPECT_EQ(span2, range->startContainer());
    EXPECT_EQ(0, range->startOffset());
    EXPECT_EQ(div, range->endContainer());
    EXPECT_EQ(2, range->endOffset());
}

// Regression test for  crbug.com/639184 
TEST_F(RangeTest, NotMarkedValidByIrrelevantTextRemove)
{
    document().body()->setInnerHTML("<div><span id=span1>foofoo</span>bar<span id=span2>baz</span></div>", ASSERT_NO_EXCEPTION);

    Element* div = document().querySelector("div");
    Element* span1 = document().getElementById("span1");
    Element* span2 = document().getElementById("span2");
    Text* text = toText(div->childNodes()->item(1));

    Range* range = Range::create(document(), span2, 0, div, 3);

    div->removeChild(span1, ASSERT_NO_EXCEPTION);
    text->deleteData(0, 3, ASSERT_NO_EXCEPTION);

    EXPECT_TRUE(range->boundaryPointsValid());
    EXPECT_EQ(span2, range->startContainer());
    EXPECT_EQ(0, range->startOffset());
    EXPECT_EQ(div, range->endContainer());
    EXPECT_EQ(2, range->endOffset());
}

Comment 2 Deleted

Project Member

Comment 3 by bugdroid1@chromium.org, Aug 19 2016

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/8cdfdf011fb08fd2dda2d02c2b89bb7f08a53272

commit 8cdfdf011fb08fd2dda2d02c2b89bb7f08a53272
Author: xiaochengh <xiaochengh@chromium.org>
Date: Fri Aug 19 11:01:11 2016

boundaryTextInserted/Removed() should not call markValid() for irrelavent changes

This patch fixes a bug related to the maintenance of RangeBoundaryPoint. Example:

Let body's content be "<div>foo<span>bar</span></foo>", and a range created as
from (<span>, 0) to (<div>, 2). Then there are two updates:

1. Insert a new sibling before the text node "foo"
2. Insert/Remove characters in the text node "foo"

In the current implementation, step 2 incorrectly marks the boundary points of
the range as up-to-date without actually updating the stored offsets in it, making
the change in step 1 ignored. Then if we call |range->endPosition()|, we still get
(<div>, 2) instead of (<div>, 3), leaving the range in an inconsistent state.

This patch ensures that boundaryTextInserted/Removed() only calls markValid()
when the current RangeBoundaryPoints's container is the CharacterData node
where text is inserted/removed, and irrelevant RangeBoundaryPoints should not
be changed.

BUG= 639184 
TEST=webkit_unit_tests --gtest_filter=RangeTest.NotMarkedValidByIrrelevantText*

Review-Url: https://codereview.chromium.org/2254423002
Cr-Commit-Position: refs/heads/master@{#413104}

[modify] https://crrev.com/8cdfdf011fb08fd2dda2d02c2b89bb7f08a53272/third_party/WebKit/Source/core/dom/Range.cpp
[modify] https://crrev.com/8cdfdf011fb08fd2dda2d02c2b89bb7f08a53272/third_party/WebKit/Source/core/dom/RangeTest.cpp

Labels: Merge-Request-53

Comment 5 by dimu@chromium.org, Aug 22 2016

Labels: -Merge-Request-53 Merge-Approved-53 Hotlist-Merge-Approved
Your change meets the bar and is auto-approved for M53 (branch: 2785)
Project Member

Comment 6 by bugdroid1@chromium.org, Aug 22 2016

Labels: -merge-approved-53 merge-merged-2785
The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/566ac45e693fb76a0dd6ff84f489e5287bf2c055

commit 566ac45e693fb76a0dd6ff84f489e5287bf2c055
Author: Xiaocheng Hu <xiaochengh@chromium.org>
Date: Mon Aug 22 03:06:54 2016

boundaryTextInserted/Removed() should not call markValid() for irrelavent changes

This patch fixes a bug related to the maintenance of RangeBoundaryPoint. Example:

Let body's content be "<div>foo<span>bar</span></foo>", and a range be created as
from (<span>, 0) to (<div>, 2). Then there are two updates:

1. Insert a new sibling before the text node "foo"
2. Insert/Remove characters in the text node "foo"

In the current implementation, step 2 incorrectly marks the boundary points of
the range as up-to-date without actually updating the stored offsets in it, making
the change in step 1 ignored. Then if we call |range->endPosition()|, we still get
(<div>, 2) instead of (<div>, 3), finding the range in an inconsistent state.

This patch ensures that boundaryTextInserted/Removed() only calls markValid()
when the current RangeBoundaryPoints's container is the CharacterData node
where text is inserted/removed, and irrelevant RangeBoundaryPoints should not
be changed.

BUG= 639184 

Review-Url: https://codereview.chromium.org/2254423002
Cr-Commit-Position: refs/heads/master@{#413104}
(cherry picked from commit 8cdfdf011fb08fd2dda2d02c2b89bb7f08a53272)

Review URL: https://codereview.chromium.org/2265853002 .

Cr-Commit-Position: refs/branch-heads/2785@{#701}
Cr-Branched-From: 68623971be0cfc492a2cb0427d7f478e7b214c24-refs/heads/master@{#403382}

[modify] https://crrev.com/566ac45e693fb76a0dd6ff84f489e5287bf2c055/third_party/WebKit/Source/core/dom/Range.cpp

Status: Fixed (was: Started)

Sign in to add a comment