|
|
@@ -5,81 +5,105 @@
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
+import Position from './position.js';
|
|
|
+import utils from '../utils.js';
|
|
|
+
|
|
|
/**
|
|
|
* @class treeView.Writer
|
|
|
*/
|
|
|
export default class Writer {
|
|
|
constructor() {
|
|
|
+ /**
|
|
|
+ * Priorities map. Maps node to priority.
|
|
|
+ * Nodes with priorities are considered as attributes.
|
|
|
+ *
|
|
|
+ * @member {WeakMap} core.treeView.Writer#_priorities
|
|
|
+ * @protected
|
|
|
+ */
|
|
|
this._priorities = new WeakMap();
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns true if provided node is a container node.
|
|
|
+ *
|
|
|
+ * @param {treeView.Node} node
|
|
|
+ * @returns {Boolean}
|
|
|
+ */
|
|
|
isContainer( node ) {
|
|
|
return !this._priorities.has( node );
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns true if provided node is an attribute node.
|
|
|
+ *
|
|
|
+ * @param {treeView.Node} node
|
|
|
+ * @returns {Boolean}
|
|
|
+ */
|
|
|
isAttribute( node ) {
|
|
|
return this._priorities.has( node );
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Sets node priority.
|
|
|
+ *
|
|
|
+ * @param {treeView.Node} node
|
|
|
+ * @param {Number} priority
|
|
|
+ */
|
|
|
+ setPriority( node, priority ) {
|
|
|
+ this._priorities.set( node, priority );
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns node's priority, undefined if node's priority cannot be found.
|
|
|
+ *
|
|
|
+ * @param {treeView.Node} node
|
|
|
+ * @returns {Number|undefined}
|
|
|
+ */
|
|
|
getPriority( node ) {
|
|
|
return this._priorities.get( node );
|
|
|
}
|
|
|
|
|
|
insertIntoContainer( position, nodes ) {
|
|
|
- const container = getParentContainer( position );
|
|
|
+ const container = this.getParentContainer( position );
|
|
|
|
|
|
const insertionPosition = this.breakAttributes( position, container );
|
|
|
|
|
|
container.insertChildren( insertionPosition, nodes );
|
|
|
|
|
|
- const length = utils.isIterable( nodes ) ? utils.getIterableCount( nodes ) : 1;
|
|
|
+ const length = utils.isIterable( nodes ) ? utils.count( nodes ) : 1;
|
|
|
const endPosition = insertionPosition.getShiftedBy( length );
|
|
|
|
|
|
this.mergeAttributes( endPosition );
|
|
|
this.mergeAttributes( insertionPosition );
|
|
|
}
|
|
|
|
|
|
- getParentContainer( position ) {
|
|
|
- let container = position.parent;
|
|
|
-
|
|
|
- while ( !this.isContainer( container ) ) {
|
|
|
- container = container.parent;
|
|
|
- }
|
|
|
-
|
|
|
- return container;
|
|
|
- }
|
|
|
-
|
|
|
// return position
|
|
|
- breakAttributes( position, limit ) {
|
|
|
- if ( !limit ) {
|
|
|
- limit = this.getParentContainer( position );
|
|
|
- }
|
|
|
+ breakAttributes( position ) {
|
|
|
+ let positionOffset = position.offset;
|
|
|
+ let positionParent = position.parent;
|
|
|
|
|
|
- let offset = position.offset;
|
|
|
- let node = position.parent;
|
|
|
-
|
|
|
- if ( this.isContainer( node ) ) {
|
|
|
+ if ( this.isContainer( positionParent ) ) {
|
|
|
return position;
|
|
|
}
|
|
|
|
|
|
- const parentIsText = node instanceof Text;
|
|
|
- const length = parentIsText ? node.data.length : node.getChildCount();
|
|
|
+ const parentIsText = positionParent instanceof Text;
|
|
|
+ const length = parentIsText ? positionParent.data.length : positionParent.getChildCount();
|
|
|
|
|
|
// <p>foo<b><u>bar|</u></b></p>
|
|
|
// <p>foo<b><u>bar</u>|</b></p>
|
|
|
// <p>foo<b><u>bar</u></b>|</p>
|
|
|
- if ( offset == length ) {
|
|
|
- const parentPosition = new Position( node.parent, node.getIndex() + 1 );
|
|
|
+ if ( positionOffset == length ) {
|
|
|
+ const parentPosition = new Position( positionParent.parent, positionParent.getIndex() + 1 );
|
|
|
|
|
|
- return this.breakAttributes( parentPosition, limit );
|
|
|
+ return this.breakAttributes( parentPosition );
|
|
|
} else
|
|
|
// <p>foo<b><u>|bar</u></b></p>
|
|
|
// <p>foo<b>|<u>bar</u></b></p>
|
|
|
// <p>foo|<b><u>bar</u></b></p>
|
|
|
- if ( offset == 0 ) {
|
|
|
- const parentPosition = new Position( node.parent, node.getIndex() );
|
|
|
+ if ( positionOffset === 0 ) {
|
|
|
+ const parentPosition = new Position( positionParent.parent, positionParent.getIndex() );
|
|
|
|
|
|
- return this.breakAttributes( parentPosition, limit );
|
|
|
+ return this.breakAttributes( parentPosition );
|
|
|
}
|
|
|
// <p>foo<b><u>"b|ar"</u></b></p>
|
|
|
// <p>foo<b><u>"b"|"ar"</u></b></p>
|
|
|
@@ -87,28 +111,28 @@
|
|
|
// <p>foo<b><u>b</u></b>|<b><u>ar</u></b></p>
|
|
|
else {
|
|
|
// Break.
|
|
|
- const offsetAfter = node.getIndex() + 1;
|
|
|
+ const offsetAfter = positionParent.getIndex() + 1;
|
|
|
|
|
|
if ( parentIsText ) {
|
|
|
// Break text.
|
|
|
- const textToMove = node.data.slice( offset );
|
|
|
- node.data = node.data.slice( 0, offset );
|
|
|
- node.parent.insertChildren( offsetAfter, new Text( textToMove ) );
|
|
|
+ const textToMove = positionParent.data.slice( positionOffset );
|
|
|
+ positionParent.data = positionParent.data.slice( 0, positionOffset );
|
|
|
+ positionParent.parent.insertChildren( offsetAfter, new Text( textToMove ) );
|
|
|
|
|
|
- return new Position( node.parent, offsetAfter );
|
|
|
+ return new Position( positionParent.parent, offsetAfter );
|
|
|
} else {
|
|
|
// Break element.
|
|
|
- const nodeClone = node.cloneNode();
|
|
|
+ const nodeClone = positionParent.cloneNode();
|
|
|
// Clone priority.
|
|
|
- this._priorities.set( nodeClone, this._priorities.get( node ) );
|
|
|
+ this._priorities.set( nodeClone, this._priorities.get( positionParent ) );
|
|
|
|
|
|
- node.parent.insertChildren( offsetAfter, nodeClone );
|
|
|
+ positionParent.parent.insertChildren( offsetAfter, nodeClone );
|
|
|
|
|
|
- const nodesToMove = sourceElement.removeChildren( sourceOffset, this.howMany );
|
|
|
+ //const nodesToMove = sourceElement.removeChildren( sourceOffset, this.howMany );
|
|
|
|
|
|
- nodeClone.appendChildren( nodesToMove );
|
|
|
+ //nodeClone.appendChildren( nodesToMove );
|
|
|
|
|
|
- return new Position( node.parent, offsetAfter );
|
|
|
+ return new Position( positionParent.parent, offsetAfter );
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -148,24 +172,24 @@
|
|
|
return position;
|
|
|
}
|
|
|
|
|
|
- removeFromContainer( range ) {
|
|
|
- }
|
|
|
-
|
|
|
- // <p><u><b>"|"</b></u></p>
|
|
|
- // <p><u><b>|</b></u></p>
|
|
|
- // <p><u>|</u></p>
|
|
|
- // <p>|</p>
|
|
|
- removeEmptyAttributes( position ) {
|
|
|
- }
|
|
|
-
|
|
|
- // f[o]o -> f<b>o</b>o
|
|
|
- // <b>f</b>[o]<b>o</b> -> <b>f</b><b>o</b><b>o</b> -> <b>foo</b>
|
|
|
- // <b>f</b>o[o<u>bo]m</u> -> <b>f</b>o<b>o</b><u><b>bo</b>m</u>
|
|
|
- // Range have to] be inside single container.
|
|
|
- wrap( range, element, priority ) {
|
|
|
- // this._priorities.set( element, priority );
|
|
|
- }
|
|
|
-
|
|
|
- unwrap( range, element ) {
|
|
|
- }
|
|
|
+ //removeFromContainer( range ) {
|
|
|
+ //}
|
|
|
+ //
|
|
|
+ //// <p><u><b>"|"</b></u></p>
|
|
|
+ //// <p><u><b>|</b></u></p>
|
|
|
+ //// <p><u>|</u></p>
|
|
|
+ //// <p>|</p>
|
|
|
+ //removeEmptyAttributes( position ) {
|
|
|
+ //}
|
|
|
+ //
|
|
|
+ //// f[o]o -> f<b>o</b>o
|
|
|
+ //// <b>f</b>[o]<b>o</b> -> <b>f</b><b>o</b><b>o</b> -> <b>foo</b>
|
|
|
+ //// <b>f</b>o[o<u>bo]m</u> -> <b>f</b>o<b>o</b><u><b>bo</b>m</u>
|
|
|
+ //// Range have to] be inside single container.
|
|
|
+ //wrap( range, element, priority ) {
|
|
|
+ // // this._priorities.set( element, priority );
|
|
|
+ //}
|
|
|
+ //
|
|
|
+ //unwrap( range, element ) {
|
|
|
+ //}
|
|
|
}
|