attribute.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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 langUtils from '../lib/lodash/lang.js';
  7. /**
  8. * Attributes can store any additional information for nodes in the data model.
  9. *
  10. * @class treeModel.Attribute
  11. */
  12. export default class Attribute {
  13. /**
  14. * Creates a new instance of the `Attribute` class. Once attribute is created it is immutable.
  15. *
  16. * @param {String} key Attribute key.
  17. * @param {Mixed} value Attribute value.
  18. * @constructor
  19. */
  20. constructor( key, value ) {
  21. /**
  22. * Attribute key.
  23. *
  24. * @readonly
  25. * @property {String} key
  26. */
  27. this.key = key;
  28. /**
  29. * Attribute value. Note that value may be any type, including objects.
  30. *
  31. * @readonly
  32. * @property {Mixed} value
  33. */
  34. this.value = value;
  35. /**
  36. * Attribute hash. Used to compare attributes. Two attributes with the same key and value will have the same hash.
  37. *
  38. * @readonly
  39. * @private
  40. * @property {String} _hash
  41. */
  42. this._hash = this.key + ': ' + JSON.stringify( this.value, sort );
  43. // We do not care about the order, so collections with the same elements should return the same hash.
  44. function sort( key, value ) {
  45. if ( !langUtils.isArray( value ) && langUtils.isObject( value ) ) {
  46. const sorted = {};
  47. // Sort keys and fill up the sorted object.
  48. Object.keys( value ).sort().forEach( ( key ) => {
  49. sorted[ key ] = value[ key ];
  50. } );
  51. return sorted;
  52. } else {
  53. return value;
  54. }
  55. }
  56. }
  57. /**
  58. * Compares two attributes. Returns `true` if two attributes have the same key and value even if the order of keys
  59. * in the value object is different.
  60. *
  61. * let attr1 = new Attribute( 'foo', { a: 1, b: 2 } );
  62. * let attr2 = new Attribute( 'foo', { b: 2, a: 1 } );
  63. * attr1.isEqual( attr2 ); // true
  64. *
  65. * @param {treeModel.Attribute} otherAttr Attribute to compare with.
  66. * @returns {Boolean} True if attributes are equal to each other.
  67. */
  68. isEqual( otherAttr ) {
  69. return this._hash === otherAttr._hash;
  70. }
  71. }