| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- /**
- * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
- 'use strict';
- import Observer from './observer.js';
- import ViewElement from '../element.js';
- import ViewText from '../text.js';
- import objectUtils from '../../lib/lodash/object.js';
- import EmitterMixin from '../../emittermixin.js';
- export default class MutationObserver extends Observer {
- constructor() {
- super();
- this.config = {
- childList: true,
- characterData: true,
- characterDataOldValue: true,
- subtree: true
- };
- }
- /**
- * @method init
- * @param {treeView.TreeView}
- */
- init( treeView ) {
- this.treeView = treeView;
- this.domRoot = treeView.domRoot;
- this._mutationObserver = new window.MutationObserver( this._onMutations.bind( this ) );
- }
- /**
- * @method attach
- */
- attach() {
- this._mutationObserver.observe( this.domRoot, this.config );
- }
- /**
- * @method detach
- */
- detach() {
- this._mutationObserver.disconnect();
- }
- _onMutations( domMutations ) {
- // Use map and set for deduplication.
- const mutatedTexts = new Map();
- const mutatedElements = new Set();
- for ( let mutation of domMutations ) {
- if ( mutation.type === 'childList' ) {
- const element = ViewElement.getCorespondingView( mutation.target );
- if ( element ) {
- mutatedElements.add( element );
- }
- }
- }
- for ( let mutation of domMutations ) {
- if ( mutation.type === 'characterData' ) {
- const text = ViewText.getCorespondingView( mutation.target );
- if ( text && !mutatedElements.has( text.parent ) ) {
- mutatedTexts.set( text, {
- type: 'text',
- oldText: text.getText(),
- newText: mutation.target.data,
- node: text
- } );
- }
- }
- }
- const viewMutations = [];
- for ( let mutatedText of mutatedTexts.values() ) {
- mutatedText.node.markToSync( 'TEXT_NEEDS_UPDATE' );
- viewMutations.push( mutatedText );
- }
- for ( let viewElement of mutatedElements ) {
- const domElement = viewElement.getCorespondingDom();
- const domChildren = domElement.childNodes;
- const viewChildren = viewElement.getChildren();
- const newViewChildren = [];
- for ( let i = 0; i < domChildren.length; i++ ) {
- newViewChildren.push( ViewElement.createFromDom( domChildren[ i ] ) );
- }
- viewElement.markToSync( 'CHILDREN_NEED_UPDATE' );
- viewMutations.push( {
- type: 'childNodes',
- oldChildren: viewChildren,
- newChildren: newViewChildren,
- node: viewElement
- } );
- }
- this.fire( 'mutations', viewMutations );
- this.treeView.render();
- }
- }
- objectUtils.extend( MutationObserver.prototype, EmitterMixin );
|