element.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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 Node from './node.js';
  7. import utils from '../utils.js';
  8. import langUtils from '../lib/lodash/lang.js';
  9. /**
  10. * Tree view element.
  11. *
  12. * @class treeView.Element
  13. */
  14. export default class Element extends Node {
  15. /**
  16. * Creates a tree view element.
  17. *
  18. * Attributes can be passes in various formats:
  19. *
  20. * new Element( 'div', { 'class': 'editor', 'contentEditable': 'true' } ); // object
  21. * new Element( 'div', [ [ 'class', 'editor' ], [ 'contentEditable', 'true' ] ] ); // map-like iterator
  22. * new Element( 'div', mapOfAttributes ); // map
  23. *
  24. * @param {String} name Node name.
  25. * @param {Object|Interable} [attrs] Collection of attributes.
  26. * @param {treeView.Node|Iterable.<treeView.Node>} [children] List of nodes to be inserted into created element.
  27. * @constructor
  28. */
  29. constructor( name, attrs, children ) {
  30. super();
  31. /**
  32. * Name of the element.
  33. *
  34. * @readonly
  35. * @property {String}
  36. */
  37. this.name = name;
  38. /**
  39. * Map of attributes, where attributes names are keys and attributes values are values.
  40. *
  41. * @protected
  42. * @property {Map} _attrs
  43. */
  44. if ( langUtils.isPlainObject( attrs ) ) {
  45. this._attrs = utils.objectToMap( attrs );
  46. } else {
  47. this._attrs = new Map( attrs );
  48. }
  49. /**
  50. * Array of child nodes.
  51. *
  52. * @protected
  53. * @property {Array.<treeView.Node>}
  54. */
  55. this._children = [];
  56. if ( children ) {
  57. this.insertChildren( 0, children );
  58. }
  59. }
  60. /**
  61. * {@link treeView.Element#insert Insert} a child node or a list of child nodes at the end of this node and sets
  62. * the parent of these nodes to this element.
  63. *
  64. * Fires the {@link treeView.Node#change change event}.
  65. *
  66. * @param {treeView.Node|Iterable.<treeView.Node>} nodes Node or the list of nodes to be inserted.
  67. */
  68. appendChildren( nodes ) {
  69. this.insertChildren( this.getChildCount(), nodes );
  70. }
  71. /**
  72. * Gets child at the given index.
  73. *
  74. * @param {Number} index Index of child.
  75. * @returns {treeView.Node} Child node.
  76. */
  77. getChild( index ) {
  78. return this._children[ index ];
  79. }
  80. /**
  81. * Gets the number of element's children.
  82. *
  83. * @returns {Number} The number of element's children.
  84. */
  85. getChildCount() {
  86. return this._children.length;
  87. }
  88. /**
  89. * Gets index of the given child node.
  90. *
  91. * @param {treeView.Node} node Child node.
  92. * @returns {Number} Index of the child node.
  93. */
  94. getChildIndex( node ) {
  95. return this._children.indexOf( node );
  96. }
  97. /**
  98. * Gets child nodes iterator.
  99. *
  100. * @returns {Iterable.<treeView.Node>} Child nodes iterator.
  101. */
  102. getChildren() {
  103. return this._children[ Symbol.iterator ]();
  104. }
  105. /**
  106. * Returns an iterator that contains the keys for attributes.
  107. *
  108. * @returns {Iterator.<String>} Keys for attributes.
  109. */
  110. getAttributeKeys() {
  111. return this._attrs.keys();
  112. }
  113. /**
  114. * Gets attribute by key.
  115. *
  116. * @param {String} key Attribute key.
  117. * @returns {String} Attribute value.
  118. */
  119. getAttribute( key ) {
  120. return this._attrs.get( key );
  121. }
  122. /**
  123. * Returns a boolean indicating whether an attribute with the specified key exists in the element.
  124. *
  125. * @param {String} key Attribute key.
  126. * @returns {Boolean} `true` if attribute with the specified key exists in the element, false otherwise.
  127. */
  128. hasAttribute( key ) {
  129. return this._attrs.has( key );
  130. }
  131. /**
  132. * Adds or overwrite attribute with a specified key and value.
  133. *
  134. * Fires the {@link treeView.Node#change change event}.
  135. *
  136. * @param {String} key Attribute key.
  137. * @param {String} value Attribute value.
  138. */
  139. setAttribute( key, value ) {
  140. this._fireChange( 'ATTRIBUTES', this );
  141. this._attrs.set( key, value );
  142. }
  143. /**
  144. * Inserts a child node or a list of child nodes on the given index and sets the parent of these nodes to
  145. * this element.
  146. *
  147. * Fires the {@link treeView.Node#change change event}.
  148. *
  149. * @param {Number} index Position where nodes should be inserted.
  150. * @param {treeView.Node|Iterable.<treeView.Node>} nodes Node or the list of nodes to be inserted.
  151. */
  152. insertChildren( index, nodes ) {
  153. this._fireChange( 'CHILDREN', this );
  154. if ( !utils.isIterable( nodes ) ) {
  155. nodes = [ nodes ];
  156. }
  157. for ( let node of nodes ) {
  158. node.parent = this;
  159. this._children.splice( index, 0, node );
  160. index++;
  161. }
  162. }
  163. /**
  164. * Removes attribute from the element.
  165. *
  166. * Fires the {@link treeView.Node#change change event}.
  167. *
  168. * @param {String} key Attribute key.
  169. * @returns {Boolead} Returns true if an attribute existed and has been removed.
  170. */
  171. removeAttribute( key ) {
  172. this._fireChange( 'ATTRIBUTES', this );
  173. return this._attrs.delete( key );
  174. }
  175. /**
  176. * Removes number of child nodes starting at the given index and set the parent of these nodes to `null`.
  177. *
  178. * Fires the {@link treeView.Node#change change event}.
  179. *
  180. * @param {Number} index Number of the first node to remove.
  181. * @param {Number} number Number of nodes to remove.
  182. * @returns {Array.<treeView.Node>} The array of removed nodes.
  183. */
  184. removeChildren( index, number ) {
  185. this._fireChange( 'CHILDREN', this );
  186. for ( let i = index; i < index + number; i++ ) {
  187. this._children[ i ].parent = null;
  188. }
  189. return this._children.splice( index, number );
  190. }
  191. }