Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1376)

Side by Side Diff: third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp

Issue 2841093002: Algorithm for deciding if a frame's selection should be hidden (Closed)
Patch Set: 2 more tests for selections in shadow trees Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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...) Expand 10 before | Expand all | Expand 10 after
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) {
353 SetBodyContent("<p id=host></p>bar");
354 ShadowRoot* shadow_root =
355 SetShadowContent("<div contenteditable id='ce'>foo</div>", "host");
356 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
357 EXPECT_FALSE(Selection().SelectionHasFocus());
358 EXPECT_TRUE(Selection().IsHidden());
359
360 Element* const ce = shadow_root->getElementById("ce");
361 ce->focus();
362 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
363 EXPECT_TRUE(Selection().SelectionHasFocus());
364 EXPECT_FALSE(Selection().IsHidden());
365
366 ce->blur(); // Move focus to document body.
367 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
368 EXPECT_FALSE(Selection().SelectionHasFocus());
369 EXPECT_TRUE(Selection().IsHidden()); // Caret is now hidden.
Xiaocheng 2017/05/08 22:08:29 nit: When documenting an EXPECT_FOO (or ASSERT_FOO
hugoh_UTC2 2017/05/09 09:22:45 Here I found it to messy to add a comment for ever
370 }
371
372 TEST_F(FrameSelectionTest, CaretInTextControl) {
373 SetBodyContent("<input id='field'>"); // <input> hosts a shadow tree.
374 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
375 EXPECT_FALSE(Selection().SelectionHasFocus());
376 EXPECT_TRUE(Selection().IsHidden());
377
378 Element* const field = GetDocument().getElementById("field");
379 field->focus();
380 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
381 EXPECT_TRUE(Selection().SelectionHasFocus());
382 EXPECT_FALSE(Selection().IsHidden());
383
384 field->blur(); // Move focus to document body.
385 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
386 EXPECT_FALSE(Selection().SelectionHasFocus());
387 EXPECT_TRUE(Selection().IsHidden()); // Caret is now hidden.
388 }
389
390 TEST_F(FrameSelectionTest, RangeInShadowTree) {
Xiaocheng 2017/05/08 22:08:29 Sorry if I made a confusion. I was expecting a tes
hugoh_UTC2 2017/05/09 09:22:45 Done in PS12.
391 SetBodyContent("<p id='host'></p>");
392 ShadowRoot* shadow_root = SetShadowContent("hey", "host");
393 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
394 EXPECT_FALSE(Selection().SelectionHasFocus());
395 EXPECT_TRUE(Selection().IsHidden());
396
397 Node* text_node = shadow_root->firstChild();
398 Selection().SetSelection(
399 SelectionInFlatTree::Builder()
400 .SetBaseAndExtent(PositionInFlatTree(text_node, 0),
401 PositionInFlatTree(text_node, 3))
402 .Build());
403 EXPECT_EQ_SELECTED_TEXT("hey");
404 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
405 EXPECT_TRUE(Selection().SelectionHasFocus());
406 EXPECT_FALSE(Selection().IsHidden());
407
408 GetDocument().body()->focus(); // Move focus to document body.
409 EXPECT_EQ_SELECTED_TEXT("hey");
410 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
411 EXPECT_TRUE(Selection().SelectionHasFocus());
412 EXPECT_FALSE(Selection().IsHidden());
413 }
414
415 TEST_F(FrameSelectionTest, RangeInTextControl) {
416 SetBodyContent("<input id='field' value='hola'>");
417 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
418 EXPECT_FALSE(Selection().SelectionHasFocus());
419 EXPECT_TRUE(Selection().IsHidden());
420
421 Element* const field = GetDocument().getElementById("field");
422 field->focus();
423 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
424 EXPECT_TRUE(Selection().SelectionHasFocus());
425 EXPECT_FALSE(Selection().IsHidden());
426
427 Selection().SelectAll();
428 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
429 EXPECT_TRUE(Selection().SelectionHasFocus());
430 EXPECT_FALSE(Selection().IsHidden());
431
432 field->blur();
433 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
434 EXPECT_FALSE(Selection().SelectionHasFocus());
435 EXPECT_TRUE(Selection().IsHidden());
436 }
437
438 // crbug.com/692898
439 TEST_F(FrameSelectionTest, FocusingLinkHidesCaretInTextControl) {
440 SetBodyContent(
441 "<input id='field'>"
442 "<a href='www' id='alink'>link</a>");
443 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
444 EXPECT_FALSE(Selection().SelectionHasFocus());
445 EXPECT_TRUE(Selection().IsHidden());
446
447 Element* const field = GetDocument().getElementById("field");
448 field->focus();
449 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
450 EXPECT_TRUE(Selection().SelectionHasFocus());
451 EXPECT_FALSE(Selection().IsHidden());
452
453 Element* const alink = GetDocument().getElementById("alink");
454 alink->focus();
455 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
456 EXPECT_FALSE(Selection().SelectionHasFocus());
457 EXPECT_TRUE(Selection().IsHidden());
458 }
459
460 // crbug.com/692898
461 TEST_F(FrameSelectionTest, FocusingLinkHidesRangeInTextControl) {
462 SetBodyContent(
463 "<input id='field' value='hola'>"
464 "<a href='www' id='alink'>link</a>");
465 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
466 EXPECT_FALSE(Selection().SelectionHasFocus());
467 EXPECT_TRUE(Selection().IsHidden());
468
469 Element* const field = GetDocument().getElementById("field");
470 field->focus();
471 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
472 EXPECT_TRUE(Selection().SelectionHasFocus());
473 EXPECT_FALSE(Selection().IsHidden());
474
475 Selection().SelectAll();
476 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
477 EXPECT_TRUE(Selection().SelectionHasFocus());
478 EXPECT_FALSE(Selection().IsHidden());
479
480 Element* const alink = GetDocument().getElementById("alink");
481 alink->focus();
482 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
483 EXPECT_FALSE(Selection().SelectionHasFocus());
484 EXPECT_TRUE(Selection().IsHidden());
485 }
486
487 TEST_F(FrameSelectionTest, FocusingButtonHidesRangeInReadOnlyTextControl) {
488 SetBodyContent(
489 "<textarea readonly>Berlin</textarea>"
490 "<input type='submit' value='Submit'>");
491 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
492 EXPECT_FALSE(Selection().SelectionHasFocus());
493 EXPECT_TRUE(Selection().IsHidden());
494
495 Element* const textarea = GetDocument().QuerySelector("textarea");
496 textarea->focus();
497 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
498
499 Selection().SelectAll();
500 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
501 EXPECT_TRUE(Selection().SelectionHasFocus());
502 EXPECT_FALSE(Selection().IsHidden());
503
504 Element* const submit = GetDocument().QuerySelector("input");
505 submit->focus();
506 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
507 EXPECT_FALSE(Selection().SelectionHasFocus());
508 EXPECT_TRUE(Selection().IsHidden());
509 }
510
511 TEST_F(FrameSelectionTest, FocusingButtonHidesRangeInDisabledTextControl) {
512 SetBodyContent(
513 "<textarea disabled>Berlin</textarea>"
514 "<input type='submit' value='Submit'>");
515 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
516 EXPECT_FALSE(Selection().SelectionHasFocus());
517 EXPECT_TRUE(Selection().IsHidden());
518
519 Element* const textarea = GetDocument().QuerySelector("textarea");
520 textarea->focus();
521 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
522
523 // We use a double click to create the selection [Berlin].
524 // FrameSelection::SelectAll (= textarea.select() in JavaScript) would have
525 // been shorter, but currently that doesn't work on a *disabled* text control.
526 const IntRect elem_bounds = textarea->BoundsInViewport();
Xiaocheng 2017/05/08 22:08:29 I still prefer setting selection directly here. A
hugoh_UTC2 2017/05/09 09:22:45 I agree, but I think it is good to keep all tests
hugoh_UTC2 2017/05/09 09:42:30 (I think it is good to use mouse clicks here since
527 WebMouseEvent double_click(WebMouseEvent::kMouseDown, 0,
528 WebInputEvent::kTimeStampForTesting);
529 double_click.SetPositionInWidget(elem_bounds.X(), elem_bounds.Y());
530 double_click.SetPositionInScreen(elem_bounds.X(), elem_bounds.Y());
531 double_click.button = WebMouseEvent::Button::kLeft;
532 double_click.click_count = 2;
533 double_click.SetFrameScale(1);
534
535 GetFrame().GetEventHandler().HandleMousePressEvent(double_click);
536 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
537 EXPECT_TRUE(Selection().SelectionHasFocus());
538 EXPECT_FALSE(Selection().IsHidden());
539
540 Element* const submit = GetDocument().QuerySelector("input");
541 submit->focus();
542 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
543 EXPECT_FALSE(Selection().SelectionHasFocus());
544 EXPECT_TRUE(Selection().IsHidden());
545 }
546
547 // crbug.com/713051
548 TEST_F(FrameSelectionTest, FocusingNonEditableParentHidesCaretInTextControl) {
549 SetBodyContent(
550 "<div tabindex='-1' id='parent'>"
551 " <input id='field'>"
552 "</div>");
553 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
554 EXPECT_FALSE(Selection().SelectionHasFocus());
555 EXPECT_TRUE(Selection().IsHidden());
556
557 Element* const field = GetDocument().getElementById("field");
558 field->focus();
559 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
560 EXPECT_TRUE(Selection().SelectionHasFocus());
561 EXPECT_FALSE(Selection().IsHidden());
562
563 // Here the selection belongs to <input>'s shadow tree and that tree has a
564 // non-editable parent that is focused.
565 Element* const parent = GetDocument().getElementById("parent");
566 parent->focus();
567 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
568 EXPECT_FALSE(Selection().SelectionHasFocus());
569 EXPECT_TRUE(Selection().IsHidden()); // Focus is outside <input>
570 // so caret should not be visible.
571
572 parent->blur(); // Move focus to document body.
573 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
574 EXPECT_FALSE(Selection().SelectionHasFocus());
575 EXPECT_TRUE(Selection().IsHidden()); // Caret is still hidden.
576 }
577
578 // crbug.com/713051
579 TEST_F(FrameSelectionTest, FocusingNonEditableParentHidesRangeInTextControl) {
580 SetBodyContent(
581 "<div tabindex='-1' id='parent'>"
582 " <input id='field' value='hola'>"
583 "</div>");
584 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
585 EXPECT_FALSE(Selection().SelectionHasFocus());
586 EXPECT_TRUE(Selection().IsHidden());
587
588 Element* const field = GetDocument().getElementById("field");
589 field->focus();
590 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
591 EXPECT_TRUE(Selection().SelectionHasFocus());
592 EXPECT_FALSE(Selection().IsHidden());
593
594 Selection().SelectAll();
595 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
596 EXPECT_TRUE(Selection().SelectionHasFocus());
597 EXPECT_FALSE(Selection().IsHidden());
598
599 // Here the selection belongs to <input>'s shadow tree and that tree has a
600 // non-editable parent that is focused.
601 Element* const parent = GetDocument().getElementById("parent");
602 parent->focus();
603 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
604 EXPECT_FALSE(Selection().SelectionHasFocus());
605 EXPECT_TRUE(Selection().IsHidden()); // Focus is outside <input>
606 // so range should not be visible.
607
608 parent->blur(); // Move focus to document body.
609 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
610 EXPECT_FALSE(Selection().SelectionHasFocus());
611 EXPECT_TRUE(Selection().IsHidden()); // Range is still hidden.
612 }
613
614 TEST_F(FrameSelectionTest, CaretInFocusedEditableDiv) {
615 SetBodyContent("<div contenteditable id='ce'>blabla</div>");
616 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
617 EXPECT_FALSE(Selection().SelectionHasFocus());
618 EXPECT_TRUE(Selection().IsHidden());
619
620 Element* const ce = GetDocument().getElementById("ce");
621 ce->focus();
622 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
623 EXPECT_TRUE(Selection().SelectionHasFocus());
624 EXPECT_FALSE(Selection().IsHidden());
625
626 ce->blur(); // Move focus to document body.
627 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
628 EXPECT_FALSE(Selection().SelectionHasFocus());
629 EXPECT_TRUE(Selection().IsHidden()); // Caret is now hidden.
630 }
631
632 TEST_F(FrameSelectionTest, RangeInFocusedEditableDiv) {
633 SetBodyContent("<div contenteditable id='ce'>blabla</div>");
634 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
635 EXPECT_FALSE(Selection().SelectionHasFocus());
636 EXPECT_TRUE(Selection().IsHidden());
637
638 Element* const ce = GetDocument().getElementById("ce");
639 ce->focus();
640 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
641 EXPECT_TRUE(Selection().SelectionHasFocus());
642 EXPECT_FALSE(Selection().IsHidden());
643
644 Selection().SelectAll();
645 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
646 EXPECT_TRUE(Selection().SelectionHasFocus());
647 EXPECT_FALSE(Selection().IsHidden());
648
649 ce->blur(); // Move focus to document body.
650 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
651 EXPECT_FALSE(Selection().SelectionHasFocus());
652 EXPECT_FALSE(Selection().IsHidden()); // Range is still visible.
653 }
654
655 TEST_F(FrameSelectionTest, FocusingLinkHidesCaretInContentEditable) {
656 SetBodyContent(
657 "<div contenteditable id='ce'>blabla</div>"
658 "<a href='www' id='alink'>link</a>");
659 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
660 EXPECT_FALSE(Selection().SelectionHasFocus());
661 EXPECT_TRUE(Selection().IsHidden());
662
663 Element* const ce = GetDocument().getElementById("ce");
664 ce->focus();
665 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
666 EXPECT_TRUE(Selection().SelectionHasFocus());
667 EXPECT_FALSE(Selection().IsHidden());
668
669 Element* const alink = GetDocument().getElementById("alink");
670 alink->focus();
671 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
672 EXPECT_FALSE(Selection().SelectionHasFocus());
673 EXPECT_TRUE(Selection().IsHidden());
674 }
675
676 TEST_F(FrameSelectionTest, FocusingLinkKeepsRangeInContentEditable) {
677 SetBodyContent(
678 "<div contenteditable id='ce'>blabla</div>"
679 "<a href='www' id='alink'>link</a>");
680 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
681 EXPECT_FALSE(Selection().SelectionHasFocus());
682 EXPECT_TRUE(Selection().IsHidden());
683
684 Element* const ce = GetDocument().getElementById("ce");
685 ce->focus();
686 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
687 EXPECT_TRUE(Selection().SelectionHasFocus());
688 EXPECT_FALSE(Selection().IsHidden());
689
690 Selection().SelectAll();
691 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
692 EXPECT_TRUE(Selection().SelectionHasFocus());
693 EXPECT_FALSE(Selection().IsHidden());
694
695 Element* const alink = GetDocument().getElementById("alink");
696 alink->focus();
697 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
698 EXPECT_FALSE(Selection().SelectionHasFocus());
699 EXPECT_FALSE(Selection().IsHidden());
700 }
701
702 TEST_F(FrameSelectionTest, FocusingEditableParentKeepsEditableCaret) {
703 SetBodyContent(
704 "<div contenteditable tabindex='-1' id='parent'>"
705 "<div contenteditable id='ce'>blabla</div>"
706 "</div>");
707 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
708 EXPECT_FALSE(Selection().SelectionHasFocus());
709 EXPECT_TRUE(Selection().IsHidden());
710
711 // TODO(editing-dev): Blink should be able to focus the inner <div>.
712 // Element* const ce = GetDocument().getElementById("ce");
713 // ce->focus();
714 // EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
715 // EXPECT_FALSE(Selection().IsHidden());
716
717 Element* const parent = GetDocument().getElementById("parent");
718 parent->focus();
719 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
720 EXPECT_TRUE(Selection().SelectionHasFocus());
721 EXPECT_FALSE(Selection().IsHidden()); // Focus is within editing boundary,
722 // caret should be visible.
723
724 parent->blur(); // Move focus to document body.
725 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
726 EXPECT_FALSE(Selection().SelectionHasFocus());
727 EXPECT_TRUE(Selection().IsHidden()); // Focus is outside editing boundary
728 // so caret should be hidden.
729 }
730
731 TEST_F(FrameSelectionTest, FocusingEditableParentKeepsEditableRange) {
732 SetBodyContent(
733 "<div contenteditable tabindex='-1' id='parent'>"
734 "<div contenteditable id='ce'>blabla</div>"
735 "</div>");
736 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
737 EXPECT_FALSE(Selection().SelectionHasFocus());
738 EXPECT_TRUE(Selection().IsHidden());
739
740 // TODO(editing-dev): Blink should be able to focus the inner <div>.
741 // Element* const ce = GetDocument().getElementById("ce");
742 // ce->focus();
743 // EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
744 // EXPECT_FALSE(Selection().IsHidden());
745
746 // Selection().SelectAll();
747 // EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
748 // EXPECT_FALSE(Selection().IsHidden());
749
750 Element* const parent = GetDocument().getElementById("parent");
751 parent->focus();
752 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
753 EXPECT_TRUE(Selection().SelectionHasFocus());
754 EXPECT_FALSE(Selection().IsHidden()); // Focus is within editing boundary,
755 // range should be visible.
756
757 Selection().SelectAll();
758 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
759 EXPECT_TRUE(Selection().SelectionHasFocus());
760 EXPECT_FALSE(Selection().IsHidden());
761
762 parent->blur(); // Move focus to document body.
763 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
764 EXPECT_FALSE(Selection().SelectionHasFocus());
765 EXPECT_FALSE(Selection().IsHidden()); // Focus is outside editing boundary
766 // but range should still be visible.
767 }
768
769 TEST_F(FrameSelectionTest, FocusingNonEditableParentHidesEditableCaret) {
770 SetBodyContent(
771 "<div tabindex='-1' id='parent'>"
772 "<div contenteditable id='ce'>blabla</div>"
773 "</div>");
774 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
775 EXPECT_FALSE(Selection().SelectionHasFocus());
776 EXPECT_TRUE(Selection().IsHidden());
777
778 Element* const ce = GetDocument().getElementById("ce");
779 ce->focus();
780 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
781 EXPECT_TRUE(Selection().SelectionHasFocus());
782 EXPECT_FALSE(Selection().IsHidden());
783
784 // Here the selection belongs to <div>'s shadow tree and that tree has a
785 // non-editable parent that is focused.
786 Element* const parent = GetDocument().getElementById("parent");
787 parent->focus();
788 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
789 EXPECT_FALSE(Selection().SelectionHasFocus());
790 EXPECT_TRUE(Selection().IsHidden()); // Focus is outside editing boundary
791 // so caret should be hidden.
792
793 parent->blur(); // Move focus to document body.
794 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
795 EXPECT_FALSE(Selection().SelectionHasFocus());
796 EXPECT_TRUE(Selection().IsHidden()); // Caret is still hidden.
797 }
798
799 TEST_F(FrameSelectionTest, FocusingNonEditableParentKeepsEditableRange) {
800 SetBodyContent(
801 "<div tabindex='-1' id='parent'>"
802 "<div contenteditable id='ce'>blabla</div>"
803 "</div>");
804 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
805 EXPECT_FALSE(Selection().SelectionHasFocus());
806 EXPECT_TRUE(Selection().IsHidden());
807
808 Element* const ce = GetDocument().getElementById("ce");
809 ce->focus();
810 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsCaret());
811 EXPECT_TRUE(Selection().SelectionHasFocus());
812 EXPECT_FALSE(Selection().IsHidden());
813
814 Selection().SelectAll();
815 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
816 EXPECT_TRUE(Selection().SelectionHasFocus());
817 EXPECT_FALSE(Selection().IsHidden());
818
819 // Here the selection belongs to <div>'s shadow tree and that tree has a
820 // non-editable parent that is focused.
821 Element* const parent = GetDocument().getElementById("parent");
822 parent->focus();
823 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
824 EXPECT_FALSE(Selection().SelectionHasFocus());
825 EXPECT_FALSE(Selection().IsHidden()); // Focus is outside editing boundary
826 // but range should still be visible.
827
828 parent->blur(); // Move focus to document body.
829 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
830 EXPECT_FALSE(Selection().SelectionHasFocus());
831 EXPECT_FALSE(Selection().IsHidden()); // Range is still visible.
832 }
833
834 // crbug.com/707143
835 TEST_F(FrameSelectionTest, RangeContainsFocus) {
836 SetBodyContent(
837 "<div>"
838 " <div>"
839 " <span id='start'>start</span>"
840 " </div>"
841 " <a href='www' id='alink'>link</a>"
842 " <div>line 1</div>"
843 " <div>line 2</div>"
844 " <div>line 3</div>"
845 " <div>line 4</div>"
846 " <span id='end'>end</span>"
847 " <div></div>"
848 "</div>");
849 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
850 EXPECT_FALSE(Selection().SelectionHasFocus());
851 EXPECT_TRUE(Selection().IsHidden());
852
853 Element* const start = GetDocument().getElementById("start");
854 Element* const end = GetDocument().getElementById("end");
855 Selection().SetSelection(
856 SelectionInDOMTree::Builder()
857 .SetBaseAndExtent(Position(start, 0), Position(end, 3))
858 .Build());
859 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
860 EXPECT_TRUE(Selection().SelectionHasFocus());
861 EXPECT_FALSE(Selection().IsHidden());
862
863 Element* const alink = GetDocument().getElementById("alink");
864 alink->focus();
865 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
866 EXPECT_FALSE(Selection().SelectionHasFocus());
867 EXPECT_FALSE(Selection().IsHidden()); // Range still visible.
868 }
869
870 // crbug.com/707143
871 TEST_F(FrameSelectionTest, RangeOutsideFocus) {
872 // Here the selection sits on a sub tree that hasn't the focused element.
873 // This test case is the reason why we separate FrameSelection::HasFocus() and
874 // FrameSelection::IsHidden(). Even when the selection's DOM nodes are
875 // completely disconnected from the focused node, we still want the selection
876 // to be visible (not hidden).
877 SetBodyContent(
878 "<a href='www' id='alink'>link</a>"
879 "<div>"
880 " <div>"
881 " <span id='start'>start</span>"
882 " </div>"
883 " <div>line 1</div>"
884 " <div>line 2</div>"
885 " <div>line 3</div>"
886 " <div>line 4</div>"
887 " <span id='end'>end</span>"
888 " <div></div>"
889 "</div>");
890 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsNone());
891 EXPECT_FALSE(Selection().SelectionHasFocus());
892 EXPECT_TRUE(Selection().IsHidden());
893
894 Element* const start = GetDocument().getElementById("start");
895 Element* const end = GetDocument().getElementById("end");
896 Selection().SetSelection(
897 SelectionInDOMTree::Builder()
898 .SetBaseAndExtent(Position(start, 0), Position(end, 3))
899 .Build());
900 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
901 EXPECT_TRUE(Selection().SelectionHasFocus());
902 EXPECT_FALSE(Selection().IsHidden());
903
904 Element* const alink = GetDocument().getElementById("alink");
905 alink->focus();
906 EXPECT_TRUE(Selection().GetSelectionInDOMTree().IsRange());
907 EXPECT_FALSE(Selection().SelectionHasFocus());
908 EXPECT_FALSE(Selection().IsHidden()); // Range still visible.
909 }
910
352 } // namespace blink 911 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698