mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-29 00:30:44 +00:00
Also render attributes of the form html/i-j/attrName in CE
Factored the parsing of html/* attributes out into a static function. Factored attribute (re)rendering out into ce.View, attribute updates are much simpler now. Change-Id: I4caa6d5e1e2c21c28ddff61c3c864e47f66cc6b2
This commit is contained in:
parent
05828cc3f1
commit
31c2165770
|
@ -63,19 +63,7 @@ ve.ce.Node.static.canBeSplit = false;
|
|||
* @param {string} to New value
|
||||
*/
|
||||
ve.ce.Node.prototype.onAttributeChange = function ( key, from, to ) {
|
||||
var htmlKey = key.substr( 7 ).toLowerCase();
|
||||
if (
|
||||
this.constructor.static.renderHtmlAttributes &&
|
||||
key.indexOf( 'html/0/' ) === 0 &&
|
||||
htmlKey.length &&
|
||||
this.constructor.static.domAttributeWhitelist.indexOf( htmlKey ) !== -1
|
||||
) {
|
||||
if ( to === undefined ) {
|
||||
this.$.removeAttr( htmlKey );
|
||||
} else {
|
||||
this.$.attr( htmlKey, to );
|
||||
}
|
||||
}
|
||||
this.renderAttributes( { key: to } );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,13 +26,7 @@ ve.ce.View = function VeCeView( model, $element ) {
|
|||
|
||||
// Initialization
|
||||
this.$.data( 'view', this );
|
||||
if ( this.constructor.static.renderHtmlAttributes ) {
|
||||
ve.setDomAttributes(
|
||||
this.$[0],
|
||||
this.model.getAttributes( 'html/0/' ),
|
||||
this.constructor.static.domAttributeWhitelist
|
||||
);
|
||||
}
|
||||
this.renderAttributes( this.model.getAttributes() );
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
@ -116,3 +110,21 @@ ve.ce.View.prototype.setLive = function ( live ) {
|
|||
this.live = live;
|
||||
this.emit( 'live' );
|
||||
};
|
||||
|
||||
ve.ce.View.prototype.renderAttributes = function ( attributes ) {
|
||||
var key, parsed,
|
||||
whitelist = this.constructor.static.domAttributeWhitelist;
|
||||
if ( !this.constructor.static.renderHtmlAttributes ) {
|
||||
return;
|
||||
}
|
||||
for ( key in attributes ) {
|
||||
parsed = ve.dm.Converter.parseHtmlAttribute( key, this.$ );
|
||||
if ( parsed && whitelist.indexOf( parsed.attribute ) !== -1 ) {
|
||||
if ( attributes[key] === undefined ) {
|
||||
parsed.domElement.removeAttribute( parsed.attribute );
|
||||
} else {
|
||||
parsed.domElement.setAttribute( parsed.attribute, attributes[key] );
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
|
@ -100,6 +100,31 @@ ve.dm.Converter.openAndCloseAnnotations = function ( currentSet, targetSet, open
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse a linear model attribute name of the form html/i-j-k/attrName.
|
||||
*
|
||||
* @param {string} attribute Name of a linear model attribute
|
||||
* @param {HTMLElement[]|jQuery} domElements DOM elements array that the attribute indexes into
|
||||
* @returns {Object|null} Object with domElement and attribute keys, or null
|
||||
*/
|
||||
ve.dm.Converter.parseHtmlAttribute = function ( attribute, domElements ) {
|
||||
var i, ilen, indexes, child,
|
||||
/*jshint regexp:false */
|
||||
matches = attribute.match( /^html\/((?:\d+\-)*\d)\/(.*)$/ );
|
||||
if ( !matches ) {
|
||||
return null;
|
||||
}
|
||||
indexes = matches[1].split( '-' ); // matches[1] like '1-2-3'
|
||||
child = domElements[indexes[0]];
|
||||
for ( i = 1, ilen = indexes.length; i < ilen; i++ ) {
|
||||
child = child && child.childNodes[indexes[i]];
|
||||
}
|
||||
if ( !child ) {
|
||||
return null;
|
||||
}
|
||||
return { 'domElement': child, 'attribute': matches[2] };
|
||||
};
|
||||
|
||||
/* Methods */
|
||||
|
||||
/**
|
||||
|
@ -201,7 +226,7 @@ ve.dm.Converter.prototype.canCloseWrapper = function () {
|
|||
* @returns {HTMLElement|boolean} DOM element, or false if the element cannot be converted
|
||||
*/
|
||||
ve.dm.Converter.prototype.getDomElementsFromDataElement = function ( dataElements, doc ) {
|
||||
var domElements, dataElementAttributes, key, matches, indexes, i, ilen, child,
|
||||
var domElements, dataElementAttributes, key, parsed,
|
||||
dataElement = ve.isArray( dataElements ) ? dataElements[0] : dataElements,
|
||||
nodeClass = this.modelRegistry.lookup( dataElement.type );
|
||||
|
||||
|
@ -218,18 +243,9 @@ ve.dm.Converter.prototype.getDomElementsFromDataElement = function ( dataElement
|
|||
dataElementAttributes = dataElement.attributes;
|
||||
if ( dataElementAttributes ) {
|
||||
for ( key in dataElementAttributes ) {
|
||||
// Only include 'html/*' attributes and strip the prefix
|
||||
/*jshint regexp:false */
|
||||
matches = key.match( /^html\/((?:\d+\-)*\d)\/(.*)$/ );
|
||||
if ( matches ) {
|
||||
indexes = matches[1].split( '-' ); // matches[1] like '1-2-3'
|
||||
child = domElements[indexes[0]];
|
||||
for ( i = 1, ilen = indexes.length; i < ilen; i++ ) {
|
||||
child = child && child.childNodes[indexes[i]];
|
||||
}
|
||||
if ( child && !child.hasAttribute( matches[2] ) ) {
|
||||
child.setAttribute( matches[2], dataElementAttributes[key] );
|
||||
}
|
||||
parsed = ve.dm.Converter.parseHtmlAttribute( key, domElements );
|
||||
if ( parsed && !parsed.domElement.hasAttribute( parsed.attribute ) ) {
|
||||
parsed.domElement.setAttribute( parsed.attribute, dataElementAttributes[key] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue