text.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /**
  2. * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. 'use strict';
  6. import toMap from '../../utils/tomap.js';
  7. /**
  8. * Data structure for text with attributes. Note that `Text` is not a {@link engine.model.Node}. This class is used
  9. * as an aggregator for multiple characters that have same attributes. Example usage:
  10. *
  11. * let myElem = new Element( 'li', [], new Text( 'text with attributes', { foo: true, bar: true } ) );
  12. *
  13. * @memberOf engine.model
  14. */
  15. export default class Text {
  16. /**
  17. * Creates a text with attributes.
  18. *
  19. * @param {String} text Described text.
  20. * @param {Iterable|Object} [attrs] Iterable collection of attributes.
  21. */
  22. constructor( text, attrs ) {
  23. /**
  24. * Text.
  25. *
  26. * @readonly
  27. * @member {String} engine.model.Text#text
  28. */
  29. this.text = text || '';
  30. /**
  31. * List of attributes bound with the text.
  32. *
  33. * @protected
  34. * @member {Map} engine.model.Text#_attrs
  35. */
  36. this._attrs = toMap( attrs );
  37. }
  38. /**
  39. * Checks if the text has an attribute for given key.
  40. *
  41. * @param {String} key Key of attribute to check.
  42. * @returns {Boolean} `true` if attribute with given key is set on text, `false` otherwise.
  43. */
  44. hasAttribute( key ) {
  45. return this._attrs.has( key );
  46. }
  47. /**
  48. * Gets an attribute value for given key or undefined if that attribute is not set on text.
  49. *
  50. * @param {String} key Key of attribute to look for.
  51. * @returns {*} Attribute value or null.
  52. */
  53. getAttribute( key ) {
  54. return this._attrs.get( key );
  55. }
  56. /**
  57. * Returns iterator that iterates over this text attributes.
  58. *
  59. * @returns {Iterable.<*>}
  60. */
  61. getAttributes() {
  62. return this._attrs[ Symbol.iterator ]();
  63. }
  64. /**
  65. * Sets attribute on text. If attribute with the same key already is set, it overwrites its value.
  66. *
  67. * @param {String} key Key of attribute to set.
  68. * @param {*} value Attribute value.
  69. */
  70. setAttribute( key, value ) {
  71. this._attrs.set( key, value );
  72. }
  73. /**
  74. * Removes all attributes from text and sets given attributes.
  75. *
  76. * @param {Iterable|Object} attrs Iterable object containing attributes to be set. See {@link engine.model.Text#getAttributes}.
  77. */
  78. setAttributesTo( attrs ) {
  79. this._attrs = toMap( attrs );
  80. }
  81. /**
  82. * Removes an attribute with given key from text.
  83. *
  84. * @param {String} key Key of attribute to remove.
  85. * @returns {Boolean} `true` if the attribute was set on text, `false` otherwise.
  86. */
  87. removeAttribute( key ) {
  88. return this._attrs.delete( key );
  89. }
  90. /**
  91. * Removes all attributes from text.
  92. */
  93. clearAttributes() {
  94. this._attrs.clear();
  95. }
  96. /**
  97. * Custom toJSON method to solve child-parent circular dependencies.
  98. *
  99. * @returns {Object} Clone of this object with the parent property replaced with its name.
  100. */
  101. toJSON() {
  102. let json = {
  103. text: this.text
  104. };
  105. if ( this._attrs.size ) {
  106. json.attributes = [ ...this._attrs ];
  107. }
  108. return json;
  109. }
  110. }