fragmentSelection.spec.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. describe('settings', () => {
  2. describe('fragmentSelection', () => {
  3. var id = 'testContainer';
  4. beforeEach(function() {
  5. this.$container = $(`<div id="${id}"></div>`).appendTo('body');
  6. });
  7. afterEach(function() {
  8. if (this.$container) {
  9. destroy();
  10. this.$container.remove();
  11. }
  12. });
  13. /**
  14. * Returns current text selection or false if there is no text selection
  15. * @returns {*}
  16. */
  17. function getSelected() {
  18. /* eslint-disable no-else-return */
  19. var text = '';
  20. // IE8
  21. if (window.getSelection && window.getSelection().toString() && $(window.getSelection()).attr('type') != 'Caret') {
  22. text = window.getSelection();
  23. return text.toString();
  24. } else { // standards
  25. var selection = document.selection && document.selection.createRange();
  26. if (!(typeof selection === 'undefined') && selection.text && selection.text.toString()) {
  27. text = selection.text;
  28. return text.toString();
  29. }
  30. }
  31. return false;
  32. }
  33. /**
  34. * Selects a <fromEl> node at as many siblings as given in the <cells> value
  35. * Note: IE8 fallback assumes that a node contains exactly one word
  36. * @param fromEl
  37. * @param siblings
  38. */
  39. function selectElementText(fromEl, siblings) {
  40. var doc = window.document;
  41. var sel;
  42. var range;
  43. if (window.getSelection && doc.createRange) { // standards
  44. sel = window.getSelection();
  45. range = doc.createRange();
  46. range.setStartBefore(fromEl, 0);
  47. while (siblings > 1) {
  48. fromEl = fromEl.nextSibling;
  49. siblings--;
  50. }
  51. range.setEndAfter(fromEl, 0);
  52. sel.removeAllRanges();
  53. sel.addRange(range);
  54. } else if (doc.body.createTextRange) { // IE8
  55. range = doc.body.createTextRange();
  56. range.moveToElementText(fromEl);
  57. range.moveEnd('word', siblings + 1);
  58. range.select();
  59. }
  60. }
  61. describe('constructor', () => {
  62. it('should disallow fragmentSelection when set to false', function() {
  63. handsontable({
  64. data: Handsontable.helper.createSpreadsheetData(4, 4),
  65. fragmentSelection: false
  66. });
  67. selectElementText(this.$container.find('tr:eq(0) td:eq(1)')[0], 3);
  68. mouseDown(this.$container.find('tr:eq(0) td:eq(3)'));
  69. mouseUp(this.$container.find('tr:eq(0) td:eq(3)'));
  70. var sel = getSelected();
  71. expect(sel).toEqual(false);
  72. });
  73. it('should allow fragmentSelection when set to true', function() {
  74. handsontable({
  75. data: Handsontable.helper.createSpreadsheetData(4, 4),
  76. fragmentSelection: true
  77. });
  78. selectElementText(this.$container.find('td')[1], 3);
  79. mouseDown(this.$container.find('tr:eq(0) td:eq(3)'));
  80. mouseUp(this.$container.find('tr:eq(0) td:eq(3)'));
  81. var sel = getSelected();
  82. sel = sel.replace(/\s/g, ''); // tabs and spaces between <td>s are inconsistent in browsers, so let's ignore them
  83. expect(sel).toEqual('B1C1D1');
  84. });
  85. it('should allow fragmentSelection from one cell when set to `cell`', function() {
  86. var hot = handsontable({
  87. data: Handsontable.helper.createSpreadsheetData(4, 4),
  88. fragmentSelection: 'cell'
  89. });
  90. selectElementText(this.$container.find('td')[1], 1);
  91. mouseDown(this.$container.find('tr:eq(0) td:eq(1)'));
  92. mouseOver(this.$container.find('tr:eq(0) td:eq(1)'));
  93. mouseMove(this.$container.find('tr:eq(0) td:eq(1)'));
  94. mouseUp(this.$container.find('tr:eq(0) td:eq(1)'));
  95. expect(getSelected().replace(/\s/g, '')).toEqual('B1');
  96. });
  97. it('should disallow fragmentSelection from one cell when set to `cell` and when user selects adjacent cell', function() {
  98. var hot = handsontable({
  99. data: Handsontable.helper.createSpreadsheetData(4, 4),
  100. fragmentSelection: 'cell'
  101. });
  102. selectElementText(this.$container.find('td')[1], 1);
  103. mouseDown(this.$container.find('tr:eq(0) td:eq(1)'));
  104. mouseOver(this.$container.find('tr:eq(0) td:eq(2)'));
  105. mouseMove(this.$container.find('tr:eq(0) td:eq(2)'));
  106. mouseUp(this.$container.find('tr:eq(0) td:eq(2)'));
  107. expect(getSelected()).toEqual(false);
  108. });
  109. it('should disallow fragmentSelection of Handsontable chrome (anything that is not table) when set to false', function() {
  110. handsontable({
  111. data: Handsontable.helper.createSpreadsheetData(4, 4),
  112. fragmentSelection: false
  113. });
  114. var $div = $('<div style="position: absolute; top: 0; left: 0">Text</div>');
  115. this.$container.append($div);
  116. selectElementText($div[0], 1);
  117. mouseDown($div);
  118. var sel = getSelected();
  119. expect(sel).toEqual(false);
  120. });
  121. it('should disallow fragmentSelection of Handsontable chrome (anything that is not table) when set to true', function() {
  122. handsontable({
  123. data: Handsontable.helper.createSpreadsheetData(4, 4),
  124. fragmentSelection: true
  125. });
  126. var $div = $('<div style="position: absolute; top: 0; left: 0">Text</div>');
  127. this.$container.append($div);
  128. selectElementText($div[0], 1);
  129. mouseDown($div);
  130. var sel = getSelected();
  131. expect(sel).toEqual(false);
  132. });
  133. });
  134. describe('dynamic', () => {
  135. it('should disallow fragmentSelection when set to false', function() {
  136. handsontable({
  137. data: Handsontable.helper.createSpreadsheetData(4, 4),
  138. fragmentSelection: true
  139. });
  140. updateSettings({fragmentSelection: false});
  141. selectElementText(this.$container.find('tr:eq(0) td:eq(1)')[0], 3);
  142. mouseDown(this.$container.find('tr:eq(0) td:eq(3)'));
  143. mouseUp(this.$container.find('tr:eq(0) td:eq(3)'));
  144. var sel = getSelected();
  145. expect(sel).toEqual(false);
  146. });
  147. it('should allow fragmentSelection when set to true', function() {
  148. handsontable({
  149. data: Handsontable.helper.createSpreadsheetData(4, 4),
  150. fragmentSelection: false
  151. });
  152. updateSettings({fragmentSelection: true});
  153. selectElementText(this.$container.find('td')[1], 3);
  154. mouseDown(this.$container.find('tr:eq(0) td:eq(3)'));
  155. mouseUp(this.$container.find('tr:eq(0) td:eq(3)'));
  156. var sel = getSelected();
  157. sel = sel.replace(/\s/g, ''); // tabs and spaces between <td>s are inconsistent in browsers, so let's ignore them
  158. expect(sel).toEqual('B1C1D1');
  159. });
  160. });
  161. });
  162. });