utils.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /**
  2. * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. 'use strict';
  6. import Range from '/ckeditor5/core/treeview/range.js';
  7. import Position from '/ckeditor5/core/treeview/position.js';
  8. const utils = {
  9. /**
  10. * Helper function that is used to create treeView elements from description object.
  11. *
  12. * @param {core.treeView.Writer} writer Writer instance. Used to set priorities.
  13. * @param {Object} description Description object.
  14. * @param {core.treeView.Range} [range] Optional parameter, used in recurrent calls.
  15. * @param {core.treeView.Position} [position] Optional parameter, used in recurrent calls.
  16. * @returns {Object} Returns object with `node`, `range`, `position` fields, containing created node and, optionally
  17. * range and position if description object contain information about them.
  18. */
  19. create( writer, description, range, position ) {
  20. const node = new description.instanceOf();
  21. if ( !range ) {
  22. range = Range.createFromParentsAndOffsets( node, 0, node, 0 );
  23. }
  24. if ( !position ) {
  25. position = new Position( node, 0 );
  26. }
  27. if ( description.name ) {
  28. node.name = description.name;
  29. }
  30. if ( description.data ) {
  31. node.data = description.data;
  32. }
  33. if ( description.attributes ) {
  34. Object.keys( description.attributes ).forEach( ( key ) => {
  35. node.setAttribute( key, description.attributes[ key ] );
  36. } );
  37. }
  38. if ( description.priority !== undefined ) {
  39. writer.setPriority( node, description.priority );
  40. }
  41. if ( description.rangeStart !== undefined ) {
  42. range.start.parent = node;
  43. range.start.offset = description.rangeStart;
  44. }
  45. if ( description.rangeEnd !== undefined ) {
  46. range.end.parent = node;
  47. range.end.offset = description.rangeEnd;
  48. }
  49. if ( description.position !== undefined ) {
  50. position.parent = node;
  51. position.offset = description.position;
  52. }
  53. if ( description.children ) {
  54. description.children.forEach( ( desc, index ) => {
  55. const created = utils.create( writer, desc, range, position );
  56. node.insertChildren( index, created.node );
  57. } );
  58. }
  59. return { node, range, position };
  60. },
  61. /**
  62. * Helper function that is used to test output of writer methods by providing declarative description of the
  63. * expected output.
  64. * Examples:
  65. * test element: `<p>fo[o<b>ba]r</b></p>`
  66. * description: {
  67. * name: 'p',
  68. * instanceOf: Element,
  69. * children:[
  70. * {
  71. * instanceOf: Text,
  72. * data: 'foo',
  73. * rangeStart: 2
  74. * },
  75. * {
  76. * name: 'b'
  77. * instanceOf: Element
  78. * priority: 1,
  79. * children: [
  80. * { instanceOf: Text, data: 'bar', rangeEnd: 2 }
  81. * ]
  82. * }
  83. * ]
  84. * }
  85. *
  86. *
  87. * @param {core.treeView.Writer} writer Writer instance. Used to test priority.
  88. * @param {core.treeView.Range|core.treeView.Position } location Range instance or Position instance.
  89. * Treated as Range when when `rangeStart`, `rangeEnd` is used, treated as Position when `position` is used.
  90. * @param {core.treeView.Node} node Element to check.
  91. * @param {Object} description Object describing expected element and its children.
  92. */
  93. test( writer, location, node, description ) {
  94. // If no root node provided - iterate over node array.
  95. if ( description instanceof Array && node instanceof Array ) {
  96. node.forEach( ( n, i ) => {
  97. utils.test( writer, location, n, description[ i ] );
  98. } );
  99. }
  100. if ( description.instanceOf ) {
  101. expect( node ).to.be.instanceof( description.instanceOf );
  102. }
  103. if ( description.name ) {
  104. expect( description.name ).to.equal( node.name );
  105. }
  106. if ( description.data ) {
  107. expect( description.data ).to.equal( node.data );
  108. }
  109. if ( description.priority !== undefined ) {
  110. expect( description.priority ).to.equal( writer.getPriority( node ) );
  111. }
  112. if ( description.rangeStart !== undefined ) {
  113. expect( node ).to.equal( location.start.parent );
  114. expect( description.rangeStart ).to.equal( location.start.offset );
  115. }
  116. if ( description.rangeEnd !== undefined ) {
  117. expect( node ).to.equal( location.end.parent );
  118. expect( description.rangeEnd ).to.equal( location.end.offset );
  119. }
  120. if ( description.attributes ) {
  121. Object.keys( description.attributes ).forEach( ( key ) => {
  122. expect( description.attributes[ key ] ).to.equal( node.getAttribute( key ) );
  123. } );
  124. }
  125. if ( description.position !== undefined ) {
  126. expect( node ).to.equal( location.parent );
  127. expect( description.position ).to.equal( location.offset );
  128. }
  129. if ( description.children ) {
  130. expect( description.children.length ).to.equal( node.getChildCount() );
  131. description.children.forEach( ( desc, index ) => {
  132. utils.test( writer, location, node.getChild( index ), desc );
  133. } );
  134. }
  135. }
  136. };
  137. export default utils;