mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-27 15:50:29 +00:00
Added getHtmlElementFromDataElement and getDataElementFromHtmlElement
Change-Id: Ie5f4fd86612b5a6c34b5843d1e9a521edc626a63
This commit is contained in:
parent
d378182bff
commit
5d20f45120
|
@ -37,12 +37,18 @@ ve.dm.DefinitionListItemNode.rules = {
|
|||
* @member
|
||||
*/
|
||||
ve.dm.DefinitionListItemNode.converters = {
|
||||
'tags': 'dl',
|
||||
'tags': ['dt', 'dd'],
|
||||
'toHtml': function( type, element ) {
|
||||
return ve.dm.createHtmlElement( 'dl' );
|
||||
return element.attributes && ( {
|
||||
'term': ve.dm.createHtmlElement( 'dt' ),
|
||||
'definition': ve.dm.createHtmlElement( 'dd' )
|
||||
} )[element.attributes['style']];
|
||||
},
|
||||
'toData': function( tag, element ) {
|
||||
return { 'type': 'definitionList' };
|
||||
return ( {
|
||||
'dt': { 'type': 'definitionListItem', 'attributes': { 'style': 'term' } },
|
||||
'dd': { 'type': 'definitionListItem', 'attributes': { 'style': 'definition' } }
|
||||
} )[tag];
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -37,18 +37,12 @@ ve.dm.DefinitionListNode.rules = {
|
|||
* @member
|
||||
*/
|
||||
ve.dm.DefinitionListNode.converters = {
|
||||
'tags': ['dt', 'dd'],
|
||||
'tags': 'dl',
|
||||
'toHtml': function( type, element ) {
|
||||
return element.attributes && ( {
|
||||
'term': ve.dm.createHtmlElement( 'dt' ),
|
||||
'definition': ve.dm.createHtmlElement( 'dd' )
|
||||
} )[element.attributes['style']];
|
||||
return ve.dm.createHtmlElement( 'dl' );
|
||||
},
|
||||
'toData': function( tag, element ) {
|
||||
return ( {
|
||||
'dt': { 'type': 'definitionList', 'attributes': { 'style': 'term' } },
|
||||
'dd': { 'type': 'definitionList', 'attributes': { 'style': 'definition' } }
|
||||
} )[tag];
|
||||
return { 'type': 'definitionList' };
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -78,6 +78,79 @@ ve.dm.Converter.prototype.onAnnotationRegister = function( type, constructor ) {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* ...
|
||||
*
|
||||
* @method
|
||||
*/
|
||||
ve.dm.Converter.prototype.getHtmlElementFromDataElement = function( dataElement ) {
|
||||
var type = dataElement.type,
|
||||
htmlElement = this.elements.toHtml[type]( type, dataElement ),
|
||||
attributes = dataElement.attributes;
|
||||
// Add 'html/*' attributes directly sans 'html/', others get packaged in the 'data-mw' attribute
|
||||
if ( attributes ) {
|
||||
var dataMw = {},
|
||||
key,
|
||||
value;
|
||||
for ( key in dataElement.attributes ) {
|
||||
value = dataElement.attributes[key];
|
||||
if ( key.indexOf( 'html/' ) === 0 ) {
|
||||
htmlElement.setAttribute( key.substr( 5 ), value );
|
||||
} else if ( key.indexOf( 'mw/' ) === 0 ) {
|
||||
dataMw[key] = value;
|
||||
}
|
||||
// Other attributes should have already been handled by the node's toHtml converter
|
||||
}
|
||||
for ( key in dataMw ) {
|
||||
htmlElement.setAttribute( 'data-mw', JSON.stringify( dataMw ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return htmlElement;
|
||||
};
|
||||
|
||||
/**
|
||||
* ...
|
||||
*
|
||||
* @method
|
||||
*/
|
||||
ve.dm.Converter.prototype.getHtmlContentFromDataContent = function( dataContent ) {
|
||||
//
|
||||
};
|
||||
|
||||
/**
|
||||
* ...
|
||||
*
|
||||
* @method
|
||||
*/
|
||||
ve.dm.Converter.prototype.getDataElementFromHtmlElement = function( htmlElement ) {
|
||||
var type = htmlElement.nodeName.toLowerCase(),
|
||||
dataElement = this.elements.toData[type]( type, htmlElement );
|
||||
// Add 'data-mw' attributes to the 'mw/' namespace, others get added under 'html/'
|
||||
for ( var i = 0; i < htmlElement.attributes.length; i++ ) {
|
||||
dataElement.attributes = {};
|
||||
var attribute = htmlElement.attributes[i];
|
||||
if ( attribute.name.toLowerCase() === 'data-mw' ) {
|
||||
var dataMw = JSON.parse( attribute.value );
|
||||
for ( var key in dataMw ) {
|
||||
dataElement.attributes['mw/' + key] = dataMw[key];
|
||||
}
|
||||
} else {
|
||||
dataElement.attributes['html/' + attribute.name] = attribute.value;
|
||||
}
|
||||
}
|
||||
return dataElement;
|
||||
};
|
||||
|
||||
/**
|
||||
* ...
|
||||
*
|
||||
* @method
|
||||
*/
|
||||
ve.dm.Converter.prototype.getDataContentFromHtmlContent = function( htmlContent ) {
|
||||
//
|
||||
};
|
||||
|
||||
/* Initialization */
|
||||
|
||||
ve.dm.converter = new ve.dm.Converter( ve.dm.nodeFactory, ve.dm.annotationFactory );
|
||||
|
|
27
tests/ve2/dm/ve.dm.Converter.test.js
Normal file
27
tests/ve2/dm/ve.dm.Converter.test.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
module( 've.dm.Converter' );
|
||||
|
||||
/* Tests */
|
||||
|
||||
test( 'getDataElementFromHtmlElement', function() {
|
||||
for ( var msg in ve.dm.example.conversions ) {
|
||||
var conversion = ve.dm.example.conversions[msg];
|
||||
deepEqual(
|
||||
ve.dm.converter.getDataElementFromHtmlElement( conversion.htmlElement ),
|
||||
conversion.dataElement,
|
||||
msg
|
||||
);
|
||||
}
|
||||
} );
|
||||
|
||||
test( 'getHtmlElementFromDataElement', function() {
|
||||
for ( var msg in ve.dm.example.conversions ) {
|
||||
var conversion = ve.dm.example.conversions[msg];
|
||||
deepEqual(
|
||||
ve.example.getHtmlElementSummary(
|
||||
ve.dm.converter.getHtmlElementFromDataElement( conversion.dataElement )
|
||||
),
|
||||
ve.example.getHtmlElementSummary( conversion.htmlElement ),
|
||||
msg
|
||||
);
|
||||
}
|
||||
} );
|
|
@ -411,3 +411,86 @@ ve.dm.example.getOffsetMap = function( root ) {
|
|||
lookup( root ) // 59 - document
|
||||
];
|
||||
};
|
||||
|
||||
ve.dm.example.conversions = {
|
||||
'definitionListItem term': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'dt' ),
|
||||
'dataElement': { 'type': 'definitionListItem', 'attributes': { 'style': 'term' } }
|
||||
},
|
||||
'definitionListItem definition': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'dd' ),
|
||||
'dataElement': { 'type': 'definitionListItem', 'attributes': { 'style': 'definition' } }
|
||||
},
|
||||
'definitionList definition': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'dl' ),
|
||||
'dataElement': { 'type': 'definitionList' }
|
||||
},
|
||||
'heading level 1': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'h1' ),
|
||||
'dataElement': { 'type': 'heading', 'attributes': { 'level': 1 } }
|
||||
},
|
||||
'heading level 2': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'h2' ),
|
||||
'dataElement': { 'type': 'heading', 'attributes': { 'level': 2 } }
|
||||
},
|
||||
'heading level 3': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'h3' ),
|
||||
'dataElement': { 'type': 'heading', 'attributes': { 'level': 3 } }
|
||||
},
|
||||
'heading level 4': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'h4' ),
|
||||
'dataElement': { 'type': 'heading', 'attributes': { 'level': 4 } }
|
||||
},
|
||||
'heading level 5': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'h5' ),
|
||||
'dataElement': { 'type': 'heading', 'attributes': { 'level': 5 } }
|
||||
},
|
||||
'heading level 6': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'h6' ),
|
||||
'dataElement': { 'type': 'heading', 'attributes': { 'level': 6 } }
|
||||
},
|
||||
'image': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'image' ),
|
||||
'dataElement': { 'type': 'image' }
|
||||
},
|
||||
'listItem': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'li' ),
|
||||
'dataElement': { 'type': 'listItem' }
|
||||
},
|
||||
'list bullet': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'ul' ),
|
||||
'dataElement': { 'type': 'list', 'attributes': { 'style': 'bullet' } }
|
||||
},
|
||||
'list number': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'ol' ),
|
||||
'dataElement': { 'type': 'list', 'attributes': { 'style': 'number' } }
|
||||
},
|
||||
'paragraph': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'p' ),
|
||||
'dataElement': { 'type': 'paragraph' }
|
||||
},
|
||||
'preformatted': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'pre' ),
|
||||
'dataElement': { 'type': 'preformatted' }
|
||||
},
|
||||
'tableCell': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'td' ),
|
||||
'dataElement': { 'type': 'tableCell' }
|
||||
},
|
||||
'table': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'table' ),
|
||||
'dataElement': { 'type': 'table' }
|
||||
},
|
||||
'tableRow': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'tr' ),
|
||||
'dataElement': { 'type': 'tableRow' }
|
||||
},
|
||||
'paragraph with mw-data attribute': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'p', { 'data-mw': '{"test":1234}' } ),
|
||||
'dataElement': { 'type': 'paragraph', 'attributes': { 'mw/test': 1234 } }
|
||||
},
|
||||
'paragraph with html attributes': {
|
||||
'htmlElement': ve.dm.createHtmlElement( 'p', { 'style': 'color:blue' } ),
|
||||
'dataElement': { 'type': 'paragraph', 'attributes': { 'html/style': 'color:blue' } }
|
||||
}
|
||||
};
|
||||
|
|
|
@ -104,6 +104,7 @@
|
|||
<script src="dm/ve.dm.NodeFactory.test.js"></script>
|
||||
<script src="dm/ve.dm.Node.test.js"></script>
|
||||
|
||||
<script src="dm/ve.dm.Converter.test.js"></script>
|
||||
<script src="dm/ve.dm.BranchNode.test.js"></script>
|
||||
<script src="dm/ve.dm.LeafNode.test.js"></script>
|
||||
<script src="dm/ve.dm.TextNode.test.js"></script>
|
||||
|
|
|
@ -282,6 +282,24 @@ ve.example.getNodeSelectionSummary = function( selection ) {
|
|||
return summary;
|
||||
};
|
||||
|
||||
/**
|
||||
* Builds a summary of an HTML element.
|
||||
*
|
||||
* Generated summaries contain...
|
||||
*
|
||||
* @method
|
||||
* @param {HTMLElement} element Element to summarize
|
||||
* @returns {Object} Summary of element
|
||||
*/
|
||||
ve.example.getHtmlElementSummary = function( element ) {
|
||||
var $element = $( element );
|
||||
return {
|
||||
'type': element.nodeName.toLowerCase(),
|
||||
'text': $element.text(),
|
||||
'html': $element.html()
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Looks up a value in a node tree.
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue