From c2a89626d564f612f2e591b1eec740ca127bc817 Mon Sep 17 00:00:00 2001 From: Rob Moen Date: Thu, 17 May 2012 10:46:27 -0700 Subject: [PATCH] Rewrite getMatchingAnnotations to return a hashmap of matching anntations in the new DM. Change method name getAnnotationRange from offset to getAnnotatedRangeFromOffset. Write tests Change-Id: I7028803065409e271ceced73e4803954d4a956dc --- modules/ve2/dm/ve.dm.DocumentFragment.js | 27 ++++- tests/ve2/dm/ve.dm.DocumentFragment.test.js | 111 +++++++++++++++++++- 2 files changed, 135 insertions(+), 3 deletions(-) diff --git a/modules/ve2/dm/ve.dm.DocumentFragment.js b/modules/ve2/dm/ve.dm.DocumentFragment.js index 1c18d4b1d6..4a3117cb30 100644 --- a/modules/ve2/dm/ve.dm.DocumentFragment.js +++ b/modules/ve2/dm/ve.dm.DocumentFragment.js @@ -223,7 +223,7 @@ ve.dm.DocumentFragment.prototype.offsetContainsAnnotation = function ( offset, a * @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 ) { +ve.dm.DocumentFragment.prototype.getAnnotatedRangeFromOffset = function ( offset, annotation ) { var start = offset, end = offset; if ( this.offsetContainsAnnotation(offset, annotation) === false ) { @@ -246,6 +246,31 @@ ve.dm.DocumentFragment.prototype.getAnnotationRangeFromOffset = function ( offse return new ve.Range( start, end ); }; +/** + * Gets a list of annotations that match a regular expression. + * + * @static + * @methodng + * @param {Array} offsetData first index is a character, followed by an object of annotations + * @param {RegExp} pattern Regular expression pattern to match with + * @returns {Object} hashmap of annotations that match the pattern + */ +ve.dm.DocumentFragment.prototype.getMatchingAnnotations = function( offsetData, pattern ) { + if ( !( pattern instanceof RegExp ) ) { + throw 'Invalid Pattern. Pattern not instance of RegExp'; + } + var annotations = offsetData[1], + annotation = {}, + matches = {}; + + for (annotation in annotations) { + if( pattern.test( annotations[annotation].type )){ + matches[annotation] = annotations[annotation]; + } + } + return matches; +}; + /** * Gets an array of common annnotations across a range. * diff --git a/tests/ve2/dm/ve.dm.DocumentFragment.test.js b/tests/ve2/dm/ve.dm.DocumentFragment.test.js index 41cfbb2866..890b1b1bbf 100644 --- a/tests/ve2/dm/ve.dm.DocumentFragment.test.js +++ b/tests/ve2/dm/ve.dm.DocumentFragment.test.js @@ -356,7 +356,7 @@ test( 'offsetContainsAnnotation', 1, function(){ } }); -test( 'getAnnotationRangeFromOffset', 1, function(){ +test( 'getAnnotatedRangeFromOffset', 1, function(){ var cases = [ { msg: 'a bold word', @@ -402,10 +402,117 @@ test( 'getAnnotationRangeFromOffset', 1, function(){ fragment = new ve.dm.DocumentFragment( cases[i].data ); deepEqual( - fragment.getAnnotationRangeFromOffset(cases[i].offset, cases[i].annotation), + fragment.getAnnotatedRangeFromOffset(cases[i].offset, cases[i].annotation), cases[i].expected, cases[i].msg ); } }); +test('getMatchingAnnotations', 1, function(){ + var cases = [ + { + msg: 'link part: ', + data: [ + ['l', { + '{"type":"bold"}': { 'type': 'bold' }, + '{"type":"italic"}': { 'type': 'italic'}, + '{"type":"underline"}': { 'type': 'underline'}, + '{"type:"link/internal"}': { 'type': 'link/internal' } + } + ], //0 + ['i', { + '{"type":"underline"}': { 'type': 'underline'}, + '{"type:"link/internal"}': { 'type': 'link/internal' }, + '{"type":"bold"}': { 'type': 'bold' }, + '{"type":"italic"}': { 'type': 'italic'} + } + ], //1 + ['n', { + '{"type:"link/internal"}': { 'type': 'link/internal' }, + '{"type":"underline"}': { 'type': 'underline'}, + '{"type":"bold"}': { 'type': 'bold' }, + '{"type":"italic"}': { 'type': 'italic'} + } + ], //2 + ['k', { + '{"type":"bold"}': { 'type': 'bold' }, + '{"type":"italic"}': { 'type': 'italic'}, + '{"type:"link/internal"}': { 'type': 'link/internal' }, + '{"type":"underline"}': { 'type': 'underline'} + } + ] //3 + ], + match: /link\/.*/, + expected: [ + { + '{"type:"link/internal"}': { 'type': 'link/internal' } + }, + { + '{"type:"link/internal"}': { 'type': 'link/internal' } + }, + { + '{"type:"link/internal"}': { 'type': 'link/internal' } + }, + { + '{"type:"link/internal"}': { 'type': 'link/internal' } + } + ] + }, + { + msg: 'bold test: ', + data: [ + ['b', { + '{"type":"bold"}': { 'type': 'bold' } + } + ], //0 + ['o', { + '{"type":"bold"}': { 'type': 'bold' } + } + ], //1 + ['l', { + '{"type":"bold"}': { 'type': 'bold' } + } + ], //2 + ['d', { + '{"type":"italic"}': { 'type': 'italic'} + } + ] //3 + ], + match: /bold/, + expected: [ + { + '{"type":"bold"}': { 'type': 'bold' } + }, + { + '{"type":"bold"}': { 'type': 'bold' } + }, + { + '{"type":"bold"}': { 'type': 'bold' } + }, + {} + ] + } + ], + fragment, + expectCount = 0; + //count tests + for (var c = 0; c < cases.length; c++) { + expectCount += cases[c].data.length; + } + + expect ( expectCount ); + + for( var i=0;i