Esanders has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/154439

Change subject: Basic block image (figure/figcaption) support
......................................................................

Basic block image (figure/figcaption) support

Change-Id: Iddb3a5f57fd0ab965db00c2b148ab4f5e89b923d
---
M .docs/eg-iframe.html
M build/modules.json
M demos/ve/desktop.html
M demos/ve/mobile.html
M demos/ve/pages/image.html
A src/ce/nodes/ve.ce.BlockImageNode.js
A src/ce/nodes/ve.ce.ImageCaptionNode.js
A src/dm/nodes/ve.dm.BlockImageNode.js
A src/dm/nodes/ve.dm.ImageCaptionNode.js
M tests/index.html
10 files changed, 353 insertions(+), 11 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/VisualEditor/VisualEditor 
refs/changes/39/154439/1

diff --git a/.docs/eg-iframe.html b/.docs/eg-iframe.html
index c819aba..79240b0 100644
--- a/.docs/eg-iframe.html
+++ b/.docs/eg-iframe.html
@@ -162,7 +162,6 @@
                <script src="../src/dm/nodes/ve.dm.DivNode.js"></script>
                <script src="../src/dm/nodes/ve.dm.DocumentNode.js"></script>
                <script src="../src/dm/nodes/ve.dm.HeadingNode.js"></script>
-               <script src="../src/dm/nodes/ve.dm.InlineImageNode.js"></script>
                <script 
src="../src/dm/nodes/ve.dm.InternalItemNode.js"></script>
                <script 
src="../src/dm/nodes/ve.dm.InternalListNode.js"></script>
                <script src="../src/dm/nodes/ve.dm.ListItemNode.js"></script>
@@ -175,6 +174,9 @@
                <script src="../src/dm/nodes/ve.dm.TableRowNode.js"></script>
                <script 
src="../src/dm/nodes/ve.dm.TableSectionNode.js"></script>
                <script src="../src/dm/nodes/ve.dm.TextNode.js"></script>
+               <script 
src="../src/dm/nodes/ve.dm.ImageCaptionNode.js"></script>
+               <script src="../src/dm/nodes/ve.dm.BlockImageNode.js"></script>
+               <script src="../src/dm/nodes/ve.dm.InlineImageNode.js"></script>
                <script 
src="../src/dm/annotations/ve.dm.LanguageAnnotation.js"></script>
                <script 
src="../src/dm/annotations/ve.dm.LinkAnnotation.js"></script>
                <script 
src="../src/dm/annotations/ve.dm.TextStyleAnnotation.js"></script>
@@ -224,7 +226,6 @@
                <script src="../src/ce/nodes/ve.ce.DivNode.js"></script>
                <script src="../src/ce/nodes/ve.ce.DocumentNode.js"></script>
                <script src="../src/ce/nodes/ve.ce.HeadingNode.js"></script>
-               <script src="../src/ce/nodes/ve.ce.InlineImageNode.js"></script>
                <script 
src="../src/ce/nodes/ve.ce.InternalItemNode.js"></script>
                <script 
src="../src/ce/nodes/ve.ce.InternalListNode.js"></script>
                <script src="../src/ce/nodes/ve.ce.ListItemNode.js"></script>
@@ -237,6 +238,9 @@
                <script src="../src/ce/nodes/ve.ce.TableRowNode.js"></script>
                <script 
src="../src/ce/nodes/ve.ce.TableSectionNode.js"></script>
                <script src="../src/ce/nodes/ve.ce.TextNode.js"></script>
+               <script 
src="../src/ce/nodes/ve.ce.ImageCaptionNode.js"></script>
+               <script src="../src/ce/nodes/ve.ce.BlockImageNode.js"></script>
+               <script src="../src/ce/nodes/ve.ce.InlineImageNode.js"></script>
                <script 
src="../src/ce/annotations/ve.ce.LanguageAnnotation.js"></script>
                <script 
src="../src/ce/annotations/ve.ce.LinkAnnotation.js"></script>
                <script 
src="../src/ce/annotations/ve.ce.TextStyleAnnotation.js"></script>
diff --git a/build/modules.json b/build/modules.json
index 31415d5..83aa2e9 100644
--- a/build/modules.json
+++ b/build/modules.json
@@ -184,7 +184,6 @@
                        "src/dm/nodes/ve.dm.DivNode.js",
                        "src/dm/nodes/ve.dm.DocumentNode.js",
                        "src/dm/nodes/ve.dm.HeadingNode.js",
