Commit 111f29c1 authored by Nick Stenning's avatar Nick Stenning

Merge pull request #3074 from hypothesis/annotation-ui-decaf

Convert 'annotation-ui' from CoffeeScript to JS
parents 38010360 57209793
value = (selection) ->
if Object.keys(selection).length then selection else null
# Holds the current state of the annotator in the attached iframes. This covers
# both tool and rendered state such as selected highlights.
module.exports = ->
visibleHighlights: false
# Contains a map of annotation tag:true pairs.
focusedAnnotationMap: null
# Contains a map of annotation id:true pairs.
selectedAnnotationMap: null
###*
# @ngdoc method
# @name annotationUI.focusedAnnotations
# @returns nothing
# @description Takes an array of annotations and uses them to set
# the focusedAnnotationMap.
###
focusAnnotations: (annotations) ->
selection = {}
selection[$$tag] = true for {$$tag} in annotations
@focusedAnnotationMap = value(selection)
###*
# @ngdoc method
# @name annotationUI.hasSelectedAnnotations
# @returns true if there are any selected annotations.
###
hasSelectedAnnotations: ->
!!@selectedAnnotationMap
###*
# @ngdoc method
# @name annotationUI.isAnnotationSelected
# @returns true if the provided annotation is selected.
###
isAnnotationSelected: (id) ->
!!@selectedAnnotationMap?[id]
###*
# @ngdoc method
# @name annotationUI.selectAnnotations
# @returns nothing
# @description Takes an array of annotation objects and uses them to
# set the selectedAnnotationMap property.
###
selectAnnotations: (annotations) ->
selection = {}
selection[id] = true for {id} in annotations
@selectedAnnotationMap = value(selection)
###*
# @ngdoc method
# @name annotationUI.xorSelectedAnnotations()
# @returns nothing
# @description takes an array of annotations and adds them to the
# selectedAnnotationMap if not present otherwise removes them.
###
xorSelectedAnnotations: (annotations) ->
selection = angular.extend({}, @selectedAnnotationMap)
for {id} in annotations
if selection[id]
delete selection[id]
else
selection[id] = true
@selectedAnnotationMap = value(selection)
###*
# @ngdoc method
# @name annotationUI.removeSelectedAnnotation()
# @returns nothing
# @description removes an annotation from the current selection.
###
removeSelectedAnnotation: (annotation) ->
selection = angular.extend({}, @selectedAnnotationMap)
if selection
delete selection[annotation.id]
@selectedAnnotationMap = value(selection)
###*
# @ngdoc method
# @name annotationUI.clearSelectedAnnotations()
# @returns nothing
# @description removes all annotations from the current selection.
###
clearSelectedAnnotations: ->
@selectedAnnotationMap = null
'use strict';
function value(selection) {
if (Object.keys(selection).length) {
return selection;
} else {
return null;
}
}
/**
* Stores the UI state of the annotator in connected clients.
*
* This includes:
* - The set of annotations that are currently selected
* - The annotation(s) that are currently hovered/focused
* - The state of the bucket bar
*
*/
module.exports = function () {
return {
visibleHighlights: false,
// Contains a map of annotation tag:true pairs.
focusedAnnotationMap: null,
// Contains a map of annotation id:true pairs.
selectedAnnotationMap: null,
/**
* @ngdoc method
* @name annotationUI.focusedAnnotations
* @returns nothing
* @description Takes an array of annotations and uses them to set
* the focusedAnnotationMap.
*/
focusAnnotations: function (annotations) {
var selection = {};
for (var i = 0, annotation; i < annotations.length; i++) {
annotation = annotations[i];
selection[annotation.$$tag] = true;
}
this.focusedAnnotationMap = value(selection);
},
/**
* @ngdoc method
* @name annotationUI.hasSelectedAnnotations
* @returns true if there are any selected annotations.
*/
hasSelectedAnnotations: function () {
return !!this.selectedAnnotationMap;
},
/**
* @ngdoc method
* @name annotationUI.isAnnotationSelected
* @returns true if the provided annotation is selected.
*/
isAnnotationSelected: function (id) {
return (this.selectedAnnotationMap || {}).hasOwnProperty(id);
},
/**
* @ngdoc method
* @name annotationUI.selectAnnotations
* @returns nothing
* @description Takes an array of annotation objects and uses them to
* set the selectedAnnotationMap property.
*/
selectAnnotations: function (annotations) {
var selection = {};
for (var i = 0, annotation; i < annotations.length; i++) {
annotation = annotations[i];
selection[annotation.id] = true;
}
this.selectedAnnotationMap = value(selection);
},
/**
* @ngdoc method
* @name annotationUI.xorSelectedAnnotations()
* @returns nothing
* @description takes an array of annotations and adds them to the
* selectedAnnotationMap if not present otherwise removes them.
*/
xorSelectedAnnotations: function (annotations) {
var selection = Object.assign({}, this.selectedAnnotationMap);
for (var i = 0, annotation; i < annotations.length; i++) {
annotation = annotations[i];
var id = annotation.id;
if (selection[id]) {
delete selection[id];
} else {
selection[id] = true;
}
}
this.selectedAnnotationMap = value(selection);
},
/**
* @ngdoc method
* @name annotationUI.removeSelectedAnnotation()
* @returns nothing
* @description removes an annotation from the current selection.
*/
removeSelectedAnnotation: function (annotation) {
var selection = Object.assign({}, this.selectedAnnotationMap);
if (selection) {
delete selection[annotation.id];
this.selectedAnnotationMap = value(selection);
}
},
/**
* @ngdoc method
* @name annotationUI.clearSelectedAnnotations()
* @returns nothing
* @description removes all annotations from the current selection.
*/
clearSelectedAnnotations: function () {
this.selectedAnnotationMap = null;
}
};
};
{module, inject} = angular.mock
describe 'annotationUI', ->
annotationUI = null
before ->
angular.module('h', [])
.service('annotationUI', require('../annotation-ui'))
beforeEach module('h')
beforeEach inject (_annotationUI_) ->
annotationUI = _annotationUI_
describe '.focusAnnotations()', ->
it 'adds the passed annotations to the focusedAnnotationMap', ->
annotationUI.focusAnnotations([{$$tag: 1}, {$$tag: 2}, {$$tag: 3}])
assert.deepEqual(annotationUI.focusedAnnotationMap, {
1: true, 2: true, 3: true
})
it 'replaces any annotations originally in the map', ->
annotationUI.focusedAnnotationMap = {1: true}
annotationUI.focusAnnotations([{$$tag: 2}, {$$tag: 3}])
assert.deepEqual(annotationUI.focusedAnnotationMap, {
2: true, 3: true
})
it 'does not modify the original map object', ->
orig = annotationUI.focusedAnnotationMap = {1: true}
annotationUI.focusAnnotations([{$$tag: 2}, {$$tag: 3}])
assert.notEqual(annotationUI.focusedAnnotationMap, orig)
it 'nulls the map if no annotations are focused', ->
orig = annotationUI.focusedAnnotationMap = {$$tag: true}
annotationUI.focusAnnotations([])
assert.isNull(annotationUI.focusedAnnotationMap)
describe '.hasSelectedAnnotations', ->
it 'returns true if there are any selected annotations', ->
annotationUI.selectedAnnotationMap = {1: true}
assert.isTrue(annotationUI.hasSelectedAnnotations())
it 'returns false if there are no selected annotations', ->
annotationUI.selectedAnnotationMap = null
assert.isFalse(annotationUI.hasSelectedAnnotations())
describe '.isAnnotationSelected', ->
it 'returns true if the id provided is selected', ->
annotationUI.selectedAnnotationMap = {1: true}
assert.isTrue(annotationUI.isAnnotationSelected(1))
it 'returns false if the id provided is not selected', ->
annotationUI.selectedAnnotationMap = {1: true}
assert.isFalse(annotationUI.isAnnotationSelected(2))
it 'returns false if there are no selected annotations', ->
annotationUI.selectedAnnotationMap = null
assert.isFalse(annotationUI.isAnnotationSelected(1))
describe '.selectAnnotations()', ->
it 'adds the passed annotations to the selectedAnnotationMap', ->
annotationUI.selectAnnotations([{id: 1}, {id: 2}, {id: 3}])
assert.deepEqual(annotationUI.selectedAnnotationMap, {
1: true, 2: true, 3: true
})
it 'replaces any annotations originally in the map', ->
annotationUI.selectedAnnotationMap = {1: true}
annotationUI.selectAnnotations([{id: 2}, {id: 3}])
assert.deepEqual(annotationUI.selectedAnnotationMap, {
2: true, 3: true
})
it 'does not modify the original map object', ->
orig = annotationUI.selectedAnnotationMap = {1: true}
annotationUI.selectAnnotations([{id: 2}, {id: 3}])
assert.notEqual(annotationUI.selectedAnnotationMap, orig)
it 'nulls the map if no annotations are selected', ->
orig = annotationUI.selectedAnnotationMap = {1: true}
annotationUI.selectAnnotations([])
assert.isNull(annotationUI.selectedAnnotationMap)
describe '.xorSelectedAnnotations()', ->
it 'adds annotations missing from the selectedAnnotationMap', ->
annotationUI.selectedAnnotationMap = {1: true, 2: true}
annotationUI.xorSelectedAnnotations([{id: 3}, {id: 4}])
assert.deepEqual(annotationUI.selectedAnnotationMap, {
1: true, 2: true, 3: true, 4: true
})
it 'removes annotations already in the selectedAnnotationMap', ->
annotationUI.selectedAnnotationMap = {1: true, 3: true}
annotationUI.xorSelectedAnnotations([{id: 1}, {id: 2}])
assert.deepEqual(annotationUI.selectedAnnotationMap, 2:true, 3: true)
it 'does not modify the original map object', ->
orig = annotationUI.selectedAnnotationMap = {1: true}
annotationUI.xorSelectedAnnotations([{id: 2}, {id: 3}])
assert.notEqual(annotationUI.selectedAnnotationMap, orig)
it 'nulls the map if no annotations are selected', ->
orig = annotationUI.selectedAnnotationMap = {1: true}
annotationUI.xorSelectedAnnotations([id: 1])
assert.isNull(annotationUI.selectedAnnotationMap)
describe '.removeSelectedAnnotation', ->
it 'removes an annotation from the selectedAnnotationMap', ->
annotationUI.selectedAnnotationMap = {1: true, 2: true, 3: true}
annotationUI.removeSelectedAnnotation(id: 2)
assert.deepEqual(annotationUI.selectedAnnotationMap, {
1: true, 3: true
})
it 'does not modify the original map object', ->
orig = annotationUI.selectedAnnotationMap = {1: true}
annotationUI.removeSelectedAnnotation(id: 1)
assert.notEqual(annotationUI.selectedAnnotationMap, orig)
it 'nulls the map if no annotations are selected', ->
orig = annotationUI.selectedAnnotationMap = {1: true}
annotationUI.removeSelectedAnnotation(id: 1)
assert.isNull(annotationUI.selectedAnnotationMap)
describe '.clearSelectedAnnotations', ->
it 'removes all annotations from the selection', ->
annotationUI.selectedAnnotationMap = {1: true, 2: true, 3: true}
annotationUI.clearSelectedAnnotations()
assert.isNull(annotationUI.selectedAnnotationMap)
'use strict';
describe('annotationUI', function () {
var annotationUI;
beforeEach(function () {
annotationUI = require('../annotation-ui')();
});
describe('.focusAnnotations()', function () {
it('adds the passed annotations to the focusedAnnotationMap', function () {
annotationUI.focusAnnotations([{ $$tag: 1 }, { $$tag: 2 }, { $$tag: 3 }]);
assert.deepEqual(annotationUI.focusedAnnotationMap, {
1: true, 2: true, 3: true
});
});
it('replaces any annotations originally in the map', function () {
annotationUI.focusedAnnotationMap = { 1: true };
annotationUI.focusAnnotations([{ $$tag: 2 }, { $$tag: 3 }]);
assert.deepEqual(annotationUI.focusedAnnotationMap, {
2: true, 3: true
});
});
it('does not modify the original map object', function () {
var orig = annotationUI.focusedAnnotationMap = { 1: true };
annotationUI.focusAnnotations([{ $$tag: 2 }, { $$tag: 3 }]);
assert.notEqual(annotationUI.focusedAnnotationMap, orig);
});
it('nulls the map if no annotations are focused', function () {
annotationUI.focusedAnnotationMap = { $$tag: true };
annotationUI.focusAnnotations([]);
assert.isNull(annotationUI.focusedAnnotationMap);
});
});
describe('.hasSelectedAnnotations', function () {
it('returns true if there are any selected annotations', function () {
annotationUI.selectedAnnotationMap = { 1: true };
assert.isTrue(annotationUI.hasSelectedAnnotations());
});
it('returns false if there are no selected annotations', function () {
annotationUI.selectedAnnotationMap = null;
assert.isFalse(annotationUI.hasSelectedAnnotations());
});
});
describe('.isAnnotationSelected', function () {
it('returns true if the id provided is selected', function () {
annotationUI.selectedAnnotationMap = { 1: true };
assert.isTrue(annotationUI.isAnnotationSelected(1));
});
it('returns false if the id provided is not selected', function () {
annotationUI.selectedAnnotationMap = { 1: true };
assert.isFalse(annotationUI.isAnnotationSelected(2));
});
it('returns false if there are no selected annotations', function () {
annotationUI.selectedAnnotationMap = null;
assert.isFalse(annotationUI.isAnnotationSelected(1));
});
});
describe('.selectAnnotations()', function () {
it('adds the passed annotations to the selectedAnnotationMap', function () {
annotationUI.selectAnnotations([{ id: 1 }, { id: 2 }, { id: 3 }]);
assert.deepEqual(annotationUI.selectedAnnotationMap, {
1: true, 2: true, 3: true
});
});
it('replaces any annotations originally in the map', function () {
annotationUI.selectedAnnotationMap = { 1: true };
annotationUI.selectAnnotations([{ id: 2 }, { id: 3 }]);
assert.deepEqual(annotationUI.selectedAnnotationMap, {
2: true, 3: true
});
});
it('does not modify the original map object', function () {
var orig = annotationUI.selectedAnnotationMap = { 1: true };
annotationUI.selectAnnotations([{ id: 2 }, { id: 3 }]);
assert.notEqual(annotationUI.selectedAnnotationMap, orig);
});
it('nulls the map if no annotations are selected', function () {
annotationUI.selectedAnnotationMap = { 1: true };
annotationUI.selectAnnotations([]);
assert.isNull(annotationUI.selectedAnnotationMap);
});
});
describe('.xorSelectedAnnotations()', function () {
it('adds annotations missing from the selectedAnnotationMap', function () {
annotationUI.selectedAnnotationMap = { 1: true, 2: true };
annotationUI.xorSelectedAnnotations([{ id: 3 }, { id: 4 }]);
assert.deepEqual(annotationUI.selectedAnnotationMap, {
1: true, 2: true, 3: true, 4: true
});
});
it('removes annotations already in the selectedAnnotationMap', function () {
annotationUI.selectedAnnotationMap = { 1: true, 3: true };
annotationUI.xorSelectedAnnotations([{ id: 1 }, { id: 2 }]);
assert.deepEqual(annotationUI.selectedAnnotationMap, { 2: true, 3: true });
});
it('does not modify the original map object', function () {
var orig = annotationUI.selectedAnnotationMap = { 1: true };
annotationUI.xorSelectedAnnotations([{ id: 2 }, { id: 3 }]);
assert.notEqual(annotationUI.selectedAnnotationMap, orig);
});
it('nulls the map if no annotations are selected', function () {
annotationUI.selectedAnnotationMap = { 1: true };
annotationUI.xorSelectedAnnotations([{ id: 1 }]);
assert.isNull(annotationUI.selectedAnnotationMap);
});
});
describe('.removeSelectedAnnotation', function () {
it('removes an annotation from the selectedAnnotationMap', function () {
annotationUI.selectedAnnotationMap = { 1: true, 2: true, 3: true };
annotationUI.removeSelectedAnnotation({ id: 2 });
assert.deepEqual(annotationUI.selectedAnnotationMap, {
1: true, 3: true
});
});
it('does not modify the original map object', function () {
var orig = annotationUI.selectedAnnotationMap = { 1: true };
annotationUI.removeSelectedAnnotation({ id: 1 });
assert.notEqual(annotationUI.selectedAnnotationMap, orig);
});
it('nulls the map if no annotations are selected', function () {
annotationUI.selectedAnnotationMap = { 1: true };
annotationUI.removeSelectedAnnotation({ id: 1 });
assert.isNull(annotationUI.selectedAnnotationMap);
});
});
describe('.clearSelectedAnnotations', function () {
it('removes all annotations from the selection', function () {
annotationUI.selectedAnnotationMap = { 1: true, 2: true, 3: true };
annotationUI.clearSelectedAnnotations();
assert.isNull(annotationUI.selectedAnnotationMap);
});
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment