mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-29 00:30:44 +00:00
Merge "Add method to ElementLinearData to get IVStore items in use"
This commit is contained in:
commit
82b591bc63
|
@ -60,7 +60,17 @@ ve.dm.ElementLinearData.prototype.isElementData = function ( offset ) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Checks if data at a given offset is a close elements.
|
||||
* Checks if data at a given offset is an open element.
|
||||
* @method
|
||||
* @param {number} offset Document offset
|
||||
* @returns {boolean} Data at offset is an open element
|
||||
*/
|
||||
ve.dm.ElementLinearData.prototype.isOpenElementData = function ( offset ) {
|
||||
return this.isElementData( offset ) && this.getData( offset ).type.charAt( 0 ) !== '/';
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if data at a given offset is a close element.
|
||||
* @method
|
||||
* @param {number} offset Document offset
|
||||
* @returns {boolean} Data at offset is a close element
|
||||
|
@ -283,6 +293,36 @@ ve.dm.ElementLinearData.prototype.isContentData = function () {
|
|||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get annotations' store indexes covered by an offset.
|
||||
*
|
||||
* @method
|
||||
* @param {number} offset Offset to get annotations for
|
||||
* @returns {number[]} An array of annotation store indexes the offset is covered by
|
||||
* @throws {Error} offset out of bounds
|
||||
*/
|
||||
ve.dm.ElementLinearData.prototype.getAnnotationIndexesFromOffset = function ( offset ) {
|
||||
if ( offset < 0 || offset > this.getLength() ) {
|
||||
throw new Error( 'offset ' + offset + ' out of bounds' );
|
||||
}
|
||||
var element = this.getData( offset );
|
||||
// Since annotations are not stored on a closing leaf node,
|
||||
// rewind offset by 1 to return annotations for that structure
|
||||
if (
|
||||
ve.isPlainObject( element ) && // structural offset
|
||||
element.hasOwnProperty( 'type' ) && // just in case
|
||||
element.type.charAt( 0 ) === '/' && // closing offset
|
||||
ve.dm.nodeFactory.canNodeHaveChildren(
|
||||
element.type.substr( 1 )
|
||||
) === false // leaf node
|
||||
) {
|
||||
offset = this.getRelativeContentOffset( offset, -1 );
|
||||
element = this.getData( offset );
|
||||
}
|
||||
|
||||
return element.annotations || element[1] || [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Get annotations covered by an offset.
|
||||
*
|
||||
|
@ -294,27 +334,7 @@ ve.dm.ElementLinearData.prototype.isContentData = function () {
|
|||
* @throws {Error} offset out of bounds
|
||||
*/
|
||||
ve.dm.ElementLinearData.prototype.getAnnotationsFromOffset = function ( offset ) {
|
||||
if ( offset < 0 || offset > this.getLength() ) {
|
||||
throw new Error( 'offset ' + offset + ' out of bounds' );
|
||||
}
|
||||
// Since annotations are not stored on a closing leaf node,
|
||||
// rewind offset by 1 to return annotations for that structure
|
||||
var annotations;
|
||||
if (
|
||||
ve.isPlainObject( this.getData( offset ) ) && // structural offset
|
||||
this.getData( offset ).hasOwnProperty( 'type' ) && // just in case
|
||||
this.getData( offset ).type.charAt( 0 ) === '/' && // closing offset
|
||||
ve.dm.nodeFactory.canNodeHaveChildren(
|
||||
this.getData( offset ).type.substr( 1 )
|
||||
) === false // leaf node
|
||||
) {
|
||||
offset = this.getRelativeContentOffset( offset, -1 );
|
||||
}
|
||||
|
||||
annotations = this.getData( offset ).annotations || this.getData( offset )[1];
|
||||
return annotations ?
|
||||
new ve.dm.AnnotationSet( this.getStore(), annotations ) :
|
||||
new ve.dm.AnnotationSet( this.getStore() );
|
||||
return new ve.dm.AnnotationSet( this.getStore(), this.getAnnotationIndexesFromOffset( offset ) );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -390,7 +410,7 @@ ve.dm.ElementLinearData.prototype.getAnnotatedRangeFromOffset = function ( offse
|
|||
*
|
||||
* @method
|
||||
* @param {number} offset Offset to begin looking forward and backward from
|
||||
* @param {Object} annotation Annotation to test for coverage with
|
||||
* @param {ve.dm.Annotation} annotation Annotation to test for coverage with
|
||||
* @returns {ve.Range|null} Range of content covered by annotation, or a copy of the range
|
||||
*/
|
||||
ve.dm.ElementLinearData.prototype.getAnnotatedRangeFromSelection = function ( range, annotation ) {
|
||||
|
@ -700,3 +720,31 @@ ve.dm.ElementLinearData.prototype.getNearestWordRange = function ( offset ) {
|
|||
|
||||
return new ve.Range( offsetLeft, offsetRight );
|
||||
};
|
||||
|
||||
/**
|
||||
* Finds all instances of items being stored in the index-value store for this data store
|
||||
*
|
||||
* Currently this is just all annotations still in use.
|
||||
*
|
||||
* @method
|
||||
* @returns {Object} Object containing all store values, indexed by store index
|
||||
*/
|
||||
ve.dm.ElementLinearData.prototype.getUsedStoreValues = function () {
|
||||
var i, indexes, j, valueStore = {};
|
||||
i = this.getLength();
|
||||
while ( i-- ) {
|
||||
// Annotations
|
||||
indexes = this.getAnnotationIndexesFromOffset( i );
|
||||
j = indexes.length;
|
||||
while ( j-- ) {
|
||||
// Just flag item as in use for now - we will add its value
|
||||
// in a separate loop to avoid multiple store lookups
|
||||
valueStore[indexes[j]] = true;
|
||||
}
|
||||
}
|
||||
for ( i in valueStore ) {
|
||||
// Fill in actual store values
|
||||
valueStore[i] = this.getStore().value( i );
|
||||
}
|
||||
return valueStore;
|
||||
};
|
|
@ -9,8 +9,8 @@
|
|||
* Annotation set.
|
||||
*
|
||||
* @constructor
|
||||
* @param {ve.dm.IndexValueStore} store Index value store
|
||||
* @param {Object[]} [indexes] Array of indexes into the store
|
||||
* @param {ve.dm.IndexValueStore} store Index-value store
|
||||
* @param {number[]} [indexes] Array of indexes into the store
|
||||
*/
|
||||
ve.dm.AnnotationSet = function VeDmAnnotationSet( store, indexes ) {
|
||||
// Parent constructor
|
||||
|
@ -63,14 +63,14 @@ ve.dm.AnnotationSet.prototype.hasAnnotationWithName = function ( name ) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Get a value or all values from the set.
|
||||
* Get an annotation or all annotations from the set.
|
||||
*
|
||||
* set.get( 5 ) returns the object at index 5, set.get() returns an array with all objects in
|
||||
* set.get( 5 ) returns the annotation at index 5, set.get() returns an array with all annotations in
|
||||
* the entire set.
|
||||
*
|
||||
* @method
|
||||
* @param {number} [index] If set, only get the element at the index
|
||||
* @returns {Array|Object|undefined} The object at index, or an array of all objects in the set
|
||||
* @param {number} [index] If set, only get the annotation at the index
|
||||
* @returns {Array|ve.dm.Annotation|undefined} The annotation at index, or an array of all annotation in the set
|
||||
*/
|
||||
ve.dm.AnnotationSet.prototype.get = function ( index ) {
|
||||
if ( index !== undefined ) {
|
||||
|
@ -81,17 +81,17 @@ ve.dm.AnnotationSet.prototype.get = function ( index ) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Get index-value store index from offset within annotation set.
|
||||
* Get store index from offset within annotation set.
|
||||
* @param {number} offset Offset within annotation set
|
||||
* @returns {number} Index-value store index at specified offset
|
||||
* @returns {number} Store index at specified offset
|
||||
*/
|
||||
ve.dm.AnnotationSet.prototype.getIndex = function ( offset ) {
|
||||
return this.storeIndexes[offset];
|
||||
};
|
||||
|
||||
/**
|
||||
* Get all index-value store indexes.
|
||||
* @returns {Array} Index-value store indexes
|
||||
* Get all store indexes.
|
||||
* @returns {Array} Store indexes
|
||||
*/
|
||||
ve.dm.AnnotationSet.prototype.getIndexes = function () {
|
||||
return this.storeIndexes;
|
||||
|
@ -101,7 +101,7 @@ ve.dm.AnnotationSet.prototype.getIndexes = function () {
|
|||
* Get the length of the set.
|
||||
*
|
||||
* @method
|
||||
* @returns {number} The number of objects in the set
|
||||
* @returns {number} The number of annotations in the set
|
||||
*/
|
||||
ve.dm.AnnotationSet.prototype.getLength = function () {
|
||||
return this.storeIndexes.length;
|
||||
|
@ -118,23 +118,24 @@ ve.dm.AnnotationSet.prototype.isEmpty = function () {
|
|||
};
|
||||
|
||||
/**
|
||||
* Check whether a given value occurs in the set.
|
||||
* Check whether a given annotation occurs in the set.
|
||||
*
|
||||
* Values are compared by IndexValueStore index.
|
||||
* Annotations are compared by store index.
|
||||
*
|
||||
* @method
|
||||
* @returns {boolean} There is an object in the set with the same hash as value
|
||||
* @param {ve.dm.Annotation} annotation Annotation
|
||||
* @returns {boolean} There is an annotation in the set with the same hash as annotation
|
||||
*/
|
||||
ve.dm.AnnotationSet.prototype.contains = function ( value ) {
|
||||
return this.indexOf( value ) !== -1;
|
||||
ve.dm.AnnotationSet.prototype.contains = function ( annotation ) {
|
||||
return this.indexOf( annotation ) !== -1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether the set contains any of the values in another set.
|
||||
* Check whether the set contains any of the annotations in another set.
|
||||
*
|
||||
* @method
|
||||
* @param {ve.dm.AnnotationSet} set Set to compare the set with
|
||||
* @returns {boolean} There is at least one value in set that is also in the set
|
||||
* @returns {boolean} There is at least one annotation in set that is also in the set
|
||||
*/
|
||||
ve.dm.AnnotationSet.prototype.containsAnyOf = function ( set ) {
|
||||
var i, length, setIndexes = set.getIndexes(), thisIndexes = this.getIndexes();
|
||||
|
@ -147,11 +148,11 @@ ve.dm.AnnotationSet.prototype.containsAnyOf = function ( set ) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Check whether the set contains all of the values in another set.
|
||||
* Check whether the set contains all of the annotations in another set.
|
||||
*
|
||||
* @method
|
||||
* @param {ve.dm.AnnotationSet} set Set to compare the set with
|
||||
* @returns {boolean} All values in set are also in the set
|
||||
* @returns {boolean} All annotations in set are also in the set
|
||||
*/
|
||||
ve.dm.AnnotationSet.prototype.containsAllOf = function ( set ) {
|
||||
var i, length, setIndexes = set.getIndexes(), thisIndexes = this.getIndexes();
|
||||
|
@ -164,28 +165,28 @@ ve.dm.AnnotationSet.prototype.containsAllOf = function ( set ) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Get the index of a given value in the set.
|
||||
* Get the index of a given annotation in the set.
|
||||
*
|
||||
* @method
|
||||
* @param {Object} value Value to search for
|
||||
* @returns {number} Index of value in the set, or -1 if value is not in the set.
|
||||
* @param {ve.dm.Annotation} annotation Annotation to search for
|
||||
* @returns {number} Index of annotation in the set, or -1 if annotation is not in the set.
|
||||
*/
|
||||
ve.dm.AnnotationSet.prototype.indexOf = function ( value ) {
|
||||
return ve.indexOf( this.store.indexOfHash( ve.getHash( value ) ), this.getIndexes() );
|
||||
ve.dm.AnnotationSet.prototype.indexOf = function ( annotation ) {
|
||||
return ve.indexOf( this.store.indexOfHash( ve.getHash( annotation ) ), this.getIndexes() );
|
||||
};
|
||||
|
||||
/**
|
||||
* Filter the set by an item property.
|
||||
*
|
||||
* This returns a new set with all values in the set for which the callback returned true for.
|
||||
* This returns a new set with all annotations in the set for which the callback returned true for.
|
||||
*
|
||||
* @method
|
||||
* @param {Function} callback Function that takes an annotation and returns boolean true to include
|
||||
* @param {boolean} [returnBool] For internal use only
|
||||
* @returns {ve.dm.AnnotationSet} New set containing only the matching values
|
||||
* @returns {ve.dm.AnnotationSet} New set containing only the matching annotations
|
||||
*/
|
||||
ve.dm.AnnotationSet.prototype.filter = function ( callback, returnBool ) {
|
||||
var i, length, result, storeIndex, value;
|
||||
var i, length, result, storeIndex, annotation;
|
||||
|
||||
if ( !returnBool ) {
|
||||
result = this.clone();
|
||||
|
@ -196,8 +197,8 @@ ve.dm.AnnotationSet.prototype.filter = function ( callback, returnBool ) {
|
|||
}
|
||||
for ( i = 0, length = this.getLength(); i < length; i++ ) {
|
||||
storeIndex = this.getIndex( i );
|
||||
value = this.getStore().value( storeIndex );
|
||||
if ( callback( value ) ) {
|
||||
annotation = this.getStore().value( storeIndex );
|
||||
if ( callback( annotation ) ) {
|
||||
if ( returnBool ) {
|
||||
return true;
|
||||
} else {
|
||||
|
@ -209,7 +210,7 @@ ve.dm.AnnotationSet.prototype.filter = function ( callback, returnBool ) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Check if the set contains at least one value where a given property matches a given filter.
|
||||
* Check if the set contains at least one annotation where a given property matches a given filter.
|
||||
*
|
||||
* This is equivalent to (but more efficient than) `!this.filter( .. ).isEmpty()`.
|
||||
*
|
||||
|
@ -217,46 +218,46 @@ 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 value matches, false otherwise
|
||||
* @returns {boolean} True if at least one annotation matches, false otherwise
|
||||
*/
|
||||
ve.dm.AnnotationSet.prototype.containsMatching = function ( callback ) {
|
||||
return this.filter( callback, true );
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a value to the set.
|
||||
* Add an annotation to the set.
|
||||
*
|
||||
* If the value is already present in the set, nothing happens.
|
||||
* If the annotation is already present in the set, nothing happens.
|
||||
*
|
||||
* The value will be inserted before the value that is currently at the given index. If index is
|
||||
* The annotation will be inserted before the annotation that is currently at the given index. If index is
|
||||
* negative, it will be counted from the end (i.e. index -1 is the last item, -2 the second-to-last,
|
||||
* etc.). If index is out of bounds, the value will be added to the end of the set.
|
||||
* etc.). If index is out of bounds, the annotation will be added to the end of the set.
|
||||
*
|
||||
* @method
|
||||
* @param {Object} value Value to add
|
||||
* @param {number} index Index to add the value at
|
||||
* @param {ve.dm.Annotation} annotation Annotation to add
|
||||
* @param {number} index Index to add the annotation at
|
||||
*/
|
||||
ve.dm.AnnotationSet.prototype.add = function ( value, index ) {
|
||||
var storeIndex = this.getStore().index( value );
|
||||
ve.dm.AnnotationSet.prototype.add = function ( annotation, index ) {
|
||||
var storeIndex = this.getStore().index( annotation );
|
||||
// negative offset
|
||||
if ( index < 0 ) {
|
||||
index = this.getLength() + index;
|
||||
}
|
||||
// greater than length, add to end
|
||||
if ( index >= this.getLength() ) {
|
||||
this.push( value );
|
||||
this.push( annotation );
|
||||
return;
|
||||
}
|
||||
// if not in set already, splice in place
|
||||
if ( !this.contains( value ) ) {
|
||||
if ( !this.contains( annotation ) ) {
|
||||
this.storeIndexes.splice( index, 0, storeIndex );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Add all values in the given set to the end of the set.
|
||||
* Add all annotations in the given set to the end of the set.
|
||||
*
|
||||
* Values from the other set that are already in the set will not be added again.
|
||||
* Annotations from the other set that are already in the set will not be added again.
|
||||
*
|
||||
* @method
|
||||
* @param {ve.dm.AnnotationSet} set Set to add to the set
|
||||
|
@ -266,22 +267,22 @@ ve.dm.AnnotationSet.prototype.addSet = function ( set ) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Add a value at the end of the set.
|
||||
* Add an annotation at the end of the set.
|
||||
*
|
||||
* If the value is already present in the set, nothing happens.
|
||||
* If the annotation is already present in the set, nothing happens.
|
||||
*
|
||||
* @method
|
||||
* @param {Object} value Value to add
|
||||
* @param {ve.dm.Annotation} annotation Annotation to add
|
||||
*/
|
||||
ve.dm.AnnotationSet.prototype.push = function ( value ) {
|
||||
var storeIndex = this.getStore().index( value );
|
||||
if ( !this.contains( value ) ) {
|
||||
ve.dm.AnnotationSet.prototype.push = function ( annotation ) {
|
||||
var storeIndex = this.getStore().index( annotation );
|
||||
if ( !this.contains( annotation ) ) {
|
||||
this.storeIndexes.push( storeIndex );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove the value at a given index.
|
||||
* Remove the annotation at a given index.
|
||||
*
|
||||
* @method
|
||||
* @param {number} index Index to remove item at. If negative, the counts from the end, see add()
|
||||
|
@ -298,22 +299,22 @@ ve.dm.AnnotationSet.prototype.removeAt = function ( index ) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Remove a given value from the set.
|
||||
* Remove a given annotation from the set.
|
||||
*
|
||||
* If the value isn't in the set, nothing happens.
|
||||
* If the annotation isn't in the set, nothing happens.
|
||||
*
|
||||
* @method
|
||||
* @param {Object} value Value to remove
|
||||
* @param {ve.dm.Annotation} annotation Annotation to remove
|
||||
*/
|
||||
ve.dm.AnnotationSet.prototype.remove = function ( value ) {
|
||||
var index = this.indexOf( value );
|
||||
ve.dm.AnnotationSet.prototype.remove = function ( annotation ) {
|
||||
var index = this.indexOf( annotation );
|
||||
if ( index !== -1 ) {
|
||||
this.storeIndexes.splice( index, 1 );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove all values.
|
||||
* Remove all annotations.
|
||||
*
|
||||
* @method
|
||||
*/
|
||||
|
@ -322,9 +323,9 @@ ve.dm.AnnotationSet.prototype.removeAll = function () {
|
|||
};
|
||||
|
||||
/**
|
||||
* Remove all values in a given set from the set.
|
||||
* Remove all annotations in a given set from the set.
|
||||
*
|
||||
* Values that aren't in the set are ignored.
|
||||
* Annotations that aren't in the set are ignored.
|
||||
*
|
||||
* @method
|
||||
* @param {ve.dm.AnnotationSet} set Set to remove from the set
|
||||
|
@ -334,7 +335,7 @@ ve.dm.AnnotationSet.prototype.removeSet = function ( set ) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Remove all values that are not also in a given other set from the set.
|
||||
* Remove all annotations that are not also in a given other set from the set.
|
||||
*
|
||||
* @method
|
||||
* @param {ve.dm.AnnotationSet} set Set to intersect with the set
|
||||
|
@ -364,7 +365,7 @@ ve.dm.AnnotationSet.prototype.reversed = function () {
|
|||
*
|
||||
* @method
|
||||
* @param {ve.dm.AnnotationSet} set Other set
|
||||
* @returns {ve.dm.AnnotationSet} Set containing all values in the set as well as all values in set
|
||||
* @returns {ve.dm.AnnotationSet} Set containing all annotations in the set as well as all annotations in set
|
||||
*/
|
||||
ve.dm.AnnotationSet.prototype.mergeWith = function ( set ) {
|
||||
var newSet = this.clone();
|
||||
|
@ -377,7 +378,7 @@ ve.dm.AnnotationSet.prototype.mergeWith = function ( set ) {
|
|||
*
|
||||
* @method
|
||||
* @param {ve.dm.AnnotationSet} set Other set
|
||||
* @returns {ve.dm.AnnotationSet} New set containing all values that are in the set but not in set
|
||||
* @returns {ve.dm.AnnotationSet} New set containing all annotations that are in the set but not in set
|
||||
*/
|
||||
ve.dm.AnnotationSet.prototype.diffWith = function ( set ) {
|
||||
var newSet = this.clone();
|
||||
|
@ -390,7 +391,7 @@ ve.dm.AnnotationSet.prototype.diffWith = function ( set ) {
|
|||
*
|
||||
* @method
|
||||
* @param {ve.dm.AnnotationSet} set Other set
|
||||
* @returns {ve.dm.AnnotationSet} New set containing all values that are both in the set and in set
|
||||
* @returns {ve.dm.AnnotationSet} New set containing all annotations that are both in the set and in set
|
||||
*/
|
||||
ve.dm.AnnotationSet.prototype.intersectWith = function ( set ) {
|
||||
var newSet = this.clone();
|
||||
|
|
|
@ -599,9 +599,10 @@ ve.init.mw.Target.prototype.reportProblem = function ( message ) {
|
|||
ve.dm.converter.getDataFromDom(
|
||||
ve.createDocumentFromHTML( '<body>' + this.originalHtml + '</body>' ),
|
||||
store, internalList
|
||||
),
|
||||
).getData(),
|
||||
'editedData': editedData,
|
||||
'editedHtml': ve.properInnerHTML( ve.dm.converter.getDomFromData( editedData, store, internalList ).body ),
|
||||
'store': doc.data.getUsedStoreValues(),
|
||||
'wiki': mw.config.get( 'wgDBname' )
|
||||
};
|
||||
$.post(
|
||||
|
|
Loading…
Reference in a new issue