Handle aliens correctly in the converter

Previously, data-mw-gc (generated content) elements were unconditionally
converted to alienInline nodes, and unrecognized elements were
unconditionally converted to alienBlock nodes. This is wrong and
produced weird results when I started experimenting with <code> tags.

Instead, I made both gc and unknown element trigger alienation, but the
decision of whether we generate an alienInline or an alienBlock node is
separate and is based only on whether we're inside a content node.

Change-Id: I12335337c3fa60c725ae7bcfbfb52a1dda153fb5
This commit is contained in:
Catrope 2012-06-14 12:18:06 -07:00
parent 86d891605d
commit bb5c82745e

View file

@ -222,11 +222,25 @@ ve.dm.Converter.prototype.getDomElementFromDataAnnotation = function( dataAnnota
* @returns {Array} Linear model data * @returns {Array} Linear model data
*/ */
ve.dm.Converter.prototype.getDataFromDom = function( domElement, annotations, dataElement, path, alreadyWrapped ) { ve.dm.Converter.prototype.getDataFromDom = function( domElement, annotations, dataElement, path, alreadyWrapped ) {
function createAlien( domElement, isInline ) {
var type = isInline ? 'alienInline' : 'alienBlock';
return [
{
'type': type,
'attributes': {
'html': $( '<div>' ).append( $( domElement ).clone() ).html()
}
},
{ 'type': '/' + type }
];
}
// Fallback to defaults // Fallback to defaults
annotations = annotations || []; annotations = annotations || [];
path = path || ['document']; path = path || ['document'];
var data = [], var data = [],
branchType = path[path.length - 1], branchType = path[path.length - 1],
branchIsContent = ve.dm.nodeFactory.canNodeContainContent( branchType ),
wrapping = false; wrapping = false;
// Open element // Open element
if ( dataElement ) { if ( dataElement ) {
@ -237,30 +251,16 @@ ve.dm.Converter.prototype.getDataFromDom = function( domElement, annotations, da
var childDomElement = domElement.childNodes[i]; var childDomElement = domElement.childNodes[i];
switch ( childDomElement.nodeType ) { switch ( childDomElement.nodeType ) {
case Node.ELEMENT_NODE: case Node.ELEMENT_NODE:
// Detect and handle inline alien nodes // Detect generated content and wrap it in an alien node
if ( if ( childDomElement.hasAttribute( 'data-mw-gc' ) ) {
// Generated content data = data.concat( createAlien( childDomElement, branchIsContent ) );
childDomElement.hasAttribute( 'data-mw-gc' ) &&
// Inside a content branch
ve.dm.nodeFactory.canNodeContainContent( branchType )
) {
// Fallback to alien inline
data = data.concat( [
{
'type': 'alienInline',
'attributes': {
'html': $( '<div>' ).append( $( childDomElement ).clone() ).html()
}
},
{ 'type': '/alienInline' }
] );
break; break;
} }
// Detect and handle annotated content // Detect and handle annotated content
var annotation = this.getDataAnnotationFromDomElement( childDomElement ); var annotation = this.getDataAnnotationFromDomElement( childDomElement );
if ( annotation ) { if ( annotation ) {
// Start auto-wrapping of bare content // Start auto-wrapping of bare content
if ( !wrapping && !alreadyWrapped && !ve.dm.nodeFactory.canNodeContainContent( branchType ) ) { if ( !wrapping && !alreadyWrapped && !branchIsContent ) {
data.push( { 'type': 'paragraph' } ); data.push( { 'type': 'paragraph' } );
wrapping = true; wrapping = true;
} }
@ -291,16 +291,8 @@ ve.dm.Converter.prototype.getDataFromDom = function( domElement, annotations, da
); );
break; break;
} }
// Fallback to alien block // We don't know what this is, fall back to alien
data = data.concat( [ data = data.concat( createAlien( childDomElement, branchIsContent ) );
{
'type': 'alienBlock',
'attributes': {
'html': $( '<div>' ).append( $( childDomElement ).clone() ).html()
}
},
{ 'type': '/alienBlock' }
] );
break; break;
case Node.TEXT_NODE: case Node.TEXT_NODE:
// HACK: strip trailing newlines in <li> tags. Workaround for a Parsoid bug // HACK: strip trailing newlines in <li> tags. Workaround for a Parsoid bug
@ -313,7 +305,7 @@ ve.dm.Converter.prototype.getDataFromDom = function( domElement, annotations, da
} }
// Start auto-wrapping of bare content // Start auto-wrapping of bare content
if ( !wrapping && !alreadyWrapped && !ve.dm.nodeFactory.canNodeContainContent( branchType ) ) { if ( !wrapping && !alreadyWrapped && !branchIsContent ) {
data.push( { 'type': 'paragraph' } ); data.push( { 'type': 'paragraph' } );
wrapping = true; wrapping = true;
} }