mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-15 18:39:52 +00:00
Rewrite data model methods needed for ui tools
getAnnotationRangeFromOffset and offsetContainsAnnotation which deprecated getAnnotationBoundaries, and getIndexOfAnnotation write unit tests for proof Change-Id: I6c0d4e3ca96dd569b1909cd22fce68c3a6fe382c
This commit is contained in:
parent
eefbee2262
commit
fbaea888b9
|
@ -198,6 +198,54 @@ ve.dm.DocumentFragment.prototype.getAnnotationsFromOffset = function( offset ) {
|
|||
return [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Does this offset contain the specified annotation
|
||||
*
|
||||
* @method
|
||||
* @param {Integer} offset Offset to look at
|
||||
* @param {Object} annotation Object to look for
|
||||
* @returns {Boolean} Whether an offset contains the specified annotation
|
||||
*/
|
||||
ve.dm.DocumentFragment.prototype.offsetContainsAnnotation = function ( offset, annotation ) {
|
||||
var annotations = this.getAnnotationsFromOffset( offset );
|
||||
for (var i=0;i<annotations.length;i++){
|
||||
if (ve.compareObjects(annotations[i], annotation)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the range of content surrounding a given offset that's covered by a given annotation.
|
||||
*
|
||||
* @param {Integer} offset Offset to begin looking forward and backward from
|
||||
* @param {Object} annotation Annotation to test for coverage with
|
||||
* @returns {ve.Range|null} Range of content covered by annotation, or null if offset is not covered
|
||||
*/
|
||||
ve.dm.DocumentFragment.prototype.getAnnotationRangeFromOffset = function ( offset, annotation ) {
|
||||
var start = offset,
|
||||
end = offset;
|
||||
if ( this.offsetContainsAnnotation(offset, annotation) === false ) {
|
||||
return null;
|
||||
}
|
||||
while ( start > 0 ) {
|
||||
start--;
|
||||
if ( this.offsetContainsAnnotation(start, annotation ) === false ) {
|
||||
start++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while ( end < this.data.length ) {
|
||||
end++;
|
||||
if ( this.offsetContainsAnnotation(end, annotation ) === false ) {
|
||||
end--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new ve.Range( start, end );
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets an array of common annnotations across a range.
|
||||
*
|
||||
|
|
|
@ -310,3 +310,102 @@ test( 'getAnnotationsFromRange', 1, function() {
|
|||
});
|
||||
|
||||
|
||||
test( 'offsetContainsAnnotation', 1, function(){
|
||||
var cases = [
|
||||
{
|
||||
msg: 'contains no annotations',
|
||||
data: [
|
||||
['a']
|
||||
],
|
||||
lookFor: {'type': 'bold'},
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
msg: 'contains bold',
|
||||
data: [
|
||||
['a', { '{"type:"bold"}': { 'type': 'bold' } } ]
|
||||
],
|
||||
lookFor: {'type': 'bold'},
|
||||
expected: true
|
||||
},
|
||||
{
|
||||
msg: 'contains bold',
|
||||
data: [
|
||||
['a', {
|
||||
'{"type:"bold"}': { 'type': 'bold' },
|
||||
'{"type":"italic"}': { 'type': 'italic'}
|
||||
}
|
||||
]
|
||||
],
|
||||
lookFor: {'type': 'bold'},
|
||||
expected: true
|
||||
}
|
||||
],
|
||||
fragment;
|
||||
|
||||
expect( cases.length );
|
||||
|
||||
for( var i=0;i<cases.length;i++) {
|
||||
fragment = new ve.dm.DocumentFragment( cases[i].data );
|
||||
|
||||
deepEqual(
|
||||
fragment.offsetContainsAnnotation(0, cases[i].lookFor),
|
||||
cases[i].expected,
|
||||
cases[i].msg
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test( 'getAnnotationRangeFromOffset', 1, function(){
|
||||
var cases = [
|
||||
{
|
||||
msg: 'a bold word',
|
||||
data: [
|
||||
['a'], //0
|
||||
['b', { '{"type:"bold"}': { 'type': 'bold' } } ], //1
|
||||
['o', { '{"type:"bold"}': { 'type': 'bold' } } ], //2
|
||||
['l', { '{"type:"bold"}': { 'type': 'bold' } } ], //3
|
||||
['d', { '{"type:"bold"}': { 'type': 'bold' } } ], //4
|
||||
['w'], //5
|
||||
['o'], //6
|
||||
['r'], //7
|
||||
['d'] //8
|
||||
],
|
||||
annotation: { 'type': 'bold' },
|
||||
offset: 3,
|
||||
expected: new ve.Range( 1, 4 )
|
||||
},
|
||||
{
|
||||
msg: 'a linked',
|
||||
data: [
|
||||
['x'], //0
|
||||
['x'], //1
|
||||
['x'], //2
|
||||
['l', { '{"type:"link/internal"}': { 'type': 'link/internal' } } ], //3
|
||||
['i', { '{"type:"link/internal"}': { 'type': 'link/internal' } } ], //4
|
||||
['n', { '{"type:"link/internal"}': { 'type': 'link/internal' } } ], //5
|
||||
['k', { '{"type:"link/internal"}': { 'type': 'link/internal' } } ], //6
|
||||
['x'], //7
|
||||
['x'], //8
|
||||
['x'] //9
|
||||
],
|
||||
annotation: { 'type': 'link/internal' },
|
||||
offset: 3,
|
||||
expected: new ve.Range( 3, 6 )
|
||||
}
|
||||
],
|
||||
fragment;
|
||||
|
||||
expect( cases.length );
|
||||
|
||||
for( var i=0;i<cases.length;i++) {
|
||||
fragment = new ve.dm.DocumentFragment( cases[i].data );
|
||||
|
||||
deepEqual(
|
||||
fragment.getAnnotationRangeFromOffset(cases[i].offset, cases[i].annotation),
|
||||
cases[i].expected,
|
||||
cases[i].msg
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue