mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-15 10:35:48 +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
|
* @param {string} to New value
|
||||||
*/
|
*/
|
||||||
ve.ce.Node.prototype.onAttributeChange = function ( key, from, to ) {
|
ve.ce.Node.prototype.onAttributeChange = function ( key, from, to ) {
|
||||||
var htmlKey = key.substr( 7 ).toLowerCase();
|
this.renderAttributes( { key: to } );
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -26,13 +26,7 @@ ve.ce.View = function VeCeView( model, $element ) {
|
||||||
|
|
||||||
// Initialization
|
// Initialization
|
||||||
this.$.data( 'view', this );
|
this.$.data( 'view', this );
|
||||||
if ( this.constructor.static.renderHtmlAttributes ) {
|
this.renderAttributes( this.model.getAttributes() );
|
||||||
ve.setDomAttributes(
|
|
||||||
this.$[0],
|
|
||||||
this.model.getAttributes( 'html/0/' ),
|
|
||||||
this.constructor.static.domAttributeWhitelist
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Inheritance */
|
/* Inheritance */
|
||||||
|
@ -116,3 +110,21 @@ ve.ce.View.prototype.setLive = function ( live ) {
|
||||||
this.live = live;
|
this.live = live;
|
||||||
this.emit( '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 */
|
/* Methods */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -201,7 +226,7 @@ ve.dm.Converter.prototype.canCloseWrapper = function () {
|
||||||
* @returns {HTMLElement|boolean} DOM element, or false if the element cannot be converted
|
* @returns {HTMLElement|boolean} DOM element, or false if the element cannot be converted
|
||||||
*/
|
*/
|
||||||
ve.dm.Converter.prototype.getDomElementsFromDataElement = function ( dataElements, doc ) {
|
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,
|
dataElement = ve.isArray( dataElements ) ? dataElements[0] : dataElements,
|
||||||
nodeClass = this.modelRegistry.lookup( dataElement.type );
|
nodeClass = this.modelRegistry.lookup( dataElement.type );
|
||||||
|
|
||||||
|
@ -218,18 +243,9 @@ ve.dm.Converter.prototype.getDomElementsFromDataElement = function ( dataElement
|
||||||
dataElementAttributes = dataElement.attributes;
|
dataElementAttributes = dataElement.attributes;
|
||||||
if ( dataElementAttributes ) {
|
if ( dataElementAttributes ) {
|
||||||
for ( key in dataElementAttributes ) {
|
for ( key in dataElementAttributes ) {
|
||||||
// Only include 'html/*' attributes and strip the prefix
|
parsed = ve.dm.Converter.parseHtmlAttribute( key, domElements );
|
||||||
/*jshint regexp:false */
|
if ( parsed && !parsed.domElement.hasAttribute( parsed.attribute ) ) {
|
||||||
matches = key.match( /^html\/((?:\d+\-)*\d)\/(.*)$/ );
|
parsed.domElement.setAttribute( parsed.attribute, dataElementAttributes[key] );
|
||||||
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] );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue