treeview.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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 EmitterMixin from '../../utils/emittermixin.js';
  7. import Renderer from './renderer.js';
  8. import DomConverter from './domconverter.js';
  9. import Writer from './writer.js';
  10. import utils from '../../utils/utils.js';
  11. /**
  12. * TreeView class combines the actual tree of view elements, tree of DOM elements,
  13. * {@link core.treeView.DomConverter DOM Converter}, {@link core.treeView.Renderer renderer} and all
  14. * {@link core.treeView.Observer observers}. It creates an abstract layer over the content editable area.
  15. *
  16. * If you want to only transform the tree of view elements to the DOM elements you can use the
  17. * {@link core.treeView.DomConverter DomConverter}.
  18. *
  19. * @memberOf core.treeView
  20. * @mixes core.EmitterMixin
  21. */
  22. export default class TreeView {
  23. /**
  24. * Creates a TreeView based on the HTMLElement.
  25. *
  26. * The constructor copies the element name and attributes to create the
  27. * root of the view, but does not copy its children. This means that the while rendering, the whole content of this
  28. * root element will be removed when you call {@link core.treeView.TreeView#render render} but the root name and
  29. * attributes will be preserved.
  30. *
  31. * @param {HTMLElement} domRoot DOM element in which the tree view should do change.
  32. */
  33. constructor( domRoot ) {
  34. /**
  35. * Root of the DOM tree.
  36. *
  37. * @member {HTMLElement} core.treeView.TreeView#domRoot
  38. */
  39. this.domRoot = domRoot;
  40. /**
  41. * Set of {@link core.treeView.Observer observers}.
  42. *
  43. * @member {Set.<core.treeView.Observer>} core.treeView.TreeView#observers
  44. */
  45. this.observers = new Set();
  46. /**
  47. * Tree View writer.
  48. *
  49. * @member {core.treeView.Writer} core.treeView.TreeView#writer
  50. */
  51. this.writer = new Writer();
  52. /**
  53. * Instance of the {@link core.treeView.DomConverter domConverter} use by
  54. * {@link core.treeView.TreeView#renderer renderer} and {@link core.treeView.TreeView#observers observers}.
  55. *
  56. * @member {core.treeView.DomConverter} core.treeView.TreeView#domConverter
  57. */
  58. this.domConverter = new DomConverter();
  59. /**
  60. * Root of the view tree.
  61. *
  62. * @member {core.treeView.Element} core.treeView.TreeView#viewRoot
  63. */
  64. this.viewRoot = this.domConverter.domToView( domRoot, { bind: true, withChildren: false } );
  65. this.viewRoot.setTreeView( this );
  66. /**
  67. * Instance of the {@link core.treeView.TreeView#renderer renderer}.
  68. *
  69. * @member {core.treeView.Renderer} core.treeView.TreeView#renderer
  70. */
  71. this.renderer = new Renderer( this.domConverter );
  72. this.renderer.markToSync( 'CHILDREN', this.viewRoot );
  73. // Mark changed nodes in the renderer.
  74. this.viewRoot.on( 'change', ( evt, type, node ) => {
  75. this.renderer.markToSync( type, node );
  76. } );
  77. }
  78. /**
  79. * Adds an observer to the set of observers. This method also {@link core.treeView.Observer#init initializes} and
  80. * {@link core.treeView.Observer#attach attaches} the observer.
  81. *
  82. * @param {core.treeView.Observer} observer Observer to add.
  83. */
  84. addObserver( observer ) {
  85. this.observers.add( observer );
  86. observer.init( this );
  87. observer.attach();
  88. }
  89. /**
  90. * Renders all changes. In order to avoid triggering the observers (e.g. mutations) all observers all detached
  91. * before rendering and reattached after that.
  92. */
  93. render() {
  94. for ( let observer of this.observers ) {
  95. observer.detach();
  96. }
  97. this.renderer.render();
  98. for ( let observer of this.observers ) {
  99. observer.attach();
  100. }
  101. }
  102. }
  103. utils.mix( TreeView, EmitterMixin );
  104. /**
  105. * Enum representing type of the change.
  106. *
  107. * Possible values:
  108. *
  109. * * `CHILDREN` - for child list changes,
  110. * * `ATTRIBUTES` - for element attributes changes,
  111. * * `TEXT` - for text nodes changes.
  112. *
  113. * @typedef {String} core.treeView.ChangeType
  114. */