-                       "src/dm/nodes/ve.dm.InlineImageNode.js",
                        "src/dm/nodes/ve.dm.InternalItemNode.js",
                        "src/dm/nodes/ve.dm.InternalListNode.js",
                        "src/dm/nodes/ve.dm.ListItemNode.js",
@@ -197,6 +196,9 @@
                        "src/dm/nodes/ve.dm.TableRowNode.js",
                        "src/dm/nodes/ve.dm.TableSectionNode.js",
                        "src/dm/nodes/ve.dm.TextNode.js",
+                       "src/dm/nodes/ve.dm.ImageCaptionNode.js",
+                       "src/dm/nodes/ve.dm.BlockImageNode.js",
+                       "src/dm/nodes/ve.dm.InlineImageNode.js",
                        "src/dm/annotations/ve.dm.LanguageAnnotation.js",
                        "src/dm/annotations/ve.dm.LinkAnnotation.js",
                        "src/dm/annotations/ve.dm.TextStyleAnnotation.js",
@@ -246,7 +248,6 @@
                        "src/ce/nodes/ve.ce.DivNode.js",
                        "src/ce/nodes/ve.ce.DocumentNode.js",
                        "src/ce/nodes/ve.ce.HeadingNode.js",
-                       "src/ce/nodes/ve.ce.InlineImageNode.js",
                        "src/ce/nodes/ve.ce.InternalItemNode.js",
                        "src/ce/nodes/ve.ce.InternalListNode.js",
                        "src/ce/nodes/ve.ce.ListItemNode.js",
@@ -259,6 +260,9 @@
                        "src/ce/nodes/ve.ce.TableRowNode.js",
                        "src/ce/nodes/ve.ce.TableSectionNode.js",
                        "src/ce/nodes/ve.ce.TextNode.js",
+                       "src/ce/nodes/ve.ce.ImageCaptionNode.js",
+                       "src/ce/nodes/ve.ce.BlockImageNode.js",
+                       "src/ce/nodes/ve.ce.InlineImageNode.js",
                        "src/ce/annotations/ve.ce.LanguageAnnotation.js",
                        "src/ce/annotations/ve.ce.LinkAnnotation.js",
                        "src/ce/annotations/ve.ce.TextStyleAnnotation.js",
diff --git a/demos/ve/desktop.html b/demos/ve/desktop.html
index 409162d..cb38cb7 100644
--- a/demos/ve/desktop.html
+++ b/demos/ve/desktop.html
@@ -174,7 +174,6 @@
                <script src="../../src/dm/nodes/ve.dm.DivNode.js"></script>
                <script src="../../src/dm/nodes/ve.dm.DocumentNode.js"></script>
                <script src="../../src/dm/nodes/ve.dm.HeadingNode.js"></script>
-               <script 
src="../../src/dm/nodes/ve.dm.InlineImageNode.js"></script>
                <script 
src="../../src/dm/nodes/ve.dm.InternalItemNode.js"></script>
                <script 
src="../../src/dm/nodes/ve.dm.InternalListNode.js"></script>
                <script src="../../src/dm/nodes/ve.dm.ListItemNode.js"></script>
@@ -187,6 +186,9 @@
                <script src="../../src/dm/nodes/ve.dm.TableRowNode.js"></script>
                <script 
src="../../src/dm/nodes/ve.dm.TableSectionNode.js"></script>
                <script src="../../src/dm/nodes/ve.dm.TextNode.js"></script>
+               <script 
src="../../src/dm/nodes/ve.dm.ImageCaptionNode.js"></script>
+               <script 
src="../../src/dm/nodes/ve.dm.BlockImageNode.js"></script>
+               <script 
src="../../src/dm/nodes/ve.dm.InlineImageNode.js"></script>
                <script 
src="../../src/dm/annotations/ve.dm.LanguageAnnotation.js"></script>
                <script 
src="../../src/dm/annotations/ve.dm.LinkAnnotation.js"></script>
                <script 
src="../../src/dm/annotations/ve.dm.TextStyleAnnotation.js"></script>
@@ -236,7 +238,6 @@
                <script src="../../src/ce/nodes/ve.ce.DivNode.js"></script>
                <script src="../../src/ce/nodes/ve.ce.DocumentNode.js"></script>
                <script src="../../src/ce/nodes/ve.ce.HeadingNode.js"></script>
