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 <memory> | 7 #include <memory> |
8 #include "bindings/core/v8/ExceptionState.h" | 8 #include "bindings/core/v8/ExceptionState.h" |
9 #include "core/dom/Document.h" | 9 #include "core/dom/Document.h" |
10 #include "core/dom/Element.h" | 10 #include "core/dom/Element.h" |
(...skipping 331 matching lines...) Loading... | |
342 .Build()); | 342 .Build()); |
343 // Should not crash inside. | 343 // Should not crash inside. |
344 const VisibleSelectionInFlatTree& selection = | 344 const VisibleSelectionInFlatTree& selection = |
345 Selection().ComputeVisibleSelectionInFlatTree(); | 345 Selection().ComputeVisibleSelectionInFlatTree(); |
346 | 346 |
347 // This only records the current behavior. It might be changed in the future. | 347 // This only records the current behavior. It might be changed in the future. |
348 EXPECT_EQ(PositionInFlatTree(foo, 0), selection.Base()); | 348 EXPECT_EQ(PositionInFlatTree(foo, 0), selection.Base()); |
349 EXPECT_EQ(PositionInFlatTree(foo, 0), selection.Extent()); | 349 EXPECT_EQ(PositionInFlatTree(foo, 0), selection.Extent()); |
350 } | 350 } |
351 | 351 |
352 TEST_F(FrameSelectionTest, CaretInShadowTree) { | |
Xiaocheng
2017/05/05 18:32:02
Let's have two test cases:
- CaretInTextControl
-
hugoh_UTC2
2017/05/08 08:28:14
You mean a caret inside a <div contenteditable> th
yosin_UTC9
2017/05/08 09:00:10
Following example can be simple(?):
SetBodyConten
hugoh_UTC2
2017/05/08 11:40:02
Done. See PS11.
| |
353 SetBodyContent("<input id='field'>"); // <input> hosts a shadow tree. | |
354 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); | |
355 EXPECT_FALSE(Selection().HasFocus()); | |
356 EXPECT_TRUE(Selection().IsHidden()); | |
357 | |
358 Element* const field = GetDocument().getElementById("field"); | |
359 field->focus(); | |
360 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
361 EXPECT_TRUE(Selection().HasFocus()); | |
362 EXPECT_FALSE(Selection().IsHidden()); | |
363 | |
364 field->blur(); // Move focus to document body. | |
365 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
366 EXPECT_FALSE(Selection().HasFocus()); | |
367 EXPECT_TRUE(Selection().IsHidden()); // Caret is now hidden. | |
368 } | |
369 | |
370 TEST_F(FrameSelectionTest, RangeInShadowTree) { | |
Xiaocheng
2017/05/05 18:32:02
Ditto.
hugoh_UTC2
2017/05/08 11:40:02
Done. See PS11.
| |
371 SetBodyContent("<input id='field' value='hola'>"); | |
372 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); | |
373 EXPECT_FALSE(Selection().HasFocus()); | |
374 EXPECT_TRUE(Selection().IsHidden()); | |
375 | |
376 Element* const field = GetDocument().getElementById("field"); | |
377 field->focus(); | |
378 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
379 EXPECT_TRUE(Selection().HasFocus()); | |
380 EXPECT_FALSE(Selection().IsHidden()); | |
381 | |
382 Selection().SelectAll(); | |
383 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
384 EXPECT_TRUE(Selection().HasFocus()); | |
385 EXPECT_FALSE(Selection().IsHidden()); | |
386 | |
387 field->blur(); // Move focus to document body. | |
388 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
389 EXPECT_FALSE(Selection().HasFocus()); | |
390 EXPECT_TRUE(Selection().IsHidden()); // Range is now hidden. | |
391 } | |
392 | |
393 // crbug.com/692898 | |
394 TEST_F(FrameSelectionTest, FocusingLinkHidesCaretInTextControl) { | |
395 SetBodyContent( | |
396 "<input id='field'>" | |
397 "<a href='www' id='alink'>link</a>"); | |
398 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); | |
399 EXPECT_FALSE(Selection().HasFocus()); | |
400 EXPECT_TRUE(Selection().IsHidden()); | |
401 | |
402 Element* const field = GetDocument().getElementById("field"); | |
403 field->focus(); | |
404 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
405 EXPECT_TRUE(Selection().HasFocus()); | |
406 EXPECT_FALSE(Selection().IsHidden()); | |
407 | |
408 Element* const alink = GetDocument().getElementById("alink"); | |
409 alink->focus(); | |
410 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
411 EXPECT_FALSE(Selection().HasFocus()); | |
412 EXPECT_TRUE(Selection().IsHidden()); | |
413 } | |
414 | |
415 // crbug.com/692898 | |
416 TEST_F(FrameSelectionTest, FocusingLinkHidesRangeInTextControl) { | |
417 SetBodyContent( | |
418 "<input id='field' value='hola'>" | |
419 "<a href='www' id='alink'>link</a>"); | |
420 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); | |
421 EXPECT_FALSE(Selection().HasFocus()); | |
422 EXPECT_TRUE(Selection().IsHidden()); | |
423 | |
424 Element* const field = GetDocument().getElementById("field"); | |
425 field->focus(); | |
426 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
427 EXPECT_TRUE(Selection().HasFocus()); | |
428 EXPECT_FALSE(Selection().IsHidden()); | |
429 | |
430 Selection().SelectAll(); | |
431 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
432 EXPECT_TRUE(Selection().HasFocus()); | |
433 EXPECT_FALSE(Selection().IsHidden()); | |
434 | |
435 Element* const alink = GetDocument().getElementById("alink"); | |
436 alink->focus(); | |
437 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
438 EXPECT_FALSE(Selection().HasFocus()); | |
439 EXPECT_TRUE(Selection().IsHidden()); | |
440 } | |
441 | |
442 TEST_F(FrameSelectionTest, FocusingButtonHidesRangeInReadOnlyTextControl) { | |
443 SetBodyContent( | |
444 "<textarea readonly>Berlin</textarea>" | |
445 "<input type='submit' value='Submit'>"); | |
446 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); | |
447 EXPECT_FALSE(Selection().HasFocus()); | |
448 EXPECT_TRUE(Selection().IsHidden()); | |
449 | |
450 Element* const textarea = GetDocument().QuerySelector("textarea"); | |
451 textarea->focus(); | |
452 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
453 | |
454 Selection().SelectAll(); | |
455 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
456 EXPECT_TRUE(Selection().HasFocus()); | |
457 EXPECT_FALSE(Selection().IsHidden()); | |
458 | |
459 Element* const submit = GetDocument().QuerySelector("input"); | |
460 submit->focus(); | |
461 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
462 EXPECT_FALSE(Selection().HasFocus()); | |
463 EXPECT_TRUE(Selection().IsHidden()); | |
464 } | |
465 | |
466 TEST_F(FrameSelectionTest, FocusingButtonHidesRangeInDisabledTextControl) { | |
467 SetBodyContent( | |
468 "<textarea disabled>Berlin</textarea>" | |
469 "<input type='submit' value='Submit'>"); | |
470 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); | |
471 EXPECT_FALSE(Selection().HasFocus()); | |
472 EXPECT_TRUE(Selection().IsHidden()); | |
473 | |
474 Element* const textarea = GetDocument().QuerySelector("textarea"); | |
475 textarea->focus(); | |
476 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); | |
477 | |
478 // We use a double click to create the selection [Berlin]. | |
Xiaocheng
2017/05/05 18:32:02
We can use FrameSelection::SetSelection to set sel
hugoh_UTC2
2017/05/08 08:28:14
Thanks. But let's use double click anyway since it
| |
479 // FrameSelection::SelectAll (= textarea.select() in JavaScript) would have | |
480 // been shorter, but currently that doesn't work on a *disabled* text control. | |
481 const IntRect elem_bounds = textarea->BoundsInViewport(); | |
482 WebMouseEvent double_click(WebMouseEvent::kMouseDown, 0, | |
483 WebInputEvent::kTimeStampForTesting); | |
484 double_click.SetPositionInWidget(elem_bounds.X(), elem_bounds.Y()); | |
485 double_click.SetPositionInScreen(elem_bounds.X(), elem_bounds.Y()); | |
486 double_click.button = WebMouseEvent::Button::kLeft; | |
487 double_click.click_count = 2; | |
488 double_click.SetFrameScale(1); | |
489 | |
490 GetFrame().GetEventHandler().HandleMousePressEvent(double_click); | |
491 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
492 EXPECT_TRUE(Selection().HasFocus()); | |
493 EXPECT_FALSE(Selection().IsHidden()); | |
494 | |
495 Element* const submit = GetDocument().QuerySelector("input"); | |
496 submit->focus(); | |
497 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
498 EXPECT_FALSE(Selection().HasFocus()); | |
499 EXPECT_TRUE(Selection().IsHidden()); | |
500 } | |
501 | |
502 // crbug.com/713051 | |
503 TEST_F(FrameSelectionTest, FocusingNonEditableParentHidesCaretInTextControl) { | |
504 SetBodyContent( | |
505 "<div tabindex='-1' id='parent'>" | |
506 " <input id='field'>" | |
507 "</div>"); | |
508 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); | |
509 EXPECT_FALSE(Selection().HasFocus()); | |
510 EXPECT_TRUE(Selection().IsHidden()); | |
511 | |
512 Element* const field = GetDocument().getElementById("field"); | |
513 field->focus(); | |
514 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
515 EXPECT_TRUE(Selection().HasFocus()); | |
516 EXPECT_FALSE(Selection().IsHidden()); | |
517 | |
518 // Here the selection belongs to <input>'s shadow tree and that tree has a | |
519 // non-editable parent that is focused. | |
520 Element* const parent = GetDocument().getElementById("parent"); | |
521 parent->focus(); | |
522 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
523 EXPECT_FALSE(Selection().HasFocus()); | |
524 EXPECT_TRUE(Selection().IsHidden()); // Focus is outside <input> | |
525 // so caret should not be visible. | |
526 | |
527 parent->blur(); // Move focus to document body. | |
528 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
529 EXPECT_FALSE(Selection().HasFocus()); | |
530 EXPECT_TRUE(Selection().IsHidden()); // Caret is still hidden. | |
531 } | |
532 | |
533 // crbug.com/713051 | |
534 TEST_F(FrameSelectionTest, FocusingNonEditableParentHidesRangeInTextControl) { | |
535 SetBodyContent( | |
536 "<div tabindex='-1' id='parent'>" | |
537 " <input id='field' value='hola'>" | |
538 "</div>"); | |
539 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); | |
540 EXPECT_FALSE(Selection().HasFocus()); | |
541 EXPECT_TRUE(Selection().IsHidden()); | |
542 | |
543 Element* const field = GetDocument().getElementById("field"); | |
544 field->focus(); | |
545 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
546 EXPECT_TRUE(Selection().HasFocus()); | |
547 EXPECT_FALSE(Selection().IsHidden()); | |
548 | |
549 Selection().SelectAll(); | |
550 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
551 EXPECT_TRUE(Selection().HasFocus()); | |
552 EXPECT_FALSE(Selection().IsHidden()); | |
553 | |
554 // Here the selection belongs to <input>'s shadow tree and that tree has a | |
555 // non-editable parent that is focused. | |
556 Element* const parent = GetDocument().getElementById("parent"); | |
557 parent->focus(); | |
558 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
559 EXPECT_FALSE(Selection().HasFocus()); | |
560 EXPECT_TRUE(Selection().IsHidden()); // Focus is outside <input> | |
561 // so range should not be visible. | |
562 | |
563 parent->blur(); // Move focus to document body. | |
564 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
565 EXPECT_FALSE(Selection().HasFocus()); | |
566 EXPECT_TRUE(Selection().IsHidden()); // Range is still hidden. | |
567 } | |
568 | |
569 TEST_F(FrameSelectionTest, CaretInFocusedEditableDiv) { | |
570 SetBodyContent("<div contenteditable id='ce'>blabla</div>"); | |
571 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); | |
572 EXPECT_FALSE(Selection().HasFocus()); | |
573 EXPECT_TRUE(Selection().IsHidden()); | |
574 | |
575 Element* const ce = GetDocument().getElementById("ce"); | |
576 ce->focus(); | |
577 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
578 EXPECT_TRUE(Selection().HasFocus()); | |
579 EXPECT_FALSE(Selection().IsHidden()); | |
580 | |
581 ce->blur(); // Move focus to document body. | |
582 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
583 EXPECT_FALSE(Selection().HasFocus()); | |
584 EXPECT_TRUE(Selection().IsHidden()); // Caret is now hidden. | |
585 } | |
586 | |
587 TEST_F(FrameSelectionTest, RangeInFocusedEditableDiv) { | |
588 SetBodyContent("<div contenteditable id='ce'>blabla</div>"); | |
589 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); | |
590 EXPECT_FALSE(Selection().HasFocus()); | |
591 EXPECT_TRUE(Selection().IsHidden()); | |
592 | |
593 Element* const ce = GetDocument().getElementById("ce"); | |
594 ce->focus(); | |
595 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
596 EXPECT_TRUE(Selection().HasFocus()); | |
597 EXPECT_FALSE(Selection().IsHidden()); | |
598 | |
599 Selection().SelectAll(); | |
600 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
601 EXPECT_TRUE(Selection().HasFocus()); | |
602 EXPECT_FALSE(Selection().IsHidden()); | |
603 | |
604 ce->blur(); // Move focus to document body. | |
605 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
606 EXPECT_FALSE(Selection().HasFocus()); | |
607 EXPECT_FALSE(Selection().IsHidden()); // Range is still visible. | |
608 } | |
609 | |
610 TEST_F(FrameSelectionTest, FocusingLinkHidesCaretInContentEditable) { | |
611 SetBodyContent( | |
612 "<div contenteditable id='ce'>blabla</div>" | |
613 "<a href='www' id='alink'>link</a>"); | |
614 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); | |
615 EXPECT_FALSE(Selection().HasFocus()); | |
616 EXPECT_TRUE(Selection().IsHidden()); | |
617 | |
618 Element* const ce = GetDocument().getElementById("ce"); | |
619 ce->focus(); | |
620 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
621 EXPECT_TRUE(Selection().HasFocus()); | |
622 EXPECT_FALSE(Selection().IsHidden()); | |
623 | |
624 Element* const alink = GetDocument().getElementById("alink"); | |
625 alink->focus(); | |
626 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
627 EXPECT_FALSE(Selection().HasFocus()); | |
628 EXPECT_TRUE(Selection().IsHidden()); | |
629 } | |
630 | |
631 TEST_F(FrameSelectionTest, FocusingLinkKeepsRangeInContentEditable) { | |
632 SetBodyContent( | |
633 "<div contenteditable id='ce'>blabla</div>" | |
634 "<a href='www' id='alink'>link</a>"); | |
635 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); | |
636 EXPECT_FALSE(Selection().HasFocus()); | |
637 EXPECT_TRUE(Selection().IsHidden()); | |
638 | |
639 Element* const ce = GetDocument().getElementById("ce"); | |
640 ce->focus(); | |
641 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
642 EXPECT_TRUE(Selection().HasFocus()); | |
643 EXPECT_FALSE(Selection().IsHidden()); | |
644 | |
645 Selection().SelectAll(); | |
646 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
647 EXPECT_TRUE(Selection().HasFocus()); | |
648 EXPECT_FALSE(Selection().IsHidden()); | |
649 | |
650 Element* const alink = GetDocument().getElementById("alink"); | |
651 alink->focus(); | |
652 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
653 EXPECT_FALSE(Selection().HasFocus()); | |
654 EXPECT_FALSE(Selection().IsHidden()); | |
655 } | |
656 | |
657 TEST_F(FrameSelectionTest, FocusingEditableParentKeepsEditableCaret) { | |
658 SetBodyContent( | |
659 "<div contenteditable tabindex='-1' id='parent'>" | |
660 "<div contenteditable id='ce'>blabla</div>" | |
661 "</div>"); | |
662 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); | |
663 EXPECT_FALSE(Selection().HasFocus()); | |
664 EXPECT_TRUE(Selection().IsHidden()); | |
665 | |
666 // TODO(editing-dev): Blink should be able to focus the inner <div>. | |
667 // Element* const ce = GetDocument().getElementById("ce"); | |
668 // ce->focus(); | |
669 // EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
670 // EXPECT_FALSE(Selection().IsHidden()); | |
671 | |
672 Element* const parent = GetDocument().getElementById("parent"); | |
673 parent->focus(); | |
674 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
675 EXPECT_TRUE(Selection().HasFocus()); | |
676 EXPECT_FALSE(Selection().IsHidden()); // Focus is within editing boundary, | |
677 // caret should be visible. | |
678 | |
679 parent->blur(); // Move focus to document body. | |
680 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
681 EXPECT_FALSE(Selection().HasFocus()); | |
682 EXPECT_TRUE(Selection().IsHidden()); // Focus is outside editing boundary | |
683 // so caret should be hidden. | |
684 } | |
685 | |
686 TEST_F(FrameSelectionTest, FocusingEditableParentKeepsEditableRange) { | |
687 SetBodyContent( | |
688 "<div contenteditable tabindex='-1' id='parent'>" | |
689 "<div contenteditable id='ce'>blabla</div>" | |
690 "</div>"); | |
691 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); | |
692 EXPECT_FALSE(Selection().HasFocus()); | |
693 EXPECT_TRUE(Selection().IsHidden()); | |
694 | |
695 // TODO(editing-dev): Blink should be able to focus the inner <div>. | |
696 // Element* const ce = GetDocument().getElementById("ce"); | |
697 // ce->focus(); | |
698 // EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
699 // EXPECT_FALSE(Selection().IsHidden()); | |
700 | |
701 // Selection().SelectAll(); | |
702 // EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
703 // EXPECT_FALSE(Selection().IsHidden()); | |
704 | |
705 Element* const parent = GetDocument().getElementById("parent"); | |
706 parent->focus(); | |
707 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
708 EXPECT_TRUE(Selection().HasFocus()); | |
709 EXPECT_FALSE(Selection().IsHidden()); // Focus is within editing boundary, | |
710 // range should be visible. | |
711 | |
712 Selection().SelectAll(); | |
713 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
714 EXPECT_TRUE(Selection().HasFocus()); | |
715 EXPECT_FALSE(Selection().IsHidden()); | |
716 | |
717 parent->blur(); // Move focus to document body. | |
718 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
719 EXPECT_FALSE(Selection().HasFocus()); | |
720 EXPECT_FALSE(Selection().IsHidden()); // Focus is outside editing boundary | |
721 // but range should still be visible. | |
722 } | |
723 | |
724 TEST_F(FrameSelectionTest, FocusingNonEditableParentHidesEditableCaret) { | |
725 SetBodyContent( | |
726 "<div tabindex='-1' id='parent'>" | |
727 "<div contenteditable id='ce'>blabla</div>" | |
728 "</div>"); | |
729 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); | |
730 EXPECT_FALSE(Selection().HasFocus()); | |
731 EXPECT_TRUE(Selection().IsHidden()); | |
732 | |
733 Element* const ce = GetDocument().getElementById("ce"); | |
734 ce->focus(); | |
735 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
736 EXPECT_TRUE(Selection().HasFocus()); | |
737 EXPECT_FALSE(Selection().IsHidden()); | |
738 | |
739 // Here the selection belongs to <divs>'s shadow tree and that tree has a | |
yosin_UTC9
2017/05/08 05:36:52
nit: s/divs/div/
hugoh_UTC2
2017/05/08 11:40:03
Done. See PS11.
| |
740 // non-editable parent that is focused. | |
741 Element* const parent = GetDocument().getElementById("parent"); | |
742 parent->focus(); | |
743 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
744 EXPECT_FALSE(Selection().HasFocus()); | |
745 EXPECT_TRUE(Selection().IsHidden()); // Focus is outside editing boundary | |
746 // so caret should be hidden. | |
747 | |
748 parent->blur(); // Move focus to document body. | |
749 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
750 EXPECT_FALSE(Selection().HasFocus()); | |
751 EXPECT_TRUE(Selection().IsHidden()); // Caret is still hidden. | |
752 } | |
753 | |
754 TEST_F(FrameSelectionTest, FocusingNonEditableParentKeepsEditableRange) { | |
755 SetBodyContent( | |
756 "<div tabindex='-1' id='parent'>" | |
757 "<div contenteditable id='ce'>blabla</div>" | |
758 "</div>"); | |
759 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); | |
760 EXPECT_FALSE(Selection().HasFocus()); | |
761 EXPECT_TRUE(Selection().IsHidden()); | |
762 | |
763 Element* const ce = GetDocument().getElementById("ce"); | |
764 ce->focus(); | |
765 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret()); | |
766 EXPECT_TRUE(Selection().HasFocus()); | |
767 EXPECT_FALSE(Selection().IsHidden()); | |
768 | |
769 Selection().SelectAll(); | |
770 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
771 EXPECT_TRUE(Selection().HasFocus()); | |
772 EXPECT_FALSE(Selection().IsHidden()); | |
773 | |
774 // Here the selection belongs to <divs>'s shadow tree and that tree has a | |
775 // non-editable parent that is focused. | |
776 Element* const parent = GetDocument().getElementById("parent"); | |
777 parent->focus(); | |
778 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
779 EXPECT_FALSE(Selection().HasFocus()); | |
780 EXPECT_FALSE(Selection().IsHidden()); // Focus is outside editing boundary | |
781 // but range should still be visible. | |
782 | |
783 parent->blur(); // Move focus to document body. | |
784 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
785 EXPECT_FALSE(Selection().HasFocus()); | |
786 EXPECT_FALSE(Selection().IsHidden()); // Range is still visible. | |
787 } | |
788 | |
789 // crbug.com/707143 | |
790 TEST_F(FrameSelectionTest, RangeContainsFocus) { | |
791 SetBodyContent( | |
792 "<div>" | |
793 " <div>" | |
794 " <span id='start'>start</span>" | |
795 " </div>" | |
796 " <a href='www' id='alink'>link</a>" | |
797 " <div>line 1</div>" | |
798 " <div id='middle'>line 2</div>" | |
799 " <div>line 3</div>" | |
800 " <div>line 4</div>" | |
801 " <span id='end'>end</span>" | |
802 " <div></div>" | |
803 "</div>"); | |
804 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); | |
805 EXPECT_FALSE(Selection().HasFocus()); | |
806 EXPECT_TRUE(Selection().IsHidden()); | |
807 | |
808 Element* const start = GetDocument().getElementById("start"); | |
809 Element* const end = GetDocument().getElementById("end"); | |
810 Selection().SetSelection( | |
811 SelectionInDOMTree::Builder() | |
812 .SetBaseAndExtent(Position(start, 0), Position(end, 0)) | |
813 .Build()); | |
814 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
815 EXPECT_TRUE(Selection().HasFocus()); | |
816 EXPECT_FALSE(Selection().IsHidden()); | |
817 | |
818 Element* const alink = GetDocument().getElementById("alink"); | |
819 alink->focus(); | |
820 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
821 EXPECT_FALSE(Selection().HasFocus()); | |
822 EXPECT_FALSE(Selection().IsHidden()); // Range still visible. | |
823 } | |
824 | |
825 // crbug.com/707143 | |
826 TEST_F(FrameSelectionTest, RangeOutsideFocus) { | |
827 // Here the selection sits on a sub tree that hasn't the focused element. | |
828 // This test case is the reason why we separate FrameSelection::HasFocus() and | |
829 // FrameSelection::IsHidden(). Even when the selection's DOM nodes are | |
830 // completely disconnected from the focused node, we still want the selection | |
831 // to be visible (not hidden). | |
832 SetBodyContent( | |
833 "<a href='www' id='alink'>link</a>" | |
834 "<div>" | |
835 " <div>" | |
836 " <span id='start'>start</span>" | |
837 " </div>" | |
838 " <div>line 1</div>" | |
839 " <div id='middle'>line 2</div>" | |
840 " <div>line 3</div>" | |
841 " <div>line 4</div>" | |
842 " <span id='end'>end</span>" | |
843 " <div></div>" | |
844 "</div>"); | |
845 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone()); | |
846 EXPECT_FALSE(Selection().HasFocus()); | |
847 EXPECT_TRUE(Selection().IsHidden()); | |
848 | |
849 Element* const start = GetDocument().getElementById("start"); | |
850 Element* const end = GetDocument().getElementById("end"); | |
851 Selection().SetSelection( | |
852 SelectionInDOMTree::Builder() | |
853 .SetBaseAndExtent(Position(start, 0), Position(end, 0)) | |
854 .Build()); | |
855 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
856 EXPECT_TRUE(Selection().HasFocus()); | |
857 EXPECT_FALSE(Selection().IsHidden()); | |
858 | |
859 Element* const alink = GetDocument().getElementById("alink"); | |
860 alink->focus(); | |
861 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange()); | |
862 EXPECT_FALSE(Selection().HasFocus()); | |
863 EXPECT_FALSE(Selection().IsHidden()); // Range still visible. | |
864 } | |
865 | |
352 } // namespace blink | 866 } // namespace blink |
OLD | NEW |