Changeset 148898 in webkit


Ignore:
Timestamp:
Apr 22, 2013 11:23:33 AM (11 years ago)
Author:
aestes@apple.com
Message:

Range.getClientRects() should not include rects for partially selected elements
https://bugs.webkit.org/show_bug.cgi?id=76839

Reviewed by Sam Weinig.

Source/WebCore:

CSSOM says that Range.getClientRects() should include the border boxes
of each element selected by the range. However, we were also
incorrectly including border boxes for partially selected elements.
For instance, consider the following selection:

<div>line one<br>line two</div>
-------------

The <div> is two lines tall, but only the first line is selected.
Despite this, we'd include the <div>'s border box since its start tag
was included in the selection.

Fix this by excluding partially selected elements. This is accomplished
by skipping over elements that come after the start boundary point of
the range but are ancestors of the end boundary point.

Added test cases to LayoutTests/fast/dom/Range/getClientRects.html.

  • dom/Range.cpp:

(WebCore::Range::getBorderAndTextQuads):

LayoutTests:

  • fast/dom/Range/getClientRects-expected.txt: Updated expected result.
  • fast/dom/Range/getClientRects.html: Added new test cases.
Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r148895 r148898  
     12013-04-22  Andy Estes  <aestes@apple.com>
     2
     3        Range.getClientRects() should not include rects for partially selected elements
     4        https://bugs.webkit.org/show_bug.cgi?id=76839
     5
     6        Reviewed by Sam Weinig.
     7
     8        * fast/dom/Range/getClientRects-expected.txt: Updated expected result.
     9        * fast/dom/Range/getClientRects.html: Added new test cases.
     10
    1112013-04-22  Eric Carlson  <eric.carlson@apple.com>
    212
  • trunk/LayoutTests/fast/dom/Range/getClientRects-expected.txt

    r92089 r148898  
    218218PASS rects[3].height is 360
    219219Test 11
     220PASS rects.length is 2
     221PASS rects[0].left is 8
     222PASS rects[0].top is 2524
     223PASS rects[0].width is 400
     224PASS rects[0].height is 40
     225PASS rects[1].left is 8
     226PASS rects[1].top is 2535
     227PASS rects[1].width is 177
     228PASS rects[1].height is 18
     229Test 12
     230PASS rects.length is 1
     231PASS rects[0].left is 8
     232PASS rects[0].top is 2760
     233PASS rects[0].width is 400
     234PASS rects[0].height is 160
     235Test 13
     236PASS rects.length is 4
     237PASS rects[0].left is 8
     238PASS rects[0].top is 2967
     239PASS rects[0].width is 396
     240PASS rects[0].height is 18
     241PASS rects[1].left is 8
     242PASS rects[1].top is 3007
     243PASS rects[1].width is 398
     244PASS rects[1].height is 18
     245PASS rects[2].left is 8
     246PASS rects[2].top is 3047
     247PASS rects[2].width is 360
     248PASS rects[2].height is 18
     249PASS rects[3].left is 8
     250PASS rects[3].top is 3087
     251PASS rects[3].width is 306
     252PASS rects[3].height is 18
     253Test 14
    220254PASS rects.length is 0
    221255PASS successfullyParsed is true
  • trunk/LayoutTests/fast/dom/Range/getClientRects.html

    r120792 r148898  
    8181
    8282<div class="box" id="test10">weee! Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
     83
     84<br><br>
     85
     86<div class="box" id="test11"><div>Lorem ipsum dolor sit amet,</div> consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
     87
     88<br><br>
     89
     90<div class="box" id="test12">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
     91
     92<br><br>
     93
     94<div class="box" id="test13">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
    8395
    8496</div>
     
    399411    shouldBe("rects[3].height", "360");
    400412
     413    // Test 11
    401414    debug("Test 11");
    402415    var range11 = document.createRange();
     416    range11.setStartBefore(document.getElementById('test11'));
     417    range11.setEndAfter(document.getElementById('test11').firstChild);
     418    show(range11);
    403419    rects = range11.getClientRects();
     420    shouldBe("rects.length", "2");
     421    shouldBe("rects[0].left", "8");
     422    shouldBe("rects[0].top", "2524");
     423    shouldBe("rects[0].width", "400");
     424    shouldBe("rects[0].height", "40");
     425    shouldBe("rects[1].left", "8");
     426    shouldBe("rects[1].top", "2535");
     427    shouldBe("rects[1].width", "177");
     428    shouldBe("rects[1].height", "18");
     429
     430    // Test 12
     431    debug("Test 12");
     432    var range12 = document.createRange();
     433    range12.setStartBefore(document.getElementById('test12'));
     434    range12.setEndBefore(document.getElementById('test12').firstChild);
     435    show(range12);
     436    rects = range12.getClientRects();
     437    shouldBe("rects.length", "1");
     438    shouldBe("rects[0].left", "8");
     439    shouldBe("rects[0].top", "2760");
     440    shouldBe("rects[0].width", "400");
     441    shouldBe("rects[0].height", "160");
     442
     443    // Test 13
     444    debug("Test 13");
     445    var range13 = document.createRange();
     446    range13.setStartBefore(document.getElementById('test13'));
     447    range13.setEndAfter(document.getElementById('test13').firstChild);
     448    show(range13);
     449    rects = range13.getClientRects();
     450    shouldBe("rects.length", "4");
     451    shouldBe("rects[0].left", "8");
     452    shouldBe("rects[0].top", "2967");
     453    shouldBe("rects[0].width", "396");
     454    shouldBe("rects[0].height", "18");
     455    shouldBe("rects[1].left", "8");
     456    shouldBe("rects[1].top", "3007");
     457    shouldBe("rects[1].width", "398");
     458    shouldBe("rects[1].height", "18");
     459    shouldBe("rects[2].left", "8");
     460    shouldBe("rects[2].top", "3047");
     461    shouldBe("rects[2].width", "360");
     462    shouldBe("rects[2].height", "18");
     463    shouldBe("rects[3].left", "8");
     464    shouldBe("rects[3].top", "3087");
     465    shouldBe("rects[3].width", "306");
     466    shouldBe("rects[3].height", "18");
     467
     468    // Test 14
     469    debug("Test 14");
     470    var range14 = document.createRange();
     471    rects = range14.getClientRects();
    404472    shouldBe("rects.length", "0");
    405473
  • trunk/Source/WebCore/ChangeLog

    r148894 r148898  
     12013-04-22  Andy Estes  <aestes@apple.com>
     2
     3        Range.getClientRects() should not include rects for partially selected elements
     4        https://bugs.webkit.org/show_bug.cgi?id=76839
     5
     6        Reviewed by Sam Weinig.
     7
     8        CSSOM says that Range.getClientRects() should include the border boxes
     9        of each element selected by the range. However, we were also
     10        incorrectly including border boxes for partially selected elements.
     11        For instance, consider the following selection:
     12
     13            <div>line one<br>line two</div>
     14            -------------
     15
     16        The <div> is two lines tall, but only the first line is selected.
     17        Despite this, we'd include the <div>'s border box since its start tag
     18        was included in the selection.
     19
     20        Fix this by excluding partially selected elements. This is accomplished
     21        by skipping over elements that come after the start boundary point of
     22        the range but are ancestors of the end boundary point.
     23
     24        Added test cases to LayoutTests/fast/dom/Range/getClientRects.html.
     25
     26        * dom/Range.cpp:
     27        (WebCore::Range::getBorderAndTextQuads):
     28
    1292013-04-22  Yi Shen  <max.hong.shen@gmail.com>
    230
  • trunk/Source/WebCore/dom/Range.cpp

    r148289 r148898  
    19101910    Node* stopNode = pastLastNode();
    19111911
    1912     HashSet<Node*> nodeSet;
     1912    HashSet<Node*> selectedElementsSet;
    19131913    for (Node* node = firstNode(); node != stopNode; node = NodeTraversal::next(node)) {
    19141914        if (node->isElementNode())
    1915             nodeSet.add(node);
    1916     }
     1915            selectedElementsSet.add(node);
     1916    }
     1917
     1918    // Don't include elements that are only partially selected.
     1919    Node* lastNode = m_end.childBefore() ? m_end.childBefore() : endContainer;
     1920    for (Node* parent = lastNode->parentNode(); parent; parent = parent->parentNode())
     1921        selectedElementsSet.remove(parent);
    19171922
    19181923    for (Node* node = firstNode(); node != stopNode; node = NodeTraversal::next(node)) {
    1919         if (node->isElementNode()) {
    1920             if (!nodeSet.contains(node->parentNode())) {
    1921                 if (RenderBoxModelObject* renderBoxModelObject = toElement(node)->renderBoxModelObject()) {
    1922                     Vector<FloatQuad> elementQuads;
    1923                     renderBoxModelObject->absoluteQuads(elementQuads);
    1924                     m_ownerDocument->adjustFloatQuadsForScrollAndAbsoluteZoomAndFrameScale(elementQuads, renderBoxModelObject);
    1925 
    1926                     quads.append(elementQuads);
    1927                 }
     1924        if (node->isElementNode() && selectedElementsSet.contains(node) && !selectedElementsSet.contains(node->parentNode())) {
     1925            if (RenderBoxModelObject* renderBoxModelObject = toElement(node)->renderBoxModelObject()) {
     1926                Vector<FloatQuad> elementQuads;
     1927                renderBoxModelObject->absoluteQuads(elementQuads);
     1928                m_ownerDocument->adjustFloatQuadsForScrollAndAbsoluteZoomAndFrameScale(elementQuads, renderBoxModelObject);
     1929
     1930                quads.append(elementQuads);
    19281931            }
    19291932        } else if (node->isTextNode()) {
Note: See TracChangeset for help on using the changeset viewer.