-               <script 
src="../../src/ce/nodes/ve.ce.InlineImageNode.js"></script>
                <script 
src="../../src/ce/nodes/ve.ce.InternalItemNode.js"></script>
                <script 
src="../../src/ce/nodes/ve.ce.InternalListNode.js"></script>
                <script src="../../src/ce/nodes/ve.ce.ListItemNode.js"></script>
@@ -249,6 +250,9 @@
                <script src="../../src/ce/nodes/ve.ce.TableRowNode.js"></script>
                <script 
src="../../src/ce/nodes/ve.ce.TableSectionNode.js"></script>
                <script src="../../src/ce/nodes/ve.ce.TextNode.js"></script>
+               <script 
src="../../src/ce/nodes/ve.ce.ImageCaptionNode.js"></script>
+               <script 
src="../../src/ce/nodes/ve.ce.BlockImageNode.js"></script>
+               <script 
src="../../src/ce/nodes/ve.ce.InlineImageNode.js"></script>
                <script 
src="../../src/ce/annotations/ve.ce.LanguageAnnotation.js"></script>
                <script 
src="../../src/ce/annotations/ve.ce.LinkAnnotation.js"></script>
                <script 
src="../../src/ce/annotations/ve.ce.TextStyleAnnotation.js"></script>
diff --git a/demos/ve/mobile.html b/demos/ve/mobile.html
index dda4efe..4480c31 100644
--- a/demos/ve/mobile.html
+++ b/demos/ve/mobile.html
@@ -175,7 +175,6 @@
                <script src="../../src/dm/nodes/ve.dm.DivNode.js"></script>
                <script src="../../src/dm/nodes/ve.dm.DocumentNode.js"></script>
                <script src="../../src/dm/nodes/ve.dm.HeadingNode.js"></script>
-               <script 
src="../../src/dm/nodes/ve.dm.InlineImageNode.js"></script>
                <script 
src="../../src/dm/nodes/ve.dm.InternalItemNode.js"></script>
                <script 
src="../../src/dm/nodes/ve.dm.InternalListNode.js"></script>
                <script src="../../src/dm/nodes/ve.dm.ListItemNode.js"></script>
@@ -188,6 +187,9 @@
                <script src="../../src/dm/nodes/ve.dm.TableRowNode.js"></script>
                <script 
src="../../src/dm/nodes/ve.dm.TableSectionNode.js"></script>
                <script src="../../src/dm/nodes/ve.dm.TextNode.js"></script>
+               <script 
src="../../src/dm/nodes/ve.dm.ImageCaptionNode.js"></script>
+               <script 
src="../../src/dm/nodes/ve.dm.BlockImageNode.js"></script>
+               <script 
src="../../src/dm/nodes/ve.dm.InlineImageNode.js"></script>
                <script 
src="../../src/dm/annotations/ve.dm.LanguageAnnotation.js"></script>
                <script 
src="../../src/dm/annotations/ve.dm.LinkAnnotation.js"></script>
                <script 
src="../../src/dm/annotations/ve.dm.TextStyleAnnotation.js"></script>
@@ -237,7 +239,6 @@
                <script src="../../src/ce/nodes/ve.ce.DivNode.js"></script>
                <script src="../../src/ce/nodes/ve.ce.DocumentNode.js"></script>
                <script src="../../src/ce/nodes/ve.ce.HeadingNode.js"></script>
-               <script 
src="../../src/ce/nodes/ve.ce.InlineImageNode.js"></script>
                <script 
src="../../src/ce/nodes/ve.ce.InternalItemNode.js"></script>
                <script 
src="../../src/ce/nodes/ve.ce.InternalListNode.js"></script>
                <script src="../../src/ce/nodes/ve.ce.ListItemNode.js"></script>
@@ -250,6 +251,9 @@
                <script src="../../src/ce/nodes/ve.ce.TableRowNode.js"></script>
                <script 
src="../../src/ce/nodes/ve.ce.TableSectionNode.js"></script>
                <script src="../../src/ce/nodes/ve.ce.TextNode.js"></script>
