Unverified Commit cf10d9f3 authored by Sean Hammond's avatar Sean Hammond Committed by GitHub

Merge pull request #695 from hypothesis/rename-annotationui-to-store

Rename "annotationUI" => "store"
parents 8b15381f f5a519be
...@@ -24,12 +24,12 @@ function fetchThread(api, id) { ...@@ -24,12 +24,12 @@ function fetchThread(api, id) {
// @ngInject // @ngInject
function AnnotationViewerContentController ( function AnnotationViewerContentController (
$location, $routeParams, annotationUI, api, rootThread, streamer, $location, $routeParams, store, api, rootThread, streamer,
streamFilter, annotationMapper streamFilter, annotationMapper
) { ) {
var self = this; var self = this;
annotationUI.setAppIsSidebar(false); store.setAppIsSidebar(false);
var id = $routeParams.id; var id = $routeParams.id;
...@@ -37,12 +37,12 @@ function AnnotationViewerContentController ( ...@@ -37,12 +37,12 @@ function AnnotationViewerContentController (
$location.path('/stream').search('q', query); $location.path('/stream').search('q', query);
}; };
annotationUI.subscribe(function () { store.subscribe(function () {
self.rootThread = rootThread.thread(annotationUI.getState()); self.rootThread = rootThread.thread(store.getState());
}); });
this.setCollapsed = function (id, collapsed) { this.setCollapsed = function (id, collapsed) {
annotationUI.setCollapsed(id, collapsed); store.setCollapsed(id, collapsed);
}; };
this.ready = fetchThread(api, id).then(function (annots) { this.ready = fetchThread(api, id).then(function (annots) {
...@@ -64,11 +64,11 @@ function AnnotationViewerContentController ( ...@@ -64,11 +64,11 @@ function AnnotationViewerContentController (
streamer.connect(); streamer.connect();
annots.forEach(function (annot) { annots.forEach(function (annot) {
annotationUI.setCollapsed(annot.id, false); store.setCollapsed(annot.id, false);
}); });
if (topLevelAnnot.id !== id) { if (topLevelAnnot.id !== id) {
annotationUI.highlightAnnotations([id]); store.highlightAnnotations([id]);
} }
}); });
} }
......
...@@ -25,7 +25,7 @@ function updateModel(annotation, changes, permissions) { ...@@ -25,7 +25,7 @@ function updateModel(annotation, changes, permissions) {
// @ngInject // @ngInject
function AnnotationController( function AnnotationController(
$document, $rootScope, $scope, $timeout, $window, analytics, annotationUI, $document, $rootScope, $scope, $timeout, $window, analytics, store,
annotationMapper, api, drafts, flash, groups, permissions, serviceUrl, annotationMapper, api, drafts, flash, groups, permissions, serviceUrl,
session, settings, streamer) { session, settings, streamer) {
...@@ -199,7 +199,7 @@ function AnnotationController( ...@@ -199,7 +199,7 @@ function AnnotationController(
}; };
annotationMapper.flagAnnotation(self.annotation).then(function(){ annotationMapper.flagAnnotation(self.annotation).then(function(){
analytics.track(analytics.events.ANNOTATION_FLAGGED); analytics.track(analytics.events.ANNOTATION_FLAGGED);
annotationUI.updateFlagStatus(self.annotation.id, true); store.updateFlagStatus(self.annotation.id, true);
}, onRejected); }, onRejected);
}; };
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
module.exports = { module.exports = {
controllerAs: 'vm', controllerAs: 'vm',
// @ngInject // @ngInject
controller: function ($scope, $window, annotationUI, serviceUrl) { controller: function ($scope, $window, store, serviceUrl) {
this.userAgent = $window.navigator.userAgent; this.userAgent = $window.navigator.userAgent;
this.version = '__VERSION__'; // replaced by versionify this.version = '__VERSION__'; // replaced by versionify
this.dateTime = new Date(); this.dateTime = new Date();
...@@ -17,7 +17,7 @@ module.exports = { ...@@ -17,7 +17,7 @@ module.exports = {
$scope.$watch( $scope.$watch(
function () { function () {
return annotationUI.frames(); return store.frames();
}, },
function (frames) { function (frames) {
if (frames.length === 0) { if (frames.length === 0) {
......
...@@ -35,7 +35,7 @@ function authStateFromProfile(profile) { ...@@ -35,7 +35,7 @@ function authStateFromProfile(profile) {
// @ngInject // @ngInject
function HypothesisAppController( function HypothesisAppController(
$document, $location, $rootScope, $route, $scope, $document, $location, $rootScope, $route, $scope,
$window, analytics, annotationUI, auth, bridge, drafts, features, $window, analytics, store, auth, bridge, drafts, features,
flash, frameSync, groups, serviceUrl, session, settings, streamer flash, frameSync, groups, serviceUrl, session, settings, streamer
) { ) {
var self = this; var self = this;
...@@ -58,14 +58,14 @@ function HypothesisAppController( ...@@ -58,14 +58,14 @@ function HypothesisAppController(
} }
this.sortKey = function () { this.sortKey = function () {
return annotationUI.getState().sortKey; return store.getState().sortKey;
}; };
this.sortKeysAvailable = function () { this.sortKeysAvailable = function () {
return annotationUI.getState().sortKeysAvailable; return store.getState().sortKeysAvailable;
}; };
this.setSortKey = annotationUI.setSortKey; this.setSortKey = store.setSortKey;
// Reload the view when the user switches accounts // Reload the view when the user switches accounts
$scope.$on(events.USER_CHANGED, function (event, data) { $scope.$on(events.USER_CHANGED, function (event, data) {
...@@ -168,10 +168,10 @@ function HypothesisAppController( ...@@ -168,10 +168,10 @@ function HypothesisAppController(
this.search = { this.search = {
query: function () { query: function () {
return annotationUI.getState().filterQuery; return store.getState().filterQuery;
}, },
update: function (query) { update: function (query) {
annotationUI.setFilterQuery(query); store.setFilterQuery(query);
}, },
}; };
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
var annotationMetadata = require('../annotation-metadata'); var annotationMetadata = require('../annotation-metadata');
// @ngInject // @ngInject
function ModerationBannerController(annotationUI, flash, api) { function ModerationBannerController(store, flash, api) {
var self = this; var self = this;
this.flagCount = function () { this.flagCount = function () {
...@@ -28,7 +28,7 @@ function ModerationBannerController(annotationUI, flash, api) { ...@@ -28,7 +28,7 @@ function ModerationBannerController(annotationUI, flash, api) {
*/ */
this.hideAnnotation = function () { this.hideAnnotation = function () {
api.annotation.hide({id: self.annotation.id}).then(function () { api.annotation.hide({id: self.annotation.id}).then(function () {
annotationUI.hideAnnotation(self.annotation.id); store.hideAnnotation(self.annotation.id);
}).catch(function () { }).catch(function () {
flash.error('Failed to hide annotation'); flash.error('Failed to hide annotation');
}); });
...@@ -39,7 +39,7 @@ function ModerationBannerController(annotationUI, flash, api) { ...@@ -39,7 +39,7 @@ function ModerationBannerController(annotationUI, flash, api) {
*/ */
this.unhideAnnotation = function () { this.unhideAnnotation = function () {
api.annotation.unhide({id: self.annotation.id}).then(function () { api.annotation.unhide({id: self.annotation.id}).then(function () {
annotationUI.unhideAnnotation(self.annotation.id); store.unhideAnnotation(self.annotation.id);
}).catch(function () { }).catch(function () {
flash.error('Failed to unhide annotation'); flash.error('Failed to unhide annotation');
}); });
......
...@@ -5,9 +5,9 @@ var events = require('../events'); ...@@ -5,9 +5,9 @@ var events = require('../events');
module.exports = { module.exports = {
controllerAs: 'vm', controllerAs: 'vm',
//@ngInject //@ngInject
controller: function ($rootScope, annotationUI) { controller: function ($rootScope, store) {
this.onNewNoteBtnClick = function(){ this.onNewNoteBtnClick = function(){
var topLevelFrame = annotationUI.frames().find(f=>!f.id); var topLevelFrame = store.frames().find(f=>!f.id);
var annot = { var annot = {
target: [], target: [],
uri: topLevelFrame.uri, uri: topLevelFrame.uri,
......
...@@ -6,7 +6,7 @@ var uiConstants = require('../ui-constants'); ...@@ -6,7 +6,7 @@ var uiConstants = require('../ui-constants');
module.exports = { module.exports = {
controllerAs: 'vm', controllerAs: 'vm',
//@ngInject //@ngInject
controller: function ($element, annotationUI, features, session, settings) { controller: function ($element, store, features, session, settings) {
this.TAB_ANNOTATIONS = uiConstants.TAB_ANNOTATIONS; this.TAB_ANNOTATIONS = uiConstants.TAB_ANNOTATIONS;
this.TAB_NOTES = uiConstants.TAB_NOTES; this.TAB_NOTES = uiConstants.TAB_NOTES;
this.TAB_ORPHANS = uiConstants.TAB_ORPHANS; this.TAB_ORPHANS = uiConstants.TAB_ORPHANS;
...@@ -16,8 +16,8 @@ module.exports = { ...@@ -16,8 +16,8 @@ module.exports = {
this.enableExperimentalNewNoteButton = settings.enableExperimentalNewNoteButton; this.enableExperimentalNewNoteButton = settings.enableExperimentalNewNoteButton;
this.selectTab = function (type) { this.selectTab = function (type) {
annotationUI.clearSelectedAnnotations(); store.clearSelectedAnnotations();
annotationUI.selectTab(type); store.selectTab(type);
}; };
this.showAnnotationsUnavailableMessage = function () { this.showAnnotationsUnavailableMessage = function () {
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
var VIA_PREFIX = 'https://via.hypothes.is/'; var VIA_PREFIX = 'https://via.hypothes.is/';
// @ngInject // @ngInject
function ShareDialogController($scope, $element, analytics, annotationUI) { function ShareDialogController($scope, $element, analytics, store) {
var self = this; var self = this;
function updateViaLink(frames) { function updateViaLink(frames) {
...@@ -24,7 +24,7 @@ function ShareDialogController($scope, $element, analytics, annotationUI) { ...@@ -24,7 +24,7 @@ function ShareDialogController($scope, $element, analytics, annotationUI) {
viaInput.focus(); viaInput.focus();
viaInput.select(); viaInput.select();
$scope.$watch(function () { return annotationUI.frames(); }, $scope.$watch(function () { return store.frames(); },
updateViaLink); updateViaLink);
$scope.onShareClick = function(target){ $scope.onShareClick = function(target){
......
...@@ -34,17 +34,17 @@ function groupIDFromSelection(selection, results) { ...@@ -34,17 +34,17 @@ function groupIDFromSelection(selection, results) {
// @ngInject // @ngInject
function SidebarContentController( function SidebarContentController(
$scope, analytics, annotationUI, annotationMapper, api, drafts, features, frameSync, $scope, analytics, store, annotationMapper, api, drafts, features, frameSync,
groups, rootThread, settings, streamer, streamFilter groups, rootThread, settings, streamer, streamFilter
) { ) {
var self = this; var self = this;
function thread() { function thread() {
return rootThread.thread(annotationUI.getState()); return rootThread.thread(store.getState());
} }
var unsubscribeAnnotationUI = annotationUI.subscribe(function () { var unsubscribeAnnotationUI = store.subscribe(function () {
var state = annotationUI.getState(); var state = store.getState();
self.rootThread = thread(); self.rootThread = thread();
self.selectedTab = state.selectedTab; self.selectedTab = state.selectedTab;
...@@ -79,13 +79,13 @@ function SidebarContentController( ...@@ -79,13 +79,13 @@ function SidebarContentController(
/** /**
* Returns the Annotation object for the first annotation in the * Returns the Annotation object for the first annotation in the
* selected annotation set. Note that 'first' refers to the order * selected annotation set. Note that 'first' refers to the order
* of annotations passed to annotationUI when selecting annotations, * of annotations passed to store when selecting annotations,
* not the order in which they appear in the document. * not the order in which they appear in the document.
*/ */
function firstSelectedAnnotation() { function firstSelectedAnnotation() {
if (annotationUI.getState().selectedAnnotationMap) { if (store.getState().selectedAnnotationMap) {
var id = Object.keys(annotationUI.getState().selectedAnnotationMap)[0]; var id = Object.keys(store.getState().selectedAnnotationMap)[0];
return annotationUI.getState().annotations.find(function (annot) { return store.getState().annotations.find(function (annot) {
return annot.id === id; return annot.id === id;
}); });
} else { } else {
...@@ -96,7 +96,7 @@ function SidebarContentController( ...@@ -96,7 +96,7 @@ function SidebarContentController(
var searchClients = []; var searchClients = [];
function _resetAnnotations() { function _resetAnnotations() {
annotationMapper.unloadAnnotations(annotationUI.savedAnnotations()); annotationMapper.unloadAnnotations(store.savedAnnotations());
} }
function _loadAnnotationsFor(uris, group) { function _loadAnnotationsFor(uris, group) {
...@@ -109,11 +109,11 @@ function SidebarContentController( ...@@ -109,11 +109,11 @@ function SidebarContentController(
}); });
searchClients.push(searchClient); searchClients.push(searchClient);
searchClient.on('results', function (results) { searchClient.on('results', function (results) {
if (annotationUI.hasSelectedAnnotations()) { if (store.hasSelectedAnnotations()) {
// Focus the group containing the selected annotation and filter // Focus the group containing the selected annotation and filter
// annotations to those from this group // annotations to those from this group
var groupID = groupIDFromSelection( var groupID = groupIDFromSelection(
annotationUI.getState().selectedAnnotationMap, results); store.getState().selectedAnnotationMap, results);
if (!groupID) { if (!groupID) {
// If the selected annotation is not available, fall back to // If the selected annotation is not available, fall back to
// loading annotations for the currently focused group // loading annotations for the currently focused group
...@@ -139,9 +139,9 @@ function SidebarContentController( ...@@ -139,9 +139,9 @@ function SidebarContentController(
searchClients.splice(searchClients.indexOf(searchClient), 1); searchClients.splice(searchClients.indexOf(searchClient), 1);
}); });
annotationUI.frames().forEach(function (frame) { store.frames().forEach(function (frame) {
if (0 <= uris.indexOf(frame.uri)) { if (0 <= uris.indexOf(frame.uri)) {
annotationUI.updateFrameAnnotationFetchStatus(frame.uri, true); store.updateFrameAnnotationFetchStatus(frame.uri, true);
} }
}); });
}); });
...@@ -149,7 +149,7 @@ function SidebarContentController( ...@@ -149,7 +149,7 @@ function SidebarContentController(
} }
function isLoading() { function isLoading() {
if (!annotationUI.frames().some(function (frame) { return frame.uri; })) { if (!store.frames().some(function (frame) { return frame.uri; })) {
// The document's URL isn't known so the document must still be loading. // The document's URL isn't known so the document must still be loading.
return true; return true;
} }
...@@ -183,10 +183,10 @@ function SidebarContentController( ...@@ -183,10 +183,10 @@ function SidebarContentController(
// the batch size, this saves an extra roundtrip to the server // the batch size, this saves an extra roundtrip to the server
// to fetch the selected annotation in order to determine which group // to fetch the selected annotation in order to determine which group
// it is in before fetching the remaining annotations. // it is in before fetching the remaining annotations.
var group = annotationUI.hasSelectedAnnotations() ? var group = store.hasSelectedAnnotations() ?
null : groups.focused().id; null : groups.focused().id;
var searchUris = annotationUI.searchUris(); var searchUris = store.searchUris();
if (searchUris.length > 0) { if (searchUris.length > 0) {
_loadAnnotationsFor(searchUris, group); _loadAnnotationsFor(searchUris, group);
...@@ -227,15 +227,15 @@ function SidebarContentController( ...@@ -227,15 +227,15 @@ function SidebarContentController(
focusAnnotation(selectedAnnot); focusAnnotation(selectedAnnot);
scrollToAnnotation(selectedAnnot); scrollToAnnotation(selectedAnnot);
annotationUI.selectTab(tabs.tabForAnnotation(selectedAnnot)); store.selectTab(tabs.tabForAnnotation(selectedAnnot));
}); });
// Re-fetch annotations when focused group, logged-in user or connected frames // Re-fetch annotations when focused group, logged-in user or connected frames
// change. // change.
$scope.$watch(() => ([ $scope.$watch(() => ([
groups.focused().id, groups.focused().id,
annotationUI.profile().userid, store.profile().userid,
...annotationUI.searchUris(), ...store.searchUris(),
]), ([currentGroupId], [prevGroupId]) => { ]), ([currentGroupId], [prevGroupId]) => {
if (currentGroupId !== prevGroupId) { if (currentGroupId !== prevGroupId) {
...@@ -246,20 +246,20 @@ function SidebarContentController( ...@@ -246,20 +246,20 @@ function SidebarContentController(
if (isLoading()) { if (isLoading()) {
return; return;
} }
annotationUI.clearSelectedAnnotations(); store.clearSelectedAnnotations();
} }
loadAnnotations(); loadAnnotations();
}, true); }, true);
this.setCollapsed = function (id, collapsed) { this.setCollapsed = function (id, collapsed) {
annotationUI.setCollapsed(id, collapsed); store.setCollapsed(id, collapsed);
}; };
this.forceVisible = function (thread) { this.forceVisible = function (thread) {
annotationUI.setForceVisible(thread.id, true); store.setForceVisible(thread.id, true);
if (thread.parent) { if (thread.parent) {
annotationUI.setCollapsed(thread.parent.id, false); store.setCollapsed(thread.parent.id, false);
} }
}; };
...@@ -267,7 +267,7 @@ function SidebarContentController( ...@@ -267,7 +267,7 @@ function SidebarContentController(
this.scrollTo = scrollToAnnotation; this.scrollTo = scrollToAnnotation;
this.selectedAnnotationCount = function () { this.selectedAnnotationCount = function () {
var selection = annotationUI.getState().selectedAnnotationMap; var selection = store.getState().selectedAnnotationMap;
if (!selection) { if (!selection) {
return 0; return 0;
} }
...@@ -275,10 +275,10 @@ function SidebarContentController( ...@@ -275,10 +275,10 @@ function SidebarContentController(
}; };
this.selectedAnnotationUnavailable = function () { this.selectedAnnotationUnavailable = function () {
var selectedID = firstKey(annotationUI.getState().selectedAnnotationMap); var selectedID = firstKey(store.getState().selectedAnnotationMap);
return !isLoading() && return !isLoading() &&
!!selectedID && !!selectedID &&
!annotationUI.annotationExists(selectedID); !store.annotationExists(selectedID);
}; };
this.shouldShowLoggedOutMessage = function () { this.shouldShowLoggedOutMessage = function () {
...@@ -302,10 +302,10 @@ function SidebarContentController( ...@@ -302,10 +302,10 @@ function SidebarContentController(
// The user is logged out and has landed on a direct linked // The user is logged out and has landed on a direct linked
// annotation. If there is an annotation selection and that // annotation. If there is an annotation selection and that
// selection is available to the user, show the CTA. // selection is available to the user, show the CTA.
var selectedID = firstKey(annotationUI.getState().selectedAnnotationMap); var selectedID = firstKey(store.getState().selectedAnnotationMap);
return !isLoading() && return !isLoading() &&
!!selectedID && !!selectedID &&
annotationUI.annotationExists(selectedID); store.annotationExists(selectedID);
}; };
this.isLoading = isLoading; this.isLoading = isLoading;
...@@ -325,13 +325,13 @@ function SidebarContentController( ...@@ -325,13 +325,13 @@ function SidebarContentController(
}; };
this.clearSelection = function () { this.clearSelection = function () {
var selectedTab = annotationUI.getState().selectedTab; var selectedTab = store.getState().selectedTab;
if (!annotationUI.getState().selectedTab || annotationUI.getState().selectedTab === uiConstants.TAB_ORPHANS) { if (!store.getState().selectedTab || store.getState().selectedTab === uiConstants.TAB_ORPHANS) {
selectedTab = uiConstants.TAB_ANNOTATIONS; selectedTab = uiConstants.TAB_ANNOTATIONS;
} }
annotationUI.clearSelectedAnnotations(); store.clearSelectedAnnotations();
annotationUI.selectTab(selectedTab); store.selectTab(selectedTab);
}; };
} }
......
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
// @ngInject // @ngInject
function StreamContentController( function StreamContentController(
$scope, $location, $route, $routeParams, annotationMapper, annotationUI, $scope, $location, $route, $routeParams, annotationMapper, store,
api, queryParser, rootThread, searchFilter, streamFilter, streamer api, queryParser, rootThread, searchFilter, streamFilter, streamer
) { ) {
var self = this; var self = this;
annotationUI.setAppIsSidebar(false); store.setAppIsSidebar(false);
/** `offset` parameter for the next search API call. */ /** `offset` parameter for the next search API call. */
var offset = 0; var offset = 0;
...@@ -39,7 +39,7 @@ function StreamContentController( ...@@ -39,7 +39,7 @@ function StreamContentController(
var lastQuery = $routeParams.q; var lastQuery = $routeParams.q;
$scope.$on('$routeUpdate', function () { $scope.$on('$routeUpdate', function () {
if ($routeParams.q !== lastQuery) { if ($routeParams.q !== lastQuery) {
annotationUI.clearAnnotations(); store.clearAnnotations();
$route.reload(); $route.reload();
} }
}); });
...@@ -57,9 +57,9 @@ function StreamContentController( ...@@ -57,9 +57,9 @@ function StreamContentController(
// Perform the initial search // Perform the initial search
fetch(20); fetch(20);
this.setCollapsed = annotationUI.setCollapsed; this.setCollapsed = store.setCollapsed;
this.forceVisible = function (id) { this.forceVisible = function (id) {
annotationUI.setForceVisible(id, true); store.setForceVisible(id, true);
}; };
Object.assign(this.search, { Object.assign(this.search, {
...@@ -71,12 +71,12 @@ function StreamContentController( ...@@ -71,12 +71,12 @@ function StreamContentController(
}, },
}); });
annotationUI.subscribe(function () { store.subscribe(function () {
self.rootThread = rootThread.thread(annotationUI.getState()); self.rootThread = rootThread.thread(store.getState());
}); });
// Sort the stream so that the newest annotations are at the top // Sort the stream so that the newest annotations are at the top
annotationUI.setSortKey('Newest'); store.setSortKey('Newest');
this.loadMore = fetch; this.loadMore = fetch;
} }
......
...@@ -101,7 +101,7 @@ describe('annotation', function() { ...@@ -101,7 +101,7 @@ describe('annotation', function() {
}; };
var fakeAnalytics; var fakeAnalytics;
var fakeAnnotationMapper; var fakeAnnotationMapper;
var fakeAnnotationUI; var fakeStore;
var fakeDrafts; var fakeDrafts;
var fakeFlash; var fakeFlash;
var fakeGroups; var fakeGroups;
...@@ -177,7 +177,7 @@ describe('annotation', function() { ...@@ -177,7 +177,7 @@ describe('annotation', function() {
flagAnnotation: sandbox.stub(), flagAnnotation: sandbox.stub(),
}; };
fakeAnnotationUI = { fakeStore = {
updateFlagStatus: sandbox.stub().returns(true), updateFlagStatus: sandbox.stub().returns(true),
}; };
...@@ -244,7 +244,7 @@ describe('annotation', function() { ...@@ -244,7 +244,7 @@ describe('annotation', function() {
$provide.value('analytics', fakeAnalytics); $provide.value('analytics', fakeAnalytics);
$provide.value('annotationMapper', fakeAnnotationMapper); $provide.value('annotationMapper', fakeAnnotationMapper);
$provide.value('annotationUI', fakeAnnotationUI); $provide.value('store', fakeStore);
$provide.value('api', fakeApi); $provide.value('api', fakeApi);
$provide.value('drafts', fakeDrafts); $provide.value('drafts', fakeDrafts);
$provide.value('flash', fakeFlash); $provide.value('flash', fakeFlash);
......
...@@ -45,7 +45,7 @@ describe('annotationViewerContent', function () { ...@@ -45,7 +45,7 @@ describe('annotationViewerContent', function () {
var locals = { var locals = {
$location: {}, $location: {},
$routeParams: { id: 'test_annotation_id' }, $routeParams: { id: 'test_annotation_id' },
annotationUI: { store: {
setAppIsSidebar: sinon.stub(), setAppIsSidebar: sinon.stub(),
setCollapsed: sinon.stub(), setCollapsed: sinon.stub(),
highlightAnnotations: sinon.stub(), highlightAnnotations: sinon.stub(),
...@@ -105,7 +105,7 @@ describe('annotationViewerContent', function () { ...@@ -105,7 +105,7 @@ describe('annotationViewerContent', function () {
]); ]);
var controller = createController({api: fakeApi}); var controller = createController({api: fakeApi});
return controller.ctrl.ready.then(function () { return controller.ctrl.ready.then(function () {
assert.notCalled(controller.annotationUI.highlightAnnotations); assert.notCalled(controller.store.highlightAnnotations);
}); });
}); });
}); });
...@@ -130,8 +130,8 @@ describe('annotationViewerContent', function () { ...@@ -130,8 +130,8 @@ describe('annotationViewerContent', function () {
]); ]);
var controller = createController({api: fakeApi}); var controller = createController({api: fakeApi});
return controller.ctrl.ready.then(function () { return controller.ctrl.ready.then(function () {
assert.calledWith(controller.annotationUI.setCollapsed, 'parent_id', false); assert.calledWith(controller.store.setCollapsed, 'parent_id', false);
assert.calledWith(controller.annotationUI.setCollapsed, 'test_annotation_id', false); assert.calledWith(controller.store.setCollapsed, 'test_annotation_id', false);
}); });
}); });
...@@ -142,7 +142,7 @@ describe('annotationViewerContent', function () { ...@@ -142,7 +142,7 @@ describe('annotationViewerContent', function () {
]); ]);
var controller = createController({api: fakeApi}); var controller = createController({api: fakeApi});
return controller.ctrl.ready.then(function () { return controller.ctrl.ready.then(function () {
assert.calledWith(controller.annotationUI.highlightAnnotations, assert.calledWith(controller.store.highlightAnnotations,
sinon.match(['test_annotation_id'])); sinon.match(['test_annotation_id']));
}); });
}); });
......
...@@ -3,12 +3,12 @@ ...@@ -3,12 +3,12 @@
var angular = require('angular'); var angular = require('angular');
describe('helpPanel', function () { describe('helpPanel', function () {
var fakeAnnotationUI; var fakeStore;
var $componentController; var $componentController;
var $rootScope; var $rootScope;
beforeEach(function () { beforeEach(function () {
fakeAnnotationUI = { fakeStore = {
frames: sinon.stub().returns([]), frames: sinon.stub().returns([]),
}; };
...@@ -16,7 +16,7 @@ describe('helpPanel', function () { ...@@ -16,7 +16,7 @@ describe('helpPanel', function () {
.component('helpPanel', require('../help-panel')); .component('helpPanel', require('../help-panel'));
angular.mock.module('h', { angular.mock.module('h', {
annotationUI: fakeAnnotationUI, store: fakeStore,
serviceUrl: sinon.stub(), serviceUrl: sinon.stub(),
}); });
...@@ -27,7 +27,7 @@ describe('helpPanel', function () { ...@@ -27,7 +27,7 @@ describe('helpPanel', function () {
}); });
it('displays the URL and fingerprint of the first connected frame', function () { it('displays the URL and fingerprint of the first connected frame', function () {
fakeAnnotationUI.frames.returns([{ fakeStore.frames.returns([{
uri: 'https://publisher.org/article.pdf', uri: 'https://publisher.org/article.pdf',
metadata: { metadata: {
documentFingerprint: '12345', documentFingerprint: '12345',
......
...@@ -12,7 +12,7 @@ describe('sidebar.components.hypothesis-app', function () { ...@@ -12,7 +12,7 @@ describe('sidebar.components.hypothesis-app', function () {
var $scope = null; var $scope = null;
var $rootScope = null; var $rootScope = null;
var fakeAnnotationMetadata = null; var fakeAnnotationMetadata = null;
var fakeAnnotationUI = null; var fakeStore = null;
var fakeAnalytics = null; var fakeAnalytics = null;
var fakeAuth = null; var fakeAuth = null;
var fakeBridge = null; var fakeBridge = null;
...@@ -64,7 +64,7 @@ describe('sidebar.components.hypothesis-app', function () { ...@@ -64,7 +64,7 @@ describe('sidebar.components.hypothesis-app', function () {
beforeEach(angular.mock.module('h')); beforeEach(angular.mock.module('h'));
beforeEach(angular.mock.module(function ($provide) { beforeEach(angular.mock.module(function ($provide) {
fakeAnnotationUI = { fakeStore = {
tool: 'comment', tool: 'comment',
clearSelectedAnnotations: sandbox.spy(), clearSelectedAnnotations: sandbox.spy(),
}; };
...@@ -130,7 +130,7 @@ describe('sidebar.components.hypothesis-app', function () { ...@@ -130,7 +130,7 @@ describe('sidebar.components.hypothesis-app', function () {
call: sandbox.stub(), call: sandbox.stub(),
}; };
$provide.value('annotationUI', fakeAnnotationUI); $provide.value('store', fakeStore);
$provide.value('auth', fakeAuth); $provide.value('auth', fakeAuth);
$provide.value('analytics', fakeAnalytics); $provide.value('analytics', fakeAnalytics);
$provide.value('drafts', fakeDrafts); $provide.value('drafts', fakeDrafts);
......
...@@ -10,7 +10,7 @@ var moderatedAnnotation = fixtures.moderatedAnnotation; ...@@ -10,7 +10,7 @@ var moderatedAnnotation = fixtures.moderatedAnnotation;
describe('moderationBanner', function () { describe('moderationBanner', function () {
var bannerEl; var bannerEl;
var fakeAnnotationUI; var fakeStore;
var fakeFlash; var fakeFlash;
var fakeApi; var fakeApi;
...@@ -20,7 +20,7 @@ describe('moderationBanner', function () { ...@@ -20,7 +20,7 @@ describe('moderationBanner', function () {
}); });
beforeEach(function () { beforeEach(function () {
fakeAnnotationUI = { fakeStore = {
hideAnnotation: sinon.stub(), hideAnnotation: sinon.stub(),
unhideAnnotation: sinon.stub(), unhideAnnotation: sinon.stub(),
}; };
...@@ -37,7 +37,7 @@ describe('moderationBanner', function () { ...@@ -37,7 +37,7 @@ describe('moderationBanner', function () {
}; };
angular.mock.module('app', { angular.mock.module('app', {
annotationUI: fakeAnnotationUI, store: fakeStore,
api: fakeApi, api: fakeApi,
flash: fakeFlash, flash: fakeFlash,
}); });
......
...@@ -8,7 +8,7 @@ var util = require('../../directive/test/util'); ...@@ -8,7 +8,7 @@ var util = require('../../directive/test/util');
describe('newNoteBtn', function () { describe('newNoteBtn', function () {
var $rootScope; var $rootScope;
var sandbox = sinon.sandbox.create(); var sandbox = sinon.sandbox.create();
var fakeAnnotationUI = { var fakeStore = {
frames: sinon.stub().returns([{ id: null, uri: 'www.example.org'}, { id: '1', uri: 'www.example.org'}]), frames: sinon.stub().returns([{ id: null, uri: 'www.example.org'}, { id: '1', uri: 'www.example.org'}]),
}; };
...@@ -25,7 +25,7 @@ describe('newNoteBtn', function () { ...@@ -25,7 +25,7 @@ describe('newNoteBtn', function () {
var fakeSettings = { theme: 'clean' }; var fakeSettings = { theme: 'clean' };
angular.mock.module('app', { angular.mock.module('app', {
annotationUI: fakeAnnotationUI, store: fakeStore,
features: fakeFeatures, features: fakeFeatures,
settings: fakeSettings, settings: fakeSettings,
}); });
...@@ -45,7 +45,7 @@ describe('newNoteBtn', function () { ...@@ -45,7 +45,7 @@ describe('newNoteBtn', function () {
uri: 'www.example.org', uri: 'www.example.org',
}; };
var elem = util.createDirective(document, 'newNoteBtn', { var elem = util.createDirective(document, 'newNoteBtn', {
annotationUI: fakeAnnotationUI, store: fakeStore,
}); });
sandbox.spy($rootScope, '$broadcast'); sandbox.spy($rootScope, '$broadcast');
elem.ctrl.onNewNoteBtnClick(); elem.ctrl.onNewNoteBtnClick();
......
...@@ -22,13 +22,13 @@ describe('selectionTabs', function () { ...@@ -22,13 +22,13 @@ describe('selectionTabs', function () {
}); });
beforeEach(function () { beforeEach(function () {
var fakeAnnotationUI = {}; var fakeStore = {};
var fakeFeatures = { var fakeFeatures = {
flagEnabled: sinon.stub().returns(true), flagEnabled: sinon.stub().returns(true),
}; };
angular.mock.module('app', { angular.mock.module('app', {
annotationUI: fakeAnnotationUI, store: fakeStore,
features: fakeFeatures, features: fakeFeatures,
session: fakeSession, session: fakeSession,
settings: fakeSettings, settings: fakeSettings,
...@@ -84,7 +84,7 @@ describe('selectionTabs', function () { ...@@ -84,7 +84,7 @@ describe('selectionTabs', function () {
it('should show the clean theme when settings contains the clean theme option', function () { it('should show the clean theme when settings contains the clean theme option', function () {
angular.mock.module('app', { angular.mock.module('app', {
annotationUI: {}, store: {},
features: { features: {
flagEnabled: sinon.stub().returns(true), flagEnabled: sinon.stub().returns(true),
}, },
......
...@@ -6,33 +6,33 @@ var util = require('../../directive/test/util'); ...@@ -6,33 +6,33 @@ var util = require('../../directive/test/util');
describe('shareDialog', function () { describe('shareDialog', function () {
var fakeAnalytics; var fakeAnalytics;
var fakeAnnotationUI; var fakeStore;
beforeEach(function () { beforeEach(function () {
fakeAnalytics = { fakeAnalytics = {
track: sinon.stub(), track: sinon.stub(),
events: {}, events: {},
}; };
fakeAnnotationUI = { frames: sinon.stub().returns([]) }; fakeStore = { frames: sinon.stub().returns([]) };
angular.module('h', []) angular.module('h', [])
.component('shareDialog', require('../share-dialog')) .component('shareDialog', require('../share-dialog'))
.value('analytics', fakeAnalytics) .value('analytics', fakeAnalytics)
.value('annotationUI', fakeAnnotationUI) .value('store', fakeStore)
.value('urlEncodeFilter', function (val) { return val; }); .value('urlEncodeFilter', function (val) { return val; });
angular.mock.module('h'); angular.mock.module('h');
}); });
it('generates new via link', function () { it('generates new via link', function () {
var element = util.createDirective(document, 'shareDialog', {}); var element = util.createDirective(document, 'shareDialog', {});
fakeAnnotationUI.frames.returns([{ uri: 'http://example.com' }]); fakeStore.frames.returns([{ uri: 'http://example.com' }]);
element.scope.$digest(); element.scope.$digest();
assert.equal(element.ctrl.viaPageLink, 'https://via.hypothes.is/http://example.com'); assert.equal(element.ctrl.viaPageLink, 'https://via.hypothes.is/http://example.com');
}); });
it('does not generate new via link if already on via', function () { it('does not generate new via link if already on via', function () {
var element = util.createDirective(document, 'shareDialog', {}); var element = util.createDirective(document, 'shareDialog', {});
fakeAnnotationUI.frames.returns([{ fakeStore.frames.returns([{
uri: 'https://via.hypothes.is/http://example.com', uri: 'https://via.hypothes.is/http://example.com',
}]); }]);
element.scope.$digest(); element.scope.$digest();
......
...@@ -15,7 +15,7 @@ describe('StreamContentController', function () { ...@@ -15,7 +15,7 @@ describe('StreamContentController', function () {
var fakeRoute; var fakeRoute;
var fakeRouteParams; var fakeRouteParams;
var fakeAnnotationMapper; var fakeAnnotationMapper;
var fakeAnnotationUI; var fakeStore;
var fakeQueryParser; var fakeQueryParser;
var fakeRootThread; var fakeRootThread;
var fakeSearchFilter; var fakeSearchFilter;
...@@ -35,7 +35,7 @@ describe('StreamContentController', function () { ...@@ -35,7 +35,7 @@ describe('StreamContentController', function () {
loadAnnotations: sinon.spy(), loadAnnotations: sinon.spy(),
}; };
fakeAnnotationUI = { fakeStore = {
clearAnnotations: sinon.spy(), clearAnnotations: sinon.spy(),
setAppIsSidebar: sinon.spy(), setAppIsSidebar: sinon.spy(),
setCollapsed: sinon.spy(), setCollapsed: sinon.spy(),
...@@ -84,7 +84,7 @@ describe('StreamContentController', function () { ...@@ -84,7 +84,7 @@ describe('StreamContentController', function () {
$route: fakeRoute, $route: fakeRoute,
$routeParams: fakeRouteParams, $routeParams: fakeRouteParams,
annotationMapper: fakeAnnotationMapper, annotationMapper: fakeAnnotationMapper,
annotationUI: fakeAnnotationUI, store: fakeStore,
api: fakeApi, api: fakeApi,
queryParser: fakeQueryParser, queryParser: fakeQueryParser,
rootThread: fakeRootThread, rootThread: fakeRootThread,
...@@ -136,7 +136,7 @@ describe('StreamContentController', function () { ...@@ -136,7 +136,7 @@ describe('StreamContentController', function () {
createController(); createController();
fakeRouteParams.q = 'new query'; fakeRouteParams.q = 'new query';
$rootScope.$broadcast('$routeUpdate'); $rootScope.$broadcast('$routeUpdate');
assert.called(fakeAnnotationUI.clearAnnotations); assert.called(fakeStore.clearAnnotations);
assert.calledOnce(fakeRoute.reload); assert.calledOnce(fakeRoute.reload);
}); });
...@@ -144,7 +144,7 @@ describe('StreamContentController', function () { ...@@ -144,7 +144,7 @@ describe('StreamContentController', function () {
fakeRouteParams.q = 'test query'; fakeRouteParams.q = 'test query';
createController(); createController();
$rootScope.$broadcast('$routeUpdate'); $rootScope.$broadcast('$routeUpdate');
assert.notCalled(fakeAnnotationUI.clearAnnotations); assert.notCalled(fakeStore.clearAnnotations);
assert.notCalled(fakeRoute.reload); assert.notCalled(fakeRoute.reload);
}); });
}); });
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
* *
*/ */
// @ngInject // @ngInject
function start(annotationUI, settings, $window) { function start(store, settings, $window) {
$window.addEventListener('message', function receiveMessage(event) { $window.addEventListener('message', function receiveMessage(event) {
let allowedOrigins = settings.rpcAllowedOrigins || []; let allowedOrigins = settings.rpcAllowedOrigins || [];
...@@ -40,7 +40,7 @@ function start(annotationUI, settings, $window) { ...@@ -40,7 +40,7 @@ function start(annotationUI, settings, $window) {
function jsonRpcResponse(request) { function jsonRpcResponse(request) {
// The set of methods that clients can call. // The set of methods that clients can call.
let methods = { let methods = {
'searchUris': annotationUI.searchUris, 'searchUris': store.searchUris,
}; };
let method = methods[request.method]; let method = methods[request.method];
......
...@@ -209,7 +209,7 @@ module.exports = angular.module('h', [ ...@@ -209,7 +209,7 @@ module.exports = angular.module('h', [
.service('viewFilter', require('./services/view-filter')) .service('viewFilter', require('./services/view-filter'))
// Redux store // Redux store
.service('annotationUI', require('./store')) .service('store', require('./store'))
// Utilities // Utilities
.value('Discovery', require('../shared/discovery')) .value('Discovery', require('../shared/discovery'))
......
...@@ -4,21 +4,21 @@ var angular = require('angular'); ...@@ -4,21 +4,21 @@ var angular = require('angular');
var events = require('../events'); var events = require('../events');
function getExistingAnnotation(annotationUI, id) { function getExistingAnnotation(store, id) {
return annotationUI.getState().annotations.find(function (annot) { return store.getState().annotations.find(function (annot) {
return annot.id === id; return annot.id === id;
}); });
} }
// Wraps the annotation store to trigger events for the CRUD actions // Wraps the annotation store to trigger events for the CRUD actions
// @ngInject // @ngInject
function annotationMapper($rootScope, annotationUI, api) { function annotationMapper($rootScope, store, api) {
function loadAnnotations(annotations, replies) { function loadAnnotations(annotations, replies) {
annotations = annotations.concat(replies || []); annotations = annotations.concat(replies || []);
var loaded = []; var loaded = [];
annotations.forEach(function (annotation) { annotations.forEach(function (annotation) {
var existing = getExistingAnnotation(annotationUI, annotation.id); var existing = getExistingAnnotation(store, annotation.id);
if (existing) { if (existing) {
$rootScope.$broadcast(events.ANNOTATION_UPDATED, annotation); $rootScope.$broadcast(events.ANNOTATION_UPDATED, annotation);
return; return;
...@@ -31,7 +31,7 @@ function annotationMapper($rootScope, annotationUI, api) { ...@@ -31,7 +31,7 @@ function annotationMapper($rootScope, annotationUI, api) {
function unloadAnnotations(annotations) { function unloadAnnotations(annotations) {
var unloaded = annotations.map(function (annotation) { var unloaded = annotations.map(function (annotation) {
var existing = getExistingAnnotation(annotationUI, annotation.id); var existing = getExistingAnnotation(store, annotation.id);
if (existing && annotation !== existing) { if (existing && annotation !== existing) {
annotation = angular.copy(annotation, existing); annotation = angular.copy(annotation, existing);
} }
......
...@@ -41,7 +41,7 @@ function formatAnnot(ann) { ...@@ -41,7 +41,7 @@ function formatAnnot(ann) {
* sidebar. * sidebar.
*/ */
// @ngInject // @ngInject
function FrameSync($rootScope, $window, Discovery, annotationUI, bridge) { function FrameSync($rootScope, $window, Discovery, store, bridge) {
// Set of tags of annotations that are currently loaded into the frame // Set of tags of annotations that are currently loaded into the frame
var inFrame = new Set(); var inFrame = new Set();
...@@ -56,8 +56,8 @@ function FrameSync($rootScope, $window, Discovery, annotationUI, bridge) { ...@@ -56,8 +56,8 @@ function FrameSync($rootScope, $window, Discovery, annotationUI, bridge) {
var prevFrames = []; var prevFrames = [];
var prevPublicAnns = 0; var prevPublicAnns = 0;
annotationUI.subscribe(function () { store.subscribe(function () {
var state = annotationUI.getState(); var state = store.getState();
if (state.annotations === prevAnnotations && if (state.annotations === prevAnnotations &&
state.frames === prevFrames) { state.frames === prevFrames) {
return; return;
...@@ -102,7 +102,7 @@ function FrameSync($rootScope, $window, Discovery, annotationUI, bridge) { ...@@ -102,7 +102,7 @@ function FrameSync($rootScope, $window, Discovery, annotationUI, bridge) {
inFrame.delete(annot.$tag); inFrame.delete(annot.$tag);
}); });
var frames = annotationUI.frames(); var frames = store.frames();
if (frames.length > 0) { if (frames.length > 0) {
if (frames.every(function (frame) { return frame.isAnnotationFetchComplete; })) { if (frames.every(function (frame) { return frame.isAnnotationFetchComplete; })) {
if (publicAnns === 0 || publicAnns !== prevPublicAnns) { if (publicAnns === 0 || publicAnns !== prevPublicAnns) {
...@@ -135,7 +135,7 @@ function FrameSync($rootScope, $window, Discovery, annotationUI, bridge) { ...@@ -135,7 +135,7 @@ function FrameSync($rootScope, $window, Discovery, annotationUI, bridge) {
// triggered by each `UPDATE_ANCHOR_STATUS` action that is dispatched. // triggered by each `UPDATE_ANCHOR_STATUS` action that is dispatched.
var anchoringStatusUpdates = {}; var anchoringStatusUpdates = {};
var scheduleAnchoringStatusUpdate = debounce(() => { var scheduleAnchoringStatusUpdate = debounce(() => {
annotationUI.updateAnchorStatus(anchoringStatusUpdates); store.updateAnchorStatus(anchoringStatusUpdates);
$rootScope.$broadcast(events.ANNOTATIONS_SYNCED, Object.keys(anchoringStatusUpdates)); $rootScope.$broadcast(events.ANNOTATIONS_SYNCED, Object.keys(anchoringStatusUpdates));
anchoringStatusUpdates = {}; anchoringStatusUpdates = {};
}, 10); }, 10);
...@@ -150,16 +150,16 @@ function FrameSync($rootScope, $window, Discovery, annotationUI, bridge) { ...@@ -150,16 +150,16 @@ function FrameSync($rootScope, $window, Discovery, annotationUI, bridge) {
}); });
bridge.on('showAnnotations', function (tags) { bridge.on('showAnnotations', function (tags) {
annotationUI.selectAnnotations(annotationUI.findIDsForTags(tags)); store.selectAnnotations(store.findIDsForTags(tags));
annotationUI.selectTab(uiConstants.TAB_ANNOTATIONS); store.selectTab(uiConstants.TAB_ANNOTATIONS);
}); });
bridge.on('focusAnnotations', function (tags) { bridge.on('focusAnnotations', function (tags) {
annotationUI.focusAnnotations(tags || []); store.focusAnnotations(tags || []);
}); });
bridge.on('toggleAnnotationSelection', function (tags) { bridge.on('toggleAnnotationSelection', function (tags) {
annotationUI.toggleSelectedAnnotations(annotationUI.findIDsForTags(tags)); store.toggleSelectedAnnotations(store.findIDsForTags(tags));
}); });
bridge.on('sidebarOpened', function () { bridge.on('sidebarOpened', function () {
...@@ -192,7 +192,7 @@ function FrameSync($rootScope, $window, Discovery, annotationUI, bridge) { ...@@ -192,7 +192,7 @@ function FrameSync($rootScope, $window, Discovery, annotationUI, bridge) {
} }
$rootScope.$broadcast(events.FRAME_CONNECTED); $rootScope.$broadcast(events.FRAME_CONNECTED);
annotationUI.connectFrame({ store.connectFrame({
id: info.frameIdentifier, id: info.frameIdentifier,
metadata: info.metadata, metadata: info.metadata,
uri: info.uri, uri: info.uri,
...@@ -201,12 +201,12 @@ function FrameSync($rootScope, $window, Discovery, annotationUI, bridge) { ...@@ -201,12 +201,12 @@ function FrameSync($rootScope, $window, Discovery, annotationUI, bridge) {
} }
function destroyFrame(frameIdentifier) { function destroyFrame(frameIdentifier) {
var frames = annotationUI.frames(); var frames = store.frames();
var frameToDestroy = frames.find(function (frame) { var frameToDestroy = frames.find(function (frame) {
return frame.id === frameIdentifier; return frame.id === frameIdentifier;
}); });
if (frameToDestroy) { if (frameToDestroy) {
annotationUI.destroyFrame(frameToDestroy); store.destroyFrame(frameToDestroy);
} }
} }
......
...@@ -18,7 +18,7 @@ var { awaitStateChange } = require('../util/state-util'); ...@@ -18,7 +18,7 @@ var { awaitStateChange } = require('../util/state-util');
var serviceConfig = require('../service-config'); var serviceConfig = require('../service-config');
// @ngInject // @ngInject
function groups($rootScope, annotationUI, api, isSidebar, localStorage, serviceUrl, session, function groups($rootScope, store, api, isSidebar, localStorage, serviceUrl, session,
settings) { settings) {
// The currently focused group. This is the group that's shown as selected in // The currently focused group. This is the group that's shown as selected in
// the groups dropdown, the annotations displayed are filtered to only ones // the groups dropdown, the annotations displayed are filtered to only ones
...@@ -33,7 +33,7 @@ function groups($rootScope, annotationUI, api, isSidebar, localStorage, serviceU ...@@ -33,7 +33,7 @@ function groups($rootScope, annotationUI, api, isSidebar, localStorage, serviceU
function getDocumentUriForGroupSearch() { function getDocumentUriForGroupSearch() {
function mainUri() { function mainUri() {
var uris = annotationUI.searchUris(); var uris = store.searchUris();
if (uris.length === 0) { if (uris.length === 0) {
return null; return null;
} }
...@@ -43,7 +43,7 @@ function groups($rootScope, annotationUI, api, isSidebar, localStorage, serviceU ...@@ -43,7 +43,7 @@ function groups($rootScope, annotationUI, api, isSidebar, localStorage, serviceU
// HTTP URLs (so eg. we cannot use a "file:" URL or PDF fingerprint). // HTTP URLs (so eg. we cannot use a "file:" URL or PDF fingerprint).
return uris.find(uri => uri.startsWith('http')); return uris.find(uri => uri.startsWith('http'));
} }
return awaitStateChange(annotationUI, mainUri); return awaitStateChange(store, mainUri);
} }
/** /**
......
...@@ -33,14 +33,14 @@ var sortFns = { ...@@ -33,14 +33,14 @@ var sortFns = {
* This performs two functions: * This performs two functions:
* *
* 1. It listens for annotations being loaded, created and unloaded and * 1. It listens for annotations being loaded, created and unloaded and
* dispatches annotationUI.{addAnnotations|removeAnnotations} actions. * dispatches store.{addAnnotations|removeAnnotations} actions.
* 2. Listens for changes in the UI state and rebuilds the root conversation * 2. Listens for changes in the UI state and rebuilds the root conversation
* thread. * thread.
* *
* The root thread is then displayed by viewer.html * The root thread is then displayed by viewer.html
*/ */
// @ngInject // @ngInject
function RootThread($rootScope, annotationUI, drafts, searchFilter, viewFilter) { function RootThread($rootScope, store, drafts, searchFilter, viewFilter) {
/** /**
* Build the root conversation thread from the given UI state. * Build the root conversation thread from the given UI state.
...@@ -84,7 +84,7 @@ function RootThread($rootScope, annotationUI, drafts, searchFilter, viewFilter) ...@@ -84,7 +84,7 @@ function RootThread($rootScope, annotationUI, drafts, searchFilter, viewFilter)
} }
function deleteNewAndEmptyAnnotations() { function deleteNewAndEmptyAnnotations() {
annotationUI.getState().annotations.filter(function (ann) { store.getState().annotations.filter(function (ann) {
return metadata.isNew(ann) && !drafts.getIfNotEmpty(ann); return metadata.isNew(ann) && !drafts.getIfNotEmpty(ann);
}).forEach(function (ann) { }).forEach(function (ann) {
drafts.remove(ann); drafts.remove(ann);
...@@ -96,13 +96,13 @@ function RootThread($rootScope, annotationUI, drafts, searchFilter, viewFilter) ...@@ -96,13 +96,13 @@ function RootThread($rootScope, annotationUI, drafts, searchFilter, viewFilter)
// and show them in the UI. // and show them in the UI.
// //
// Note: These events could all be converted into actions that are handled by // Note: These events could all be converted into actions that are handled by
// the Redux store in annotationUI. // the Redux store in store.
var loadEvents = [events.ANNOTATION_CREATED, var loadEvents = [events.ANNOTATION_CREATED,
events.ANNOTATION_UPDATED, events.ANNOTATION_UPDATED,
events.ANNOTATIONS_LOADED]; events.ANNOTATIONS_LOADED];
loadEvents.forEach(function (event) { loadEvents.forEach(function (event) {
$rootScope.$on(event, function (event, annotation) { $rootScope.$on(event, function (event, annotation) {
annotationUI.addAnnotations([].concat(annotation)); store.addAnnotations([].concat(annotation));
}); });
}); });
...@@ -111,37 +111,37 @@ function RootThread($rootScope, annotationUI, drafts, searchFilter, viewFilter) ...@@ -111,37 +111,37 @@ function RootThread($rootScope, annotationUI, drafts, searchFilter, viewFilter)
// that are empty. // that are empty.
deleteNewAndEmptyAnnotations(); deleteNewAndEmptyAnnotations();
annotationUI.addAnnotations([ann]); store.addAnnotations([ann]);
// If the annotation is of type note or annotation, make sure // If the annotation is of type note or annotation, make sure
// the appropriate tab is selected. If it is of type reply, user // the appropriate tab is selected. If it is of type reply, user
// stays in the selected tab. // stays in the selected tab.
if (metadata.isPageNote(ann)) { if (metadata.isPageNote(ann)) {
annotationUI.selectTab(uiConstants.TAB_NOTES); store.selectTab(uiConstants.TAB_NOTES);
} else if (metadata.isAnnotation(ann)) { } else if (metadata.isAnnotation(ann)) {
annotationUI.selectTab(uiConstants.TAB_ANNOTATIONS); store.selectTab(uiConstants.TAB_ANNOTATIONS);
} }
(ann.references || []).forEach(function (parent) { (ann.references || []).forEach(function (parent) {
annotationUI.setCollapsed(parent, false); store.setCollapsed(parent, false);
}); });
}); });
// Remove any annotations that are deleted or unloaded // Remove any annotations that are deleted or unloaded
$rootScope.$on(events.ANNOTATION_DELETED, function (event, annotation) { $rootScope.$on(events.ANNOTATION_DELETED, function (event, annotation) {
annotationUI.removeAnnotations([annotation]); store.removeAnnotations([annotation]);
if (annotation.id) { if (annotation.id) {
annotationUI.removeSelectedAnnotation(annotation.id); store.removeSelectedAnnotation(annotation.id);
} }
}); });
$rootScope.$on(events.ANNOTATIONS_UNLOADED, function (event, annotations) { $rootScope.$on(events.ANNOTATIONS_UNLOADED, function (event, annotations) {
annotationUI.removeAnnotations(annotations); store.removeAnnotations(annotations);
}); });
// Once the focused group state is moved to the app state store, then the // Once the focused group state is moved to the app state store, then the
// logic in this event handler can be moved to the annotations reducer. // logic in this event handler can be moved to the annotations reducer.
$rootScope.$on(events.GROUP_FOCUSED, function (event, focusedGroupId) { $rootScope.$on(events.GROUP_FOCUSED, function (event, focusedGroupId) {
var updatedAnnots = annotationUI.getState().annotations.filter(function (ann) { var updatedAnnots = store.getState().annotations.filter(function (ann) {
return metadata.isNew(ann) && !metadata.isReply(ann); return metadata.isNew(ann) && !metadata.isReply(ann);
}).map(function (ann) { }).map(function (ann) {
return Object.assign(ann, { return Object.assign(ann, {
...@@ -149,7 +149,7 @@ function RootThread($rootScope, annotationUI, drafts, searchFilter, viewFilter) ...@@ -149,7 +149,7 @@ function RootThread($rootScope, annotationUI, drafts, searchFilter, viewFilter)
}); });
}); });
if (updatedAnnots.length > 0) { if (updatedAnnots.length > 0) {
annotationUI.addAnnotations(updatedAnnots); store.addAnnotations(updatedAnnots);
} }
}); });
......
...@@ -33,16 +33,16 @@ var urlUtil = require('../util/url-util'); ...@@ -33,16 +33,16 @@ var urlUtil = require('../util/url-util');
* *
* @ngInject * @ngInject
*/ */
function serviceUrl(annotationUI, apiRoutes) { function serviceUrl(store, apiRoutes) {
apiRoutes.links() apiRoutes.links()
.then(annotationUI.updateLinks) .then(store.updateLinks)
.catch(function(error) { .catch(function(error) {
console.warn('The links API request was rejected: ' + error.message); console.warn('The links API request was rejected: ' + error.message);
}); });
return function(linkName, params) { return function(linkName, params) {
var links = annotationUI.getState().links; var links = store.getState().links;
if (links === null) { if (links === null) {
return ''; return '';
......
...@@ -20,7 +20,7 @@ var CACHE_TTL = 5 * 60 * 1000; // 5 minutes ...@@ -20,7 +20,7 @@ var CACHE_TTL = 5 * 60 * 1000; // 5 minutes
* *
* @ngInject * @ngInject
*/ */
function session($q, $rootScope, analytics, annotationUI, api, auth, function session($q, $rootScope, analytics, store, api, auth,
flash, raven, settings, serviceConfig) { flash, raven, settings, serviceConfig) {
// Cache the result of load() // Cache the result of load()
var lastLoad; var lastLoad;
...@@ -93,11 +93,11 @@ function session($q, $rootScope, analytics, annotationUI, api, auth, ...@@ -93,11 +93,11 @@ function session($q, $rootScope, analytics, annotationUI, api, auth,
* @return {Profile} The updated profile data * @return {Profile} The updated profile data
*/ */
function update(model) { function update(model) {
var prevSession = annotationUI.getState().session; var prevSession = store.getState().session;
var userChanged = model.userid !== prevSession.userid; var userChanged = model.userid !== prevSession.userid;
// Update the session model used by the application // Update the session model used by the application
annotationUI.updateSession(model); store.updateSession(model);
lastLoad = Promise.resolve(model); lastLoad = Promise.resolve(model);
lastLoadTime = Date.now(); lastLoadTime = Date.now();
...@@ -167,9 +167,9 @@ function session($q, $rootScope, analytics, annotationUI, api, auth, ...@@ -167,9 +167,9 @@ function session($q, $rootScope, analytics, annotationUI, api, auth,
// For the moment, we continue to expose the session state as a property on // For the moment, we continue to expose the session state as a property on
// this service. In future, other services which access the session state // this service. In future, other services which access the session state
// will do so directly from annotationUI or via selector functions // will do so directly from store or via selector functions
get state() { get state() {
return annotationUI.getState().session; return store.getState().session;
}, },
update, update,
......
...@@ -20,7 +20,7 @@ var Socket = require('../websocket'); ...@@ -20,7 +20,7 @@ var Socket = require('../websocket');
* @param settings - Application settings * @param settings - Application settings
*/ */
// @ngInject // @ngInject
function Streamer($rootScope, annotationMapper, annotationUI, auth, function Streamer($rootScope, annotationMapper, store, auth,
groups, session, settings) { groups, session, settings) {
// The randomly generated session UUID // The randomly generated session UUID
var clientId = uuid.v4(); var clientId = uuid.v4();
...@@ -37,7 +37,7 @@ function Streamer($rootScope, annotationMapper, annotationUI, auth, ...@@ -37,7 +37,7 @@ function Streamer($rootScope, annotationMapper, annotationUI, auth,
// app. // app.
// //
// This state should be managed as part of the global app state in // This state should be managed as part of the global app state in
// annotationUI, but that is currently difficult because applying updates // store, but that is currently difficult because applying updates
// requires filtering annotations against the focused group (information not // requires filtering annotations against the focused group (information not
// currently stored in the app state) and triggering events in order to update // currently stored in the app state) and triggering events in order to update
// the annotations displayed in the page. // the annotations displayed in the page.
...@@ -62,7 +62,7 @@ function Streamer($rootScope, annotationMapper, annotationUI, auth, ...@@ -62,7 +62,7 @@ function Streamer($rootScope, annotationMapper, annotationUI, auth,
// focused group, since we only display annotations from the focused // focused group, since we only display annotations from the focused
// group and reload all annotations and discard pending updates // group and reload all annotations and discard pending updates
// when switching groups. // when switching groups.
if (ann.group === groups.focused().id || !annotationUI.isSidebar()) { if (ann.group === groups.focused().id || !store.isSidebar()) {
pendingUpdates[ann.id] = ann; pendingUpdates[ann.id] = ann;
} }
}); });
...@@ -78,14 +78,14 @@ function Streamer($rootScope, annotationMapper, annotationUI, auth, ...@@ -78,14 +78,14 @@ function Streamer($rootScope, annotationMapper, annotationUI, auth,
// even if the annotation is from the current group, it might be for a // even if the annotation is from the current group, it might be for a
// new annotation (saved in pendingUpdates and removed above), that has // new annotation (saved in pendingUpdates and removed above), that has
// not yet been loaded. // not yet been loaded.
if (annotationUI.annotationExists(ann.id)) { if (store.annotationExists(ann.id)) {
pendingDeletions[ann.id] = true; pendingDeletions[ann.id] = true;
} }
}); });
break; break;
} }
if (!annotationUI.isSidebar()) { if (!store.isSidebar()) {
applyPendingUpdates(); applyPendingUpdates();
} }
} }
...@@ -125,7 +125,7 @@ function Streamer($rootScope, annotationMapper, annotationUI, auth, ...@@ -125,7 +125,7 @@ function Streamer($rootScope, annotationMapper, annotationUI, auth,
} else if (message.type === 'session-change') { } else if (message.type === 'session-change') {
handleSessionChangeNotification(message); handleSessionChangeNotification(message);
} else if (message.type === 'whoyouare') { } else if (message.type === 'whoyouare') {
var userid = annotationUI.getState().session.userid; var userid = store.getState().session.userid;
if (message.userid !== userid) { if (message.userid !== userid) {
console.warn('WebSocket user ID "%s" does not match logged-in ID "%s"', message.userid, userid); console.warn('WebSocket user ID "%s" does not match logged-in ID "%s"', message.userid, userid);
} }
......
...@@ -8,7 +8,7 @@ var events = require('../../events'); ...@@ -8,7 +8,7 @@ var events = require('../../events');
describe('annotationMapper', function() { describe('annotationMapper', function() {
var sandbox = sinon.sandbox.create(); var sandbox = sinon.sandbox.create();
var $rootScope; var $rootScope;
var annotationUI; var store;
var fakeApi; var fakeApi;
var annotationMapper; var annotationMapper;
...@@ -21,15 +21,15 @@ describe('annotationMapper', function() { ...@@ -21,15 +21,15 @@ describe('annotationMapper', function() {
}; };
angular.module('app', []) angular.module('app', [])
.service('annotationMapper', require('../annotation-mapper')) .service('annotationMapper', require('../annotation-mapper'))
.service('annotationUI', require('../../store')) .service('store', require('../../store'))
.value('api', fakeApi) .value('api', fakeApi)
.value('settings', {}); .value('settings', {});
angular.mock.module('app'); angular.mock.module('app');
angular.mock.inject(function (_$rootScope_, _annotationUI_, _annotationMapper_) { angular.mock.inject(function (_$rootScope_, _store_, _annotationMapper_) {
$rootScope = _$rootScope_; $rootScope = _$rootScope_;
annotationMapper = _annotationMapper_; annotationMapper = _annotationMapper_;
annotationUI = _annotationUI_; store = _store_;
}); });
}); });
...@@ -60,7 +60,7 @@ describe('annotationMapper', function() { ...@@ -60,7 +60,7 @@ describe('annotationMapper', function() {
it('triggers the annotationUpdated event for each loaded annotation', function () { it('triggers the annotationUpdated event for each loaded annotation', function () {
sandbox.stub($rootScope, '$broadcast'); sandbox.stub($rootScope, '$broadcast');
var annotations = immutable([{id: 1}, {id: 2}, {id: 3}]); var annotations = immutable([{id: 1}, {id: 2}, {id: 3}]);
annotationUI.addAnnotations(angular.copy(annotations)); store.addAnnotations(angular.copy(annotations));
annotationMapper.loadAnnotations(annotations); annotationMapper.loadAnnotations(annotations);
assert.called($rootScope.$broadcast); assert.called($rootScope.$broadcast);
...@@ -72,7 +72,7 @@ describe('annotationMapper', function() { ...@@ -72,7 +72,7 @@ describe('annotationMapper', function() {
sandbox.stub($rootScope, '$broadcast'); sandbox.stub($rootScope, '$broadcast');
var annotations = [{id: 1}]; var annotations = [{id: 1}];
var replies = [{id: 2}, {id: 3}, {id: 4}]; var replies = [{id: 2}, {id: 3}, {id: 4}];
annotationUI.addAnnotations([{id:3}]); store.addAnnotations([{id:3}]);
annotationMapper.loadAnnotations(annotations, replies); annotationMapper.loadAnnotations(annotations, replies);
assert($rootScope.$broadcast.calledWith(events.ANNOTATION_UPDATED, assert($rootScope.$broadcast.calledWith(events.ANNOTATION_UPDATED,
...@@ -82,7 +82,7 @@ describe('annotationMapper', function() { ...@@ -82,7 +82,7 @@ describe('annotationMapper', function() {
it('replaces the properties on the cached annotation with those from the loaded one', function () { it('replaces the properties on the cached annotation with those from the loaded one', function () {
sandbox.stub($rootScope, '$broadcast'); sandbox.stub($rootScope, '$broadcast');
var annotations = [{id: 1, url: 'http://example.com'}]; var annotations = [{id: 1, url: 'http://example.com'}];
annotationUI.addAnnotations([{id:1, $tag: 'tag1'}]); store.addAnnotations([{id:1, $tag: 'tag1'}]);
annotationMapper.loadAnnotations(annotations); annotationMapper.loadAnnotations(annotations);
assert.called($rootScope.$broadcast); assert.called($rootScope.$broadcast);
...@@ -95,7 +95,7 @@ describe('annotationMapper', function() { ...@@ -95,7 +95,7 @@ describe('annotationMapper', function() {
it('excludes cached annotations from the annotationLoaded event', function () { it('excludes cached annotations from the annotationLoaded event', function () {
sandbox.stub($rootScope, '$broadcast'); sandbox.stub($rootScope, '$broadcast');
var annotations = [{id: 1, url: 'http://example.com'}]; var annotations = [{id: 1, url: 'http://example.com'}];
annotationUI.addAnnotations([{id: 1, $tag: 'tag1'}]); store.addAnnotations([{id: 1, $tag: 'tag1'}]);
annotationMapper.loadAnnotations(annotations); annotationMapper.loadAnnotations(annotations);
assert.called($rootScope.$broadcast); assert.called($rootScope.$broadcast);
...@@ -115,7 +115,7 @@ describe('annotationMapper', function() { ...@@ -115,7 +115,7 @@ describe('annotationMapper', function() {
it('replaces the properties on the cached annotation with those from the deleted one', function () { it('replaces the properties on the cached annotation with those from the deleted one', function () {
sandbox.stub($rootScope, '$broadcast'); sandbox.stub($rootScope, '$broadcast');
var annotations = [{id: 1, url: 'http://example.com'}]; var annotations = [{id: 1, url: 'http://example.com'}];
annotationUI.addAnnotations([{id: 1, $tag: 'tag1'}]); store.addAnnotations([{id: 1, $tag: 'tag1'}]);
annotationMapper.unloadAnnotations(annotations); annotationMapper.unloadAnnotations(annotations);
assert.calledWith($rootScope.$broadcast, events.ANNOTATIONS_UNLOADED, [{ assert.calledWith($rootScope.$broadcast, events.ANNOTATIONS_UNLOADED, [{
......
...@@ -6,7 +6,7 @@ var EventEmitter = require('tiny-emitter'); ...@@ -6,7 +6,7 @@ var EventEmitter = require('tiny-emitter');
var annotationFixtures = require('../../test/annotation-fixtures'); var annotationFixtures = require('../../test/annotation-fixtures');
var events = require('../../events'); var events = require('../../events');
var FrameSync = require('../frame-sync').default; var FrameSync = require('../frame-sync').default;
var fakeStore = require('../../test/fake-redux-store'); var createFakeStore = require('../../test/fake-redux-store');
var formatAnnot = require('../frame-sync').formatAnnot; var formatAnnot = require('../frame-sync').formatAnnot;
var uiConstants = require('../../ui-constants'); var uiConstants = require('../../ui-constants');
...@@ -51,7 +51,7 @@ var fixtures = { ...@@ -51,7 +51,7 @@ var fixtures = {
}; };
describe('sidebar.frame-sync', function () { describe('sidebar.frame-sync', function () {
var fakeAnnotationUI; var fakeStore;
var fakeBridge; var fakeBridge;
var frameSync; var frameSync;
var $rootScope; var $rootScope;
...@@ -62,7 +62,7 @@ describe('sidebar.frame-sync', function () { ...@@ -62,7 +62,7 @@ describe('sidebar.frame-sync', function () {
}); });
beforeEach(function () { beforeEach(function () {
fakeAnnotationUI = fakeStore({annotations: []}, { fakeStore = createFakeStore({annotations: []}, {
connectFrame: sinon.stub(), connectFrame: sinon.stub(),
destroyFrame: sinon.stub(), destroyFrame: sinon.stub(),
findIDsForTags: sinon.stub(), findIDsForTags: sinon.stub(),
...@@ -92,7 +92,7 @@ describe('sidebar.frame-sync', function () { ...@@ -92,7 +92,7 @@ describe('sidebar.frame-sync', function () {
angular.mock.module('app', { angular.mock.module('app', {
Discovery: FakeDiscovery, Discovery: FakeDiscovery,
annotationUI: fakeAnnotationUI, store: fakeStore,
bridge: fakeBridge, bridge: fakeBridge,
}); });
...@@ -108,7 +108,7 @@ describe('sidebar.frame-sync', function () { ...@@ -108,7 +108,7 @@ describe('sidebar.frame-sync', function () {
context('when annotations are loaded into the sidebar', function () { context('when annotations are loaded into the sidebar', function () {
it('sends a "loadAnnotations" message to the frame', function () { it('sends a "loadAnnotations" message to the frame', function () {
fakeAnnotationUI.setState({annotations: [fixtures.ann]}); fakeStore.setState({annotations: [fixtures.ann]});
assert.calledWithMatch(fakeBridge.call, 'loadAnnotations', sinon.match([ assert.calledWithMatch(fakeBridge.call, 'loadAnnotations', sinon.match([
formatAnnot(fixtures.ann), formatAnnot(fixtures.ann),
])); ]));
...@@ -116,10 +116,10 @@ describe('sidebar.frame-sync', function () { ...@@ -116,10 +116,10 @@ describe('sidebar.frame-sync', function () {
it('sends a "loadAnnotations" message only for new annotations', function () { it('sends a "loadAnnotations" message only for new annotations', function () {
var ann2 = Object.assign({}, fixtures.ann, {$tag: 't2', id: 'a2'}); var ann2 = Object.assign({}, fixtures.ann, {$tag: 't2', id: 'a2'});
fakeAnnotationUI.setState({annotations: [fixtures.ann]}); fakeStore.setState({annotations: [fixtures.ann]});
fakeBridge.call.reset(); fakeBridge.call.reset();
fakeAnnotationUI.setState({annotations: [fixtures.ann, ann2]}); fakeStore.setState({annotations: [fixtures.ann, ann2]});
assert.calledWithMatch(fakeBridge.call, 'loadAnnotations', sinon.match([ assert.calledWithMatch(fakeBridge.call, 'loadAnnotations', sinon.match([
formatAnnot(ann2), formatAnnot(ann2),
...@@ -127,37 +127,37 @@ describe('sidebar.frame-sync', function () { ...@@ -127,37 +127,37 @@ describe('sidebar.frame-sync', function () {
}); });
it('does not send a "loadAnnotations" message for replies', function () { it('does not send a "loadAnnotations" message for replies', function () {
fakeAnnotationUI.setState({annotations: [annotationFixtures.newReply()]}); fakeStore.setState({annotations: [annotationFixtures.newReply()]});
assert.isFalse(fakeBridge.call.calledWith('loadAnnotations')); assert.isFalse(fakeBridge.call.calledWith('loadAnnotations'));
}); });
}); });
context('when annotation count has changed', function () { context('when annotation count has changed', function () {
it('sends a "publicAnnotationCountChanged" message to the frame when there are public annotations', function () { it('sends a "publicAnnotationCountChanged" message to the frame when there are public annotations', function () {
fakeAnnotationUI.setState({ fakeStore.setState({
annotations: [annotationFixtures.publicAnnotation()], annotations: [annotationFixtures.publicAnnotation()],
}); });
assert.calledWithMatch(fakeBridge.call, 'publicAnnotationCountChanged', sinon.match(1)); assert.calledWithMatch(fakeBridge.call, 'publicAnnotationCountChanged', sinon.match(1));
}); });
it('sends a "publicAnnotationCountChanged" message to the frame when there are only private annotations', function () { it('sends a "publicAnnotationCountChanged" message to the frame when there are only private annotations', function () {
fakeAnnotationUI.setState({ fakeStore.setState({
annotations: [annotationFixtures.defaultAnnotation()], annotations: [annotationFixtures.defaultAnnotation()],
}); });
assert.calledWithMatch(fakeBridge.call, 'publicAnnotationCountChanged', sinon.match(0)); assert.calledWithMatch(fakeBridge.call, 'publicAnnotationCountChanged', sinon.match(0));
}); });
it('does not send a "publicAnnotationCountChanged" message to the frame if annotation fetch is not complete', function () { it('does not send a "publicAnnotationCountChanged" message to the frame if annotation fetch is not complete', function () {
fakeAnnotationUI.frames.returns([{uri: 'http://example.com'}]); fakeStore.frames.returns([{uri: 'http://example.com'}]);
fakeAnnotationUI.setState({ fakeStore.setState({
annotations: [annotationFixtures.publicAnnotation()], annotations: [annotationFixtures.publicAnnotation()],
}); });
assert.isFalse(fakeBridge.call.calledWith('publicAnnotationCountChanged')); assert.isFalse(fakeBridge.call.calledWith('publicAnnotationCountChanged'));
}); });
it('does not send a "publicAnnotationCountChanged" message if there are no connected frames', function () { it('does not send a "publicAnnotationCountChanged" message if there are no connected frames', function () {
fakeAnnotationUI.frames.returns([]); fakeStore.frames.returns([]);
fakeAnnotationUI.setState({ fakeStore.setState({
annotations: [annotationFixtures.publicAnnotation()], annotations: [annotationFixtures.publicAnnotation()],
}); });
assert.isFalse(fakeBridge.call.calledWith('publicAnnotationCountChanged')); assert.isFalse(fakeBridge.call.calledWith('publicAnnotationCountChanged'));
...@@ -166,8 +166,8 @@ describe('sidebar.frame-sync', function () { ...@@ -166,8 +166,8 @@ describe('sidebar.frame-sync', function () {
context('when annotations are removed from the sidebar', function () { context('when annotations are removed from the sidebar', function () {
it('sends a "deleteAnnotation" message to the frame', function () { it('sends a "deleteAnnotation" message to the frame', function () {
fakeAnnotationUI.setState({annotations: [fixtures.ann]}); fakeStore.setState({annotations: [fixtures.ann]});
fakeAnnotationUI.setState({annotations: []}); fakeStore.setState({annotations: []});
assert.calledWithMatch(fakeBridge.call, 'deleteAnnotation', assert.calledWithMatch(fakeBridge.call, 'deleteAnnotation',
sinon.match(formatAnnot(fixtures.ann))); sinon.match(formatAnnot(fixtures.ann)));
}); });
...@@ -210,7 +210,7 @@ describe('sidebar.frame-sync', function () { ...@@ -210,7 +210,7 @@ describe('sidebar.frame-sync', function () {
expireDebounceTimeout(); expireDebounceTimeout();
assert.calledWith(fakeAnnotationUI.updateAnchorStatus, { t1: 'anchored' }); assert.calledWith(fakeStore.updateAnchorStatus, { t1: 'anchored' });
}); });
it('coalesces multiple "sync" messages', () => { it('coalesces multiple "sync" messages', () => {
...@@ -219,7 +219,7 @@ describe('sidebar.frame-sync', function () { ...@@ -219,7 +219,7 @@ describe('sidebar.frame-sync', function () {
expireDebounceTimeout(); expireDebounceTimeout();
assert.calledWith(fakeAnnotationUI.updateAnchorStatus, { assert.calledWith(fakeStore.updateAnchorStatus, {
t1: 'anchored', t1: 'anchored',
t2: 'orphan', t2: 'orphan',
}); });
...@@ -249,7 +249,7 @@ describe('sidebar.frame-sync', function () { ...@@ -249,7 +249,7 @@ describe('sidebar.frame-sync', function () {
fakeBridge.emit('connect', fakeChannel); fakeBridge.emit('connect', fakeChannel);
assert.calledWith(fakeAnnotationUI.connectFrame, { assert.calledWith(fakeStore.connectFrame, {
id: frameInfo.frameIdentifier, id: frameInfo.frameIdentifier,
metadata: frameInfo.metadata, metadata: frameInfo.metadata,
uri: frameInfo.uri, uri: frameInfo.uri,
...@@ -263,32 +263,32 @@ describe('sidebar.frame-sync', function () { ...@@ -263,32 +263,32 @@ describe('sidebar.frame-sync', function () {
it('removes the frame from the frames list', function () { it('removes the frame from the frames list', function () {
fakeBridge.emit('destroyFrame', frameId); fakeBridge.emit('destroyFrame', frameId);
assert.calledWith(fakeAnnotationUI.destroyFrame, fixtures.framesListEntry); assert.calledWith(fakeStore.destroyFrame, fixtures.framesListEntry);
}); });
}); });
describe('on "showAnnotations" message', function () { describe('on "showAnnotations" message', function () {
it('selects annotations which have an ID', function () { it('selects annotations which have an ID', function () {
fakeAnnotationUI.findIDsForTags.returns(['id1','id2','id3']); fakeStore.findIDsForTags.returns(['id1','id2','id3']);
fakeBridge.emit('showAnnotations', ['tag1', 'tag2', 'tag3']); fakeBridge.emit('showAnnotations', ['tag1', 'tag2', 'tag3']);
assert.calledWith(fakeAnnotationUI.selectAnnotations, ['id1', 'id2', 'id3']); assert.calledWith(fakeStore.selectAnnotations, ['id1', 'id2', 'id3']);
assert.calledWith(fakeAnnotationUI.selectTab, uiConstants.TAB_ANNOTATIONS); assert.calledWith(fakeStore.selectTab, uiConstants.TAB_ANNOTATIONS);
}); });
}); });
describe('on "focusAnnotations" message', function () { describe('on "focusAnnotations" message', function () {
it('focuses the annotations', function () { it('focuses the annotations', function () {
fakeBridge.emit('focusAnnotations', ['tag1', 'tag2', 'tag3']); fakeBridge.emit('focusAnnotations', ['tag1', 'tag2', 'tag3']);
assert.calledWith(fakeAnnotationUI.focusAnnotations, ['tag1', 'tag2', 'tag3']); assert.calledWith(fakeStore.focusAnnotations, ['tag1', 'tag2', 'tag3']);
}); });
}); });
describe('on "toggleAnnotationSelection" message', function () { describe('on "toggleAnnotationSelection" message', function () {
it('toggles the selected state of the annotations', function () { it('toggles the selected state of the annotations', function () {
fakeAnnotationUI.findIDsForTags.returns(['id1','id2','id3']); fakeStore.findIDsForTags.returns(['id1','id2','id3']);
fakeBridge.emit('toggleAnnotationSelection', ['tag1', 'tag2', 'tag3']); fakeBridge.emit('toggleAnnotationSelection', ['tag1', 'tag2', 'tag3']);
assert.calledWith(fakeAnnotationUI.toggleSelectedAnnotations, ['id1', 'id2', 'id3']); assert.calledWith(fakeStore.toggleSelectedAnnotations, ['id1', 'id2', 'id3']);
}); });
}); });
......
...@@ -13,7 +13,7 @@ var sessionWithThreeGroups = function() { ...@@ -13,7 +13,7 @@ var sessionWithThreeGroups = function() {
}; };
describe('groups', function() { describe('groups', function() {
var fakeAnnotationUI; var fakeStore;
var fakeIsSidebar; var fakeIsSidebar;
var fakeSession; var fakeSession;
var fakeSettings; var fakeSettings;
...@@ -26,7 +26,7 @@ describe('groups', function() { ...@@ -26,7 +26,7 @@ describe('groups', function() {
beforeEach(function() { beforeEach(function() {
sandbox = sinon.sandbox.create(); sandbox = sinon.sandbox.create();
fakeAnnotationUI = fakeReduxStore({ fakeStore = fakeReduxStore({
searchUris: ['http://example.org'], searchUris: ['http://example.org'],
},{ },{
searchUris() { searchUris() {
...@@ -77,7 +77,7 @@ describe('groups', function() { ...@@ -77,7 +77,7 @@ describe('groups', function() {
}); });
function service() { function service() {
return groups(fakeRootScope, fakeAnnotationUI, fakeApi, fakeIsSidebar, fakeLocalStorage, fakeServiceUrl, return groups(fakeRootScope, fakeStore, fakeApi, fakeIsSidebar, fakeLocalStorage, fakeServiceUrl,
fakeSession, fakeSettings); fakeSession, fakeSettings);
} }
...@@ -134,9 +134,9 @@ describe('groups', function() { ...@@ -134,9 +134,9 @@ describe('groups', function() {
it('waits for the document URL to be determined', () => { it('waits for the document URL to be determined', () => {
var svc = service(); var svc = service();
fakeAnnotationUI.setState({ searchUris: [] }); fakeStore.setState({ searchUris: [] });
var loaded = svc.load(); var loaded = svc.load();
fakeAnnotationUI.setState({ searchUris: ['https://asite.com'] }); fakeStore.setState({ searchUris: ['https://asite.com'] });
return loaded.then(() => { return loaded.then(() => {
assert.calledWith(fakeApi.groups.list, { document_uri: 'https://asite.com' }); assert.calledWith(fakeApi.groups.list, { document_uri: 'https://asite.com' });
...@@ -150,7 +150,7 @@ describe('groups', function() { ...@@ -150,7 +150,7 @@ describe('groups', function() {
}); });
it('does not wait for the document URL', () => { it('does not wait for the document URL', () => {
fakeAnnotationUI.setState({ searchUris: [] }); fakeStore.setState({ searchUris: [] });
var svc = service(); var svc = service();
return svc.load().then(() => { return svc.load().then(() => {
assert.calledWith(fakeApi.groups.list, {}); assert.calledWith(fakeApi.groups.list, {});
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
var proxyquire = require('proxyquire'); var proxyquire = require('proxyquire');
/** Return a fake annotationUI object. */ /** Return a fake store object. */
function fakeAnnotationUI() { function fakeStore() {
var links = null; var links = null;
return { return {
updateLinks: function(newLinks) { updateLinks: function(newLinks) {
...@@ -24,16 +24,16 @@ function createServiceUrl(linksPromise) { ...@@ -24,16 +24,16 @@ function createServiceUrl(linksPromise) {
'../util/url-util': { replaceURLParams: replaceURLParams }, '../util/url-util': { replaceURLParams: replaceURLParams },
}); });
var annotationUI = fakeAnnotationUI(); var store = fakeStore();
var apiRoutes = { var apiRoutes = {
links: sinon.stub().returns(linksPromise), links: sinon.stub().returns(linksPromise),
}; };
return { return {
annotationUI: annotationUI, store: store,
apiRoutes, apiRoutes,
serviceUrl: serviceUrlFactory(annotationUI, apiRoutes), serviceUrl: serviceUrlFactory(store, apiRoutes),
replaceURLParams: replaceURLParams, replaceURLParams: replaceURLParams,
}; };
} }
...@@ -76,7 +76,7 @@ describe('sidebar.service-url', function () { ...@@ -76,7 +76,7 @@ describe('sidebar.service-url', function () {
}); });
context('after the API response has been received', function() { context('after the API response has been received', function() {
var annotationUI; var store;
var linksPromise; var linksPromise;
var replaceURLParams; var replaceURLParams;
var serviceUrl; var serviceUrl;
...@@ -90,14 +90,14 @@ describe('sidebar.service-url', function () { ...@@ -90,14 +90,14 @@ describe('sidebar.service-url', function () {
var parts = createServiceUrl(linksPromise); var parts = createServiceUrl(linksPromise);
annotationUI = parts.annotationUI; store = parts.store;
serviceUrl = parts.serviceUrl; serviceUrl = parts.serviceUrl;
replaceURLParams = parts.replaceURLParams; replaceURLParams = parts.replaceURLParams;
}); });
it('updates annotationUI with the real links', function() { it('updates store with the real links', function() {
return linksPromise.then(function(links) { return linksPromise.then(function(links) {
assert.deepEqual(annotationUI.getState(), {links: links}); assert.deepEqual(store.getState(), {links: links});
}); });
}); });
......
...@@ -32,7 +32,7 @@ describe('sidebar.session', function () { ...@@ -32,7 +32,7 @@ describe('sidebar.session', function () {
track: sinon.stub(), track: sinon.stub(),
events: require('../analytics')().events, events: require('../analytics')().events,
}; };
var fakeAnnotationUI = { var fakeStore = {
getState: function () { getState: function () {
return {session: state}; return {session: state};
}, },
...@@ -60,7 +60,7 @@ describe('sidebar.session', function () { ...@@ -60,7 +60,7 @@ describe('sidebar.session', function () {
mock.module('h', { mock.module('h', {
analytics: fakeAnalytics, analytics: fakeAnalytics,
annotationUI: fakeAnnotationUI, store: fakeStore,
api: fakeApi, api: fakeApi,
auth: fakeAuth, auth: fakeAuth,
flash: fakeFlash, flash: fakeFlash,
......
...@@ -67,7 +67,7 @@ inherits(FakeSocket, EventEmitter); ...@@ -67,7 +67,7 @@ inherits(FakeSocket, EventEmitter);
describe('Streamer', function () { describe('Streamer', function () {
var fakeAnnotationMapper; var fakeAnnotationMapper;
var fakeAnnotationUI; var fakeStore;
var fakeAuth; var fakeAuth;
var fakeGroups; var fakeGroups;
var fakeRootScope; var fakeRootScope;
...@@ -80,7 +80,7 @@ describe('Streamer', function () { ...@@ -80,7 +80,7 @@ describe('Streamer', function () {
activeStreamer = new Streamer( activeStreamer = new Streamer(
fakeRootScope, fakeRootScope,
fakeAnnotationMapper, fakeAnnotationMapper,
fakeAnnotationUI, fakeStore,
fakeAuth, fakeAuth,
fakeGroups, fakeGroups,
fakeSession, fakeSession,
...@@ -112,7 +112,7 @@ describe('Streamer', function () { ...@@ -112,7 +112,7 @@ describe('Streamer', function () {
unloadAnnotations: sinon.stub(), unloadAnnotations: sinon.stub(),
}; };
fakeAnnotationUI = { fakeStore = {
annotationExists: sinon.stub().returns(false), annotationExists: sinon.stub().returns(false),
isSidebar: sinon.stub().returns(true), isSidebar: sinon.stub().returns(true),
getState: sinon.stub().returns({ getState: sinon.stub().returns({
...@@ -254,7 +254,7 @@ describe('Streamer', function () { ...@@ -254,7 +254,7 @@ describe('Streamer', function () {
context('when the app is the stream', function () { context('when the app is the stream', function () {
beforeEach(function () { beforeEach(function () {
fakeAnnotationUI.isSidebar.returns(false); fakeStore.isSidebar.returns(false);
}); });
it('does not defer updates', function () { it('does not defer updates', function () {
...@@ -288,7 +288,7 @@ describe('Streamer', function () { ...@@ -288,7 +288,7 @@ describe('Streamer', function () {
it('saves pending deletions if the annotation is loaded', function () { it('saves pending deletions if the annotation is loaded', function () {
var id = fixtures.deleteNotification.payload[0].id; var id = fixtures.deleteNotification.payload[0].id;
fakeAnnotationUI.annotationExists.returns(true); fakeStore.annotationExists.returns(true);
fakeWebSocket.notify(fixtures.deleteNotification); fakeWebSocket.notify(fixtures.deleteNotification);
...@@ -298,7 +298,7 @@ describe('Streamer', function () { ...@@ -298,7 +298,7 @@ describe('Streamer', function () {
it('discards pending deletions if the annotation is not loaded', function () { it('discards pending deletions if the annotation is not loaded', function () {
var id = fixtures.deleteNotification.payload[0].id; var id = fixtures.deleteNotification.payload[0].id;
fakeAnnotationUI.annotationExists.returns(false); fakeStore.annotationExists.returns(false);
fakeWebSocket.notify(fixtures.deleteNotification); fakeWebSocket.notify(fixtures.deleteNotification);
...@@ -312,7 +312,7 @@ describe('Streamer', function () { ...@@ -312,7 +312,7 @@ describe('Streamer', function () {
}); });
it('discards pending updates if an unloaded annotation is deleted', function () { it('discards pending updates if an unloaded annotation is deleted', function () {
fakeAnnotationUI.annotationExists.returns(false); fakeStore.annotationExists.returns(false);
fakeWebSocket.notify(fixtures.createNotification); fakeWebSocket.notify(fixtures.createNotification);
fakeWebSocket.notify(fixtures.deleteNotification); fakeWebSocket.notify(fixtures.deleteNotification);
...@@ -346,7 +346,7 @@ describe('Streamer', function () { ...@@ -346,7 +346,7 @@ describe('Streamer', function () {
}); });
it('applies pending deletions', function () { it('applies pending deletions', function () {
fakeAnnotationUI.annotationExists.returns(true); fakeStore.annotationExists.returns(true);
fakeWebSocket.notify(fixtures.deleteNotification); fakeWebSocket.notify(fixtures.deleteNotification);
activeStreamer.applyPendingUpdates(); activeStreamer.applyPendingUpdates();
...@@ -382,7 +382,7 @@ describe('Streamer', function () { ...@@ -382,7 +382,7 @@ describe('Streamer', function () {
}, changeEvents); }, changeEvents);
unroll('discards pending deletions when #event occurs', function (testCase) { unroll('discards pending deletions when #event occurs', function (testCase) {
fakeAnnotationUI.annotationExists.returns(true); fakeStore.annotationExists.returns(true);
fakeWebSocket.notify(fixtures.deleteNotification); fakeWebSocket.notify(fixtures.deleteNotification);
fakeRootScope.$broadcast(testCase.event, {id: 'an-id'}); fakeRootScope.$broadcast(testCase.event, {id: 'an-id'});
...@@ -432,7 +432,7 @@ describe('Streamer', function () { ...@@ -432,7 +432,7 @@ describe('Streamer', function () {
}); });
unroll('does nothing if the userid matches the logged-in userid', function (testCase) { unroll('does nothing if the userid matches the logged-in userid', function (testCase) {
fakeAnnotationUI.getState.returns({ fakeStore.getState.returns({
session: { session: {
userid: testCase.userid, userid: testCase.userid,
}, },
...@@ -454,7 +454,7 @@ describe('Streamer', function () { ...@@ -454,7 +454,7 @@ describe('Streamer', function () {
}]); }]);
unroll('logs a warning if the userid does not match the logged-in userid', function (testCase) { unroll('logs a warning if the userid does not match the logged-in userid', function (testCase) {
fakeAnnotationUI.getState.returns({ fakeStore.getState.returns({
session: { session: {
userid: testCase.userid, userid: testCase.userid,
}, },
......
...@@ -89,12 +89,12 @@ function store($rootScope, settings) { ...@@ -89,12 +89,12 @@ function store($rootScope, settings) {
enhancer); enhancer);
// Expose helper functions that create actions as methods of the // Expose helper functions that create actions as methods of the
// `annotationUI` service to make using them easier from app code. eg. // `store` service to make using them easier from app code. eg.
// //
// Instead of: // Instead of:
// annotationUI.dispatch(annotations.actions.addAnnotations(annotations)) // store.dispatch(annotations.actions.addAnnotations(annotations))
// You can use: // You can use:
// annotationUI.addAnnotations(annotations) // store.addAnnotations(annotations)
// //
var actionCreators = redux.bindActionCreators(Object.assign({}, var actionCreators = redux.bindActionCreators(Object.assign({},
annotationsModule.actions, annotationsModule.actions,
...@@ -105,13 +105,13 @@ function store($rootScope, settings) { ...@@ -105,13 +105,13 @@ function store($rootScope, settings) {
viewerModule.actions viewerModule.actions
), store.dispatch); ), store.dispatch);
// Expose selectors as methods of the `annotationUI` to make using them easier // Expose selectors as methods of the `store` to make using them easier
// from app code. // from app code.
// //
// eg. Instead of: // eg. Instead of:
// selection.isAnnotationSelected(annotationUI.getState(), id) // selection.isAnnotationSelected(store.getState(), id)
// You can use: // You can use:
// annotationUI.isAnnotationSelected(id) // store.isAnnotationSelected(id)
var selectors = util.bindSelectors(Object.assign({}, var selectors = util.bindSelectors(Object.assign({},
annotationsModule.selectors, annotationsModule.selectors,
framesModule.selectors, framesModule.selectors,
......
This diff is collapsed.
...@@ -5,13 +5,13 @@ var crossOriginRPC = require('../cross-origin-rpc'); ...@@ -5,13 +5,13 @@ var crossOriginRPC = require('../cross-origin-rpc');
describe('crossOriginRPC', function() { describe('crossOriginRPC', function() {
describe('server', function() { describe('server', function() {
let addedListener; // The postMessage() listener that the server adds. let addedListener; // The postMessage() listener that the server adds.
let fakeAnnotationUI; let fakeStore;
let fakeWindow; let fakeWindow;
let settings; let settings;
let source; let source;
beforeEach(function() { beforeEach(function() {
fakeAnnotationUI = { fakeStore = {
searchUris: sinon.stub().returns('THE_SEARCH_URIS'), searchUris: sinon.stub().returns('THE_SEARCH_URIS'),
}; };
...@@ -40,14 +40,14 @@ describe('crossOriginRPC', function() { ...@@ -40,14 +40,14 @@ describe('crossOriginRPC', function() {
} }
it('adds a postMessage() event listener function', function() { it('adds a postMessage() event listener function', function() {
crossOriginRPC.server.start(fakeAnnotationUI, {}, fakeWindow); crossOriginRPC.server.start(fakeStore, {}, fakeWindow);
assert.isTrue(fakeWindow.addEventListener.calledOnce); assert.isTrue(fakeWindow.addEventListener.calledOnce);
assert.isTrue(fakeWindow.addEventListener.calledWith('message')); assert.isTrue(fakeWindow.addEventListener.calledWith('message'));
}); });
it('sends a response with the result from the called method', function() { it('sends a response with the result from the called method', function() {
crossOriginRPC.server.start(fakeAnnotationUI, settings, fakeWindow); crossOriginRPC.server.start(fakeStore, settings, fakeWindow);
postMessage({ postMessage({
data: { method: 'searchUris', id: 42 }, data: { method: 'searchUris', id: 42 },
...@@ -72,7 +72,7 @@ describe('crossOriginRPC', function() { ...@@ -72,7 +72,7 @@ describe('crossOriginRPC', function() {
{ rpcAllowedOrigins: ['https://allowed1.com', 'https://allowed2.com'] }, { rpcAllowedOrigins: ['https://allowed1.com', 'https://allowed2.com'] },
].forEach(function(settings) { ].forEach(function(settings) {
it("doesn't respond if the origin isn't allowed", function() { it("doesn't respond if the origin isn't allowed", function() {
crossOriginRPC.server.start(fakeAnnotationUI, settings, fakeWindow); crossOriginRPC.server.start(fakeStore, settings, fakeWindow);
postMessage({ postMessage({
origin: 'https://notallowed.com', origin: 'https://notallowed.com',
...@@ -85,7 +85,7 @@ describe('crossOriginRPC', function() { ...@@ -85,7 +85,7 @@ describe('crossOriginRPC', function() {
}); });
it("responds with an error if there's no method", function() { it("responds with an error if there's no method", function() {
crossOriginRPC.server.start(fakeAnnotationUI, settings, fakeWindow); crossOriginRPC.server.start(fakeStore, settings, fakeWindow);
let jsonRpcRequest = { id: 42 }; // No "method" member. let jsonRpcRequest = { id: 42 }; // No "method" member.
postMessage({ postMessage({
...@@ -113,7 +113,7 @@ describe('crossOriginRPC', function() { ...@@ -113,7 +113,7 @@ describe('crossOriginRPC', function() {
null, null,
].forEach(function(method) { ].forEach(function(method) {
it('responds with an error if the method is unknown', function() { it('responds with an error if the method is unknown', function() {
crossOriginRPC.server.start(fakeAnnotationUI, settings, fakeWindow); crossOriginRPC.server.start(fakeStore, settings, fakeWindow);
postMessage({ postMessage({
origin: 'https://allowed1.com', origin: 'https://allowed1.com',
......
...@@ -30,7 +30,7 @@ var fixtures = immutable({ ...@@ -30,7 +30,7 @@ var fixtures = immutable({
}); });
describe('annotation threading', function () { describe('annotation threading', function () {
var annotationUI; var store;
var rootThread; var rootThread;
beforeEach(function () { beforeEach(function () {
...@@ -44,7 +44,7 @@ describe('annotation threading', function () { ...@@ -44,7 +44,7 @@ describe('annotation threading', function () {
}; };
angular.module('app', []) angular.module('app', [])
.service('annotationUI', require('../../store')) .service('store', require('../../store'))
.service('drafts', require('../../services/drafts')) .service('drafts', require('../../services/drafts'))
.service('rootThread', require('../../services/root-thread')) .service('rootThread', require('../../services/root-thread'))
.service('searchFilter', require('../../services/search-filter')) .service('searchFilter', require('../../services/search-filter'))
...@@ -55,34 +55,34 @@ describe('annotation threading', function () { ...@@ -55,34 +55,34 @@ describe('annotation threading', function () {
angular.mock.module('app'); angular.mock.module('app');
angular.mock.inject(function (_annotationUI_, _rootThread_) { angular.mock.inject(function (_store_, _rootThread_) {
annotationUI = _annotationUI_; store = _store_;
rootThread = _rootThread_; rootThread = _rootThread_;
}); });
}); });
it('should display newly loaded annotations', function () { it('should display newly loaded annotations', function () {
annotationUI.addAnnotations(fixtures.annotations); store.addAnnotations(fixtures.annotations);
assert.equal(rootThread.thread(annotationUI.getState()).children.length, 2); assert.equal(rootThread.thread(store.getState()).children.length, 2);
}); });
it('should not display unloaded annotations', function () { it('should not display unloaded annotations', function () {
annotationUI.addAnnotations(fixtures.annotations); store.addAnnotations(fixtures.annotations);
annotationUI.removeAnnotations(fixtures.annotations); store.removeAnnotations(fixtures.annotations);
assert.equal(rootThread.thread(annotationUI.getState()).children.length, 0); assert.equal(rootThread.thread(store.getState()).children.length, 0);
}); });
it('should filter annotations when a search is set', function () { it('should filter annotations when a search is set', function () {
annotationUI.addAnnotations(fixtures.annotations); store.addAnnotations(fixtures.annotations);
annotationUI.setFilterQuery('second'); store.setFilterQuery('second');
assert.equal(rootThread.thread(annotationUI.getState()).children.length, 1); assert.equal(rootThread.thread(store.getState()).children.length, 1);
assert.equal(rootThread.thread(annotationUI.getState()).children[0].id, '2'); assert.equal(rootThread.thread(store.getState()).children[0].id, '2');
}); });
unroll('should sort annotations by #mode', function (testCase) { unroll('should sort annotations by #mode', function (testCase) {
annotationUI.addAnnotations(fixtures.annotations); store.addAnnotations(fixtures.annotations);
annotationUI.setSortKey(testCase.sortKey); store.setSortKey(testCase.sortKey);
var actualOrder = rootThread.thread(annotationUI.getState()).children.map(function (thread) { var actualOrder = rootThread.thread(store.getState()).children.map(function (thread) {
return thread.annotation.id; return thread.annotation.id;
}); });
assert.deepEqual(actualOrder, testCase.expectedOrder); assert.deepEqual(actualOrder, testCase.expectedOrder);
......
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