diff --git a/modules/ve-mw/ce/nodes/ve.ce.MWTransclusionNode.js b/modules/ve-mw/ce/nodes/ve.ce.MWTransclusionNode.js index 75abd5ef9d..966c624963 100644 --- a/modules/ve-mw/ce/nodes/ve.ce.MWTransclusionNode.js +++ b/modules/ve-mw/ce/nodes/ve.ce.MWTransclusionNode.js @@ -11,9 +11,10 @@ * @class * @abstract * @extends ve.ce.LeafNode - * @mixins ve.ce.FocusableNode * @mixins OO.ui.mixin.IconElement * @mixins ve.ce.GeneratedContentNode + * @mixins ve.ce.FocusableNode + * @mixins ve.ce.TableCellableNode * * @constructor * @param {ve.dm.MWTransclusionNode} model Model to observe @@ -21,21 +22,23 @@ */ ve.ce.MWTransclusionNode = function VeCeMWTransclusionNode( model, config ) { // Parent constructor - ve.ce.LeafNode.call( this, model, config ); + ve.ce.MWTransclusionNode.super.call( this, model, config ); // Mixin constructors - ve.ce.FocusableNode.call( this ); OO.ui.mixin.IconElement.call( this, config ); ve.ce.GeneratedContentNode.call( this ); + ve.ce.FocusableNode.call( this ); + ve.ce.TableCellableNode.call( this ); }; /* Inheritance */ OO.inheritClass( ve.ce.MWTransclusionNode, ve.ce.LeafNode ); -OO.mixinClass( ve.ce.MWTransclusionNode, ve.ce.FocusableNode ); -OO.mixinClass( ve.ce.MWTransclusionNode, ve.ce.GeneratedContentNode ); OO.mixinClass( ve.ce.MWTransclusionNode, OO.ui.mixin.IconElement ); +OO.mixinClass( ve.ce.MWTransclusionNode, ve.ce.GeneratedContentNode ); +OO.mixinClass( ve.ce.MWTransclusionNode, ve.ce.FocusableNode ); +OO.mixinClass( ve.ce.MWTransclusionNode, ve.ce.TableCellableNode ); /* Static Properties */ @@ -205,7 +208,7 @@ ve.ce.MWTransclusionNode.prototype.onParseError = function ( deferred ) { */ ve.ce.MWTransclusionBlockNode = function VeCeMWTransclusionBlockNode( model ) { // Parent constructor - ve.ce.MWTransclusionNode.call( this, model ); + ve.ce.MWTransclusionBlockNode.super.call( this, model ); }; /* Inheritance */ @@ -228,7 +231,7 @@ ve.ce.MWTransclusionBlockNode.static.tagName = 'div'; */ ve.ce.MWTransclusionInlineNode = function VeCeMWTransclusionInlineNode( model ) { // Parent constructor - ve.ce.MWTransclusionNode.call( this, model ); + ve.ce.MWTransclusionInlineNode.super.call( this, model ); }; /* Inheritance */ diff --git a/modules/ve-mw/dm/nodes/ve.dm.MWTableNode.js b/modules/ve-mw/dm/nodes/ve.dm.MWTableNode.js index 57d5d02692..b211195198 100644 --- a/modules/ve-mw/dm/nodes/ve.dm.MWTableNode.js +++ b/modules/ve-mw/dm/nodes/ve.dm.MWTableNode.js @@ -42,6 +42,7 @@ ve.dm.MWTableNode.static.classAttributes = { // HACK: users of parentNodeTypes should be fixed to check for inherited classes. ve.dm.TableSectionNode.static.parentNodeTypes.push( 'mwTable' ); ve.dm.TableCaptionNode.static.parentNodeTypes.push( 'mwTable' ); +ve.dm.TableRowNode.static.childNodeTypes.push( 'mwTransclusionTableCell' ); ve.dm.MWTableNode.static.toDataElement = function ( domElements ) { var attributes = {}, diff --git a/modules/ve-mw/dm/nodes/ve.dm.MWTransclusionNode.js b/modules/ve-mw/dm/nodes/ve.dm.MWTransclusionNode.js index ef6ce63e13..9898aea4d6 100644 --- a/modules/ve-mw/dm/nodes/ve.dm.MWTransclusionNode.js +++ b/modules/ve-mw/dm/nodes/ve.dm.MWTransclusionNode.js @@ -13,6 +13,7 @@ * @extends ve.dm.LeafNode * @mixins ve.dm.GeneratedContentNode * @mixins ve.dm.FocusableNode + * @mixins ve.dm.TableCellableNode * * @constructor * @param {Object} [element] Reference to element in linear model @@ -24,6 +25,7 @@ ve.dm.MWTransclusionNode = function VeDmMWTransclusionNode() { // Mixin constructors ve.dm.GeneratedContentNode.call( this ); ve.dm.FocusableNode.call( this ); + ve.dm.TableCellableNode.call( this ); // Properties this.partsList = null; @@ -40,6 +42,8 @@ OO.mixinClass( ve.dm.MWTransclusionNode, ve.dm.GeneratedContentNode ); OO.mixinClass( ve.dm.MWTransclusionNode, ve.dm.FocusableNode ); +OO.mixinClass( ve.dm.MWTransclusionNode, ve.dm.TableCellableNode ); + /* Static members */ ve.dm.MWTransclusionNode.static.name = 'mwTransclusion'; @@ -67,12 +71,30 @@ ve.dm.MWTransclusionNode.static.getHashObject = function ( dataElement ) { }; }; +/** + * Node type to use when the transclusion is inline + * + * @static + * @property {string} + * @inheritable + */ +ve.dm.MWTransclusionNode.static.inlineType = 'mwTransclusionInline'; + +/** + * Node type to use when the transclusion is a block + * + * @static + * @property {string} + * @inheritable + */ +ve.dm.MWTransclusionNode.static.blockType = 'mwTransclusionBlock'; + ve.dm.MWTransclusionNode.static.toDataElement = function ( domElements, converter ) { var dataElement, index, mwDataJSON = domElements[0].getAttribute( 'data-mw' ), mwData = mwDataJSON ? JSON.parse( mwDataJSON ) : {}, isInline = this.isHybridInline( domElements, converter ), - type = isInline ? 'mwTransclusionInline' : 'mwTransclusionBlock'; + type = isInline ? this.inlineType : this.blockType; dataElement = { type: type, @@ -82,6 +104,11 @@ ve.dm.MWTransclusionNode.static.toDataElement = function ( domElements, converte } }; + if ( domElements.length === 1 && [ 'td', 'th' ].indexOf( domElements[0].nodeName.toLowerCase() ) !== -1 ) { + dataElement.attributes.cellable = true; + ve.dm.TableCellableNode.static.setAttributes( dataElement.attributes, domElements ); + } + if ( !domElements[0].getAttribute( 'data-ve-no-generated-contents' ) ) { index = this.storeGeneratedContents( dataElement, domElements, converter.getStore() ); dataElement.attributes.originalIndex = index; @@ -244,6 +271,13 @@ ve.dm.MWTransclusionNode.prototype.onAttributeChange = function ( key ) { } }; +/** + * @inheritdoc + */ +ve.dm.MWTransclusionNode.prototype.isCellable = function () { + return !!this.getAttribute( 'cellable' ); +}; + /** * Check if transclusion contains only a single template. * diff --git a/modules/ve-mw/ui/contextitems/ve.ui.MWTransclusionContextItem.js b/modules/ve-mw/ui/contextitems/ve.ui.MWTransclusionContextItem.js index b4793f8054..cb3d55f9e0 100644 --- a/modules/ve-mw/ui/contextitems/ve.ui.MWTransclusionContextItem.js +++ b/modules/ve-mw/ui/contextitems/ve.ui.MWTransclusionContextItem.js @@ -73,6 +73,21 @@ ve.ui.MWTransclusionContextItem.prototype.getDescription = function () { ); }; +/** + * @inheritdoc + */ +ve.ui.MWTransclusionContextItem.prototype.onEditButtonClick = function () { + var surfaceModel = this.context.getSurface().getModel(), + selection = surfaceModel.getSelection(); + + if ( selection instanceof ve.dm.TableSelection ) { + surfaceModel.setLinearSelection( selection.getOuterRanges()[0] ); + } + + // Parent method + ve.ui.MWTransclusionContextItem.super.prototype.onEditButtonClick.apply( this, arguments ); +}; + /* Registration */ ve.ui.contextItemFactory.register( ve.ui.MWTransclusionContextItem );