+               <script 
src="../../src/ce/nodes/ve.ce.ImageCaptionNode.js"></script>
+               <script 
src="../../src/ce/nodes/ve.ce.BlockImageNode.js"></script>
+               <script 
src="../../src/ce/nodes/ve.ce.InlineImageNode.js"></script>
                <script 
src="../../src/ce/annotations/ve.ce.LanguageAnnotation.js"></script>
                <script 
src="../../src/ce/annotations/ve.ce.LinkAnnotation.js"></script>
                <script 
src="../../src/ce/annotations/ve.ce.TextStyleAnnotation.js"></script>
diff --git a/demos/ve/pages/image.html b/demos/ve/pages/image.html
index 860cf9c..3d363b8 100644
--- a/demos/ve/pages/image.html
+++ b/demos/ve/pages/image.html
@@ -1,4 +1,8 @@
-<p>This is a local image: <img alt="VisualEditor logo" 
src="VisualEditor-logo.svg" width="320" height="112">foo</p>
+<figure style="float: right;">
+       <img alt="VisualEditor logo" src="VisualEditor-logo.svg" width="160" 
height="56">
+       <figcaption>Block image with <i>caption</i></figcaption>
+</figure>
+<p>This is a local image: <img alt="VisualEditor logo" 
src="VisualEditor-logo.svg" width="160" height="56">foo</p>
 <p>Remote image outside of paragraph:</p>
 <img alt="Wikipedia Logo" 
src="//upload.wikimedia.org/wikipedia/commons/b/b3/Wikipedia-logo-v2-en.svg" 
width="135" height="155">
 <p>Image without dimensions attributes: <img 
