Added update handlers to heading, list, list item and image ce nodes

* Also renamed convertDomElement to replaceDomWrapper in ve.ce.BranchNode
* Also added extra documentation for node rules

Change-Id: Ia8ac6be34e2b021be96974ac1ba9119bd8077d60
This commit is contained in:
Trevor Parscal 2012-05-02 11:29:44 -07:00
parent 94f53dc6c7
commit 1d94af144a
25 changed files with 257 additions and 20 deletions

View file

@ -14,7 +14,11 @@ ve.ce.AlienNode = function( model ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.ce.NodeFactory
* @static
* @member
*/
ve.ce.AlienNode.rules = {
'canHaveChildren': false,

View file

@ -14,7 +14,11 @@ ve.ce.DocumentNode = function( model ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.ce.NodeFactory
* @static
* @member
*/
ve.ce.DocumentNode.rules = {
'canHaveChildren': true,

View file

@ -9,12 +9,22 @@
ve.ce.HeadingNode = function( model ) {
// Inheritance
ve.ce.BranchNode.call( this, model, ve.ce.HeadingNode.getDomElement( model ) );
// Properties
this.currentLevel = model.getAttribute( 'level' );
// Events
this.model.addListenerMethod( 'update', this, 'onUpdate' );
};
/* Static Members */
/**
* Node rules.
*
* @see ve.ce.NodeFactory
* @static
* @member
*/
ve.ce.HeadingNode.rules = {
'canHaveChildren': true,
@ -22,7 +32,13 @@ ve.ce.HeadingNode.rules = {
'canBeSplit': true
};
ve.ce.HeadingNode.domNodeTypes = {
/**
* Mapping of heading level values and DOM wrapper element types.
*
* @static
* @member
*/
ve.ce.HeadingNode.domWrapperElementTypes = {
'1': 'h1',
'2': 'h2',
'3': 'h3',
@ -33,15 +49,43 @@ ve.ce.HeadingNode.domNodeTypes = {
/* Static Methods */
ve.ce.HeadingNode.getDomElement = function( model ) {
var level = model.getElementAttribute( 'level' ),
type = ve.ce.HeadingNode.domNodeTypes[level];
/**
* Gets an appropriate DOM wrapper for the model.
*
* This method is static because it is used before the node is fully constructed. Before all parent
* constructors are called this.model may not be ready to be used.
*
* @static
* @method
* @param {ve.dm.HeadingNode} model Model to create DOM wrapper for
* @returns {jQuery} Selection containing DOM wrapper
*/
ve.ce.HeadingNode.getDomWrapper = function( model ) {
var level = model.getAttribute( 'level' ),
type = ve.ce.HeadingNode.domWrapperElementTypes[level];
if ( type === undefined ) {
throw 'Invalid level attribute in heading node model: ' + level;
}
return $( '<' + type + '></' + type + '>' );
};
/* Methods */
/**
* Responds to model update events.
*
* If the level changed since last update the DOM wrapper will be replaced with an appropriate one.
*
* @method
*/
ve.ce.HeadingNode.prototype.onUpdate = function() {
var level = this.model.getAttribute( 'level' );
if ( level !== this.currentLevel ) {
this.currentLevel = level;
this.replaceDomWrapper( ve.ce.HeadingNode.getDomWrapper( this.model ) );
}
};
/* Registration */
ve.ce.factory.register( 'heading', ve.ce.HeadingNode );

View file

@ -9,12 +9,22 @@
ve.ce.ImageNode = function( model ) {
// Inheritance
ve.ce.LeafNode.call( this, model, $( '<img>' ) );
// Properties
this.currentSource = model.getAttribute( 'html/src' );
// Events
this.model.addListenerMethod( 'update', this, 'onUpdate' );
};
/* Static Members */
/**
* Node rules.
*
* @see ve.ce.NodeFactory
* @static
* @member
*/
ve.ce.ImageNode.rules = {
'canHaveChildren': false,
@ -22,6 +32,23 @@ ve.ce.ImageNode.rules = {
'canBeSplit': false
};
/* Methods */
/**
* Responds to model update events.
*
* If the source changed since last update the image's src attribute will be updated accordingly.
*
* @method
*/
ve.ce.ImageNode.prototype.onUpdate = function() {
var source = this.model.getAttribute( 'html/src' );
if ( source !== this.currentSource ) {
this.currentSource = source;
this.$.attr( 'src', source );
}
};
/* Registration */
ve.ce.factory.register( 'image', ve.ce.ImageNode );

View file

@ -9,12 +9,22 @@
ve.ce.ListItemNode = function( model ) {
// Inheritance
ve.ce.BranchNode.call( this, model, ve.ce.ListItemNode.getDomElement( model ) );
// Properties
this.currentStyle = model.getAttribute( 'style' );
// Events
this.model.addListenerMethod( 'update', this, 'onUpdate' );
};
/* Static Members */
/**
* Node rules.
*
* @see ve.ce.NodeFactory
* @static
* @member
*/
ve.ce.ListItemNode.rules = {
'canHaveChildren': true,
@ -22,7 +32,13 @@ ve.ce.ListItemNode.rules = {
'canBeSplit': false
};
ve.ce.ListItemNode.domNodeTypes = {
/**
* Mapping of list item style values and DOM wrapper element types.
*
* @static
* @member
*/
ve.ce.ListItemNode.domWrapperElementTypes = {
'item': 'li',
'definition': 'dd',
'term': 'dt'
@ -30,15 +46,43 @@ ve.ce.ListItemNode.domNodeTypes = {
/* Static Methods */
ve.ce.ListItemNode.getDomElement = function( model ) {
var style = model.getElementAttribute( 'style' ),
type = ve.ce.ListItemNode.domNodeTypes[style];
/**
* Gets an appropriate DOM wrapper for the model.
*
* This method is static because it is used before the node is fully constructed. Before all parent
* constructors are called this.model may not be ready to be used.
*
* @static
* @method
* @param {ve.dm.ListItemNode} model Model to create DOM wrapper for
* @returns {jQuery} Selection containing DOM wrapper
*/
ve.ce.ListItemNode.getDomWrapper = function( model ) {
var style = model.getAttribute( 'style' ),
type = ve.ce.ListItemNode.domWrapperElementTypes[style];
if ( type === undefined ) {
throw 'Invalid style attribute in list node model: ' + style;
throw 'Invalid style attribute in list item node model: ' + style;
}
return $( '<' + type + '></' + type + '>' );
};
/* Methods */
/**
* Responds to model update events.
*
* If the style changed since last update the DOM wrapper will be replaced with an appropriate one.
*
* @method
*/
ve.ce.ListItemNode.prototype.onUpdate = function() {
var style = this.model.getAttribute( 'style' );
if ( style !== this.currentStyle ) {
this.currentStyle = style;
this.replaceDomWrapper( ve.ce.ListItemNode.getDomWrapper( this.model ) );
}
};
/* Registration */
ve.ce.factory.register( 'listItem', ve.ce.ListItemNode );

View file

@ -9,12 +9,22 @@
ve.ce.ListNode = function( model ) {
// Inheritance
ve.ce.BranchNode.call( this, model, ve.ce.ListNode.getDomElement( model ) );
// Properties
this.currentStyle = model.getAttribute( 'style' );
// Events
this.model.addListenerMethod( 'update', this, 'onUpdate' );
};
/* Static Members */
/**
* Node rules.
*
* @see ve.ce.NodeFactory
* @static
* @member
*/
ve.ce.ListNode.rules = {
'canHaveChildren': true,
@ -22,7 +32,13 @@ ve.ce.ListNode.rules = {
'canBeSplit': false
};
ve.ce.ListNode.domNodeTypes = {
/**
* Mapping of list style values and DOM wrapper element types.
*
* @static
* @member
*/
ve.ce.ListNode.domWrapperElementTypes = {
'bullet': 'ul',
'number': 'ol',
'definition': 'dl'
@ -30,15 +46,43 @@ ve.ce.ListNode.domNodeTypes = {
/* Static Methods */
ve.ce.ListNode.getDomElement = function( model ) {
var style = model.getElementAttribute( 'style' ),
type = ve.ce.ListNode.domNodeTypes[style];
/**
* Gets an appropriate DOM wrapper for the model.
*
* This method is static because it is used before the node is fully constructed. Before all parent
* constructors are called this.model may not be ready to be used.
*
* @static
* @method
* @param {ve.dm.ListNode} model Model to create DOM wrapper for
* @returns {jQuery} Selection containing DOM wrapper
*/
ve.ce.ListNode.getDomWrapper = function( model ) {
var style = model.getAttribute( 'style' ),
type = ve.ce.ListNode.domWrapperElementTypes[style];
if ( type === undefined ) {
throw 'Invalid style attribute in list node model: ' + style;
}
return $( '<' + type + '></' + type + '>' );
};
/* Methods */
/**
* Responds to model update events.
*
* If the style changed since last update the DOM wrapper will be replaced with an appropriate one.
*
* @method
*/
ve.ce.ListNode.prototype.onUpdate = function() {
var style = this.model.getAttribute( 'style' );
if ( style !== this.currentStyle ) {
this.currentStyle = style;
this.replaceDomWrapper( ve.ce.ListNode.getDomWrapper( this.model ) );
}
};
/* Registration */
ve.ce.factory.register( 'list', ve.ce.ListNode );

View file

@ -14,7 +14,11 @@ ve.ce.ParagraphNode = function( model ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.ce.NodeFactory
* @static
* @member
*/
ve.ce.ParagraphNode.rules = {
'canHaveChildren': true,

View file

@ -14,7 +14,11 @@ ve.ce.PreformattedNode = function( model ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.ce.NodeFactory
* @static
* @member
*/
ve.ce.PreformattedNode.rules = {
'canHaveChildren': true,

View file

@ -14,7 +14,11 @@ ve.ce.TableCellNode = function( model ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.ce.NodeFactory
* @static
* @member
*/
ve.ce.TableCellNode.rules = {
'canHaveChildren': true,

View file

@ -14,7 +14,11 @@ ve.ce.TableNode = function( model ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.ce.NodeFactory
* @static
* @member
*/
ve.ce.TableNode.rules = {
'canHaveChildren': true,

View file

@ -14,7 +14,11 @@ ve.ce.TableRowNode = function( model ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.ce.NodeFactory
* @static
* @member
*/
ve.ce.TableRowNode.rules = {
'canHaveChildren': true,

View file

@ -14,7 +14,11 @@ ve.ce.TextNode = function( model ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.ce.NodeFactory
* @static
* @member
*/
ve.ce.TextNode.rules = {
'canHaveChildren': false,

View file

@ -23,17 +23,15 @@ ve.ce.BranchNode = function( model, $element ) {
/* Methods */
ve.ce.BranchNode.prototype.convertDomElement = function( type ) {
// Create new element
var $new = $( '<' + type + '></' + type + '>' );
ve.ce.BranchNode.prototype.replaceDomWrapper = function( $element ) {
// Copy classes
$new.attr( 'class', this.$.attr( 'class' ) );
$element.attr( 'class', this.$.attr( 'class' ) );
// Move contents
$new.append( this.$.contents() );
$element.append( this.$.contents() );
// Swap elements
this.$.replaceWith( $new );
this.$.replaceWith( $element );
// Use new element from now on
this.$ = $new;
this.$ = $element;
};
ve.ce.BranchNode.prototype.onSplice = function( index, howmany ) {

View file

@ -15,7 +15,11 @@ ve.dm.AlienNode = function( length, attributes ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.dm.NodeFactory
* @static
* @member
*/
ve.dm.AlienNode.rules = {
'canHaveChildren': false,

View file

@ -15,7 +15,11 @@ ve.dm.DocumentNode = function( children, attributes ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.dm.NodeFactory
* @static
* @member
*/
ve.dm.DocumentNode.rules = {
'canHaveChildren': true,

View file

@ -15,7 +15,11 @@ ve.dm.HeadingNode = function( children, attributes ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.dm.NodeFactory
* @static
* @member
*/
ve.dm.HeadingNode.rules = {
'canHaveChildren': true,

View file

@ -15,7 +15,11 @@ ve.dm.ImageNode = function( length, attributes ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.dm.NodeFactory
* @static
* @member
*/
ve.dm.ImageNode.rules = {
'canHaveChildren': false,

View file

@ -15,7 +15,11 @@ ve.dm.ListItemNode = function( children, attributes ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.dm.NodeFactory
* @static
* @member
*/
ve.dm.ListItemNode.rules = {
'canHaveChildren': true,

View file

@ -15,7 +15,11 @@ ve.dm.ListNode = function( children, attributes ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.dm.NodeFactory
* @static
* @member
*/
ve.dm.ListNode.rules = {
'canHaveChildren': true,

View file

@ -15,7 +15,11 @@ ve.dm.ParagraphNode = function( children, attributes ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.dm.NodeFactory
* @static
* @member
*/
ve.dm.ParagraphNode.rules = {
'canHaveChildren': true,

View file

@ -15,7 +15,11 @@ ve.dm.PreformattedNode = function( children, attributes ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.dm.NodeFactory
* @static
* @member
*/
ve.dm.PreformattedNode.rules = {
'canHaveChildren': true,

View file

@ -15,7 +15,11 @@ ve.dm.TableCellNode = function( children, attributes ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.dm.NodeFactory
* @static
* @member
*/
ve.dm.TableCellNode.rules = {
'canHaveChildren': true,

View file

@ -15,7 +15,11 @@ ve.dm.TableNode = function( children, attributes ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.dm.NodeFactory
* @static
* @member
*/
ve.dm.TableNode.rules = {
'canHaveChildren': true,

View file

@ -15,7 +15,11 @@ ve.dm.TableRowNode = function( children, attributes ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.dm.NodeFactory
* @static
* @member
*/
ve.dm.TableRowNode.rules = {
'canHaveChildren': true,

View file

@ -14,7 +14,11 @@ ve.dm.TextNode = function( length ) {
/* Static Members */
/**
* Node rules.
*
* @see ve.dm.NodeFactory
* @static
* @member
*/
ve.dm.TextNode.rules = {
'canHaveChildren': false,