template.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /**
  2. * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /* bender-tags: ui */
  6. /* global HTMLElement */
  7. 'use strict';
  8. import testUtils from '/tests/_utils/utils.js';
  9. import Template from '/ckeditor5/core/ui/template.js';
  10. testUtils.createSinonSandbox();
  11. describe( 'Template', () => {
  12. describe( 'constructor', () => {
  13. it( 'accepts the definition', () => {
  14. let def = {
  15. tag: 'p'
  16. };
  17. expect( new Template( def ).def ).to.equal( def );
  18. } );
  19. } );
  20. describe( 'render', () => {
  21. it( 'returns null when no definition', () => {
  22. expect( new Template().render() ).to.be.null;
  23. } );
  24. it( 'creates an element', () => {
  25. let el = new Template( {
  26. tag: 'p',
  27. attrs: {
  28. 'class': [ 'a', 'b' ],
  29. x: 'bar'
  30. },
  31. text: 'foo'
  32. } ).render();
  33. expect( el ).to.be.instanceof( HTMLElement );
  34. expect( el.parentNode ).to.be.null;
  35. expect( el.outerHTML ).to.be.equal( '<p class="a b" x="bar">foo</p>' );
  36. } );
  37. it( 'creates element\'s children', () => {
  38. let el = new Template( {
  39. tag: 'p',
  40. attrs: {
  41. a: 'A'
  42. },
  43. children: [
  44. {
  45. tag: 'b',
  46. text: 'B'
  47. },
  48. {
  49. tag: 'i',
  50. text: 'C',
  51. children: [
  52. {
  53. tag: 'b',
  54. text: 'D'
  55. }
  56. ]
  57. }
  58. ]
  59. } ).render();
  60. expect( el.outerHTML ).to.be.equal( '<p a="A"><b>B</b><i>C<b>D</b></i></p>' );
  61. } );
  62. describe( 'callback', () => {
  63. it( 'works for attributes', () => {
  64. let spy1 = testUtils.sinon.spy();
  65. let spy2 = testUtils.sinon.spy();
  66. let el = new Template( {
  67. tag: 'p',
  68. attrs: {
  69. 'class': spy1
  70. },
  71. children: [
  72. {
  73. tag: 'span',
  74. attrs: {
  75. id: spy2
  76. }
  77. }
  78. ]
  79. } ).render();
  80. sinon.assert.calledWithExactly( spy1, el, sinon.match.func );
  81. sinon.assert.calledWithExactly( spy2, el.firstChild, sinon.match.func );
  82. spy1.firstCall.args[ 1 ]( el, 'foo' );
  83. spy2.firstCall.args[ 1 ]( el.firstChild, 'bar' );
  84. expect( el.outerHTML ).to.be.equal( '<p class="foo"><span id="bar"></span></p>' );
  85. } );
  86. it( 'works for "text" property', () => {
  87. let spy1 = testUtils.sinon.spy();
  88. let spy2 = testUtils.sinon.spy();
  89. let el = new Template( {
  90. tag: 'p',
  91. text: spy1,
  92. children: [
  93. {
  94. tag: 'span',
  95. text: spy2
  96. }
  97. ]
  98. } ).render();
  99. sinon.assert.calledWithExactly( spy1, el, sinon.match.func );
  100. sinon.assert.calledWithExactly( spy2, el.firstChild, sinon.match.func );
  101. spy2.firstCall.args[ 1 ]( el.firstChild, 'bar' );
  102. expect( el.outerHTML ).to.be.equal( '<p><span>bar</span></p>' );
  103. spy1.firstCall.args[ 1 ]( el, 'foo' );
  104. expect( el.outerHTML ).to.be.equal( '<p>foo</p>' );
  105. } );
  106. it( 'works for "on" property', () => {
  107. let spy1 = testUtils.sinon.spy();
  108. let spy2 = testUtils.sinon.spy();
  109. let spy3 = testUtils.sinon.spy();
  110. let spy4 = testUtils.sinon.spy();
  111. let el = new Template( {
  112. tag: 'p',
  113. children: [
  114. {
  115. tag: 'span',
  116. on: {
  117. bar: spy2
  118. }
  119. }
  120. ],
  121. on: {
  122. foo: spy1,
  123. baz: [ spy3, spy4 ]
  124. }
  125. } ).render();
  126. sinon.assert.calledWithExactly( spy1, el, 'foo', null );
  127. sinon.assert.calledWithExactly( spy2, el.firstChild, 'bar', null );
  128. sinon.assert.calledWithExactly( spy3, el, 'baz', null );
  129. sinon.assert.calledWithExactly( spy4, el, 'baz', null );
  130. } );
  131. it( 'works for "on" property with selectors', () => {
  132. let spy1 = testUtils.sinon.spy();
  133. let spy2 = testUtils.sinon.spy();
  134. let spy3 = testUtils.sinon.spy();
  135. let spy4 = testUtils.sinon.spy();
  136. let el = new Template( {
  137. tag: 'p',
  138. children: [
  139. {
  140. tag: 'span',
  141. attrs: {
  142. 'id': 'x'
  143. }
  144. },
  145. {
  146. tag: 'span',
  147. attrs: {
  148. 'class': 'y'
  149. },
  150. on: {
  151. 'bar@p': spy2
  152. }
  153. },
  154. ],
  155. on: {
  156. 'foo@span': spy1,
  157. 'baz@.y': [ spy3, spy4 ]
  158. }
  159. } ).render();
  160. sinon.assert.calledWithExactly( spy1, el, 'foo', 'span' );
  161. sinon.assert.calledWithExactly( spy2, el.lastChild, 'bar', 'p' );
  162. sinon.assert.calledWithExactly( spy3, el, 'baz', '.y' );
  163. sinon.assert.calledWithExactly( spy4, el, 'baz', '.y' );
  164. } );
  165. } );
  166. } );
  167. } );