src="//upload.wikimedia.org/wikipedia/commons/0/03/Dialog-information.svg" 
alt="Lightbulb"></p>
\ No newline at end of file
diff --git a/src/ce/nodes/ve.ce.BlockImageNode.js 
b/src/ce/nodes/ve.ce.BlockImageNode.js
new file mode 100644
index 0000000..6d17cbd
--- /dev/null
+++ b/src/ce/nodes/ve.ce.BlockImageNode.js
@@ -0,0 +1,101 @@
+/*!
+ * VisualEditor ContentEditable ImageNode class.
+ *
+ * @copyright 2011-2014 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+/**
+ * ContentEditable block image node.
+ *
+ * @class
+ * @extends ve.ce.BranchNode
+ * @mixins ve.ce.FocusableNode
+ * @mixins ve.ce.ResizableNode
+ *
+ * @constructor
+ * @param {ve.dm.BlockImageNode} model Model to observe
+ * @param {Object} [config] Configuration options
+ */
+ve.ce.BlockImageNode = function VeCeImageNode( model, config ) {
+       config = ve.extendObject( {
+               minDimensions: { width: 1, height: 1 }
+       }, config );
+
+       // Parent constructor
+       ve.ce.BranchNode.call( this, model, config );
+
+       // Build DOM
+       this.$image = this.$( '<img>' )
+               .attr( 'src', this.getResolvedAttribute( 'src' ) )
+               .prependTo( this.$element );
+
+       // Mixin constructors
+       ve.ce.FocusableNode.call( this );
+       ve.ce.ResizableNode.call( this, this.$image, config );
+
+       // Events
+       this.$image.on( 'load', ve.bind( this.onLoad, this ) );
+       this.model.connect( this, { attributeChange: 'onAttributeChange' } );
+
+       // Initialization
+       this.$element.addClass( 've-ce-imageNode' );
+       this.$image
+               .attr( {
+                       alt: this.model.getAttribute( 'alt' ),
+                       src: this.getResolvedAttribute( 'src' )
+               } )
+               .css( {
+                       width: this.model.getAttribute( 'width' ),
+                       height: this.model.getAttribute( 'height' )
+               } );
+};
+
+/* Inheritance */
+
+OO.inheritClass( ve.ce.BlockImageNode, ve.ce.BranchNode );
+
+OO.mixinClass( ve.ce.BlockImageNode, ve.ce.FocusableNode );
+OO.mixinClass( ve.ce.BlockImageNode, ve.ce.ResizableNode );
+
+/* Static Properties */
+
+ve.ce.BlockImageNode.static.name = 'blockImage';
+
+ve.ce.BlockImageNode.static.tagName = 'figure';
+
+/* Methods */
+
+/**
+ * Update the rendering of the 'src', 'width' and 'height' attributes when 
they change in the model.
+ *
+ * @method
+ * @param {string} key Attribute key
+ * @param {string} from Old value
+ * @param {string} to New value
+ */
+ve.ce.BlockImageNode.prototype.onAttributeChange = function ( key, from, to ) {
+       if ( key === 'src' ) {
+               this.$image.attr( 'src', this.getResolvedAttribute( 'src' ) );
+       }
+       if ( key === 'width' || key === 'height' ) {
+               this.$image.css( key, to !== null ? to : '' );
+       }
+};
+
+/**
+ * Handle the image load
+ *
+ * @method
+ * @param {jQuery.Event} e Load event
+ */
+ve.ce.BlockImageNode.prototype.onLoad = function () {
+       this.setOriginalDimensions( {
+               width: this.$image.prop( 'naturalWidth' ),
+               height: this.$image.prop( 'naturalHeight' )
+       } );
+};
+
+/* Registration */
+
+ve.ce.nodeFactory.register( ve.ce.BlockImageNode );
diff --git a/src/ce/nodes/ve.ce.ImageCaptionNode.js 
b/src/ce/nodes/ve.ce.ImageCaptionNode.js
new file mode 100644
index 0000000..9c82517
--- /dev/null
+++ b/src/ce/nodes/ve.ce.ImageCaptionNode.js
@@ -0,0 +1,34 @@
+/*!
+ * VisualEditor ContentEditable ListItemNode class.
+ *
+ * @copyright 2011-2014 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+/**
+ * ContentEditable image caption item node.
+ *
+ * @class
+ * @extends ve.ce.BranchNode
+ * @constructor
+ * @param {ve.dm.ImageCaptionNode} model Model to observe
+ * @param {Object} [config] Configuration options
+ */
+ve.ce.ImageCaptionNode = function VeCeImageCaptionNode( model, config ) {
+       // Parent constructor
+       ve.ce.BranchNode.call( this, model, config );
+};
+
+/* Inheritance */
+
+OO.inheritClass( ve.ce.ImageCaptionNode, ve.ce.BranchNode );
+
+/* Static Properties */
+
+ve.ce.ImageCaptionNode.static.name = 'imageCaption';
+
+ve.ce.ImageCaptionNode.static.tagName = 'figcaption';
+
+/* Registration */
+
+ve.ce.nodeFactory.register( ve.ce.ImageCaptionNode );
diff --git a/src/dm/nodes/ve.dm.BlockImageNode.js 
b/src/dm/nodes/ve.dm.BlockImageNode.js
new file mode 100644
index 0000000..ce633be
--- /dev/null
+++ b/src/dm/nodes/ve.dm.BlockImageNode.js
@@ -0,0 +1,146 @@
+/*!
+ * VisualEditor DataModel BlockImageNode class.
+ *
+ * @copyright 2011-2014 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+/**
+ * DataModel block image node.
+ *
+ * @class
+ * @extends ve.dm.BranchNode
+ * @mixins ve.dm.ResizableNode
+ *
+ * @constructor
+ * @param {Object} [element] Reference to element in linear model
+ * @param {ve.dm.Node[]} [children]
+ */
+ve.dm.BlockImageNode = function VeDmBlockImageNode() {
+       // Parent constructor
+       ve.dm.BranchNode.apply( this, arguments );
+
+       // Mixin constructor
+       ve.dm.ResizableNode.call( this );
+};
+
+/* Inheritance */
+
+OO.inheritClass( ve.dm.BlockImageNode, ve.dm.BranchNode );
+
+OO.mixinClass( ve.dm.BlockImageNode, ve.dm.ResizableNode );
+
+/* Static Properties */
+
+ve.dm.BlockImageNode.static.name = 'blockImage';
+
+ve.dm.BlockImageNode.static.storeHtmlAttributes = {
+       'blacklist': [ 'typeof', 'class', 'src', 'resource', 'width', 'height', 
'href', 'rel' ]
+};
+
+ve.dm.BlockImageNode.static.handlesOwnChildren = true;
+
+ve.dm.BlockImageNode.static.childNodeTypes = [ 'imageCaption' ];
+
+ve.dm.BlockImageNode.static.matchTagNames = [ 'figure' ];
+
+//ve.dm.BlockImageNode.static.blacklistedAnnotationTypes = [ 'link' ];
+
+ve.dm.BlockImageNode.static.toDataElement = function ( domElements, converter 
) {
+       var dataElement,
+               $figure = $( domElements[0] ),
+               $img = $figure.children( 'img' ).eq( 0 ),
+               $caption = $figure.children( 'figcaption' ).eq( 0 ),
+               attributes = {
+                       src: $img.attr( 'src' )
+               },
+               width = $img.attr( 'width' ),
+               height = $img.attr( 'height' ),
+               altText = $img.attr( 'alt' );
+
+       if ( altText !== undefined ) {
+               attributes.alt = altText;
+       }
+
+       attributes.width = width !== undefined && width !== '' ? Number( width 
) : null;
+       attributes.height = height !== undefined && height !== '' ? Number( 
height ) : null;
+
+       dataElement = { 'type': this.name, 'attributes': attributes };
+
+       if ( $caption.length === 0 ) {
+               return [
+                       dataElement,
+                       { 'type': 'imageCaption' },
+                       { 'type': 'imageCaption' },
+                       { 'type': '/' + this.name }
+               ];
+       } else {
+               return [ dataElement ].
+                       concat( converter.getDataFromDomClean( $caption[0], { 
'type': 'imageCaption' } ) ).
+                       concat( [ { 'type': '/' + this.name } ] );
+       }
+};
+
+// TODO: Consider using jQuery instead of pure JS.
+// TODO: At this moment node is not resizable but when it will be then adding 
defaultSize class
+// should be more conditional.
+ve.dm.BlockImageNode.static.toDomElements = function ( data, doc, converter ) {
+       var dataElement = data[0],
+               width = dataElement.attributes.width,
+               height = dataElement.attributes.height,
+               figure = doc.createElement( 'figure' ),
+               img = doc.createElement( 'img' ),
+               wrapper = doc.createElement( 'div' ),
+               captionData = data.slice( 1, -1 );
+
+       img.setAttribute( 'src', dataElement.attributes.src );
+       img.setAttribute( 'width', width );
+       img.setAttribute( 'height', height );
+       if ( dataElement.attributes.alt !== undefined ) {
+               img.setAttribute( 'alt', dataElement.attributes.alt );
+       }
+       figure.appendChild( img );
+
+       // If length of captionData is smaller or equal to 2 it means that 
there is no caption or that
+       // it is empty - in both cases we are going to skip appending 
<figcaption>.
+       if ( captionData.length > 2 ) {
+               converter.getDomSubtreeFromData( data.slice( 1, -1 ), wrapper );
+               while ( wrapper.firstChild ) {
+                       figure.appendChild( wrapper.firstChild );
+               }
+       }
+       return [ figure ];
+};
+
+/* Methods */
+
+/**
+ * Get the caption node of the image.
+ *
+ * @method
+ * @returns {ve.dm.ImageCaptionNode|null} Caption node, if present
+ */
+ve.dm.BlockImageNode.prototype.getCaptionNode = function () {
+       var node = this.children[0];
+       return node instanceof ve.dm.ImageCaptionNode ? node : null;
+};
+
+/**
+ * @inheritdoc
+ */
+ve.dm.BlockImageNode.prototype.createScalable = function () {
+       return new ve.dm.Scalable( {
+               currentDimensions: {
+                       width: this.getAttribute( 'width' ),
+                       height: this.getAttribute( 'height' )
+               },
+               minDimensions: {
+                       width: 1,
+                       height: 1
+               }
+       } );
+};
+
+/* Registration */
+
+ve.dm.modelRegistry.register( ve.dm.BlockImageNode );
diff --git a/src/dm/nodes/ve.dm.ImageCaptionNode.js 
b/src/dm/nodes/ve.dm.ImageCaptionNode.js
new file mode 100644
index 0000000..9772dae
--- /dev/null
+++ b/src/dm/nodes/ve.dm.ImageCaptionNode.js
@@ -0,0 +1,37 @@
+/*!
+ * VisualEditor DataModel ImageCaptionNode class.
+ *
+ * @copyright 2011-2014 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+/**
+ * DataModel image caption node.
+ *
+ * @class
+ * @extends ve.dm.BranchNode
+ *
+ * @constructor
+ * @param {Object} [element] Reference to element in linear model
+ * @param {ve.dm.Node[]} [children]
+ */
+ve.dm.ImageCaptionNode = function VeDmImageCaptionNode() {
+       // Parent constructor
+       ve.dm.BranchNode.apply( this, arguments );
+};
+
+OO.inheritClass( ve.dm.ImageCaptionNode, ve.dm.BranchNode );
+
+ve.dm.ImageCaptionNode.static.name = 'imageCaption';
+
+ve.dm.ImageCaptionNode.static.matchTagNames = [];
+
+ve.dm.ImageCaptionNode.static.parentNodeTypes = [ 'blockImage' ];
+
+ve.dm.ImageCaptionNode.static.toDomElements = function ( dataElement, doc ) {
+       return [ doc.createElement( 'figcaption' ) ];
+};
+
+/* Registration */
+
+ve.dm.modelRegistry.register( ve.dm.ImageCaptionNode );
diff --git a/tests/index.html b/tests/index.html
index c2a0152..24bd13d 100644
--- a/tests/index.html
+++ b/tests/index.html
@@ -123,7 +123,6 @@
                <script src="../src/dm/nodes/ve.dm.DivNode.js"></script>
                <script src="../src/dm/nodes/ve.dm.DocumentNode.js"></script>
                <script src="../src/dm/nodes/ve.dm.HeadingNode.js"></script>
