2013-03-01 01:17:02 +00:00
|
|
|
/*!
|
|
|
|
* VisualEditor DataModel MWHeadingNode class.
|
|
|
|
*
|
2018-01-03 00:54:47 +00:00
|
|
|
* @copyright 2011-2018 VisualEditor Team and others; see AUTHORS.txt
|
2013-03-01 01:17:02 +00:00
|
|
|
* @license The MIT License (MIT); see LICENSE.txt
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2013-04-17 17:53:26 +00:00
|
|
|
* DataModel MediaWiki heading node.
|
2013-03-01 01:17:02 +00:00
|
|
|
*
|
|
|
|
* @class
|
|
|
|
* @extends ve.dm.HeadingNode
|
2014-06-07 03:17:26 +00:00
|
|
|
*
|
2013-03-01 01:17:02 +00:00
|
|
|
* @constructor
|
|
|
|
* @param {Object} [element] Reference to element in linear model
|
2014-06-07 03:17:26 +00:00
|
|
|
* @param {ve.dm.Node[]} [children]
|
2013-03-01 01:17:02 +00:00
|
|
|
*/
|
2014-06-07 03:17:26 +00:00
|
|
|
ve.dm.MWHeadingNode = function VeDmMWHeadingNode() {
|
2013-03-01 01:17:02 +00:00
|
|
|
// Parent constructor
|
2016-07-06 14:16:00 +00:00
|
|
|
ve.dm.MWHeadingNode.super.apply( this, arguments );
|
2013-03-01 01:17:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Inheritance */
|
|
|
|
|
2013-10-11 21:44:09 +00:00
|
|
|
OO.inheritClass( ve.dm.MWHeadingNode, ve.dm.HeadingNode );
|
2013-03-01 01:17:02 +00:00
|
|
|
|
|
|
|
/* Static Properties */
|
|
|
|
|
2013-05-28 11:31:41 +00:00
|
|
|
ve.dm.MWHeadingNode.static.name = 'mwHeading';
|
2013-03-01 01:17:02 +00:00
|
|
|
|
2017-03-01 23:11:54 +00:00
|
|
|
// Headings in wikitext only work in some contexts, they're impossible e.g. in list items
|
2017-05-04 11:43:36 +00:00
|
|
|
ve.dm.MWHeadingNode.static.suggestedParentNodeTypes = [ 'document', 'tableCell', 'div' ];
|
2013-03-01 01:17:02 +00:00
|
|
|
|
2015-08-03 22:48:42 +00:00
|
|
|
ve.dm.MWHeadingNode.static.handlesOwnChildren = true;
|
|
|
|
|
|
|
|
ve.dm.MWHeadingNode.static.toDataElement = function ( domElements, converter ) {
|
2015-08-19 17:33:02 +00:00
|
|
|
var shouldConvert = this.shouldConvertToParagraph( domElements[ 0 ] ),
|
2015-08-03 22:48:42 +00:00
|
|
|
parentResult = ve.dm.MWHeadingNode.super.static.toDataElement.apply( this, arguments );
|
|
|
|
parentResult.type = this.name;
|
|
|
|
if ( shouldConvert ) {
|
|
|
|
ve.setProp( parentResult, 'attributes', 'noconvert', true );
|
|
|
|
}
|
|
|
|
return converter.getDataFromDomSubtree(
|
2015-08-19 17:33:02 +00:00
|
|
|
domElements[ 0 ],
|
2015-08-03 22:48:42 +00:00
|
|
|
parentResult,
|
|
|
|
new ve.dm.AnnotationSet( converter.getStore() )
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
ve.dm.MWHeadingNode.static.toDomElements = function ( dataElements, doc, converter ) {
|
|
|
|
var paragraph,
|
2015-08-19 17:33:02 +00:00
|
|
|
parentResult = ve.dm.MWHeadingNode.super.static.toDomElements.call( this, dataElements[ 0 ], doc, converter );
|
|
|
|
converter.getDomSubtreeFromData( dataElements.slice( 1, -1 ), parentResult[ 0 ] );
|
2015-08-03 22:48:42 +00:00
|
|
|
|
|
|
|
if (
|
2015-08-19 17:33:02 +00:00
|
|
|
( !dataElements[ 0 ].attributes || !dataElements[ 0 ].attributes.noconvert ) &&
|
|
|
|
this.shouldConvertToParagraph( parentResult[ 0 ] )
|
2015-08-03 22:48:42 +00:00
|
|
|
) {
|
|
|
|
// Change parentResult[0] to a paragraph
|
|
|
|
paragraph = doc.createElement( 'p' );
|
2015-08-19 17:33:02 +00:00
|
|
|
while ( parentResult[ 0 ].firstChild ) {
|
|
|
|
paragraph.appendChild( parentResult[ 0 ].firstChild );
|
2015-08-03 22:48:42 +00:00
|
|
|
}
|
2015-08-19 17:33:02 +00:00
|
|
|
parentResult[ 0 ] = paragraph;
|
2015-08-03 22:48:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return parentResult;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Determine whether a heading should be converted to a paragraph.
|
|
|
|
*
|
|
|
|
* This function is called by toDomElements to determine whether the heading should be
|
|
|
|
* converted to a paragraph, and also by toDataElement to determine whether the heading
|
|
|
|
* already met the conversion criteria coming in (in which case it won't be converted).
|
|
|
|
*
|
|
|
|
* This implementation returns true if the heading does not contain a non-whitespace character,
|
|
|
|
* but subclasses may override this to add their own logic.
|
|
|
|
*
|
|
|
|
* @param {HTMLElement} headingElement Heading DOM element
|
|
|
|
* @return {boolean} Whether the heading should be converted to a paragraph
|
|
|
|
*/
|
|
|
|
ve.dm.MWHeadingNode.static.shouldConvertToParagraph = function ( headingElement ) {
|
|
|
|
function containsNonWhitespace( el ) {
|
|
|
|
var i, len, childNode;
|
|
|
|
for ( i = 0, len = el.childNodes.length; i < len; i++ ) {
|
2015-08-19 17:33:02 +00:00
|
|
|
childNode = el.childNodes[ i ];
|
2015-08-03 22:48:42 +00:00
|
|
|
if (
|
|
|
|
childNode.nodeType === Node.TEXT_NODE &&
|
|
|
|
childNode.data.match( /\S/ )
|
|
|
|
) {
|
|
|
|
// Text node with a non-whitespace character
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if ( childNode.nodeType === Node.ELEMENT_NODE && containsNonWhitespace( childNode ) ) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return !containsNonWhitespace( headingElement );
|
|
|
|
};
|
|
|
|
|
2013-03-01 01:17:02 +00:00
|
|
|
/* Registration */
|
|
|
|
|
|
|
|
ve.dm.modelRegistry.register( ve.dm.MWHeadingNode );
|