mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-15 10:35:48 +00:00
Merge "Use a smarter comparison of annotations when creating open/close tags"
This commit is contained in:
commit
bf0a227fd6
|
@ -45,6 +45,15 @@ ve.dm.LinkAnnotation.static.toDomElements = function ( dataElement, doc ) {
|
|||
return [ domElement ];
|
||||
};
|
||||
|
||||
/* Methods */
|
||||
|
||||
ve.dm.LinkAnnotation.prototype.getComparableObject = function () {
|
||||
return {
|
||||
'type': this.getType(),
|
||||
'href': this.getAttribute( 'href' )
|
||||
};
|
||||
};
|
||||
|
||||
/* Registration */
|
||||
|
||||
ve.dm.modelRegistry.register( ve.dm.LinkAnnotation );
|
||||
|
|
|
@ -50,6 +50,16 @@ ve.dm.MWExternalLinkAnnotation.static.toDomElements = function ( dataElement ) {
|
|||
return parentResult;
|
||||
};
|
||||
|
||||
/* Methods */
|
||||
|
||||
ve.dm.MWExternalLinkAnnotation.prototype.getComparableObject = function () {
|
||||
return {
|
||||
'type': this.getType(),
|
||||
'href': this.getAttribute( 'href' ),
|
||||
'rel': this.getAttribute( 'rel' ) || 'mw:ExtLink'
|
||||
};
|
||||
};
|
||||
|
||||
/* Registration */
|
||||
|
||||
ve.dm.modelRegistry.register( ve.dm.MWExternalLinkAnnotation );
|
||||
|
|
|
@ -67,6 +67,15 @@ ve.dm.MWInternalLinkAnnotation.static.toDomElements = function ( dataElement, do
|
|||
return [ domElement ];
|
||||
};
|
||||
|
||||
/* Methods */
|
||||
|
||||
ve.dm.MWInternalLinkAnnotation.prototype.getComparableObject = function () {
|
||||
return {
|
||||
'type': this.getType(),
|
||||
'title': this.getAttribute( 'title' )
|
||||
};
|
||||
};
|
||||
|
||||
/* Registration */
|
||||
|
||||
ve.dm.modelRegistry.register( ve.dm.MWInternalLinkAnnotation );
|
||||
|
|
|
@ -65,6 +65,11 @@ ve.dm.TextStyleAnnotation.static.toDomElements = function ( dataElement, doc ) {
|
|||
return [ doc.createElement( nodeNames[dataElement.type.substring( 10 )] ) ];
|
||||
};
|
||||
|
||||
/* Methods */
|
||||
|
||||
ve.dm.TextStyleAnnotation.prototype.getComparableObject = function () {
|
||||
return { 'type': this.getType() };
|
||||
};
|
||||
|
||||
/* Registration */
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
* only override static properties and functions.
|
||||
*
|
||||
* @class
|
||||
* @extends {ve.dm.Model}
|
||||
* @constructor
|
||||
* @param {Object} element Linear model annotation
|
||||
*/
|
||||
|
@ -51,3 +52,17 @@ ve.dm.Annotation.static.enableAboutGrouping = false;
|
|||
ve.dm.Annotation.prototype.getDomElements = function ( doc ) {
|
||||
return this.constructor.static.toDomElements( this.element, doc || document );
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an object containing comparable annotation properties.
|
||||
*
|
||||
* This is used by the converter to merge adjacent annotations.
|
||||
*
|
||||
* @returns {Object} An object containing a subset of the annotation's properties
|
||||
*/
|
||||
ve.dm.Annotation.prototype.getComparableObject = function () {
|
||||
return {
|
||||
'type': this.getType(),
|
||||
'attributes': this.getAttributes()
|
||||
};
|
||||
};
|
||||
|
|
|
@ -111,7 +111,7 @@ ve.dm.AnnotationSet.prototype.getLength = function () {
|
|||
* Check if the set is empty.
|
||||
*
|
||||
* @method
|
||||
* @returns {boolean} True if the set is empty, false otherwise
|
||||
* @returns {boolean} The set is empty
|
||||
*/
|
||||
ve.dm.AnnotationSet.prototype.isEmpty = function () {
|
||||
return this.getLength() === 0;
|
||||
|
@ -220,6 +220,24 @@ ve.dm.AnnotationSet.prototype.filter = function ( callback, returnBool ) {
|
|||
return returnBool ? false : result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the set contains an annotation comparable to the specified one.
|
||||
*
|
||||
* getComparableObject is used to compare the annotations, and should return
|
||||
* true if an annotation is found which is mergeable with the specified one.
|
||||
*
|
||||
* @param {ve.dm.Annotation} annotation Annotation to compare to
|
||||
* @returns {boolean} At least one comprable annotation found
|
||||
*/
|
||||
ve.dm.AnnotationSet.prototype.containsComparable = function ( annotation ) {
|
||||
return this.filter( function ( a ) {
|
||||
return ve.compareObjects(
|
||||
annotation.getComparableObject(),
|
||||
a.getComparableObject()
|
||||
);
|
||||
}, true );
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the set contains at least one annotation where a given property matches a given filter.
|
||||
*
|
||||
|
@ -229,7 +247,7 @@ ve.dm.AnnotationSet.prototype.filter = function ( callback, returnBool ) {
|
|||
*
|
||||
* @method
|
||||
* @param {Function} callback Function that takes an annotation and returns boolean true to include
|
||||
* @returns {boolean} True if at least one annotation matches, false otherwise
|
||||
* @returns {boolean} At least one matching annotation found
|
||||
*/
|
||||
ve.dm.AnnotationSet.prototype.containsMatching = function ( callback ) {
|
||||
return this.filter( callback, true );
|
||||
|
|
|
@ -63,17 +63,15 @@ ve.dm.Converter.getDataContentFromText = function ( text, annotations ) {
|
|||
* @param {ve.dm.AnnotationSet} currentSet The set of annotations currently opened. Will be modified.
|
||||
* @param {ve.dm.AnnotationSet} targetSet The set of annotations we want to have.
|
||||
* @param {Function} open Callback called when an annotation is opened. Passed a ve.dm.Annotation.
|
||||
* @param {Function} close Callback called when an annotation is closed. Passed a ve.dm.Annotation.
|
||||
* @param {Function} close Callback called when an annotation is closed.
|
||||
*/
|
||||
ve.dm.Converter.openAndCloseAnnotations = function ( currentSet, targetSet, open, close ) {
|
||||
var i, len, arr, annotation, annotationIndex, startClosingAt;
|
||||
var i, len, annotation, startClosingAt;
|
||||
// Close annotations as needed
|
||||
// Go through annotationStack from bottom to top (low to high),
|
||||
// and find the first annotation that's not in annotations.
|
||||
arr = currentSet.getIndexes();
|
||||
for ( i = 0, len = arr.length; i < len; i++ ) {
|
||||
annotationIndex = arr[i];
|
||||
if ( !targetSet.containsIndex( annotationIndex ) ) {
|
||||
for ( i = 0, len = currentSet.getLength(); i < len; i++ ) {
|
||||
if ( !targetSet.containsComparable( currentSet.get( i ) ) ) {
|
||||
startClosingAt = i;
|
||||
break;
|
||||
}
|
||||
|
@ -82,18 +80,16 @@ ve.dm.Converter.openAndCloseAnnotations = function ( currentSet, targetSet, open
|
|||
// Close all annotations from top to bottom (high to low)
|
||||
// until we reach startClosingAt
|
||||
for ( i = currentSet.getLength() - 1; i >= startClosingAt; i-- ) {
|
||||
close( arr[i] );
|
||||
close();
|
||||
// Remove from currentClone
|
||||
currentSet.removeAt( i );
|
||||
}
|
||||
}
|
||||
|
||||
// Open annotations as needed
|
||||
arr = targetSet.getIndexes();
|
||||
for ( i = 0, len = arr.length; i < len; i++ ) {
|
||||
annotationIndex = arr[i];
|
||||
if ( !currentSet.containsIndex( annotationIndex ) ) {
|
||||
annotation = targetSet.getStore().value( annotationIndex );
|
||||
for ( i = 0, len = targetSet.getLength(); i < len; i++ ) {
|
||||
annotation = targetSet.get( i );
|
||||
if ( !currentSet.containsComparable( annotation ) ) {
|
||||
open( annotation );
|
||||
// Add to currentClone
|
||||
currentSet.push( annotation );
|
||||
|
|
Loading…
Reference in a new issue