-               <script src="../src/dm/nodes/ve.dm.InlineImageNode.js"></script>
                <script 
src="../src/dm/nodes/ve.dm.InternalItemNode.js"></script>
                <script 
src="../src/dm/nodes/ve.dm.InternalListNode.js"></script>
                <script src="../src/dm/nodes/ve.dm.ListItemNode.js"></script>
@@ -136,6 +135,9 @@
                <script src="../src/dm/nodes/ve.dm.TableRowNode.js"></script>
                <script 
src="../src/dm/nodes/ve.dm.TableSectionNode.js"></script>
                <script src="../src/dm/nodes/ve.dm.TextNode.js"></script>
+               <script 
src="../src/dm/nodes/ve.dm.ImageCaptionNode.js"></script>
+               <script src="../src/dm/nodes/ve.dm.BlockImageNode.js"></script>
+               <script src="../src/dm/nodes/ve.dm.InlineImageNode.js"></script>
                <script 
src="../src/dm/annotations/ve.dm.LanguageAnnotation.js"></script>
                <script 
src="../src/dm/annotations/ve.dm.LinkAnnotation.js"></script>
                <script 
src="../src/dm/annotations/ve.dm.TextStyleAnnotation.js"></script>
@@ -185,7 +187,6 @@
                <script src="../src/ce/nodes/ve.ce.DivNode.js"></script>
                <script src="../src/ce/nodes/ve.ce.DocumentNode.js"></script>
                <script src="../src/ce/nodes/ve.ce.HeadingNode.js"></script>
