2012-04-19 20:54:34 +00:00
|
|
|
/**
|
2012-04-30 23:58:41 +00:00
|
|
|
* Generic DataModel node.
|
2012-05-14 22:05:09 +00:00
|
|
|
*
|
2012-04-19 20:54:34 +00:00
|
|
|
* @class
|
|
|
|
* @abstract
|
|
|
|
* @constructor
|
|
|
|
* @extends {ve.Node}
|
2012-05-17 03:25:43 +00:00
|
|
|
* @param {String} type Symbolic name of node type
|
2012-04-19 20:54:34 +00:00
|
|
|
* @param {Integer} [length] Length of content data in document
|
|
|
|
* @param {Object} [attributes] Reference to map of attribute key/value pairs
|
|
|
|
*/
|
|
|
|
ve.dm.Node = function( type, length, attributes ) {
|
|
|
|
// Inheritance
|
|
|
|
ve.Node.call( this, type );
|
|
|
|
|
|
|
|
// Properties
|
|
|
|
this.length = length || 0;
|
|
|
|
this.attributes = attributes || {};
|
2012-05-01 02:38:42 +00:00
|
|
|
this.doc = undefined;
|
2012-04-19 20:54:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Methods */
|
|
|
|
|
2012-05-05 00:50:54 +00:00
|
|
|
/**
|
|
|
|
* Checks if this node can have child nodes.
|
2012-05-14 22:05:09 +00:00
|
|
|
*
|
2012-05-05 00:50:54 +00:00
|
|
|
* @method
|
2012-05-10 04:11:09 +00:00
|
|
|
* @returns {Boolean} Node can have children
|
2012-05-05 00:50:54 +00:00
|
|
|
*/
|
|
|
|
ve.dm.Node.prototype.canHaveChildren = function() {
|
|
|
|
return ve.dm.factory.canNodeHaveChildren( this.type );
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if this node can have child nodes which can also have child nodes.
|
2012-05-14 22:05:09 +00:00
|
|
|
*
|
2012-05-05 00:50:54 +00:00
|
|
|
* @method
|
2012-05-10 04:11:09 +00:00
|
|
|
* @returns {Boolean} Node can have grandchildren
|
2012-05-05 00:50:54 +00:00
|
|
|
*/
|
|
|
|
ve.dm.Node.prototype.canHaveGrandchildren = function() {
|
|
|
|
return ve.dm.factory.canNodeHaveGrandchildren( this.type );
|
|
|
|
};
|
|
|
|
|
2012-05-10 04:11:09 +00:00
|
|
|
/**
|
|
|
|
* Checks if this node represents a wrapped element in the linear model.
|
2012-05-14 22:05:09 +00:00
|
|
|
*
|
2012-05-10 04:11:09 +00:00
|
|
|
* @method
|
|
|
|
* @returns {Boolean} Node represents a wrapped element
|
|
|
|
*/
|
2012-05-07 19:00:07 +00:00
|
|
|
ve.dm.Node.prototype.isWrapped = function() {
|
|
|
|
return ve.dm.factory.isNodeWrapped( this.type );
|
|
|
|
};
|
|
|
|
|
2012-05-22 00:39:03 +00:00
|
|
|
/**
|
|
|
|
* Checks if this node can contain content.
|
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @returns {Boolean} Node can contain content
|
|
|
|
*/
|
|
|
|
ve.dm.Node.prototype.canContainContent = function() {
|
|
|
|
return ve.dm.factory.canNodeContainContent( this.type );
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if this node is content.
|
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @returns {Boolean} Node is content
|
|
|
|
*/
|
|
|
|
ve.dm.Node.prototype.isContent = function() {
|
|
|
|
return ve.dm.factory.isNodeContent( this.type );
|
|
|
|
};
|
|
|
|
|
2012-04-19 20:54:34 +00:00
|
|
|
/**
|
|
|
|
* Gets the inner length.
|
2012-05-14 22:05:09 +00:00
|
|
|
*
|
2012-04-19 20:54:34 +00:00
|
|
|
* @method
|
|
|
|
* @returns {Integer} Length of the node's contents
|
|
|
|
*/
|
2012-04-19 21:17:59 +00:00
|
|
|
ve.dm.Node.prototype.getLength = function() {
|
2012-04-19 20:54:34 +00:00
|
|
|
return this.length;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the outer length, including any opening/closing elements.
|
2012-05-14 22:05:09 +00:00
|
|
|
*
|
2012-04-19 20:54:34 +00:00
|
|
|
* @method
|
|
|
|
* @returns {Integer} Length of the entire node
|
|
|
|
*/
|
2012-04-19 21:17:59 +00:00
|
|
|
ve.dm.Node.prototype.getOuterLength = function() {
|
2012-05-07 19:00:07 +00:00
|
|
|
return this.length + ( this.isWrapped() ? 2 : 0 );
|
2012-04-19 20:54:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the inner length.
|
2012-05-14 22:05:09 +00:00
|
|
|
*
|
2012-04-19 20:54:34 +00:00
|
|
|
* @method
|
|
|
|
* @param {Integer} length Length of content
|
|
|
|
* @throws Invalid content length error if length is less than 0
|
|
|
|
* @emits lengthChange (diff)
|
|
|
|
* @emits update
|
|
|
|
*/
|
2012-04-19 21:17:59 +00:00
|
|
|
ve.dm.Node.prototype.setLength = function( length ) {
|
2012-04-19 20:54:34 +00:00
|
|
|
if ( length < 0 ) {
|
|
|
|
throw 'Length cannot be negative';
|
|
|
|
}
|
|
|
|
// Compute length adjustment from old length
|
|
|
|
var diff = length - this.length;
|
|
|
|
// Set new length
|
|
|
|
this.length = length;
|
|
|
|
// Adjust the parent's length
|
|
|
|
if ( this.parent ) {
|
|
|
|
this.parent.adjustLength( diff );
|
|
|
|
}
|
|
|
|
// Emit events
|
|
|
|
this.emit( 'lengthChange', diff );
|
|
|
|
this.emit( 'update' );
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adjust the length.
|
2012-05-14 22:05:09 +00:00
|
|
|
*
|
2012-04-19 20:54:34 +00:00
|
|
|
* @method
|
|
|
|
* @param {Integer} adjustment Amount to adjust length by
|
|
|
|
* @throws Invalid adjustment error if resulting length is less than 0
|
|
|
|
* @emits lengthChange (diff)
|
|
|
|
* @emits update
|
|
|
|
*/
|
2012-04-19 21:17:59 +00:00
|
|
|
ve.dm.Node.prototype.adjustLength = function( adjustment ) {
|
2012-04-19 20:54:34 +00:00
|
|
|
this.setLength( this.length + adjustment );
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets an element attribute value.
|
2012-05-14 22:05:09 +00:00
|
|
|
*
|
2012-04-19 20:54:34 +00:00
|
|
|
* @method
|
|
|
|
* @returns {Mixed} Value of attribute, or undefined if no such attribute exists
|
|
|
|
*/
|
|
|
|
ve.dm.Node.prototype.getAttribute = function( key ) {
|
|
|
|
return this.attributes[key];
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Inheritance */
|
|
|
|
|
|
|
|
ve.extendClass( ve.dm.Node, ve.Node );
|