diff options
author | darin@apple.com <darin@apple.com@bbb929c8-8fbe-4397-9dbb-9b2b20218538> | 2009-08-10 17:28:49 +0000 |
---|---|---|
committer | darin@apple.com <darin@apple.com@bbb929c8-8fbe-4397-9dbb-9b2b20218538> | 2009-08-10 17:28:49 +0000 |
commit | 79fe7ab2d331a1fec1096c8ed6a7af75f77f289b (patch) | |
tree | a511b26eb0cd4798800c9fd5bbac78614acef9c8 | |
parent | a3709ef91529eede9bf2ebf79d6f771cf639cadd (diff) | |
download | chromium_src-79fe7ab2d331a1fec1096c8ed6a7af75f77f289b.zip chromium_src-79fe7ab2d331a1fec1096c8ed6a7af75f77f289b.tar.gz chromium_src-79fe7ab2d331a1fec1096c8ed6a7af75f77f289b.tar.bz2 |
WebCore: When empty <input> is focused, getSelection() exposes shadow tree nodes
https://bugs.webkit.org/show_bug.cgi?id=15903
Patch by Darin Adler <darin@apple.com> on 2009-08-10
Reviewed by Dan Bernstein.
Test: fast/forms/shadow-tree-exposure.html
* page/DOMSelection.cpp:
(WebCore::selectionShadowAncestor): Added.
(WebCore::DOMSelection::anchorNode): Return the parent of the shadow
ancestor if the selection is in a shadow tree. Matches Firefox.
(WebCore::DOMSelection::anchorOffset): Return the index of the shadow
ancestor if the selection is in a shadow tree. Matches Firefox.
(WebCore::DOMSelection::focusNode): Ditto.
(WebCore::DOMSelection::focusOffset): Ditto.
(WebCore::DOMSelection::baseNode): More of the same, but since this
is a WebKit-invented property, it does not match Firefox.
(WebCore::DOMSelection::baseOffset): Ditto.
(WebCore::DOMSelection::extentNode): Ditto.
(WebCore::DOMSelection::extentOffset): Ditto.
(WebCore::DOMSelection::isCollapsed): Return true even when the
selection is a range, if the selection is in the shadow tree.
Matches Firefox. Also changed behavior when called and the frame
is gone to return true instead of false which makes more sense.
(WebCore::DOMSelection::empty): Use clear() just like the other
selection-clearing function in this file does.
(WebCore::DOMSelection::getRangeAt): Return a range that starts
and ends before the shadow ancestor. Matches Firefox.
LayoutTests: When empty <input> is focused, getSelection() exposes shadow tree nodes
https://bugs.webkit.org/show_bug.cgi?id=15903
Patch by Darin Adler <darin@apple.com> on 2009-08-07
Reviewed by Dan Bernstein.
Also updated a recently introduced non-standard test to work in a more
standard way.
* fast/forms/resources/shadow-tree-exposure.js: Added.
* fast/forms/shadow-tree-exposure-expected.txt: Added.
* fast/forms/shadow-tree-exposure.html: Added.
* fast/js/method-check-expected.txt: Updated.
* fast/js/method-check.html: Regenerated using the make-js-test-wrappers script.
* fast/js/resources/method-check.js: Replaced a comment talking about the lack
of a gc() function with a call to GCController.collect(). Also removed the
shouldBeTrue call at the end of the fiel that wasn't needed.
git-svn-id: svn://svn.chromium.org/blink/trunk@46982 bbb929c8-8fbe-4397-9dbb-9b2b20218538
9 files changed, 249 insertions, 18 deletions
diff --git a/third_party/WebKit/LayoutTests/ChangeLog b/third_party/WebKit/LayoutTests/ChangeLog index 602be7a..f8f504b 100644 --- a/third_party/WebKit/LayoutTests/ChangeLog +++ b/third_party/WebKit/LayoutTests/ChangeLog @@ -1,3 +1,23 @@ +2009-08-07 Darin Adler <darin@apple.com> + + Reviewed by Dan Bernstein. + + When empty <input> is focused, getSelection() exposes shadow tree nodes + https://bugs.webkit.org/show_bug.cgi?id=15903 + + Also updated a recently introduced non-standard test to work in a more + standard way. + + * fast/forms/resources/shadow-tree-exposure.js: Added. + * fast/forms/shadow-tree-exposure-expected.txt: Added. + * fast/forms/shadow-tree-exposure.html: Added. + + * fast/js/method-check-expected.txt: Updated. + * fast/js/method-check.html: Regenerated using the make-js-test-wrappers script. + * fast/js/resources/method-check.js: Replaced a comment talking about the lack + of a gc() function with a call to GCController.collect(). Also removed the + shouldBeTrue call at the end of the fiel that wasn't needed. + 2009-08-10 Renata Hodovan <hodovan.renata@stud.u-szeged.hu> Reviewed by Simon Hausmann. diff --git a/third_party/WebKit/LayoutTests/fast/forms/resources/shadow-tree-exposure.js b/third_party/WebKit/LayoutTests/fast/forms/resources/shadow-tree-exposure.js new file mode 100644 index 0000000..a096e7b --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/resources/shadow-tree-exposure.js @@ -0,0 +1,75 @@ +description("Test to make sure shadow nodes are not exposed."); + +var container = document.createElement("p"); +document.body.appendChild(container); + +container.appendChild(document.createTextNode("Some text: ")); + +shouldBe("getSelection().anchorNode", "null"); +shouldBe("getSelection().anchorOffset", "0"); +shouldBe("getSelection().focusNode", "null"); +shouldBe("getSelection().focusOffset", "0"); +shouldBe("getSelection().isCollapsed", "true"); +shouldBe("getSelection().rangeCount", "0"); + +shouldBe("getSelection().baseNode", "null"); +shouldBe("getSelection().baseOffset", "0"); +shouldBe("getSelection().extentNode", "null"); +shouldBe("getSelection().extentOffset", "0"); +shouldBe("getSelection().type", "'None'"); + +debug("\nAdd an input element.\n"); + +var input = document.createElement("input"); +container.appendChild(input); +input.value = "text"; +input.focus(); +input.select(); + +shouldBe("getSelection().anchorNode", "container"); +shouldBe("getSelection().anchorOffset", "1"); +shouldBe("getSelection().focusNode", "container"); +shouldBe("getSelection().focusOffset", "1"); +shouldBe("getSelection().isCollapsed", "true"); +shouldBe("getSelection().rangeCount", "1"); +shouldBe("getSelection().getRangeAt(0).startContainer", "container"); +shouldBe("getSelection().getRangeAt(0).startOffset", "1"); +shouldBe("getSelection().getRangeAt(0).endContainer", "container"); +shouldBe("getSelection().getRangeAt(0).endOffset", "1"); + +shouldBe("getSelection().baseNode", "container"); +shouldBe("getSelection().baseOffset", "1"); +shouldBe("getSelection().extentNode", "container"); +shouldBe("getSelection().extentOffset", "1"); +shouldBe("getSelection().type", "'Range'"); + +debug("\nAdd a textarea element.\n"); + +var textarea = document.createElement("textarea"); +container.appendChild(textarea); +textarea.value = "text"; +textarea.focus(); +textarea.select(); + +shouldBe("getSelection().anchorNode", "container"); +shouldBe("getSelection().anchorOffset", "2"); +shouldBe("getSelection().focusNode", "container"); +shouldBe("getSelection().focusOffset", "2"); +shouldBe("getSelection().isCollapsed", "true"); +shouldBe("getSelection().rangeCount", "1"); +shouldBe("getSelection().getRangeAt(0).startContainer", "container"); +shouldBe("getSelection().getRangeAt(0).startOffset", "2"); +shouldBe("getSelection().getRangeAt(0).endContainer", "container"); +shouldBe("getSelection().getRangeAt(0).endOffset", "2"); + +shouldBe("getSelection().baseNode", "container"); +shouldBe("getSelection().baseOffset", "2"); +shouldBe("getSelection().extentNode", "container"); +shouldBe("getSelection().extentOffset", "2"); +shouldBe("getSelection().type", "'Range'"); + +document.body.removeChild(container); + +debug(""); + +var successfullyParsed = true; diff --git a/third_party/WebKit/LayoutTests/fast/forms/shadow-tree-exposure-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/shadow-tree-exposure-expected.txt new file mode 100644 index 0000000..c0ad6f0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/shadow-tree-exposure-expected.txt @@ -0,0 +1,57 @@ +Test to make sure shadow nodes are not exposed. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS getSelection().anchorNode is null +PASS getSelection().anchorOffset is 0 +PASS getSelection().focusNode is null +PASS getSelection().focusOffset is 0 +PASS getSelection().isCollapsed is true +PASS getSelection().rangeCount is 0 +PASS getSelection().baseNode is null +PASS getSelection().baseOffset is 0 +PASS getSelection().extentNode is null +PASS getSelection().extentOffset is 0 +PASS getSelection().type is 'None' + +Add an input element. + +PASS getSelection().anchorNode is container +PASS getSelection().anchorOffset is 1 +PASS getSelection().focusNode is container +PASS getSelection().focusOffset is 1 +PASS getSelection().isCollapsed is true +PASS getSelection().rangeCount is 1 +PASS getSelection().getRangeAt(0).startContainer is container +PASS getSelection().getRangeAt(0).startOffset is 1 +PASS getSelection().getRangeAt(0).endContainer is container +PASS getSelection().getRangeAt(0).endOffset is 1 +PASS getSelection().baseNode is container +PASS getSelection().baseOffset is 1 +PASS getSelection().extentNode is container +PASS getSelection().extentOffset is 1 +PASS getSelection().type is 'Range' + +Add a textarea element. + +PASS getSelection().anchorNode is container +PASS getSelection().anchorOffset is 2 +PASS getSelection().focusNode is container +PASS getSelection().focusOffset is 2 +PASS getSelection().isCollapsed is true +PASS getSelection().rangeCount is 1 +PASS getSelection().getRangeAt(0).startContainer is container +PASS getSelection().getRangeAt(0).startOffset is 2 +PASS getSelection().getRangeAt(0).endContainer is container +PASS getSelection().getRangeAt(0).endOffset is 2 +PASS getSelection().baseNode is container +PASS getSelection().baseOffset is 2 +PASS getSelection().extentNode is container +PASS getSelection().extentOffset is 2 +PASS getSelection().type is 'Range' + +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/third_party/WebKit/LayoutTests/fast/forms/shadow-tree-exposure.html b/third_party/WebKit/LayoutTests/fast/forms/shadow-tree-exposure.html new file mode 100644 index 0000000..d41332f --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/shadow-tree-exposure.html @@ -0,0 +1,13 @@ +<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> +<html> +<head> +<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css"> +<script src="../../fast/js/resources/js-test-pre.js"></script> +</head> +<body> +<p id="description"></p> +<div id="console"></div> +<script src="resources/shadow-tree-exposure.js"></script> +<script src="../../fast/js/resources/js-test-post.js"></script> +</body> +</html> diff --git a/third_party/WebKit/LayoutTests/fast/js/method-check-expected.txt b/third_party/WebKit/LayoutTests/fast/js/method-check-expected.txt index 6fb2b01..c45fbff6 100644 --- a/third_party/WebKit/LayoutTests/fast/js/method-check-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/js/method-check-expected.txt @@ -3,5 +3,7 @@ This test yields PASS, if malloc does not reuse the memory address for the struc On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -PASS true is true +PASS successfullyParsed is true + +TEST COMPLETE diff --git a/third_party/WebKit/LayoutTests/fast/js/method-check.html b/third_party/WebKit/LayoutTests/fast/js/method-check.html index 4551248..12f7a7d 100644 --- a/third_party/WebKit/LayoutTests/fast/js/method-check.html +++ b/third_party/WebKit/LayoutTests/fast/js/method-check.html @@ -8,5 +8,6 @@ <p id="description"></p> <div id="console"></div> <script src="resources/method-check.js"></script> +<script src="resources/js-test-post.js"></script> </body> </html> diff --git a/third_party/WebKit/LayoutTests/fast/js/resources/method-check.js b/third_party/WebKit/LayoutTests/fast/js/resources/method-check.js index 5b0cecc..ed62713 100644 --- a/third_party/WebKit/LayoutTests/fast/js/resources/method-check.js +++ b/third_party/WebKit/LayoutTests/fast/js/resources/method-check.js @@ -9,16 +9,18 @@ function func() String.prototype.a = function() { } String.prototype.b = function() { } - // there is no gc() call in LayoutTests! - - // The following 3 lines cause gc() flush on a Debian - // Linux machine, but there is no garantee, it works on - // any other computer. (Not even another Debian Linux) - // If func2() is not called or a much bigger or lower - // value than 5000 is chosen, the crash won't happen - func2() - for (var i = 0; i < 5000; ++i) - new Boolean() + if (window.GCController) + GCController.collect(); + else { + // The following 3 lines cause gc() flush on a Debian + // Linux machine, but there is no garantee, it works on + // any other computer. (Not even another Debian Linux) + // If func2() is not called or a much bigger or lower + // value than 5000 is chosen, the crash won't happen + func2() + for (var i = 0; i < 5000; ++i) + new Boolean() + } var str = "" for (var i = 0; i < 5; ++i) @@ -28,6 +30,4 @@ function func() func() func() -shouldBeTrue("true"); var successfullyParsed = true; - diff --git a/third_party/WebKit/WebCore/ChangeLog b/third_party/WebKit/WebCore/ChangeLog index 3b5615e..0ef85fc 100644 --- a/third_party/WebKit/WebCore/ChangeLog +++ b/third_party/WebKit/WebCore/ChangeLog @@ -1,3 +1,34 @@ +2009-08-10 Darin Adler <darin@apple.com> + + Reviewed by Dan Bernstein. + + When empty <input> is focused, getSelection() exposes shadow tree nodes + https://bugs.webkit.org/show_bug.cgi?id=15903 + + Test: fast/forms/shadow-tree-exposure.html + + * page/DOMSelection.cpp: + (WebCore::selectionShadowAncestor): Added. + (WebCore::DOMSelection::anchorNode): Return the parent of the shadow + ancestor if the selection is in a shadow tree. Matches Firefox. + (WebCore::DOMSelection::anchorOffset): Return the index of the shadow + ancestor if the selection is in a shadow tree. Matches Firefox. + (WebCore::DOMSelection::focusNode): Ditto. + (WebCore::DOMSelection::focusOffset): Ditto. + (WebCore::DOMSelection::baseNode): More of the same, but since this + is a WebKit-invented property, it does not match Firefox. + (WebCore::DOMSelection::baseOffset): Ditto. + (WebCore::DOMSelection::extentNode): Ditto. + (WebCore::DOMSelection::extentOffset): Ditto. + (WebCore::DOMSelection::isCollapsed): Return true even when the + selection is a range, if the selection is in the shadow tree. + Matches Firefox. Also changed behavior when called and the frame + is gone to return true instead of false which makes more sense. + (WebCore::DOMSelection::empty): Use clear() just like the other + selection-clearing function in this file does. + (WebCore::DOMSelection::getRangeAt): Return a range that starts + and ends before the shadow ancestor. Matches Firefox. + 2009-08-10 Pavel Feldman <pfeldman@chromium.org> Reviewed by Timothy Hatcher. diff --git a/third_party/WebKit/WebCore/page/DOMSelection.cpp b/third_party/WebKit/WebCore/page/DOMSelection.cpp index 23c695e..0d21c56 100644 --- a/third_party/WebKit/WebCore/page/DOMSelection.cpp +++ b/third_party/WebKit/WebCore/page/DOMSelection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -41,6 +41,17 @@ namespace WebCore { +static Node* selectionShadowAncestor(Frame* frame) +{ + Node* node = frame->selection()->selection().base().anchorNode(); + if (!node) + return 0; + Node* shadowAncestor = node->shadowAncestorNode(); + if (shadowAncestor == node) + return 0; + return shadowAncestor; +} + DOMSelection::DOMSelection(Frame* frame) : m_frame(frame) { @@ -88,6 +99,8 @@ Node* DOMSelection::anchorNode() const { if (!m_frame) return 0; + if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) + return shadowAncestor->parentNode(); return anchorPosition(visibleSelection()).node(); } @@ -95,6 +108,8 @@ int DOMSelection::anchorOffset() const { if (!m_frame) return 0; + if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) + return shadowAncestor->nodeIndex(); return anchorPosition(visibleSelection()).deprecatedEditingOffset(); } @@ -102,6 +117,8 @@ Node* DOMSelection::focusNode() const { if (!m_frame) return 0; + if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) + return shadowAncestor->parentNode(); return focusPosition(visibleSelection()).node(); } @@ -109,6 +126,8 @@ int DOMSelection::focusOffset() const { if (!m_frame) return 0; + if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) + return shadowAncestor->nodeIndex(); return focusPosition(visibleSelection()).deprecatedEditingOffset(); } @@ -116,6 +135,8 @@ Node* DOMSelection::baseNode() const { if (!m_frame) return 0; + if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) + return shadowAncestor->parentNode(); return basePosition(visibleSelection()).node(); } @@ -123,14 +144,17 @@ int DOMSelection::baseOffset() const { if (!m_frame) return 0; + if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) + return shadowAncestor->nodeIndex(); return basePosition(visibleSelection()).deprecatedEditingOffset(); } - Node* DOMSelection::extentNode() const { if (!m_frame) return 0; + if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) + return shadowAncestor->parentNode(); return extentPosition(visibleSelection()).node(); } @@ -138,13 +162,15 @@ int DOMSelection::extentOffset() const { if (!m_frame) return 0; + if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) + return shadowAncestor->nodeIndex(); return extentPosition(visibleSelection()).deprecatedEditingOffset(); } bool DOMSelection::isCollapsed() const { - if (!m_frame) - return false; + if (!m_frame || selectionShadowAncestor(m_frame)) + return true; return !m_frame->selection()->isRange(); } @@ -206,7 +232,7 @@ void DOMSelection::empty() { if (!m_frame) return; - m_frame->selection()->moveTo(VisiblePosition()); + m_frame->selection()->clear(); } void DOMSelection::setBaseAndExtent(Node* baseNode, int baseOffset, Node* extentNode, int extentOffset, ExceptionCode& ec) @@ -317,6 +343,12 @@ PassRefPtr<Range> DOMSelection::getRangeAt(int index, ExceptionCode& ec) // If you're hitting this, you've added broken multi-range selection support ASSERT(rangeCount() == 1); + if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) { + Node* container = shadowAncestor->parentNode(); + int offset = shadowAncestor->nodeIndex(); + return Range::create(shadowAncestor->document(), container, offset, container, offset); + } + const VisibleSelection& selection = m_frame->selection()->selection(); return selection.firstRange(); } |