-               <script src="../src/ce/nodes/ve.ce.InlineImageNode.js"></script>
                <script 
src="../src/ce/nodes/ve.ce.InternalItemNode.js"></script>
                <script 
src="../src/ce/nodes/ve.ce.InternalListNode.js"></script>
                <script src="../src/ce/nodes/ve.ce.ListItemNode.js"></script>
@@ -198,6 +199,9 @@
                <script src="../src/ce/nodes/ve.ce.TableRowNode.js"></script>
                <script 
src="../src/ce/nodes/ve.ce.TableSectionNode.js"></script>
                <script src="../src/ce/nodes/ve.ce.TextNode.js"></script>
+               <script 
src="../src/ce/nodes/ve.ce.ImageCaptionNode.js"></script>
+               <script src="../src/ce/nodes/ve.ce.BlockImageNode.js"></script>
+               <script src="../src/ce/nodes/ve.ce.InlineImageNode.js"></script>
                <script 
src="../src/ce/annotations/ve.ce.LanguageAnnotation.js"></script>
                <script 
src="../src/ce/annotations/ve.ce.LinkAnnotation.js"></script>
                <script 
src="../src/ce/annotations/ve.ce.TextStyleAnnotation.js"></script>

-- 
To view, visit https://gerrit.wikimedia.org/r/154439
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iddb3a5f57fd0ab965db00c2b148ab4f5e89b923d
Gerrit-PatchSet: 1
Gerrit-Project: VisualEditor/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Esanders <esand...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to