diff --git a/js/src/annotations/annotationTooltip.js b/js/src/annotations/annotationTooltip.js
index 19b1c469e9..94903797b1 100644
--- a/js/src/annotations/annotationTooltip.js
+++ b/js/src/annotations/annotationTooltip.js
@@ -153,19 +153,19 @@
event: false
},
events: {
- show: function(event, api) {
+ shown: function(event, api) {
if (params.onTooltipShown) { params.onTooltipShown(event, api); }
},
hidden: function(event, api) {
if (params.onTooltipHidden) { params.onTooltipHidden(event, api); }
+ _this.removeAllEvents(api, params);
},
visible: function (event, api) {
- _this.removeAllEvents(api, params);
_this.addViewerEvents(api, params);
},
move: function (event, api) {
- _this.removeAllEvents(api, params);
- _this.addViewerEvents(api, params);
+ // _this.removeAllEvents(api, params);
+ // _this.addViewerEvents(api, params);
}
}
});
@@ -232,6 +232,8 @@
_this.addEditorEvents(api, viewerParams);
} else {
_this.eventEmitter.publish('annotationInEditMode.' + _this.windowId,[oaAnno]);
+ api.destroy();
+ jQuery(api.tooltip).remove();
}
_this.eventEmitter.publish('SET_ANNOTATION_EDITING.' + _this.windowId, {
diff --git a/js/src/annotations/osd-region-draw-tool.js b/js/src/annotations/osd-region-draw-tool.js
index 64755502a5..de1d38db43 100644
--- a/js/src/annotations/osd-region-draw-tool.js
+++ b/js/src/annotations/osd-region-draw-tool.js
@@ -76,37 +76,38 @@
}
},
- render: function() {
+ render: function () {
+
+ if(this.parent.mode !== $.AnnotationsLayer.DISPLAY_ANNOTATIONS){
+ return ;
+ }
this.svgOverlay.restoreEditedShapes();
this.svgOverlay.paperScope.activate();
this.svgOverlay.paperScope.project.clear();
var _this = this;
_this.annotationsToShapesMap = {};
- var deferreds = jQuery.map(this.list, function(annotation) {
- var deferred = jQuery.Deferred(),
- shapeArray;
+
+ for (var i = 0; i < this.list.length; i++) {
+ var shapeArray;
+ var annotation = this.list[i];
if (annotation.on && typeof annotation.on === 'object') {
if (!annotation.on.selector) {
- return deferred;
+ continue;
} else if (annotation.on.selector.value.indexOf('";
- } else if (!text || item['@language'] === language) {
- // {@value: ..., @language: ...}
- text = item['@value'];
+ jQuery.each(propertyValue, function(idx, item) {
+ var textToAdd = '';
+ if (typeof item === 'string' && displayLanguage === null) {
+ textToAdd = item;
+ } else if (item['@language'] === displayLanguage) {
+ textToAdd = item['@value'];
+ }
+ if (textToAdd !== '' && text !== '') {
+ text += '
';
}
+ text += textToAdd;
});
return text;
} else {
diff --git a/js/src/widgets/annotationsLayer.js b/js/src/widgets/annotationsLayer.js
index b2d59560c8..9e3096b925 100755
--- a/js/src/widgets/annotationsLayer.js
+++ b/js/src/widgets/annotationsLayer.js
@@ -17,6 +17,8 @@
this.init();
};
+ $.AnnotationsLayer.DISPLAY_ANNOTATIONS = 'displayAnnotations';
+
$.AnnotationsLayer.prototype = {
init: function() {
diff --git a/js/src/widgets/imageView.js b/js/src/widgets/imageView.js
index 06a7fd7dc1..055af96503 100755
--- a/js/src/widgets/imageView.js
+++ b/js/src/widgets/imageView.js
@@ -270,8 +270,7 @@
this.element.find('.mirador-osd-refresh-mode').on('click', function() {
//update annotation list from endpoint
- _this.eventEmitter.publish('updateAnnotationList.'+_this.windowId);
- // _this.eventEmitter.publish('refreshOverlay.'+_this.windowId, '');
+ _this.eventEmitter.publish('updateAnnotationList.' + _this.windowId);
});
//Annotation specific controls
diff --git a/js/src/widgets/sidePanel.js b/js/src/widgets/sidePanel.js
index ae5eff71a7..27619b43d9 100644
--- a/js/src/widgets/sidePanel.js
+++ b/js/src/widgets/sidePanel.js
@@ -187,18 +187,11 @@
render: function(renderingData) {
var _this = this;
-
if (!this.element) {
this.element = this.appendTo;
jQuery(_this.template(renderingData)).appendTo(_this.appendTo);
return;
}
-
- if (renderingData.open) {
- this.appendTo.removeClass('minimized');
- } else {
- this.appendTo.addClass('minimized');
- }
},
template: Handlebars.compile([
diff --git a/js/src/workspace.js b/js/src/workspace.js
index 4ba7c55239..86c17886a8 100644
--- a/js/src/workspace.js
+++ b/js/src/workspace.js
@@ -364,6 +364,7 @@
//delete targetSlot;
_this.layoutDescription = root;
_this.calculateLayout();
+ _this.eventEmitter.publish('slotRemoved',targetSlot);
},
newNode: function(type, parent) {
diff --git a/js/src/workspaces/slot.js b/js/src/workspaces/slot.js
index 1292fa5715..fc54581de5 100644
--- a/js/src/workspaces/slot.js
+++ b/js/src/workspaces/slot.js
@@ -20,6 +20,7 @@
$.Slot.prototype = {
init: function () {
+ this.events = [];
this.element = jQuery(this.template({
workspaceSlotCls: this.workspaceSlotCls,
slotID: this.slotId
@@ -30,78 +31,76 @@
this.listenForActions();
},
- listenForActions: function() {
+ listenForActions: function () {
var _this = this;
- _this.eventEmitter.subscribe('windowRemoved', function(event, id) {
- if (_this.window && _this.window.id === id) {
- // This prevents the save controller
- // from attempting to re-save the window
- // after having already removed it.
- _this.clearSlot();
- }
- });
-
- _this.eventEmitter.subscribe('layoutChanged', function(event, layoutRoot) {
- // Must reset the slotAddress of the window.
- if (_this.window) {
- _this.window.slotAddress = _this.layoutAddress;
- _this.eventEmitter.publish('windowSlotAddressUpdated', {
- id: _this.window.id,
- slotAddress: _this.window.slotAddress
- });
- }
- });
+ this.events = [
+ _this.eventEmitter.subscribe('slotRemoved', function (event, slot) {
+ if (_this.slotID === slot.slotID) {
+ _this.clearSlot();
+ }
+ }),
+
+ _this.eventEmitter.subscribe('layoutChanged', function (event, layoutRoot) {
+ // Must reset the slotAddress of the window.
+ if (_this.window) {
+ _this.window.slotAddress = _this.layoutAddress;
+ _this.eventEmitter.publish('windowSlotAddressUpdated', {
+ id: _this.window.id,
+ slotAddress: _this.window.slotAddress
+ });
+ }
+ }),
- _this.eventEmitter.subscribe('HIDE_REMOVE_SLOT', function(event) {
- _this.element.find('.remove-slot-option').hide();
- if (_this.window) {
- _this.eventEmitter.publish('HIDE_REMOVE_OBJECT.' + _this.window.id);
- }
- });
+ _this.eventEmitter.subscribe('HIDE_REMOVE_SLOT', function (event) {
+ _this.element.find('.remove-slot-option').hide();
+ if (_this.window) {
+ _this.eventEmitter.publish('HIDE_REMOVE_OBJECT.' + _this.window.id);
+ }
+ }),
- _this.eventEmitter.subscribe('SHOW_REMOVE_SLOT', function(event) {
- _this.element.find('.remove-slot-option').show();
- if (_this.window) {
- _this.eventEmitter.publish('SHOW_REMOVE_OBJECT.' + _this.window.id);
- }
- });
+ _this.eventEmitter.subscribe('SHOW_REMOVE_SLOT', function (event) {
+ _this.element.find('.remove-slot-option').show();
+ if (_this.window) {
+ _this.eventEmitter.publish('SHOW_REMOVE_OBJECT.' + _this.window.id);
+ }
+ }),
- _this.eventEmitter.subscribe('ADD_ITEM_FROM_WINDOW', function(event, id) {
- if (_this.window && _this.window.id === id) {
- _this.addItem();
- }
- });
+ _this.eventEmitter.subscribe('ADD_ITEM_FROM_WINDOW', function (event, id) {
+ if (_this.window && _this.window.id === id) {
+ _this.addItem();
+ }
+ }),
- _this.eventEmitter.subscribe('REMOVE_SLOT_FROM_WINDOW', function(event, id) {
- if (_this.window && _this.window.id === id) {
- _this.eventEmitter.publish('REMOVE_NODE', _this);
- }
- });
+ _this.eventEmitter.subscribe('REMOVE_SLOT_FROM_WINDOW', function (event, id) {
+ if (_this.window && _this.window.id === id) {
+ _this.eventEmitter.publish('REMOVE_NODE', _this);
+ }
+ }),
- _this.eventEmitter.subscribe('SPLIT_RIGHT_FROM_WINDOW', function(event, id) {
- if (_this.window && _this.window.id === id) {
- _this.eventEmitter.publish('SPLIT_RIGHT', _this);
- }
- });
+ _this.eventEmitter.subscribe('SPLIT_RIGHT_FROM_WINDOW', function (event, id) {
+ if (_this.window && _this.window.id === id) {
+ _this.eventEmitter.publish('SPLIT_RIGHT', _this);
+ }
+ }),
- _this.eventEmitter.subscribe('SPLIT_LEFT_FROM_WINDOW', function(event, id) {
- if (_this.window && _this.window.id === id) {
- _this.eventEmitter.publish('SPLIT_LEFT', _this);
- }
- });
+ _this.eventEmitter.subscribe('SPLIT_LEFT_FROM_WINDOW', function (event, id) {
+ if (_this.window && _this.window.id === id) {
+ _this.eventEmitter.publish('SPLIT_LEFT', _this);
+ }
+ }),
- _this.eventEmitter.subscribe('SPLIT_DOWN_FROM_WINDOW', function(event, id) {
- if (_this.window && _this.window.id === id) {
- _this.eventEmitter.publish('SPLIT_DOWN', _this);
- }
- });
+ _this.eventEmitter.subscribe('SPLIT_DOWN_FROM_WINDOW', function (event, id) {
+ if (_this.window && _this.window.id === id) {
+ _this.eventEmitter.publish('SPLIT_DOWN', _this);
+ }
+ }),
- _this.eventEmitter.subscribe('SPLIT_UP_FROM_WINDOW', function(event, id) {
- if (_this.window && _this.window.id === id) {
- _this.eventEmitter.publish('SPLIT_UP', _this);
- }
- });
+ _this.eventEmitter.subscribe('SPLIT_UP_FROM_WINDOW', function (event, id) {
+ if (_this.window && _this.window.id === id) {
+ _this.eventEmitter.publish('SPLIT_UP', _this);
+ }
+ })];
},
bindEvents: function() {
@@ -236,9 +235,21 @@
});
},
- clearSlot: function() {
+ destroyEvents:function(){
+ var _this = this;
+ this.events.forEach(function(event){
+ _this.eventEmitter.unsubscribe(event.name,event.handler);
+ });
+ },
+
+ clearSlot: function () {
+ this.destroyEvents();
+
+ // @TODO This is not a task that slots should fulfil
+ // This prevents the save controller
+ // from attempting to re-save the window
+ // after having already removed it.
if (this.window) {
- this.window.element.remove();
delete this.window;
}
},
diff --git a/js/src/workspaces/window.js b/js/src/workspaces/window.js
index 8a4aba103c..1274ab6708 100644
--- a/js/src/workspaces/window.js
+++ b/js/src/workspaces/window.js
@@ -66,6 +66,8 @@
focusState = _this.viewType,
templateData = {};
+ this.events = [];
+
//make sure annotations list is cleared out when changing objects within window
while(_this.annotationsList.length > 0) {
_this.annotationsList.pop();
@@ -229,6 +231,21 @@
this.bottomPanelVisibility(this.bottomPanelVisible);
}
this.sidePanelVisibility(this.sidePanelVisible, '0s');
+
+ this.events.push(this.eventEmitter.subscribe('windowRemoved',function(event,id){
+ if(_this.id === id){
+ _this.destroy();
+ }
+ }));
+ },
+
+ destroy:function(){
+ var _this = this;
+ this.events.forEach(function(event){
+ _this.eventEmitter.unsubscribe(event.name,event.handler);
+ });
+
+ this.element.remove();
},
update: function(options) {
@@ -266,15 +283,15 @@
}
});
- _this.eventEmitter.subscribe('HIDE_REMOVE_OBJECT.' + _this.id, function(event) {
+ _this.events.push(_this.eventEmitter.subscribe('HIDE_REMOVE_OBJECT.' + _this.id, function(event) {
_this.element.find('.remove-object-option').hide();
- });
+ }));
- _this.eventEmitter.subscribe('SHOW_REMOVE_OBJECT.' + _this.id, function(event) {
+ _this.events.push(this.eventEmitter.subscribe('SHOW_REMOVE_OBJECT.' + _this.id, function(event) {
_this.element.find('.remove-object-option').show();
- });
+ }));
- _this.eventEmitter.subscribe('sidePanelStateUpdated.' + this.id, function(event, state) {
+ _this.events.push(_this.eventEmitter.subscribe('sidePanelStateUpdated.' + this.id, function(event, state) {
if (state.open) {
_this.element.find('.mirador-icon-toc').addClass('selected');
_this.element.find('.view-container').removeClass('maximised');
@@ -282,57 +299,57 @@
_this.element.find('.mirador-icon-toc').removeClass('selected');
_this.element.find('.view-container').addClass('maximised');
}
- });
+ }));
// TODO: temporary logic to minimize side panel if only tab is toc and toc is empty
- _this.eventEmitter.subscribe('sidePanelVisibilityByTab.' + this.id, function(event, visible) {
+ _this.events.push(_this.eventEmitter.subscribe('sidePanelVisibilityByTab.' + this.id, function(event, visible) {
_this.sidePanelVisibility(visible, '0s');
- });
+ }));
- _this.eventEmitter.subscribe('SET_CURRENT_CANVAS_ID.' + this.id, function(event, canvasID) {
+ _this.events.push(_this.eventEmitter.subscribe('SET_CURRENT_CANVAS_ID.' + this.id, function(event, canvasID) {
_this.setCurrentCanvasID(canvasID);
- });
+ }));
- _this.eventEmitter.subscribe('REMOVE_CLASS.' + this.id, function(event, className) {
+ _this.events.push(_this.eventEmitter.subscribe('REMOVE_CLASS.' + this.id, function(event, className) {
_this.element.find('.view-container').removeClass(className);
- });
+ }));
- _this.eventEmitter.subscribe('ADD_CLASS.' + this.id, function(event, className) {
+ _this.events.push(_this.eventEmitter.subscribe('ADD_CLASS.' + this.id, function(event, className) {
_this.element.find('.view-container').addClass(className);
- });
+ }));
- _this.eventEmitter.subscribe('UPDATE_FOCUS_IMAGES.' + this.id, function(event, images) {
+ _this.events.push(_this.eventEmitter.subscribe('UPDATE_FOCUS_IMAGES.' + this.id, function(event, images) {
_this.updateFocusImages(images.array);
- });
+ }));
- _this.eventEmitter.subscribe('HIDE_ICON_TOC.' + this.id, function(event) {
+ _this.events.push(_this.eventEmitter.subscribe('HIDE_ICON_TOC.' + this.id, function(event) {
_this.element.find('.mirador-icon-toc').hide();
- });
+ }));
- _this.eventEmitter.subscribe('SHOW_ICON_TOC.' + this.id, function(event) {
+ _this.events.push(_this.eventEmitter.subscribe('SHOW_ICON_TOC.' + this.id, function(event) {
_this.element.find('.mirador-icon-toc').show();
- });
+ }));
- _this.eventEmitter.subscribe('SET_BOTTOM_PANEL_VISIBILITY.' + this.id, function(event, visibility) {
+ _this.events.push(_this.eventEmitter.subscribe('SET_BOTTOM_PANEL_VISIBILITY.' + this.id, function(event, visibility) {
if (typeof visibility !== 'undefined' && visibility !== null) {
_this.bottomPanelVisibility(visibility);
} else {
_this.bottomPanelVisibility(_this.bottomPanelVisible);
}
- });
+ }));
- _this.eventEmitter.subscribe('TOGGLE_BOTTOM_PANEL_VISIBILITY.' + this.id, function(event) {
+ _this.events.push(_this.eventEmitter.subscribe('TOGGLE_BOTTOM_PANEL_VISIBILITY.' + this.id, function(event) {
var visible = !_this.bottomPanelVisible;
_this.bottomPanelVisibility(visible);
- });
+ }));
- _this.eventEmitter.subscribe('DISABLE_WINDOW_FULLSCREEN', function(event) {
+ _this.events.push(_this.eventEmitter.subscribe('DISABLE_WINDOW_FULLSCREEN', function(event) {
_this.element.find('.mirador-osd-fullscreen').hide();
- });
+ }));
- _this.eventEmitter.subscribe('ENABLE_WINDOW_FULLSCREEN', function(event) {
+ _this.events.push(_this.eventEmitter.subscribe('ENABLE_WINDOW_FULLSCREEN', function(event) {
_this.element.find('.mirador-osd-fullscreen').show();
- });
+ }));
},
bindEvents: function() {
@@ -385,10 +402,10 @@
_this.eventEmitter.subscribe('annotationUpdated.'+_this.id, function(event, oaAnno) {
//first function is success callback, second is error callback
- _this.endpoint.update(oaAnno, function() {
+ _this.endpoint.update(oaAnno, function(data) {
jQuery.each(_this.annotationsList, function(index, value) {
- if (value['@id'] === oaAnno['@id']) {
- _this.annotationsList[index] = oaAnno;
+ if (value['@id'] === data['@id']) {
+ _this.annotationsList[index] = data;
return false;
}
});
@@ -806,7 +823,7 @@
_this.endpoint.set('dfd', dfd);
} else {
options.dfd = dfd;
- options.windowID = _this.id;
+ options.windowIDwindowID = _this.id;
options.imagesList = _this.imagesList;
options.eventEmitter = _this.eventEmitter;
_this.endpoint = new $[module](options);
diff --git a/locales/fr/translation.json b/locales/fr/translation.json
index a87aa43a25..4fab836ebb 100644
--- a/locales/fr/translation.json
+++ b/locales/fr/translation.json
@@ -1,8 +1,8 @@
{
"addItem": "Ajouter un objet",
"addNewObject": "Ajouter un objet à partir de son URL",
- "addSlotAbove": "Ajouter une fenêtre en dessous",
- "addSlotBelow": "Ajouter une fenêtre au-dessus",
+ "addSlotAbove": "Ajouter une fenêtre au-dessus",
+ "addSlotBelow": "Ajouter une fenêtre en dessous",
"addSlotLeft": "Ajouter une fenêtre à gauche",
"addSlotRight": "Ajouter une fenêtre à droite",
"addTagsHere": "Ajouter des mots-clés",
diff --git a/spec/annotations/event-emitter.stub.js b/spec/event-emitter.stub.js
similarity index 100%
rename from spec/annotations/event-emitter.stub.js
rename to spec/event-emitter.stub.js
diff --git a/spec/utils/jsonLd.test.js b/spec/utils/jsonLd.test.js
index 90aee401ff..bd4348c5a8 100644
--- a/spec/utils/jsonLd.test.js
+++ b/spec/utils/jsonLd.test.js
@@ -41,5 +41,51 @@ describe('JsonLd', function () {
expect(Mirador.JsonLd.getTextValue(sample, 'en')).toEqual("Super waahoo");
expect(Mirador.JsonLd.getTextValue(sample)).toEqual("Super waahoo");
});
+
+ it('should return all values when no value has a langue associated', function() {
+ var sample = ['First value',
+ 'Second value'];
+ expect(Mirador.JsonLd.getTextValue(sample)).toEqual('First value
Second value');
+ });
+
+ it('should return all values that best match the language preference', function() {
+ var sample = [
+ 'This is a value without a language.',
+ {'@value': "This is an American value.",
+ '@language': "en-US"},
+ {'@value': "This ia a British value.",
+ '@language': "en-UK"},
+ 'This is another value without a language.',
+ {'@value': "C'est une valeur française.",
+ '@language': "fr"}];
+ window.navigator.languages = ['en-US', 'en']
+ expect(Mirador.JsonLd.getTextValue(sample)).toEqual("This is an American value.");
+ });
+
+ it('should pick a language if all values have a language but none match the preference', function() {
+ var sample = [
+ {'@value': "This is an American value.",
+ '@language': "en-US"},
+ {'@value': "This is another American value.",
+ '@language': "en-US"},
+ {'@value': "C'est une valeur française.",
+ '@language': "fr"}];
+ window.navigator.languages = ['de-DE', 'de'];
+ expect(Mirador.JsonLd.getTextValue(sample))
+ .toEqual('This is an American value.
' +
+ 'This is another American value.');
+ });
+
+ it('should return all values without an associated language if some have one, but none match the preference', function() {
+ var sample = [
+ {'@value': "C'est une valeur française.",
+ '@language': "fr"},
+ 'This is a value without a language.',
+ 'This is another value without a language.'];
+ window.navigator.languages = ['en-US', 'en'];
+ expect(Mirador.JsonLd.getTextValue(sample))
+ .toEqual('This is a value without a language.
' +
+ 'This is another value without a language.');
+ })
});
});
diff --git a/spec/widgets/sidePanel.test.js b/spec/widgets/sidePanel.test.js
index 1f463c82f8..0dbaa19f06 100644
--- a/spec/widgets/sidePanel.test.js
+++ b/spec/widgets/sidePanel.test.js
@@ -1,16 +1,46 @@
describe('SidePanel', function() {
+
+ function createSidePanel(sidePanelOptions) {
+ sidePanelOptions = sidePanelOptions || {};
+
+ var eventEmitter = new Mirador.EventEmitter();
+ var state = new Mirador.SaveController(jQuery.extend(
+ true, {}, Mirador.DEFAULT_SETTINGS, {eventEmitter: eventEmitter}
+ ));
+ var fixture = getJSONFixture('BNF-condorcet-florus-dispersus-manifest.json');
+ var manifest = new Mirador.Manifest(fixture['@id'], 'IIIF', fixture);
+ var canvasID = manifest.getCanvases()[0]['@id'];
+ var appendTo = jQuery('