template.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /**
  2. * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /* bender-tags: core, ui */
  6. /* global HTMLElement */
  7. 'use strict';
  8. const modules = bender.amd.require( 'ckeditor', 'ui/view', 'ui/template' );
  9. let Template;
  10. bender.tools.createSinonSandbox();
  11. beforeEach( createClassReferences );
  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. } );
  63. describe( 'callback value', () => {
  64. it( 'works for attributes', () => {
  65. let spy1 = bender.sinon.spy();
  66. let spy2 = bender.sinon.spy();
  67. let el = new Template( {
  68. tag: 'p',
  69. attrs: {
  70. 'class': spy1
  71. },
  72. children: [
  73. {
  74. tag: 'span',
  75. attrs: {
  76. id: spy2
  77. }
  78. }
  79. ]
  80. } ).render();
  81. sinon.assert.calledWithExactly( spy1, el, sinon.match.func );
  82. sinon.assert.calledWithExactly( spy2, el.firstChild, sinon.match.func );
  83. spy1.firstCall.args[ 1 ]( el, 'foo' );
  84. spy2.firstCall.args[ 1 ]( el.firstChild, 'bar' );
  85. expect( el.outerHTML ).to.be.equal( '<p class="foo"><span id="bar"></span></p>' );
  86. } );
  87. it( 'works for "text" property', () => {
  88. let spy1 = bender.sinon.spy();
  89. let spy2 = bender.sinon.spy();
  90. let el = new Template( {
  91. tag: 'p',
  92. text: spy1,
  93. children: [
  94. {
  95. tag: 'span',
  96. text: spy2
  97. }
  98. ]
  99. } ).render();
  100. sinon.assert.calledWithExactly( spy1, el, sinon.match.func );
  101. sinon.assert.calledWithExactly( spy2, el.firstChild, sinon.match.func );
  102. spy2.firstCall.args[ 1 ]( el.firstChild, 'bar' );
  103. expect( el.outerHTML ).to.be.equal( '<p><span>bar</span></p>' );
  104. spy1.firstCall.args[ 1 ]( el, 'foo' );
  105. expect( el.outerHTML ).to.be.equal( '<p>foo</p>' );
  106. } );
  107. it( 'works for "on" property', () => {
  108. let spy1 = bender.sinon.spy();
  109. let spy2 = bender.sinon.spy();
  110. let spy3 = bender.sinon.spy();
  111. let spy4 = bender.sinon.spy();
  112. let el = new Template( {
  113. tag: 'p',
  114. children: [
  115. {
  116. tag: 'span',
  117. on: {
  118. bar: spy2
  119. }
  120. }
  121. ],
  122. on: {
  123. foo: spy1,
  124. baz: [ spy3, spy4 ]
  125. }
  126. } ).render();
  127. sinon.assert.calledWithExactly( spy1, el, 'foo', null );
  128. sinon.assert.calledWithExactly( spy2, el.firstChild, 'bar', null );
  129. sinon.assert.calledWithExactly( spy3, el, 'baz', null );
  130. sinon.assert.calledWithExactly( spy4, el, 'baz', null );
  131. } );
  132. it( 'works for "on" property with selectors', () => {
  133. let spy1 = bender.sinon.spy();
  134. let spy2 = bender.sinon.spy();
  135. let spy3 = bender.sinon.spy();
  136. let spy4 = bender.sinon.spy();
  137. let el = new Template( {
  138. tag: 'p',
  139. children: [
  140. {
  141. tag: 'span',
  142. attrs: {
  143. 'id': 'x'
  144. }
  145. },
  146. {
  147. tag: 'span',
  148. attrs: {
  149. 'class': 'y'
  150. },
  151. on: {
  152. 'bar@p': spy2
  153. }
  154. },
  155. ],
  156. on: {
  157. 'foo@span': spy1,
  158. 'baz@.y': [ spy3, spy4 ]
  159. }
  160. } ).render();
  161. sinon.assert.calledWithExactly( spy1, el, 'foo', 'span' );
  162. sinon.assert.calledWithExactly( spy2, el.lastChild, 'bar', 'p' );
  163. sinon.assert.calledWithExactly( spy3, el, 'baz', '.y' );
  164. sinon.assert.calledWithExactly( spy4, el, 'baz', '.y' );
  165. } );
  166. } );
  167. function createClassReferences() {
  168. Template = modules[ 'ui/template' ];
  169. }