| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/editing/FrameSelection.h" | 5 #include "core/editing/FrameSelection.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/ExceptionStatePlaceholder.h" | 7 #include "bindings/core/v8/ExceptionStatePlaceholder.h" |
| 8 #include "core/dom/Document.h" | 8 #include "core/dom/Document.h" |
| 9 #include "core/dom/Element.h" | 9 #include "core/dom/Element.h" |
| 10 #include "core/dom/Text.h" | 10 #include "core/dom/Text.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 Text* FrameSelectionTest::appendTextNode(const String& data) | 61 Text* FrameSelectionTest::appendTextNode(const String& data) |
| 62 { | 62 { |
| 63 Text* text = document().createTextNode(data); | 63 Text* text = document().createTextNode(data); |
| 64 document().body()->appendChild(text); | 64 document().body()->appendChild(text); |
| 65 return text; | 65 return text; |
| 66 } | 66 } |
| 67 | 67 |
| 68 TEST_F(FrameSelectionTest, SetValidSelection) | 68 TEST_F(FrameSelectionTest, SetValidSelection) |
| 69 { | 69 { |
| 70 Text* text = appendTextNode("Hello, World!"); | 70 Text* text = appendTextNode("Hello, World!"); |
| 71 VisibleSelection validSelection(Position(text, 0), Position(text, 5)); | 71 VisibleSelection validSelection = createVisibleSelectionDeprecated(Position(
text, 0), Position(text, 5)); |
| 72 EXPECT_FALSE(validSelection.isNone()); | 72 EXPECT_FALSE(validSelection.isNone()); |
| 73 setSelection(validSelection); | 73 setSelection(validSelection); |
| 74 EXPECT_FALSE(selection().isNone()); | 74 EXPECT_FALSE(selection().isNone()); |
| 75 } | 75 } |
| 76 | 76 |
| 77 TEST_F(FrameSelectionTest, InvalidateCaretRect) | 77 TEST_F(FrameSelectionTest, InvalidateCaretRect) |
| 78 { | 78 { |
| 79 Text* text = appendTextNode("Hello, World!"); | 79 Text* text = appendTextNode("Hello, World!"); |
| 80 document().view()->updateAllLifecyclePhases(); | 80 document().view()->updateAllLifecyclePhases(); |
| 81 | 81 |
| 82 VisibleSelection validSelection(Position(text, 0), Position(text, 0)); | 82 VisibleSelection validSelection = createVisibleSelectionDeprecated(Position(
text, 0), Position(text, 0)); |
| 83 setSelection(validSelection); | 83 setSelection(validSelection); |
| 84 selection().setCaretRectNeedsUpdate(); | 84 selection().setCaretRectNeedsUpdate(); |
| 85 EXPECT_TRUE(selection().isCaretBoundsDirty()); | 85 EXPECT_TRUE(selection().isCaretBoundsDirty()); |
| 86 selection().invalidateCaretRect(); | 86 selection().invalidateCaretRect(); |
| 87 EXPECT_FALSE(selection().isCaretBoundsDirty()); | 87 EXPECT_FALSE(selection().isCaretBoundsDirty()); |
| 88 | 88 |
| 89 document().body()->removeChild(text); | 89 document().body()->removeChild(text); |
| 90 document().updateStyleAndLayoutIgnorePendingStylesheets(); | 90 document().updateStyleAndLayoutIgnorePendingStylesheets(); |
| 91 selection().setCaretRectNeedsUpdate(); | 91 selection().setCaretRectNeedsUpdate(); |
| 92 EXPECT_TRUE(selection().isCaretBoundsDirty()); | 92 EXPECT_TRUE(selection().isCaretBoundsDirty()); |
| 93 selection().invalidateCaretRect(); | 93 selection().invalidateCaretRect(); |
| 94 EXPECT_FALSE(selection().isCaretBoundsDirty()); | 94 EXPECT_FALSE(selection().isCaretBoundsDirty()); |
| 95 } | 95 } |
| 96 | 96 |
| 97 TEST_F(FrameSelectionTest, PaintCaretShouldNotLayout) | 97 TEST_F(FrameSelectionTest, PaintCaretShouldNotLayout) |
| 98 { | 98 { |
| 99 Text* text = appendTextNode("Hello, World!"); | 99 Text* text = appendTextNode("Hello, World!"); |
| 100 document().view()->updateAllLifecyclePhases(); | 100 document().view()->updateAllLifecyclePhases(); |
| 101 | 101 |
| 102 document().body()->setContentEditable("true", ASSERT_NO_EXCEPTION); | 102 document().body()->setContentEditable("true", ASSERT_NO_EXCEPTION); |
| 103 document().body()->focus(); | 103 document().body()->focus(); |
| 104 EXPECT_TRUE(document().body()->focused()); | 104 EXPECT_TRUE(document().body()->focused()); |
| 105 | 105 |
| 106 VisibleSelection validSelection(Position(text, 0), Position(text, 0)); | 106 VisibleSelection validSelection = createVisibleSelectionDeprecated(Position(
text, 0), Position(text, 0)); |
| 107 selection().setCaretVisible(true); | 107 selection().setCaretVisible(true); |
| 108 setSelection(validSelection); | 108 setSelection(validSelection); |
| 109 EXPECT_TRUE(selection().isCaret()); | 109 EXPECT_TRUE(selection().isCaret()); |
| 110 EXPECT_TRUE(shouldPaintCaretForTesting()); | 110 EXPECT_TRUE(shouldPaintCaretForTesting()); |
| 111 | 111 |
| 112 int startCount = layoutCount(); | 112 int startCount = layoutCount(); |
| 113 { | 113 { |
| 114 // To force layout in next updateLayout calling, widen view. | 114 // To force layout in next updateLayout calling, widen view. |
| 115 FrameView& frameView = dummyPageHolder().frameView(); | 115 FrameView& frameView = dummyPageHolder().frameView(); |
| 116 IntRect frameRect = frameView.frameRect(); | 116 IntRect frameRect = frameView.frameRect(); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 } | 200 } |
| 201 | 201 |
| 202 TEST_F(FrameSelectionTest, ModifyExtendWithFlatTree) | 202 TEST_F(FrameSelectionTest, ModifyExtendWithFlatTree) |
| 203 { | 203 { |
| 204 setBodyContent("<span id=host></span>one"); | 204 setBodyContent("<span id=host></span>one"); |
| 205 setShadowContent("two<content></content>", "host"); | 205 setShadowContent("two<content></content>", "host"); |
| 206 Element* host = document().getElementById("host"); | 206 Element* host = document().getElementById("host"); |
| 207 Node* const two = FlatTreeTraversal::firstChild(*host); | 207 Node* const two = FlatTreeTraversal::firstChild(*host); |
| 208 // Select "two" for selection in DOM tree | 208 // Select "two" for selection in DOM tree |
| 209 // Select "twoone" for selection in Flat tree | 209 // Select "twoone" for selection in Flat tree |
| 210 selection().setSelection(VisibleSelectionInFlatTree(PositionInFlatTree(host,
0), PositionInFlatTree(document().body(), 2))); | 210 selection().setSelection(createVisibleSelectionDeprecated(PositionInFlatTree
(host, 0), PositionInFlatTree(document().body(), 2))); |
| 211 selection().modify(FrameSelection::AlterationExtend, DirectionForward, WordG
ranularity); | 211 selection().modify(FrameSelection::AlterationExtend, DirectionForward, WordG
ranularity); |
| 212 EXPECT_EQ(Position(two, 0), visibleSelectionInDOMTree().start()); | 212 EXPECT_EQ(Position(two, 0), visibleSelectionInDOMTree().start()); |
| 213 EXPECT_EQ(Position(two, 3), visibleSelectionInDOMTree().end()); | 213 EXPECT_EQ(Position(two, 3), visibleSelectionInDOMTree().end()); |
| 214 EXPECT_EQ(PositionInFlatTree(two, 0), visibleSelectionInFlatTree().start()); | 214 EXPECT_EQ(PositionInFlatTree(two, 0), visibleSelectionInFlatTree().start()); |
| 215 EXPECT_EQ(PositionInFlatTree(two, 3), visibleSelectionInFlatTree().end()); | 215 EXPECT_EQ(PositionInFlatTree(two, 3), visibleSelectionInFlatTree().end()); |
| 216 } | 216 } |
| 217 | 217 |
| 218 TEST_F(FrameSelectionTest, ModifyWithUserTriggered) | 218 TEST_F(FrameSelectionTest, ModifyWithUserTriggered) |
| 219 { | 219 { |
| 220 setBodyContent("<div id=sample>abc</div>"); | 220 setBodyContent("<div id=sample>abc</div>"); |
| 221 Element* sample = document().getElementById("sample"); | 221 Element* sample = document().getElementById("sample"); |
| 222 const Position endOfText(sample->firstChild(), 3); | 222 const Position endOfText(sample->firstChild(), 3); |
| 223 selection().setSelection(VisibleSelection(endOfText)); | 223 selection().setSelection(createVisibleSelectionDeprecated(endOfText)); |
| 224 | 224 |
| 225 EXPECT_FALSE(selection().modify(FrameSelection::AlterationMove, DirectionFor
ward, CharacterGranularity, NotUserTriggered)) | 225 EXPECT_FALSE(selection().modify(FrameSelection::AlterationMove, DirectionFor
ward, CharacterGranularity, NotUserTriggered)) |
| 226 << "Selection.modify() returns false for non-user-triggered call when se
lection isn't modified."; | 226 << "Selection.modify() returns false for non-user-triggered call when se
lection isn't modified."; |
| 227 EXPECT_EQ(endOfText, selection().start()) | 227 EXPECT_EQ(endOfText, selection().start()) |
| 228 << "Selection isn't modified"; | 228 << "Selection isn't modified"; |
| 229 | 229 |
| 230 EXPECT_TRUE(selection().modify(FrameSelection::AlterationMove, DirectionForw
ard, CharacterGranularity, UserTriggered)) | 230 EXPECT_TRUE(selection().modify(FrameSelection::AlterationMove, DirectionForw
ard, CharacterGranularity, UserTriggered)) |
| 231 << "Selection.modify() returns true for user-triggered call"; | 231 << "Selection.modify() returns true for user-triggered call"; |
| 232 EXPECT_EQ(endOfText, selection().start()) | 232 EXPECT_EQ(endOfText, selection().start()) |
| 233 << "Selection isn't modified"; | 233 << "Selection isn't modified"; |
| 234 } | 234 } |
| 235 | 235 |
| 236 TEST_F(FrameSelectionTest, MoveRangeSelectionTest) | 236 TEST_F(FrameSelectionTest, MoveRangeSelectionTest) |
| 237 { | 237 { |
| 238 // "Foo Bar Baz," | 238 // "Foo Bar Baz," |
| 239 Text* text = appendTextNode("Foo Bar Baz,"); | 239 Text* text = appendTextNode("Foo Bar Baz,"); |
| 240 updateAllLifecyclePhases(); | 240 updateAllLifecyclePhases(); |
| 241 | 241 |
| 242 // Itinitializes with "Foo B|a>r Baz," (| means start and > means end). | 242 // Itinitializes with "Foo B|a>r Baz," (| means start and > means end). |
| 243 selection().setSelection(VisibleSelection(Position(text, 5), Position(text,
6))); | 243 selection().setSelection(createVisibleSelectionDeprecated(Position(text, 5),
Position(text, 6))); |
| 244 EXPECT_EQ_SELECTED_TEXT("a"); | 244 EXPECT_EQ_SELECTED_TEXT("a"); |
| 245 | 245 |
| 246 // "Foo B|ar B>az," with the Character granularity. | 246 // "Foo B|ar B>az," with the Character granularity. |
| 247 selection().moveRangeSelection(createVisiblePosition(Position(text, 5)), cre
ateVisiblePosition(Position(text, 9)), CharacterGranularity); | 247 selection().moveRangeSelection(createVisiblePosition(Position(text, 5)), cre
ateVisiblePosition(Position(text, 9)), CharacterGranularity); |
| 248 EXPECT_EQ_SELECTED_TEXT("ar B"); | 248 EXPECT_EQ_SELECTED_TEXT("ar B"); |
| 249 // "Foo B|ar B>az," with the Word granularity. | 249 // "Foo B|ar B>az," with the Word granularity. |
| 250 selection().moveRangeSelection(createVisiblePosition(Position(text, 5)), cre
ateVisiblePosition(Position(text, 9)), WordGranularity); | 250 selection().moveRangeSelection(createVisiblePosition(Position(text, 5)), cre
ateVisiblePosition(Position(text, 9)), WordGranularity); |
| 251 EXPECT_EQ_SELECTED_TEXT("Bar Baz"); | 251 EXPECT_EQ_SELECTED_TEXT("Bar Baz"); |
| 252 // "Fo<o B|ar Baz," with the Character granularity. | 252 // "Fo<o B|ar Baz," with the Character granularity. |
| 253 selection().moveRangeSelection(createVisiblePosition(Position(text, 5)), cre
ateVisiblePosition(Position(text, 2)), CharacterGranularity); | 253 selection().moveRangeSelection(createVisiblePosition(Position(text, 5)), cre
ateVisiblePosition(Position(text, 2)), CharacterGranularity); |
| 254 EXPECT_EQ_SELECTED_TEXT("o B"); | 254 EXPECT_EQ_SELECTED_TEXT("o B"); |
| 255 // "Fo<o B|ar Baz," with the Word granularity. | 255 // "Fo<o B|ar Baz," with the Word granularity. |
| 256 selection().moveRangeSelection(createVisiblePosition(Position(text, 5)), cre
ateVisiblePosition(Position(text, 2)), WordGranularity); | 256 selection().moveRangeSelection(createVisiblePosition(Position(text, 5)), cre
ateVisiblePosition(Position(text, 2)), WordGranularity); |
| 257 EXPECT_EQ_SELECTED_TEXT("Foo Bar"); | 257 EXPECT_EQ_SELECTED_TEXT("Foo Bar"); |
| 258 } | 258 } |
| 259 | 259 |
| 260 TEST_F(FrameSelectionTest, setNonDirectionalSelectionIfNeeded) | 260 TEST_F(FrameSelectionTest, setNonDirectionalSelectionIfNeeded) |
| 261 { | 261 { |
| 262 const char* bodyContent = "<span id=top>top</span><span id=host></span>"; | 262 const char* bodyContent = "<span id=top>top</span><span id=host></span>"; |
| 263 const char* shadowContent = "<span id=bottom>bottom</span>"; | 263 const char* shadowContent = "<span id=bottom>bottom</span>"; |
| 264 setBodyContent(bodyContent); | 264 setBodyContent(bodyContent); |
| 265 ShadowRoot* shadowRoot = setShadowContent(shadowContent, "host"); | 265 ShadowRoot* shadowRoot = setShadowContent(shadowContent, "host"); |
| 266 | 266 |
| 267 Node* top = document().getElementById("top")->firstChild(); | 267 Node* top = document().getElementById("top")->firstChild(); |
| 268 Node* bottom = shadowRoot->getElementById("bottom")->firstChild(); | 268 Node* bottom = shadowRoot->getElementById("bottom")->firstChild(); |
| 269 Node* host = document().getElementById("host"); | 269 Node* host = document().getElementById("host"); |
| 270 | 270 |
| 271 // top to bottom | 271 // top to bottom |
| 272 selection().setNonDirectionalSelectionIfNeeded(VisibleSelectionInFlatTree(Po
sitionInFlatTree(top, 1), PositionInFlatTree(bottom, 3)), CharacterGranularity); | 272 selection().setNonDirectionalSelectionIfNeeded(createVisibleSelectionDepreca
ted(PositionInFlatTree(top, 1), PositionInFlatTree(bottom, 3)), CharacterGranula
rity); |
| 273 EXPECT_EQ(Position(top, 1), visibleSelectionInDOMTree().base()); | 273 EXPECT_EQ(Position(top, 1), visibleSelectionInDOMTree().base()); |
| 274 EXPECT_EQ(Position::beforeNode(host), visibleSelectionInDOMTree().extent()); | 274 EXPECT_EQ(Position::beforeNode(host), visibleSelectionInDOMTree().extent()); |
| 275 EXPECT_EQ(Position(top, 1), visibleSelectionInDOMTree().start()); | 275 EXPECT_EQ(Position(top, 1), visibleSelectionInDOMTree().start()); |
| 276 EXPECT_EQ(Position(top, 3), visibleSelectionInDOMTree().end()); | 276 EXPECT_EQ(Position(top, 3), visibleSelectionInDOMTree().end()); |
| 277 | 277 |
| 278 EXPECT_EQ(PositionInFlatTree(top, 1), visibleSelectionInFlatTree().base()); | 278 EXPECT_EQ(PositionInFlatTree(top, 1), visibleSelectionInFlatTree().base()); |
| 279 EXPECT_EQ(PositionInFlatTree(bottom, 3), visibleSelectionInFlatTree().extent
()); | 279 EXPECT_EQ(PositionInFlatTree(bottom, 3), visibleSelectionInFlatTree().extent
()); |
| 280 EXPECT_EQ(PositionInFlatTree(top, 1), visibleSelectionInFlatTree().start()); | 280 EXPECT_EQ(PositionInFlatTree(top, 1), visibleSelectionInFlatTree().start()); |
| 281 EXPECT_EQ(PositionInFlatTree(bottom, 3), visibleSelectionInFlatTree().end())
; | 281 EXPECT_EQ(PositionInFlatTree(bottom, 3), visibleSelectionInFlatTree().end())
; |
| 282 | 282 |
| 283 // bottom to top | 283 // bottom to top |
| 284 selection().setNonDirectionalSelectionIfNeeded(VisibleSelectionInFlatTree(Po
sitionInFlatTree(bottom, 3), PositionInFlatTree(top, 1)), CharacterGranularity); | 284 selection().setNonDirectionalSelectionIfNeeded(createVisibleSelectionDepreca
ted(PositionInFlatTree(bottom, 3), PositionInFlatTree(top, 1)), CharacterGranula
rity); |
| 285 EXPECT_EQ(Position(bottom, 3), visibleSelectionInDOMTree().base()); | 285 EXPECT_EQ(Position(bottom, 3), visibleSelectionInDOMTree().base()); |
| 286 EXPECT_EQ(Position::beforeNode(bottom->parentNode()), visibleSelectionInDOMT
ree().extent()); | 286 EXPECT_EQ(Position::beforeNode(bottom->parentNode()), visibleSelectionInDOMT
ree().extent()); |
| 287 EXPECT_EQ(Position(bottom, 0), visibleSelectionInDOMTree().start()); | 287 EXPECT_EQ(Position(bottom, 0), visibleSelectionInDOMTree().start()); |
| 288 EXPECT_EQ(Position(bottom, 3), visibleSelectionInDOMTree().end()); | 288 EXPECT_EQ(Position(bottom, 3), visibleSelectionInDOMTree().end()); |
| 289 | 289 |
| 290 EXPECT_EQ(PositionInFlatTree(bottom, 3), visibleSelectionInFlatTree().base()
); | 290 EXPECT_EQ(PositionInFlatTree(bottom, 3), visibleSelectionInFlatTree().base()
); |
| 291 EXPECT_EQ(PositionInFlatTree(top, 1), visibleSelectionInFlatTree().extent())
; | 291 EXPECT_EQ(PositionInFlatTree(top, 1), visibleSelectionInFlatTree().extent())
; |
| 292 EXPECT_EQ(PositionInFlatTree(top, 1), visibleSelectionInFlatTree().start()); | 292 EXPECT_EQ(PositionInFlatTree(top, 1), visibleSelectionInFlatTree().start()); |
| 293 EXPECT_EQ(PositionInFlatTree(bottom, 3), visibleSelectionInFlatTree().end())
; | 293 EXPECT_EQ(PositionInFlatTree(bottom, 3), visibleSelectionInFlatTree().end())
; |
| 294 } | 294 } |
| 295 | 295 |
| 296 TEST_F(FrameSelectionTest, SelectAllWithUnselectableRoot) | 296 TEST_F(FrameSelectionTest, SelectAllWithUnselectableRoot) |
| 297 { | 297 { |
| 298 Element* select = document().createElement("select", ASSERT_NO_EXCEPTION); | 298 Element* select = document().createElement("select", ASSERT_NO_EXCEPTION); |
| 299 document().replaceChild(select, document().documentElement()); | 299 document().replaceChild(select, document().documentElement()); |
| 300 selection().selectAll(); | 300 selection().selectAll(); |
| 301 EXPECT_TRUE(selection().isNone()) << "Nothing should be selected if the cont
ent of the documentElement is not selctable."; | 301 EXPECT_TRUE(selection().isNone()) << "Nothing should be selected if the cont
ent of the documentElement is not selctable."; |
| 302 } | 302 } |
| 303 | 303 |
| 304 TEST_F(FrameSelectionTest, updateIfNeededAndFrameCaret) | 304 TEST_F(FrameSelectionTest, updateIfNeededAndFrameCaret) |
| 305 { | 305 { |
| 306 setBodyContent("<style id=sample></style>"); | 306 setBodyContent("<style id=sample></style>"); |
| 307 document().setDesignMode("on"); | 307 document().setDesignMode("on"); |
| 308 Element* sample = document().getElementById("sample"); | 308 Element* sample = document().getElementById("sample"); |
| 309 setSelection(VisibleSelection(Position(sample, 0))); | 309 setSelection(createVisibleSelectionDeprecated(Position(sample, 0))); |
| 310 EXPECT_EQ(Position(document().body(), 0), selection().start()); | 310 EXPECT_EQ(Position(document().body(), 0), selection().start()); |
| 311 EXPECT_EQ(selection().start(), caretPosition().position()); | 311 EXPECT_EQ(selection().start(), caretPosition().position()); |
| 312 document().body()->remove(); | 312 document().body()->remove(); |
| 313 // TODO(yosin): Once lazy canonicalization implemented, selection.start | 313 // TODO(yosin): Once lazy canonicalization implemented, selection.start |
| 314 // should be Position(HTML, 0). | 314 // should be Position(HTML, 0). |
| 315 EXPECT_EQ(Position(document().documentElement(), 1), selection().start()); | 315 EXPECT_EQ(Position(document().documentElement(), 1), selection().start()); |
| 316 EXPECT_EQ(selection().start(), caretPosition().position()); | 316 EXPECT_EQ(selection().start(), caretPosition().position()); |
| 317 selection().updateIfNeeded(); | 317 selection().updateIfNeeded(); |
| 318 | 318 |
| 319 // TODO(yosin): Once lazy canonicalization implemented, selection.start | 319 // TODO(yosin): Once lazy canonicalization implemented, selection.start |
| 320 // should be Position(HTML, 0). | 320 // should be Position(HTML, 0). |
| 321 EXPECT_EQ(Position(), selection().start()) | 321 EXPECT_EQ(Position(), selection().start()) |
| 322 << "updateIfNeeded() makes selection to null."; | 322 << "updateIfNeeded() makes selection to null."; |
| 323 EXPECT_EQ(selection().start(), caretPosition().position()); | 323 EXPECT_EQ(selection().start(), caretPosition().position()); |
| 324 } | 324 } |
| 325 | 325 |
| 326 } // namespace blink | 326 } // namespace blink |
| OLD | NEW |