-
Notifications
You must be signed in to change notification settings - Fork 422
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3131 from hypothesis/t256-annotation-ui-decaf
Convert AnnotationUI, AnnotationUISync from CoffeeScript to JS
- Loading branch information
Showing
8 changed files
with
349 additions
and
251 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
'use strict'; | ||
|
||
/** Watch the UI state and update scope properties. */ | ||
// @ngInject | ||
function AnnotationUIController($rootScope, $scope, annotationUI) { | ||
$rootScope.$watch(function () { | ||
return annotationUI.selectedAnnotationMap; | ||
}, function (map) { | ||
map = map || {}; | ||
var count = Object.keys(map).length; | ||
$scope.selectedAnnotationsCount = count; | ||
|
||
if (count) { | ||
$scope.selectedAnnotations = map; | ||
} else { | ||
$scope.selectedAnnotations = null; | ||
} | ||
}); | ||
|
||
$rootScope.$watch(function () { | ||
return annotationUI.focusedAnnotationMap; | ||
}, function (map) { | ||
map = map || {}; | ||
$scope.focusedAnnotations = map; | ||
}); | ||
|
||
$rootScope.$on('annotationDeleted', function (event, annotation) { | ||
annotationUI.removeSelectedAnnotation(annotation); | ||
}); | ||
} | ||
|
||
module.exports = AnnotationUIController; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
'use strict'; | ||
|
||
/** | ||
* Uses a channel between the sidebar and the attached frames to ensure | ||
* the interface remains in sync. | ||
* | ||
* @name AnnotationUISync | ||
* @param {$window} $window An Angular window service. | ||
* @param {Bridge} bridge | ||
* @param {AnnotationSync} annotationSync | ||
* @param {AnnotationUI} annotationUI An instance of the AnnotatonUI service | ||
* @description | ||
* Listens for incoming events over the bridge concerning the annotation | ||
* interface and updates the applications internal state. It also ensures | ||
* that the messages are broadcast out to other frames. | ||
*/ | ||
// @ngInject | ||
function AnnotationUISync($rootScope, $window, bridge, annotationSync, | ||
annotationUI) { | ||
// Retrieves annotations from the annotationSync cache. | ||
var getAnnotationsByTags = function (tags) { | ||
return tags.map(annotationSync.getAnnotationForTag, annotationSync); | ||
}; | ||
|
||
var channelListeners = { | ||
showAnnotations: function (tags) { | ||
tags = tags || []; | ||
var annotations = getAnnotationsByTags(tags); | ||
annotationUI.selectAnnotations(annotations); | ||
}, | ||
focusAnnotations: function (tags) { | ||
tags = tags || []; | ||
var annotations = getAnnotationsByTags(tags); | ||
annotationUI.focusAnnotations(annotations); | ||
}, | ||
toggleAnnotationSelection: function (tags) { | ||
tags = tags || []; | ||
var annotations = getAnnotationsByTags(tags); | ||
annotationUI.xorSelectedAnnotations(annotations); | ||
}, | ||
setVisibleHighlights: function (state) { | ||
if (typeof state !== 'boolean') { | ||
state = true; | ||
} | ||
if (annotationUI.visibleHighlights !== state) { | ||
annotationUI.visibleHighlights = state; | ||
bridge.call('setVisibleHighlights', state); | ||
} | ||
} | ||
}; | ||
|
||
// Because the channel events are all outside of the angular framework we | ||
// need to inform Angular that it needs to re-check it's state and re-draw | ||
// any UI that may have been affected by the handlers. | ||
var ensureDigest = function (fn) { | ||
return function () { | ||
fn.apply(this, arguments); | ||
$rootScope.$digest(); | ||
}; | ||
}; | ||
|
||
for (var channel in channelListeners) { | ||
if (Object.prototype.hasOwnProperty.call(channelListeners, channel)) { | ||
var listener = channelListeners[channel]; | ||
bridge.on(channel, ensureDigest(listener)); | ||
} | ||
} | ||
|
||
var onConnect = function (channel, source) { | ||
if (source === $window.parent) { | ||
// The host initializes its own state | ||
return; | ||
} else { | ||
// Synchronize the state of guests | ||
channel.call('setVisibleHighlights', annotationUI.visibleHighlights); | ||
} | ||
}; | ||
|
||
bridge.onConnect(onConnect); | ||
} | ||
|
||
module.exports = AnnotationUISync; |
56 changes: 0 additions & 56 deletions
56
h/static/scripts/test/annotation-ui-controller-test.coffee
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
'use strict'; | ||
|
||
var angular = require('angular'); | ||
|
||
describe('AnnotationUIController', function () { | ||
var $scope; | ||
var $rootScope; | ||
var annotationUI; | ||
var sandbox; | ||
|
||
before(function () { | ||
angular.module('h', []) | ||
.controller('AnnotationUIController', | ||
require('../annotation-ui-controller')); | ||
}); | ||
|
||
beforeEach(angular.mock.module('h')); | ||
beforeEach(angular.mock.inject(function ($controller, _$rootScope_) { | ||
sandbox = sinon.sandbox.create(); | ||
|
||
$rootScope = _$rootScope_; | ||
$scope = $rootScope.$new(); | ||
$scope.search = {}; | ||
|
||
annotationUI = { | ||
tool: 'comment', | ||
selectedAnnotationMap: null, | ||
focusedAnnotationsMap: null, | ||
removeSelectedAnnotation: sandbox.stub() | ||
}; | ||
|
||
$controller('AnnotationUIController', { | ||
$scope: $scope, | ||
annotationUI: annotationUI, | ||
}); | ||
})); | ||
|
||
afterEach(function () { | ||
sandbox.restore(); | ||
}); | ||
|
||
it('updates the view when the selection changes', function () { | ||
annotationUI.selectedAnnotationMap = { 1: true, 2: true }; | ||
$rootScope.$digest(); | ||
assert.deepEqual($scope.selectedAnnotations, { 1: true, 2: true }); | ||
}); | ||
|
||
it('updates the selection counter when the selection changes', function () { | ||
annotationUI.selectedAnnotationMap = { 1: true, 2: true }; | ||
$rootScope.$digest(); | ||
assert.deepEqual($scope.selectedAnnotationsCount, 2); | ||
}); | ||
|
||
it('clears the selection when no annotations are selected', function () { | ||
annotationUI.selectedAnnotationMap = {}; | ||
$rootScope.$digest(); | ||
assert.deepEqual($scope.selectedAnnotations, null); | ||
assert.deepEqual($scope.selectedAnnotationsCount, 0); | ||
}); | ||
|
||
it('updates the focused annotations when the focus map changes', function () { | ||
annotationUI.focusedAnnotationMap = { 1: true, 2: true }; | ||
$rootScope.$digest(); | ||
assert.deepEqual($scope.focusedAnnotations, { 1: true, 2: true }); | ||
}); | ||
|
||
describe('on annotationDeleted', function () { | ||
it('removes the deleted annotation from the selection', function () { | ||
$rootScope.$emit('annotationDeleted', { id: 1 }); | ||
assert.calledWith(annotationUI.removeSelectedAnnotation, { id: 1 }); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.