fragmentSelection.spec.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. describe('settings', () => {
  2. describe('fragmentSelection', () => {
  3. const 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. let 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. const 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. const doc = window.document;
  41. let element = fromEl;
  42. let numOfSiblings = siblings;
  43. let sel;
  44. let range;
  45. if (window.getSelection && doc.createRange) { // standards
  46. sel = window.getSelection();
  47. range = doc.createRange();
  48. range.setStartBefore(element, 0);
  49. while (numOfSiblings > 1) {
  50. element = element.nextSibling;
  51. numOfSiblings -= 1;
  52. }
  53. range.setEndAfter(element, 0);
  54. sel.removeAllRanges();
  55. sel.addRange(range);
  56. } else if (doc.body.createTextRange) { // IE8
  57. range = doc.body.createTextRange();
  58. range.moveToElementText(element);
  59. range.moveEnd('word', numOfSiblings + 1);
  60. range.select();
  61. }
  62. }
  63. describe('constructor', () => {
  64. it('should disallow fragmentSelection when set to false', () => {
  65. handsontable({
  66. data: Handsontable.helper.createSpreadsheetData(4, 4),
  67. fragmentSelection: false
  68. });
  69. selectElementText(spec().$container.find('tr:eq(0) td:eq(1)')[0], 3);
  70. mouseDown(spec().$container.find('tr:eq(0) td:eq(3)'));
  71. mouseUp(spec().$container.find('tr:eq(0) td:eq(3)'));
  72. const sel = getSelected();
  73. expect(sel).toEqual(' '); // copyPaste has selected space in textarea
  74. });
  75. xit('should allow fragmentSelection when set to true', () => {
  76. // We have to try another way to simulate text selection.
  77. handsontable({
  78. data: Handsontable.helper.createSpreadsheetData(4, 4),
  79. fragmentSelection: true
  80. });
  81. selectElementText(spec().$container.find('td')[1], 3);
  82. mouseDown(spec().$container.find('tr:eq(0) td:eq(3)'));
  83. mouseUp(spec().$container.find('tr:eq(0) td:eq(3)'));
  84. let sel = getSelected();
  85. sel = sel.replace(/\s/g, ''); // tabs and spaces between <td>s are inconsistent in browsers, so let's ignore them
  86. expect(sel).toEqual('B1C1D1');
  87. });
  88. xit('should allow fragmentSelection from one cell when set to `cell`', () => {
  89. // We have to try another way to simulate text selection.
  90. handsontable({
  91. data: Handsontable.helper.createSpreadsheetData(4, 4),
  92. fragmentSelection: 'cell'
  93. });
  94. selectElementText(spec().$container.find('td')[1], 1);
  95. mouseDown(spec().$container.find('tr:eq(0) td:eq(1)'));
  96. mouseUp(spec().$container.find('tr:eq(0) td:eq(1)'));
  97. expect(getSelected().replace(/\s/g, '')).toEqual('B1');
  98. });
  99. it('should disallow fragmentSelection from one cell when set to `cell` and when user selects adjacent cell', () => {
  100. handsontable({
  101. data: Handsontable.helper.createSpreadsheetData(4, 4),
  102. fragmentSelection: 'cell'
  103. });
  104. selectElementText(spec().$container.find('td')[1], 1);
  105. mouseDown(spec().$container.find('tr:eq(0) td:eq(1)'));
  106. mouseOver(spec().$container.find('tr:eq(0) td:eq(2)'));
  107. mouseMove(spec().$container.find('tr:eq(0) td:eq(2)'));
  108. mouseUp(spec().$container.find('tr:eq(0) td:eq(2)'));
  109. expect(getSelected()).toEqual(' '); // copyPaste has selected space in textarea
  110. });
  111. it('should disallow fragmentSelection of Handsontable chrome (anything that is not table) when set to false', () => {
  112. handsontable({
  113. data: Handsontable.helper.createSpreadsheetData(4, 4),
  114. fragmentSelection: false
  115. });
  116. const $div = $('<div style="position: absolute; top: 0; left: 0">Text</div>');
  117. spec().$container.append($div);
  118. selectElementText($div[0], 1);
  119. mouseDown($div);
  120. const sel = getSelected();
  121. expect(sel).toEqual(false);
  122. });
  123. it('should disallow fragmentSelection of Handsontable chrome (anything that is not table) when set to true', () => {
  124. handsontable({
  125. data: Handsontable.helper.createSpreadsheetData(4, 4),
  126. fragmentSelection: true
  127. });
  128. const $div = $('<div style="position: absolute; top: 0; left: 0">Text</div>');
  129. spec().$container.append($div);
  130. selectElementText($div[0], 1);
  131. mouseDown($div);
  132. const sel = getSelected();
  133. expect(sel).toEqual(false);
  134. });
  135. });
  136. describe('dynamic', () => {
  137. it('should disallow fragmentSelection when set to false', () => {
  138. handsontable({
  139. data: Handsontable.helper.createSpreadsheetData(4, 4),
  140. fragmentSelection: true
  141. });
  142. updateSettings({ fragmentSelection: false });
  143. selectElementText(spec().$container.find('tr:eq(0) td:eq(1)')[0], 3);
  144. mouseDown(spec().$container.find('tr:eq(0) td:eq(3)'));
  145. mouseUp(spec().$container.find('tr:eq(0) td:eq(3)'));
  146. const sel = getSelected();
  147. expect(sel).toEqual(' '); // copyPaste has selected space in textarea
  148. });
  149. xit('should allow fragmentSelection when set to true', () => {
  150. // We have to try another way to simulate text selection.
  151. handsontable({
  152. data: Handsontable.helper.createSpreadsheetData(4, 4),
  153. fragmentSelection: false
  154. });
  155. updateSettings({ fragmentSelection: true });
  156. selectElementText(spec().$container.find('td')[1], 3);
  157. mouseDown(spec().$container.find('tr:eq(0) td:eq(3)'));
  158. mouseUp(spec().$container.find('tr:eq(0) td:eq(3)'));
  159. let sel = getSelected();
  160. sel = sel.replace(/\s/g, ''); // tabs and spaces between <td>s are inconsistent in browsers, so let's ignore them
  161. expect(sel).toEqual('B1C1D1');
  162. });
  163. });
  164. });
  165. });