Merge "Strip generated <p> tags in dataToDom"

This commit is contained in:
Trevor Parscal 2012-08-17 17:42:38 +00:00 committed by Gerrit Code Review
commit 735c4cd20e
2 changed files with 43 additions and 13 deletions

View file

@ -275,7 +275,12 @@ ve.dm.Converter.prototype.getDataFromDom = function ( domElement, annotations, d
if ( annotation ) { if ( annotation ) {
// Start auto-wrapping of bare content // Start auto-wrapping of bare content
if ( !wrapping && !alreadyWrapped && !branchIsContent ) { if ( !wrapping && !alreadyWrapped && !branchIsContent ) {
data.push( { 'type': 'paragraph' } ); // Mark this paragraph as having been generated by
// us, so we can strip it on the way out
data.push( {
'type': 'paragraph',
'internal': { 'generated': 'wrapper' }
} );
wrapping = true; wrapping = true;
} }
// Append child element data // Append child element data
@ -328,7 +333,12 @@ ve.dm.Converter.prototype.getDataFromDom = function ( domElement, annotations, d
// Start auto-wrapping of bare content // Start auto-wrapping of bare content
if ( !wrapping && !alreadyWrapped && !branchIsContent ) { if ( !wrapping && !alreadyWrapped && !branchIsContent ) {
paragraph = { 'type': 'paragraph' }; // Mark this paragraph as having been generated by
// us, so we can strip it on the way out
paragraph = {
'type': 'paragraph',
'internal': { 'generated': 'wrapper' }
};
data.push( paragraph ); data.push( paragraph );
wrapping = true; wrapping = true;
wrapperElement = paragraph; wrapperElement = paragraph;
@ -400,7 +410,7 @@ ve.dm.Converter.prototype.getDataFromDom = function ( domElement, annotations, d
!ve.dm.nodeFactory.isNodeContent( branchType ) && !ve.dm.nodeFactory.isNodeContent( branchType ) &&
( childTypes === null || ve.indexOf( 'paragraph', childTypes ) !== -1 ) ( childTypes === null || ve.indexOf( 'paragraph', childTypes ) !== -1 )
) { ) {
data.push( { 'type': 'paragraph' } ); data.push( { 'type': 'paragraph', 'internal': { 'generated': 'wrapper' } } );
data.push( { 'type': '/paragraph' } ); data.push( { 'type': '/paragraph' } );
} }
@ -410,7 +420,10 @@ ve.dm.Converter.prototype.getDataFromDom = function ( domElement, annotations, d
} }
// Don't return an empty document // Don't return an empty document
if ( branchType === 'document' && data.length === 0 ) { if ( branchType === 'document' && data.length === 0 ) {
return [{ 'type': 'paragraph' }, { 'type': '/paragraph' }]; return [
{ 'type': 'paragraph', 'internal': { 'generated': 'wrapper' } },
{ 'type': '/paragraph' }
];
} }
return data; return data;
}; };
@ -423,8 +436,8 @@ ve.dm.Converter.prototype.getDataFromDom = function ( domElement, annotations, d
* @returns {HTMLElement} Wrapper div containing the resulting HTML * @returns {HTMLElement} Wrapper div containing the resulting HTML
*/ */
ve.dm.Converter.prototype.getDomFromData = function ( data ) { ve.dm.Converter.prototype.getDomFromData = function ( data ) {
var text, i, annotations, hash, annotationElement, done, dataElement, wrapper, var text, i, j, annotations, hash, annotationElement, done, dataElement, wrapper,
childDomElement, pre, post, childDomElement, pre, post, parentDomElement,
container = document.createElement( 'div' ), container = document.createElement( 'div' ),
domElement = container, domElement = container,
annotationStack = {}; // { hash: DOMnode } annotationStack = {}; // { hash: DOMnode }
@ -572,13 +585,30 @@ ve.dm.Converter.prototype.getDomFromData = function ( data ) {
} }
} }
} }
// If closing a generated wrapper node, unwrap it
// It would be nicer if we could avoid generating in the first
// place, but then remembering where we have to skip ascending
// to the parent would be tricky.
parentDomElement = domElement.parentNode;
if ( domElement.veInternal && domElement.veInternal.generated === 'wrapper' ) {
for ( j = 0; j < domElement.childNodes.length; j++ ) {
parentDomElement.insertBefore(
domElement.childNodes[j],
domElement
);
}
parentDomElement.removeChild( domElement );
}
// Clean up the internal data
delete domElement.veInternal; delete domElement.veInternal;
// Ascend to parent node // Ascend to parent node
domElement = domElement.parentNode; domElement = parentDomElement;
} else { } else {
// Create node from data // Create node from data
childDomElement = this.getDomElementFromDataElement( dataElement ); childDomElement = this.getDomElementFromDataElement( dataElement );
// Add reference to internal data to propagate whitespace info // Add reference to internal data
if ( dataElement.internal ) { if ( dataElement.internal ) {
childDomElement.veInternal = dataElement.internal; childDomElement.veInternal = dataElement.internal;
} }

View file

@ -13,6 +13,7 @@ ve.dm.example = {};
* Serialized HTML. * Serialized HTML.
* *
* This is what the parser will emit. * This is what the parser will emit.
* TODO remove some of the <p>s here to test automatic wrapping
*/ */
ve.dm.example.html = ve.dm.example.html =
'<h1>a<b>b</b><i>c</i></h1>' + '<h1>a<b>b</b><i>c</i></h1>' +
@ -677,26 +678,25 @@ ve.dm.example.domToDataCases = {
] ]
}, },
'whitespace preservation in list items': { 'whitespace preservation in list items': {
'normalizedHtml': '<ul><li><p>Foo</p></li><li><p> Bar</p></li><li><p>Baz </p></li><li><p> Quux </p></li></ul>',
'html': '<ul><li>Foo</li><li> Bar</li><li>Baz </li><li> Quux </li></ul>', 'html': '<ul><li>Foo</li><li> Bar</li><li>Baz </li><li> Quux </li></ul>',
'data': [ 'data': [
{ 'type': 'list', 'attributes': { 'style': 'bullet' } }, { 'type': 'list', 'attributes': { 'style': 'bullet' } },
{ 'type': 'listItem' }, { 'type': 'listItem' },
{ 'type': 'paragraph' }, { 'type': 'paragraph', 'internal': { 'generated': 'wrapper' } },
'F', 'F',
'o', 'o',
'o', 'o',
{ 'type': '/paragraph' }, { 'type': '/paragraph' },
{ 'type': '/listItem' }, { 'type': '/listItem' },
{ 'type': 'listItem' }, { 'type': 'listItem' },
{ 'type': 'paragraph', 'internal': { 'whitespace': [ undefined, ' ' ] } }, { 'type': 'paragraph', 'internal': { 'whitespace': [ undefined, ' ' ], 'generated': 'wrapper' } },
'B', 'B',
'a', 'a',
'r', 'r',
{ 'type': '/paragraph' }, { 'type': '/paragraph' },
{ 'type': '/listItem' }, { 'type': '/listItem' },
{ 'type': 'listItem' }, { 'type': 'listItem' },
{ 'type': 'paragraph', 'internal': { 'whitespace': [ undefined, undefined, ' ' ] } }, { 'type': 'paragraph', 'internal': { 'whitespace': [ undefined, undefined, ' ' ], 'generated': 'wrapper' } },
'B', 'B',
'a', 'a',
'z', 'z',
@ -705,7 +705,7 @@ ve.dm.example.domToDataCases = {
{ 'type': 'listItem' }, { 'type': 'listItem' },
{ {
'type': 'paragraph', 'type': 'paragraph',
'internal': { 'whitespace': [ undefined, ' ', ' ' ] } 'internal': { 'whitespace': [ undefined, ' ', ' ' ], 'generated': 'wrapper' }
}, },
'Q', 'Q',
'u', 'u',