Remove html/* attributes in getClonedElement()

Subbu said that cloning of attributes like data-parsoid or typeof would
cause problems for Parsoid.

Also remove the attributes object if it becomes empty, and do the same
for the internal object.

Bug: 47297
Change-Id: I428becf95c70d0ed8af5b0c408e3966dc47fd8c3
This commit is contained in:
Catrope 2013-04-18 08:56:33 -07:00
parent 16d164ed6d
commit 533e43ea80
2 changed files with 162 additions and 2 deletions

View file

@ -209,14 +209,27 @@ ve.dm.Node.static.isHybridInline = function ( domElements, converter ) {
* Get a clone of the node's document data element.
*
* The attributes object will be deep-copied, and the .internal.generated property will be removed,
* if present.
* if present. Any html/* attributes will be removed as well.
*
* @returns {Object} Cloned element object
*/
ve.dm.Node.prototype.getClonedElement = function () {
var clone = ve.copyObject( this.element );
var attr, clone = ve.copyObject( this.element );
if ( clone.internal ) {
delete clone.internal.generated;
if ( ve.isEmptyObject( clone.internal ) ) {
delete clone.internal;
}
}
if ( this.element.attributes ) {
for ( attr in this.element.attributes ) {
if ( attr.substr( 0, 5 ) === 'html/' ) {
delete clone.attributes[attr];
}
}
if ( ve.isEmptyObject( clone.attributes ) ) {
delete clone.attributes;
}
}
return clone;
};

View file

@ -110,3 +110,150 @@ QUnit.test( 'canBeMergedWith', 4, function ( assert ) {
assert.strictEqual( node2.canBeMergedWith( node1 ), false, 'different level, different type' );
assert.strictEqual( node2.canBeMergedWith( node4 ), false, 'same level, different type' );
} );
QUnit.test( 'getClonedElement', function ( assert ) {
var i, node,
cases = [
{
'original': {
'type': 'foo'
},
'clone': {
'type': 'foo'
},
'msg': 'Simple element is cloned verbatim'
},
{
'original': {
'type': 'foo',
'attributes': {
'bar': 'baz'
}
},
'clone': {
'type': 'foo',
'attributes': {
'bar': 'baz'
}
},
'msg': 'Element with simple attributes is cloned verbatim'
},
{
'original': {
'type': 'foo',
'attributes': {
'bar': 'baz',
'html/0/typeof': 'Foo',
'html/0/href': 'Bar'
}
},
'clone': {
'type': 'foo',
'attributes': {
'bar': 'baz'
}
},
'msg': 'html/* attributes are removed from clone'
},
{
'original': {
'type': 'foo',
'attributes': {
'html/0/typeof': 'Foo'
}
},
'clone': {
'type': 'foo'
},
'msg': 'attributes object containing only html/* attributes is removed from clone'
},
{
'original': {
'type': 'foo',
'attributes': {
'html': '<foo></foo>'
}
},
'clone': {
'type': 'foo',
'attributes': {
'html': '<foo></foo>'
}
},
'msg': 'html attribute (without slash) is not removed'
},
{
'original': {
'type': 'foo',
'internal': {
'generated': 'wrapper',
'whitespace': [ undefined, ' ' ]
}
},
'clone': {
'type': 'foo',
'internal': {
'whitespace': [ undefined, ' ' ]
}
},
'msg': 'internal.generated property is removed from clone'
},
{
'original': {
'type': 'foo',
'internal': {
'generated': 'wrapper'
}
},
'clone': {
'type': 'foo'
},
'msg': 'internal property is removed if it only contained .generated'
},
{
'original': {
'type': 'foo',
'internal': {
'generated': 'wrapper'
},
'attributes': {
'html/0/typeof': 'Foo',
'html/1/href': 'Bar'
}
},
'clone': {
'type': 'foo'
},
'msg': 'internal and attribute properties are both removed'
},
{
'original': {
'type': 'foo',
'internal': {
'generated': 'wrapper',
'whitespace': [ undefined, ' ' ],
},
'attributes': {
'html/0/typeof': 'Foo',
'bar': 'baz'
}
},
'clone': {
'type': 'foo',
'internal': {
'whitespace': [ undefined, ' ' ],
},
'attributes': {
'bar': 'baz'
}
},
'msg': 'internal.generated and attributes.html/* are both removed'
}
];
QUnit.expect( cases.length );
for ( i = 0; i < cases.length; i++ ) {
node = new ve.dm.NodeStub( 0, cases[i].original );
assert.deepEqual( node.getClonedElement(), cases[i].clone, cases[i].msg );
}
} );