focuscycler.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /**
  2. * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. import ViewCollection from 'ckeditor5-ui/src/viewcollection';
  6. import View from 'ckeditor5-ui/src/view';
  7. import FocusCycler from 'ckeditor5-utils/src/focuscycler';
  8. describe( 'FocusCycler', () => {
  9. let viewCollection, focusTracker, cycler;
  10. beforeEach( () => {
  11. viewCollection = new ViewCollection();
  12. focusTracker = {
  13. focusedElement: null
  14. };
  15. cycler = new FocusCycler( viewCollection, focusTracker );
  16. viewCollection.add( nonFocusable() );
  17. viewCollection.add( focusable() );
  18. viewCollection.add( focusable() );
  19. viewCollection.add( focusable() );
  20. viewCollection.add( nonFocusable() );
  21. } );
  22. describe( 'constructor()', () => {
  23. it( 'sets class properties', () => {
  24. expect( cycler.viewCollection ).to.equal( viewCollection );
  25. expect( cycler.focusTracker ).to.equal( focusTracker );
  26. } );
  27. } );
  28. describe( 'current()', () => {
  29. it( 'returns null when no view is focused', () => {
  30. expect( cycler.current ).to.equal( null );
  31. focusTracker.focusedElement = viewCollection.get( 2 ).element;
  32. expect( cycler.current ).to.equal( 2 );
  33. focusTracker.focusedElement = null;
  34. expect( cycler.current ).to.equal( null );
  35. } );
  36. } );
  37. describe( 'first()', () => {
  38. it( 'returns first focusable view', () => {
  39. expect( cycler.first ).to.equal( viewCollection.get( 1 ) );
  40. } );
  41. it( 'returns null when no focusable items', () => {
  42. viewCollection = new ViewCollection();
  43. cycler = new FocusCycler( viewCollection, focusTracker );
  44. viewCollection.add( nonFocusable() );
  45. viewCollection.add( nonFocusable() );
  46. expect( cycler.first ).to.be.null;
  47. } );
  48. it( 'returns null when no items', () => {
  49. viewCollection = new ViewCollection();
  50. cycler = new FocusCycler( viewCollection, focusTracker );
  51. expect( cycler.first ).to.be.null;
  52. } );
  53. } );
  54. describe( 'next()', () => {
  55. it( 'cycles to return the next focusable view', () => {
  56. focusTracker.focusedElement = viewCollection.get( 2 ).element;
  57. expect( cycler.next ).to.equal( viewCollection.get( 3 ) );
  58. focusTracker.focusedElement = viewCollection.get( 3 ).element;
  59. expect( cycler.next ).to.equal( viewCollection.get( 1 ) );
  60. focusTracker.focusedElement = viewCollection.get( 1 ).element;
  61. expect( cycler.next ).to.equal( viewCollection.get( 2 ) );
  62. } );
  63. it( 'returns null when no view is focused', () => {
  64. focusTracker.focusedElement = null;
  65. expect( cycler.next ).to.be.null;
  66. } );
  67. it( 'returns null when no items', () => {
  68. viewCollection = new ViewCollection();
  69. cycler = new FocusCycler( viewCollection, focusTracker );
  70. expect( cycler.next ).to.be.null;
  71. } );
  72. it( 'returns null when no focusable items', () => {
  73. viewCollection = new ViewCollection();
  74. cycler = new FocusCycler( viewCollection, focusTracker );
  75. viewCollection.add( nonFocusable() );
  76. viewCollection.add( nonFocusable() );
  77. expect( cycler.next ).to.be.null;
  78. } );
  79. it( 'returns null if the only focusable in viewCollection', () => {
  80. viewCollection = new ViewCollection();
  81. cycler = new FocusCycler( viewCollection, focusTracker );
  82. viewCollection.add( nonFocusable() );
  83. viewCollection.add( focusable() );
  84. viewCollection.add( nonFocusable() );
  85. focusTracker.focusedElement = viewCollection.get( 1 ).element;
  86. expect( cycler.first ).to.equal( viewCollection.get( 1 ) );
  87. expect( cycler.next ).to.be.null;
  88. } );
  89. } );
  90. describe( 'previous()', () => {
  91. it( 'cycles to return the previous focusable view', () => {
  92. focusTracker.focusedElement = viewCollection.get( 1 ).element;
  93. expect( cycler.previous ).to.equal( viewCollection.get( 3 ) );
  94. focusTracker.focusedElement = viewCollection.get( 2 ).element;
  95. expect( cycler.previous ).to.equal( viewCollection.get( 1 ) );
  96. focusTracker.focusedElement = viewCollection.get( 3 ).element;
  97. expect( cycler.previous ).to.equal( viewCollection.get( 2 ) );
  98. } );
  99. it( 'returns null when no view is focused', () => {
  100. focusTracker.focusedElement = null;
  101. expect( cycler.previous ).to.be.null;
  102. } );
  103. it( 'returns null when no items', () => {
  104. viewCollection = new ViewCollection();
  105. cycler = new FocusCycler( viewCollection, focusTracker );
  106. expect( cycler.previous ).to.be.null;
  107. } );
  108. it( 'returns null when no focusable items', () => {
  109. viewCollection = new ViewCollection();
  110. cycler = new FocusCycler( viewCollection, focusTracker );
  111. viewCollection.add( nonFocusable() );
  112. viewCollection.add( nonFocusable() );
  113. expect( cycler.previous ).to.be.null;
  114. } );
  115. it( 'returns null if the only focusable in viewCollection', () => {
  116. viewCollection = new ViewCollection();
  117. cycler = new FocusCycler( viewCollection, focusTracker );
  118. viewCollection.add( nonFocusable() );
  119. viewCollection.add( focusable() );
  120. viewCollection.add( nonFocusable() );
  121. focusTracker.focusedElement = viewCollection.get( 1 ).element;
  122. expect( cycler.first ).to.equal( viewCollection.get( 1 ) );
  123. expect( cycler.previous ).to.be.null;
  124. } );
  125. } );
  126. } );
  127. function focusable() {
  128. const view = new View();
  129. view.focus = () => {};
  130. view.element = {};
  131. return view;
  132. }
  133. function nonFocusable() {
  134. return new View();
  135. }