Element.spec.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. import {
  2. addClass,
  3. closestDown,
  4. getParent,
  5. hasClass,
  6. isInput,
  7. removeClass,
  8. } from 'handsontable/helpers/dom/element';
  9. describe('DomElement helper', () => {
  10. //
  11. // Handsontable.helper.isInput
  12. //
  13. describe('isInput', () => {
  14. it('should return true for inputs, selects, and textareas', () => {
  15. expect(isInput(document.createElement('input'))).toBe(true);
  16. expect(isInput(document.createElement('select'))).toBe(true);
  17. expect(isInput(document.createElement('textarea'))).toBe(true);
  18. });
  19. it('should return true for contentEditable elements', () => {
  20. const div = document.createElement('div');
  21. div.contentEditable = 'true';
  22. expect(isInput(div)).toBe(true);
  23. });
  24. });
  25. //
  26. // Handsontable.helper.closestDown
  27. //
  28. describe('closestDown', () => {
  29. const test1 = '<div class="wrapper1"><table><tbody><tr><td class="test1">test1</td></tr></tbody></table></div>';
  30. const test2 = `<div class="wrapper2"><table><tbody><tr><td class="test2">test2${test1}</td></tr></tbody></table></div>`;
  31. it('should return last TD element (starting from last child element)', () => {
  32. const wrapper = document.createElement('div');
  33. wrapper.innerHTML = test2;
  34. const td1 = wrapper.querySelector('.test1');
  35. const td2 = wrapper.querySelector('.test2');
  36. expect(closestDown(td1, ['TD'])).toBe(td2);
  37. });
  38. it('should return proper value depends on passed `until` element', () => {
  39. const td = document.createElement('td');
  40. td.innerHTML = test2;
  41. const wrapper2 = td.querySelector('.wrapper2');
  42. expect(closestDown(wrapper2, ['TD'])).toBe(td);
  43. expect(closestDown(wrapper2, ['TD'], wrapper2.firstChild)).toBe(null);
  44. });
  45. });
  46. //
  47. // Handsontable.helper.getParent
  48. //
  49. describe('getParent', () => {
  50. let element = null;
  51. beforeEach(() => {
  52. element = document.createElement('div');
  53. element.innerHTML = '<div id="a1"><ul id="a2"></ul><ul id="b2"><li id="a3"><span id="a4">HELLO</span></li></ul></div>';
  54. });
  55. afterEach(() => {
  56. element = null;
  57. });
  58. it('should return the node parent only from the one level deep', () => {
  59. expect(getParent(element.querySelector('#a4'))).toBe(element.querySelector('#a3'));
  60. expect(getParent(element.querySelector('#a1'))).toBe(element);
  61. });
  62. it('should return the node parent from the defined level deep', () => {
  63. expect(getParent(element.querySelector('#a4'), 0)).toBe(element.querySelector('#a3'));
  64. expect(getParent(element.querySelector('#a4'), 1)).toBe(element.querySelector('#b2'));
  65. expect(getParent(element.querySelector('#a4'), 2)).toBe(element.querySelector('#a1'));
  66. expect(getParent(element.querySelector('#a4'), 3)).toBe(element);
  67. expect(getParent(element.querySelector('#a4'), 4)).toBe(null);
  68. expect(getParent(element.querySelector('#a4'), 5)).toBe(null);
  69. expect(getParent(element.querySelector('#a2'), 0)).toBe(element.querySelector('#a1'));
  70. expect(getParent(element.querySelector('#a2'), 1)).toBe(element);
  71. });
  72. });
  73. /**
  74. * Handsontable.helper.hasClass
  75. */
  76. describe('hasClass', () => {
  77. let element = null;
  78. beforeEach(() => {
  79. element = document.createElement('div');
  80. element.className = 'test1';
  81. });
  82. afterEach(() => {
  83. element = null;
  84. });
  85. it('should not throw an error when checked the element has not classList property', () => {
  86. expect(() => { hasClass(document, 'test2'); }).not.toThrow();
  87. });
  88. it('should return true if element has className', () => {
  89. expect(hasClass(element, 'test1')).toBeTruthy();
  90. });
  91. it('should return false if element has not className', () => {
  92. expect(hasClass(element, 'test2')).toBeFalsy();
  93. });
  94. it('should not touch the DOM element when the passed argument is empty', () => {
  95. const elementMock = {
  96. classList: {
  97. contains: jasmine.createSpy('classList'),
  98. }
  99. };
  100. hasClass(elementMock);
  101. expect(elementMock.classList.contains).not.toHaveBeenCalled();
  102. elementMock.classList.contains.calls.reset();
  103. hasClass(elementMock, '');
  104. expect(elementMock.classList.contains).not.toHaveBeenCalled();
  105. elementMock.classList.contains.calls.reset();
  106. hasClass(elementMock, []);
  107. expect(elementMock.classList.contains).not.toHaveBeenCalled();
  108. elementMock.classList.contains.calls.reset();
  109. hasClass(elementMock, ['']);
  110. expect(elementMock.classList.contains).not.toHaveBeenCalled();
  111. });
  112. });
  113. /**
  114. * Handsontable.helper.addClass
  115. */
  116. describe('addClass', () => {
  117. let element = null;
  118. beforeEach(() => {
  119. element = document.createElement('div');
  120. element.className = 'test1';
  121. });
  122. afterEach(() => {
  123. element = null;
  124. });
  125. it('should add CSS class without removing old one', () => {
  126. addClass(element, 'test2');
  127. expect(element.className).toBe('test1 test2');
  128. });
  129. it('should add multiple CSS classes without removing old one (delimited by an empty space)', () => {
  130. addClass(element, 'test2 test4 test3');
  131. expect(element.className).toBe('test1 test2 test4 test3');
  132. });
  133. it('should add multiple CSS classes without removing old one (passed as an array)', () => {
  134. addClass(element, ['test2', 'test4', 'test3']);
  135. expect(element.className).toBe('test1 test2 test4 test3');
  136. });
  137. it('should not touch the DOM element when the passed argument is empty', () => {
  138. const elementMock = {
  139. classList: {
  140. add: jasmine.createSpy('classList'),
  141. }
  142. };
  143. addClass(elementMock);
  144. expect(elementMock.classList.add).not.toHaveBeenCalled();
  145. elementMock.classList.add.calls.reset();
  146. addClass(elementMock, '');
  147. expect(elementMock.classList.add).not.toHaveBeenCalled();
  148. elementMock.classList.add.calls.reset();
  149. addClass(elementMock, []);
  150. expect(elementMock.classList.add).not.toHaveBeenCalled();
  151. elementMock.classList.add.calls.reset();
  152. addClass(elementMock, ['']);
  153. expect(elementMock.classList.add).not.toHaveBeenCalled();
  154. });
  155. });
  156. /**
  157. * Handsontable.helper.removeClass
  158. */
  159. describe('removeClass', () => {
  160. let element = null;
  161. beforeEach(() => {
  162. element = document.createElement('div');
  163. element.className = 'test1 test3';
  164. });
  165. afterEach(() => {
  166. element = null;
  167. });
  168. it('should remove CSS class without removing rest CSS classes', () => {
  169. removeClass(element, 'test1');
  170. expect(element.className).toBe('test3');
  171. });
  172. it('should remove multiple CSS classes (delimited by an empty space)', () => {
  173. removeClass(element, 'test2 test3 test1');
  174. expect(element.className).toBe('');
  175. });
  176. it('should remove CSS multiple classes (passed as an array)', () => {
  177. removeClass(element, ['test2', 'test3', 'test1']);
  178. expect(element.className).toBe('');
  179. });
  180. it('should not touch the DOM element when the passed argument is empty', () => {
  181. const elementMock = {
  182. classList: {
  183. remove: jasmine.createSpy('classList'),
  184. }
  185. };
  186. removeClass(elementMock);
  187. expect(elementMock.classList.remove).not.toHaveBeenCalled();
  188. elementMock.classList.remove.calls.reset();
  189. removeClass(elementMock, '');
  190. expect(elementMock.classList.remove).not.toHaveBeenCalled();
  191. elementMock.classList.remove.calls.reset();
  192. removeClass(elementMock, []);
  193. expect(elementMock.classList.remove).not.toHaveBeenCalled();
  194. elementMock.classList.remove.calls.reset();
  195. removeClass(elementMock, ['']);
  196. expect(elementMock.classList.remove).not.toHaveBeenCalled();
  197. });
  198. });
  199. });