8
0

nodelist.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /**
  2. * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. 'use strict';
  6. CKEDITOR.define( [
  7. 'document/character',
  8. 'document/text',
  9. 'document/node',
  10. 'utils'
  11. ], function( Character, Text, Node, utils ) {
  12. /**
  13. * List of nodes. It is used to represent multiple nodes with a given order, for example children of
  14. * elements {@link document.Element}.
  15. *
  16. * This class let you modify list of nodes, for example nodes to insert and pass the reference for such list.
  17. *
  18. * Thanks to the constructor which accept various structure, this class let you easily create list of text node.
  19. *
  20. * It also may internally compress nodes.
  21. *
  22. * @class document.NodeList
  23. */
  24. class NodeList {
  25. /**
  26. * Constructor let you create a list of nodes in many ways. See examples:
  27. *
  28. * var nodeList = new NodeList( [ new Element( p1 ), new Element( p1 ) ] );
  29. * nodeList.length; // 2
  30. *
  31. * var nodeList = new NodeList( new Element( p ) );
  32. * nodeList.length; // 1
  33. *
  34. * var nodeList = new NodeList( [ 'foo', new Element( p ), 'bar' ] );
  35. * nodeList.length; // 7
  36. *
  37. * var nodeList = new NodeList( 'foo' );
  38. * nodeList.length; // 3
  39. *
  40. * var nodeList = new NodeList( new Text( 'foo', [ new Attribute( 'bar', 'bom' ) ] ) );
  41. * nodeList.length; // 3
  42. * nodeList.get( 0 ).getAttr( 'bar' ); // 'bom'
  43. * nodeList.get( 1 ).getAttr( 'bar' ); // 'bom'
  44. * nodeList.get( 2 ).getAttr( 'bar' ); // 'bom'
  45. *
  46. * var nodeListA = new NodeList( 'foo' );
  47. * var nodeListB = new NodeList( nodeListA );
  48. * nodeListA === nodeListB // true
  49. * nodeListB.length // 3
  50. *
  51. * @param {document.Node|document.Text|document.NodeList|String|Array} nodes List of nodes.
  52. * @constructor
  53. */
  54. constructor( nodes ) {
  55. if ( nodes instanceof NodeList ) {
  56. // We do not clone anything.
  57. return nodes;
  58. }
  59. /**
  60. * Internal array to store nodes.
  61. *
  62. * @private
  63. * @property {Array} _nodes
  64. */
  65. this._nodes = [];
  66. if ( nodes ) {
  67. var node, i, j, nodeLen, nodesLen;
  68. if ( !utils.isArray( nodes ) ) {
  69. nodes = [ nodes ];
  70. }
  71. for ( i = 0, nodesLen = nodes.length; i < nodesLen; i++ ) {
  72. node = nodes[ i ];
  73. // Node.
  74. if ( node instanceof Node ) {
  75. this._nodes.push( node );
  76. }
  77. // Text.
  78. else if ( node instanceof Text ) {
  79. for ( j = 0, nodeLen = node.text.length; j < nodeLen; j++ ) {
  80. this._nodes.push( new Character( node.text[ j ], node.attrs ) );
  81. }
  82. }
  83. // String.
  84. else {
  85. for ( j = 0, nodeLen = node.length; j < nodeLen; j++ ) {
  86. this._nodes.push( new Character( node[ j ] ) );
  87. }
  88. }
  89. }
  90. }
  91. }
  92. /**
  93. * Returns node at the given index.
  94. *
  95. * @param {Number} index Node index.
  96. * @returns {document.Node} Node at given index.
  97. */
  98. get( index ) {
  99. return this._nodes[ index ];
  100. }
  101. /**
  102. * Inserts nodes from the given node list into this node list at the given index.
  103. *
  104. * @param {Number} index Position where nodes should be inserted.
  105. * @param {document.NodeList} nodeList List of nodes to insert.
  106. */
  107. insert( index, nodeList ) {
  108. this._nodes.splice.apply( this._nodes, [ index, 0 ].concat( nodeList._nodes ) );
  109. }
  110. /**
  111. * Removes number of nodes starting at the given index.
  112. *
  113. * @param {Number} index Position of the first node to remove.
  114. * @param {Number} number Number of nodes to remove.
  115. */
  116. remove( index, number ) {
  117. this._nodes.splice( index, number );
  118. }
  119. /**
  120. * Search for the node in the node list.
  121. *
  122. * @param {document.Node} node Node to found.
  123. * @returns {Number} Number representing the position where the specified search value occurs for the first time,
  124. * or -1 if it never occurs.
  125. */
  126. indexOf( node ) {
  127. return this._nodes.indexOf( node );
  128. }
  129. /**
  130. * Number of nodes in the node list.
  131. *
  132. * @readonly
  133. * @property {Number} length
  134. */
  135. get length() {
  136. return this._nodes.length;
  137. }
  138. /**
  139. * Node list iterator.
  140. */
  141. [ Symbol.iterator ]() {
  142. return this._nodes[ Symbol.iterator ]();
  143. }
  144. }
  145. return NodeList;
  146. } );