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

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

Powered by Google App Engine
This is Rietveld 408576698