template.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /**
  2. * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /* global document */
  6. 'use strict';
  7. /**
  8. * Basic Template class.
  9. *
  10. * @class Template
  11. */
  12. CKEDITOR.define( function() {
  13. class Template {
  14. /**
  15. * Creates an instance of the {@link Template} class.
  16. *
  17. * @param {Model} mode (View)Model of this Template.
  18. * @constructor
  19. */
  20. constructor( def ) {
  21. /**
  22. * Definition of this Template.
  23. */
  24. this.def = def;
  25. }
  26. /**
  27. * Renders HTMLElement using {@link def}.
  28. *
  29. * @param {Object} [def] Template definition to be rendered.
  30. * @returns {HTMLElement}
  31. */
  32. render() {
  33. return renderElement( this.def );
  34. }
  35. }
  36. var getTextUpdater = () =>
  37. ( el, value ) => el.innerHTML = value;
  38. var getAttributeUpdater = ( attr ) =>
  39. ( el, value ) => el.setAttribute( attr, value );
  40. function renderElement( def ) {
  41. if ( !def ) {
  42. return null;
  43. }
  44. var el = document.createElement( def.tag );
  45. // Set the text first.
  46. renderElementText( def, el );
  47. // Set attributes.
  48. renderElementAttributes( def, el );
  49. // Invoke children recursively.
  50. renderElementChildren( def, el );
  51. return el;
  52. }
  53. function renderElementText( def, el ) {
  54. if ( def.text ) {
  55. if ( typeof def.text == 'function' ) {
  56. def.text( el, getTextUpdater() );
  57. } else {
  58. el.innerHTML = def.text;
  59. }
  60. }
  61. }
  62. function renderElementAttributes( def, el ) {
  63. var value;
  64. var attr;
  65. for ( attr in def.attributes ) {
  66. value = def.attributes[ attr ];
  67. // Attribute bound directly to the model.
  68. if ( typeof value == 'function' ) {
  69. value( el, getAttributeUpdater( attr ) );
  70. }
  71. // Explicit attribute definition (string).
  72. else {
  73. // Attribute can be an array, i.e. classes.
  74. if ( Array.isArray( value ) ) {
  75. value = value.join( ' ' );
  76. }
  77. el.setAttribute( attr, value );
  78. }
  79. }
  80. }
  81. function renderElementChildren( def, el ) {
  82. var child;
  83. if ( def.children ) {
  84. for ( child of def.children ) {
  85. el.appendChild( renderElement( child ) );
  86. }
  87. }
  88. }
  89. return Template;
  90. } );