mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-24 22:35:41 +00:00
Change the HTML attribute prefix from html/ to html/0/
This means that <p data-foo="bar"> will now be converted to a paragraph with attributes {"html/0/data-foo":"bar"} rather than {"html/foo":"bar"} This paves the way for multi-element node (about group) handling in the node API: nodes representing multiple DOM elements will have html/i/attr to represent an attribute of the i'th DOM element. Change-Id: Iea52bdccd721942ca708c8f9f47e934524809845
This commit is contained in:
parent
edd0baf4fe
commit
591f2e7396
|
@ -33,7 +33,7 @@ ve.ce.Node = function VeCeNode( type, model, $element ) {
|
|||
this.$.data( 'node', this );
|
||||
ve.setDomAttributes(
|
||||
this.$[0],
|
||||
this.model.getAttributes( 'html/' ),
|
||||
this.model.getAttributes( 'html/0/' ),
|
||||
this.constructor.static.domAttributeWhitelist
|
||||
);
|
||||
};
|
||||
|
@ -117,9 +117,9 @@ ve.ce.Node.static.$shieldTemplate = $( '<img>' )
|
|||
* @param {string} to New value
|
||||
*/
|
||||
ve.ce.Node.prototype.onAttributeChange = function ( key, from, to ) {
|
||||
var htmlKey = key.substr( 5 ).toLowerCase();
|
||||
var htmlKey = key.substr( 7 ).toLowerCase();
|
||||
if (
|
||||
key.indexOf( 'html/' ) === 0 &&
|
||||
key.indexOf( 'html/0/' ) === 0 &&
|
||||
htmlKey.length &&
|
||||
this.constructor.static.domAttributeWhitelist.indexOf( htmlKey ) !== -1
|
||||
) {
|
||||
|
|
|
@ -128,9 +128,9 @@ ve.dm.Converter.prototype.getDomElementFromDataElement = function ( dataElement
|
|||
dataElementAttributes = dataElement.attributes;
|
||||
if ( dataElementAttributes ) {
|
||||
for ( key in dataElementAttributes ) {
|
||||
// Only include 'html/*' attributes and strip the 'html/' from the beginning of the name
|
||||
if ( key.indexOf( 'html/' ) === 0 ) {
|
||||
domElement.setAttribute( key.substr( 5 ), dataElementAttributes[key] );
|
||||
// Only include 'html/0/*' attributes and strip the 'html/0/' from the beginning of the name
|
||||
if ( key.indexOf( 'html/0/' ) === 0 ) {
|
||||
domElement.setAttribute( key.substr( 7 ), dataElementAttributes[key] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -172,10 +172,10 @@ ve.dm.Converter.prototype.getDataElementFromDomElement = function ( domElement,
|
|||
domElementAttributes = domElement.attributes;
|
||||
if ( domElementAttributes.length ) {
|
||||
dataElementAttributes = dataElement.attributes = dataElement.attributes || {};
|
||||
// Include all attributes and prepend 'html/' to each attribute name
|
||||
// Include all attributes and prepend 'html/0/' to each attribute name
|
||||
for ( i = 0; i < domElementAttributes.length; i++ ) {
|
||||
domElementAttribute = domElementAttributes[i];
|
||||
dataElementAttributes['html/' + domElementAttribute.name] = domElementAttribute.value;
|
||||
dataElementAttributes['html/0/' + domElementAttribute.name] = domElementAttribute.value;
|
||||
}
|
||||
}
|
||||
if ( this.nodeFactory.isNodeContent( dataElement.type ) && !annotations.isEmpty() ) {
|
||||
|
@ -434,7 +434,7 @@ ve.dm.Converter.prototype.getDataFromDom = function ( domElement, annotations, d
|
|||
}
|
||||
// Preserve HTML attributes
|
||||
// FIXME the following is duplicated from getDataElementFromDomElement()
|
||||
// Include all attributes and prepend 'html/' to each attribute name
|
||||
// Include all attributes and prepend 'html/0/' to each attribute name
|
||||
for ( j = 0; j < childDomElement.attributes.length; j++ ) {
|
||||
// ..but exclude attributes we've already processed,
|
||||
// because they'll be overwritten otherwise *sigh*
|
||||
|
@ -443,7 +443,7 @@ ve.dm.Converter.prototype.getDataFromDom = function ( domElement, annotations, d
|
|||
childDomElement.attributes[j].name !== ( isLink ? 'rel' : 'property' ) &&
|
||||
childDomElement.attributes[j].name !== ( isLink ? 'href' : 'content' )
|
||||
) {
|
||||
childDataElement.attributes['html/' + childDomElement.attributes[j].name] = childDomElement.attributes[j].value;
|
||||
childDataElement.attributes['html/0/' + childDomElement.attributes[j].name] = childDomElement.attributes[j].value;
|
||||
}
|
||||
}
|
||||
data.push( childDataElement );
|
||||
|
|
|
@ -218,7 +218,7 @@ QUnit.test( 'getRenderedContents', function ( assert ) {
|
|||
['b', [ { 'type': 'textStyle/bold' } ]],
|
||||
{
|
||||
'type': 'MWentity',
|
||||
'attributes': { 'character': 'c', 'html/typeof': 'mw:Entity' },
|
||||
'attributes': { 'character': 'c', 'html/0/typeof': 'mw:Entity' },
|
||||
'annotations': [ { 'type': 'textStyle/bold' } ]
|
||||
},
|
||||
{ 'type': '/MWentity' },
|
||||
|
|
|
@ -274,7 +274,7 @@ QUnit.test( 'newFromRemoval', 15, function ( assert ) {
|
|||
'type': 'replace',
|
||||
'remove': [
|
||||
'h',
|
||||
{ 'type': 'image', 'attributes': { 'html/src': 'image.png' } },
|
||||
{ 'type': 'image', 'attributes': { 'html/0/src': 'image.png' } },
|
||||
{ 'type': '/image' },
|
||||
'i'
|
||||
],
|
||||
|
|
|
@ -142,13 +142,13 @@ QUnit.test( 'commit/rollback', 66, function ( assert ) {
|
|||
['pushReplaceElementAttribute', 'style', 'bullet', 'number'],
|
||||
['pushReplaceElementAttribute', 'test', undefined, 'abcd'],
|
||||
['pushRetain', 27],
|
||||
['pushReplaceElementAttribute', 'html/src', 'image.png', undefined]
|
||||
['pushReplaceElementAttribute', 'html/0/src', 'image.png', undefined]
|
||||
],
|
||||
'expected': function ( data ) {
|
||||
data[0].attributes.level = 2;
|
||||
data[12].attributes.style = 'number';
|
||||
data[12].attributes.test = 'abcd';
|
||||
delete data[39].attributes['html/src'];
|
||||
delete data[39].attributes['html/0/src'];
|
||||
ve.setProp( data[0], 'internal', 'changed', 'attributes', 1 );
|
||||
ve.setProp( data[12], 'internal', 'changed', 'attributes', 2 );
|
||||
ve.setProp( data[39], 'internal', 'changed', 'attributes', 1 );
|
||||
|
|
|
@ -218,7 +218,7 @@ ve.dm.example.data = [
|
|||
// 38 - Plain "h"
|
||||
'h',
|
||||
// 39 - Beginning of inline image
|
||||
{ 'type': 'image', 'attributes': { 'html/src': 'image.png' } },
|
||||
{ 'type': 'image', 'attributes': { 'html/0/src': 'image.png' } },
|
||||
// 40 - End of inline image
|
||||
{ 'type': '/image' },
|
||||
// 41 - Plain "i"
|
||||
|
@ -374,8 +374,8 @@ ve.dm.example.withMeta = [
|
|||
'attributes': {
|
||||
'style': 'meta',
|
||||
'key': null,
|
||||
'html/typeof': 'mw:Placeholder',
|
||||
'html/data-parsoid': 'foobar'
|
||||
'html/0/typeof': 'mw:Placeholder',
|
||||
'html/0/data-parsoid': 'foobar'
|
||||
}
|
||||
},
|
||||
{ 'type': '/metaBlock' }
|
||||
|
@ -477,8 +477,8 @@ ve.dm.example.withMetaMetaData = [
|
|||
'attributes': {
|
||||
'style': 'meta',
|
||||
'key': null,
|
||||
'html/typeof': 'mw:Placeholder',
|
||||
'html/data-parsoid': 'foobar'
|
||||
'html/0/typeof': 'mw:Placeholder',
|
||||
'html/0/data-parsoid': 'foobar',
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -639,13 +639,13 @@ ve.dm.example.conversions = {
|
|||
'domElement': ve.example.createDomElement( 'tr' ),
|
||||
'dataElement': { 'type': 'tableRow' }
|
||||
},
|
||||
'paragraph with mw-data attribute': {
|
||||
'paragraph with data-mw attribute': {
|
||||
'domElement': ve.example.createDomElement( 'p', { 'data-mw': '{"test":1234}' } ),
|
||||
'dataElement': { 'type': 'paragraph', 'attributes': { 'html/data-mw': '{"test":1234}' } }
|
||||
'dataElement': { 'type': 'paragraph', 'attributes': { 'html/0/data-mw': '{"test":1234}' } }
|
||||
},
|
||||
'paragraph with style attribute': {
|
||||
'domElement': ve.example.createDomElement( 'p', { 'style': 'color:blue' } ),
|
||||
'dataElement': { 'type': 'paragraph', 'attributes': { 'html/style': 'color:blue' } }
|
||||
'dataElement': { 'type': 'paragraph', 'attributes': { 'html/0/style': 'color:blue' } }
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -674,7 +674,7 @@ ve.dm.example.domToDataCases = {
|
|||
'html': '<img src="image.png">',
|
||||
'data': [
|
||||
{ 'type': 'paragraph', 'internal': { 'generated': 'wrapper' } },
|
||||
{ 'type': 'image', 'attributes' : { 'html/src' : 'image.png' } },
|
||||
{ 'type': 'image', 'attributes' : { 'html/0/src' : 'image.png' } },
|
||||
{ 'type' : '/image' },
|
||||
{ 'type': '/paragraph' }
|
||||
]
|
||||
|
@ -724,7 +724,7 @@ ve.dm.example.domToDataCases = {
|
|||
{ 'type': '/alienInline' },
|
||||
{
|
||||
'type': 'MWentity',
|
||||
'attributes': { 'character': 'c', 'html/typeof': 'mw:Entity' },
|
||||
'attributes': { 'character': 'c', 'html/0/typeof': 'mw:Entity' },
|
||||
'annotations': [ ve.dm.example.bold, ve.dm.example.italic ]
|
||||
},
|
||||
{ 'type': '/MWentity' },
|
||||
|
@ -763,7 +763,7 @@ ve.dm.example.domToDataCases = {
|
|||
'html': '<img src="foo.jpg">12',
|
||||
'data': [
|
||||
{ 'type': 'paragraph', 'internal': { 'generated': 'wrapper' } },
|
||||
{ 'type': 'image', 'attributes': { 'html/src': 'foo.jpg' } },
|
||||
{ 'type': 'image', 'attributes': { 'html/0/src': 'foo.jpg' } },
|
||||
{ 'type': '/image' },
|
||||
'1',
|
||||
'2',
|
||||
|
@ -1839,12 +1839,12 @@ ve.dm.example.domToDataCases = {
|
|||
'data': [
|
||||
{ 'type': 'paragraph' },
|
||||
'a',
|
||||
{ 'type': 'MWentity', 'attributes': { 'character': '¢', 'html/typeof': 'mw:Entity' } },
|
||||
{ 'type': 'MWentity', 'attributes': { 'character': '¢', 'html/0/typeof': 'mw:Entity' } },
|
||||
{ 'type': '/MWentity' },
|
||||
'b',
|
||||
{ 'type': 'MWentity', 'attributes': { 'character': '¥', 'html/typeof': 'mw:Entity' } },
|
||||
{ 'type': 'MWentity', 'attributes': { 'character': '¥', 'html/0/typeof': 'mw:Entity' } },
|
||||
{ 'type': '/MWentity' },
|
||||
{ 'type': 'MWentity', 'attributes': { 'character': '™', 'html/typeof': 'mw:Entity' } },
|
||||
{ 'type': 'MWentity', 'attributes': { 'character': '™', 'html/0/typeof': 'mw:Entity' } },
|
||||
{ 'type': '/MWentity' },
|
||||
{ 'type': '/paragraph' }
|
||||
]
|
||||
|
@ -1854,12 +1854,12 @@ ve.dm.example.domToDataCases = {
|
|||
'data': [
|
||||
{ 'type': 'paragraph', 'internal': { 'generated': 'wrapper' } },
|
||||
'a',
|
||||
{ 'type': 'MWentity', 'attributes': { 'character': '¢', 'html/typeof': 'mw:Entity' } },
|
||||
{ 'type': 'MWentity', 'attributes': { 'character': '¢', 'html/0/typeof': 'mw:Entity' } },
|
||||
{ 'type': '/MWentity' },
|
||||
'b',
|
||||
{ 'type': 'MWentity', 'attributes': { 'character': '¥', 'html/typeof': 'mw:Entity' } },
|
||||
{ 'type': 'MWentity', 'attributes': { 'character': '¥', 'html/0/typeof': 'mw:Entity' } },
|
||||
{ 'type': '/MWentity' },
|
||||
{ 'type': 'MWentity', 'attributes': { 'character': '™', 'html/typeof': 'mw:Entity' } },
|
||||
{ 'type': 'MWentity', 'attributes': { 'character': '™', 'html/0/typeof': 'mw:Entity' } },
|
||||
{ 'type': '/MWentity' },
|
||||
{ 'type': '/paragraph' }
|
||||
]
|
||||
|
@ -1871,7 +1871,7 @@ ve.dm.example.domToDataCases = {
|
|||
'a',
|
||||
' ',
|
||||
' ',
|
||||
{ 'type': 'MWentity', 'attributes': { 'character': ' ', 'html/typeof': 'mw:Entity' } },
|
||||
{ 'type': 'MWentity', 'attributes': { 'character': ' ', 'html/0/typeof': 'mw:Entity' } },
|
||||
{ 'type': '/MWentity' },
|
||||
' ',
|
||||
' ',
|
||||
|
@ -1881,10 +1881,10 @@ ve.dm.example.domToDataCases = {
|
|||
' ',
|
||||
' ',
|
||||
' ',
|
||||
{ 'type': 'MWentity', 'attributes': { 'character': '¥', 'html/typeof': 'mw:Entity' } },
|
||||
{ 'type': 'MWentity', 'attributes': { 'character': '¥', 'html/0/typeof': 'mw:Entity' } },
|
||||
{ 'type': '/MWentity' },
|
||||
'\t',
|
||||
{ 'type': 'MWentity', 'attributes': { 'character': '™', 'html/typeof': 'mw:Entity' } },
|
||||
{ 'type': 'MWentity', 'attributes': { 'character': '™', 'html/0/typeof': 'mw:Entity' } },
|
||||
{ 'type': '/MWentity' },
|
||||
{ 'type': '/paragraph' }
|
||||
]
|
||||
|
|
Loading…
Reference in a new issue