8
0

characterproxy.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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 toMap from '../../utils/tomap.js';
  8. /**
  9. * A proxy object representing one character stored in the tree data model. It looks and behaves like
  10. * normal node, but is a read-only structure. This is a representation of the data. Manipulating it won't affect
  11. * the actual nodes in tree model.
  12. *
  13. * Keep in mind that CharacterProxy is static, meaning that it won't change when tree model changes. For example, if you
  14. * have a {engine.treeModel.Element element} `myEl` containing text `foobar` and then assign `let b = myEl.getChild( 3 )`
  15. * and then remove all nodes from `myEl`, `b` will still have character `b`, parent `myEl` and offset `3`.
  16. *
  17. * CharacterProxy is created on the fly basing on tree model. It is not an explicit node in a tree model but
  18. * rather represents it. Because of this, it is not advised to store or compare instances of CharacterProxy class.
  19. * If you want to keep live reference to a point in a text, you should use {@link engine.treeModel.LivePosition}.
  20. *
  21. * You should never create an instance of this class by your own. When passing parameters to constructors,
  22. * use string literals or {@link engine.treeModel.Text} instead.
  23. *
  24. * @memberOf engine.treeModel
  25. * @extends engine.treeModel.Node
  26. */
  27. export default class CharacterProxy extends Node {
  28. /**
  29. * Creates character node proxy.
  30. *
  31. * @protected
  32. * @param {engine.treeModel.NodeListText} nodeListText Reference to a text object in a node list containing this character.
  33. * @param {Number} index Index of the character in `nodeListText`.
  34. */
  35. constructor( nodeListText, index ) {
  36. super( nodeListText._attrs );
  37. /**
  38. * Character represented by this proxy.
  39. *
  40. * @readonly
  41. * @member {String} engine.treeModel.CharacterProxy#character
  42. */
  43. this.character = nodeListText.text.substr( index, 1 );
  44. /**
  45. * @inheritdoc
  46. */
  47. this.parent = nodeListText.parent;
  48. /**
  49. * Reference to a text object in a node list containing this character.
  50. *
  51. * @protected
  52. * @readonly
  53. * @member {engine.treeModel.NodeListText} engine.treeModel.CharacterProxy#_nodeListText
  54. */
  55. this._nodeListText = nodeListText;
  56. /**
  57. * Index of the character in `nodeListText`.
  58. *
  59. * @protected
  60. * @readonly
  61. * @member {Number} engine.treeModel.CharacterProxy#_index
  62. */
  63. this._index = index;
  64. }
  65. /**
  66. * Sets attribute on the text fragment. If attribute with the same key already is set, it overwrites its values.
  67. *
  68. * **Note:** Changing attributes of text fragment affects document state. This TextProxy instance properties
  69. * will be refreshed, but other may get invalidated. It is highly unrecommended to store references to TextProxy instances.
  70. *
  71. * @param {String} key Key of attribute to set.
  72. * @param {*} value Attribute value.
  73. */
  74. setAttribute( key, value ) {
  75. let index = this.getIndex();
  76. this.parent._children.setAttribute( index, 1, key, value );
  77. this._attrs.set( key, value );
  78. }
  79. /**
  80. * Removes all attributes from the character proxy and sets given attributes.
  81. *
  82. * **Note:** Changing attributes of character proxy affects document state. This `CharacterProxy` instance properties
  83. * will be refreshed, but other instances of `CharacterProxy` and `TextProxy` may get invalidated.
  84. * It is highly unrecommended to store references to `CharacterProxy` instances.
  85. *
  86. * @param {Iterable|Object} attrs Iterable object containing attributes to be set. See
  87. * {@link engine.treeModel.CharacterProxy#getAttributes}.
  88. */
  89. setAttributesTo( attrs ) {
  90. let attrsMap = toMap( attrs );
  91. this.clearAttributes();
  92. for ( let attr of attrsMap ) {
  93. this.setAttribute( attr[ 0 ], attr[ 1 ] );
  94. }
  95. }
  96. /**
  97. * Removes an attribute with given key from the character proxy.
  98. *
  99. * **Note:** Changing attributes of character proxy affects document state. This `CharacterProxy` instance properties
  100. * will be refreshed, but other instances of `CharacterProxy` and `TextProxy` may get invalidated.
  101. * It is highly unrecommended to store references to `CharacterProxy` instances.
  102. *
  103. * @param {String} key Key of attribute to remove.
  104. */
  105. removeAttribute( key ) {
  106. this.setAttribute( key, null );
  107. }
  108. /**
  109. * Removes all attributes from the character proxy.
  110. *
  111. * **Note:** Changing attributes of character proxy affects document state. This `CharacterProxy` instance properties
  112. * will be refreshed, but other instances of `CharacterProxy` and `TextProxy` may get invalidated.
  113. * It is highly unrecommended to store references to `CharacterProxy` instances.
  114. */
  115. clearAttributes() {
  116. for ( let attr of this.getAttributes() ) {
  117. this.removeAttribute( attr[ 0 ] );
  118. }
  119. }
  120. }