Skip to content

Commit

Permalink
Merge pull request #6 from NCSU-Libraries/enhancement/api3.0
Browse files Browse the repository at this point in the history
Enhancement/api3.0
  • Loading branch information
dnoneill authored Jun 26, 2020
2 parents 163c631 + 83d50f6 commit 50b1b20
Show file tree
Hide file tree
Showing 21 changed files with 171 additions and 95 deletions.
2 changes: 1 addition & 1 deletion dist/css/annona.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/js/annona.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/js/annona.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/3-rangestoryboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ See [toolbar icon](/{{site.baseurl}}/storyboard/#toolbar-icons) table for other
```
<iiif-rangestoryboard rangeurl="https://iiif.bodleian.ox.ac.uk/iiif/manifest/748a9d50-5a3a-440e-ab9d-567dd68b6abb.json" styling="overlaynext: true"></iiif-rangestoryboard>
```
**Page 4 has a really cool annotation**
**fols. 2b and 3a & fols. 32b and 33a are particularly cool**

<iiif-rangestoryboard rangeurl="https://iiif.bodleian.ox.ac.uk/iiif/manifest/748a9d50-5a3a-440e-ab9d-567dd68b6abb.json" styling="overlaynext: true"></iiif-rangestoryboard>

Expand Down
2 changes: 1 addition & 1 deletion docs/dist/annona.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/dist/annona.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/dist/annona.js.map

Large diffs are not rendered by default.

Binary file modified docs/dist2.zip
Binary file not shown.
2 changes: 1 addition & 1 deletion docs/latest/annona.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/latest/annona.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/latest/annona.js.map

Large diffs are not rendered by default.

Binary file modified docs/latest/dist2.zip
Binary file not shown.
26 changes: 7 additions & 19 deletions src/components/iiifannotation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,6 @@ export default {
this.annoloop(false)
}
},
//get full image URL
getImages: function(baseImageUrl, canvasRegion, size, jpgformat='default.jpg'){
baseImageUrl = baseImageUrl.indexOf('upload.wikimedia.org') > -1 ? `https://tools.wmflabs.org/zoomviewer/proxy.php?iiif=${baseImageUrl.split('/').slice(-1)[0]}` : baseImageUrl;
var extension = shared.getExtension(baseImageUrl);
var imageurl = shared.imageextensions.includes(extension) ? baseImageUrl : `${baseImageUrl}/${canvasRegion}/${size}/0/${jpgformat}`;
var fullImage = shared.imageextensions.includes(extension) ? baseImageUrl : canvasRegion !== "full" ? `${baseImageUrl}/full/${size}/0/${jpgformat}` : '';
return {'fullImage':fullImage, 'imageurl': imageurl};
},
//get manifest data from URL
getManifestData: function(){
axios.get(this.manifestlink).then(response => {
Expand Down Expand Up @@ -123,7 +115,7 @@ export default {
for (var cn = 0; cn < canvasId.length; cn++){
var canvasItem = canvasId[cn];
var canvasRegion = shared.canvasRegion(canvasItem, undefined);
var imagedict = this.getImages(canvasRegion['canvasId'], canvasRegion['canvasRegion'], size);
var imagedict = shared.getImages(canvasRegion['canvasId'], canvasRegion['canvasRegion'], size);
var imageurl = imagedict['imageurl'];
dictionary['fullImage'] = imagedict['fullImage']
var imagehtml = this.createimagehtml(imageurl, canvasRegion, dictionary, cn);
Expand Down Expand Up @@ -202,25 +194,21 @@ export default {
var ondict = shared.on_structure(anno);
ondict = ondict ? ondict[cn] : ondict;
var canvasRegion = shared.canvasRegion(canvasItem, ondict);
for(var idx = 0; idx < this.manifest.sequences[0].canvases.length; idx++){
var existing = this.manifest.sequences[0].canvases[idx];
var cleanexisting = existing['@id'].replace("https", "http").replace('/info.json', '')
if(cleanexisting === canvasRegion['canvasId'].replace("https", "http")){
var canvas = existing;
}
}
var canvas = shared.matchCanvas(this.manifest, canvasRegion['canvasId'])['images'];
var regionCanvas = canvasRegion['canvasRegion'];
var baseImageUrl;
if (canvas === undefined) {
baseImageUrl = canvasItem.split("#")[0];
} else {
baseImageUrl = canvas.images[0].resource.service ? canvas.images[0].resource.service['@id'] : canvas.images[0].resource['@id'];
var canvas_tile = shared.getCanvasTile(canvas[0])
baseImageUrl = canvas_tile['canvas_tile'];
var imgResource = canvas_tile['img_resource'];
}
//get jpg format
var resourceid = canvas.images[0].resource['@id'] && canvas.images[0].resource['@id'].includes('/full') ? canvas.images[0].resource['@id'] : '';
var resourceid = imgResource['@id'] && shared.getId(imgResource).includes('/full') ? shared.getId(imgResource) : '';
var jpgformat = resourceid ? resourceid.split("/").slice(-1)[0] : 'default.jpg';
size = size != 'full' ? size : resourceid ? resourceid.split("/").slice(-3)[0] : 'full';
var imagedict = this.getImages(baseImageUrl, regionCanvas, size, jpgformat);
var imagedict = shared.getImages(baseImageUrl, regionCanvas, size, jpgformat);
fullImage = imagedict['fullImage'];
//construct image URL
var imageurl = imagedict['imageurl'];
Expand Down
51 changes: 29 additions & 22 deletions src/components/rangestoryboard.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div v-bind:id="rangeid" class="rangestoryboard" v-bind:class="[!settings.fullpage && !isfullscreen ? 'rangestoryboardview' : 'rangefullpage']">
<storyboard :key="position" v-if="annotationurl" v-bind:jsonannotation="annotationurl.jsonanno" v-bind:annotationlist="annotationurl.anno" v-bind:manifesturl="annotationurl.manifest" v-bind:styling="stylingstring" v-bind:ws="isws" v-bind:layers="customlayers"></storyboard>
<storyboard v-bind:key="position" v-if="ready" v-bind:jsonannotation="annotationurl.jsonanno" v-bind:annotationlist="annotationurl.anno" v-bind:manifesturl="annotationurl.manifest" v-bind:styling="stylingstring" v-bind:ws="isws" v-bind:layers="customlayers"></storyboard>
<button id="previousPageInactiveButton" v-hotkey="prevshortcut" v-on:click="nextItemRange('prev')" class="pageButton toolbarButton" v-bind:class="[{ 'pageinactive' : prevPageInactive}, viewingDirection == 'rtl' ? 'floatleft' : 'floatright' ]">
<span v-html="buttons.prev"></span>
<span class="toolbartext">Previous page</span>
Expand Down Expand Up @@ -63,7 +63,8 @@ export default {
viewingDirection: 'ltr',
rangetitle: '',
nextshortcut: ['alt+n', 'alt+.', 'alt+right'],
prevshortcut: ['alt+p', 'alt+,', 'alt+left']
prevshortcut: ['alt+p', 'alt+,', 'alt+left'],
ready: false
}
},
created(){
Expand All @@ -90,39 +91,49 @@ export default {
},
getManifestData: function(manifest) {
var otherContent = [];
if (manifest['sequences']){
var canvases = shared.flatten(manifest['sequences'].map(element => element['canvases']));
if (manifest['sequences'] || manifest['items']){
var canvases = manifest['items'] ? shared.flatten(manifest['items']) : shared.flatten(manifest['sequences'].map(element => element['canvases']));
for (var cv=0; cv<canvases.length; cv++){
var canvas = canvases[cv];
var canvasid = shared.getId(canvas);
if (canvas['otherContent']){
otherContent.push(canvas['otherContent']);
var annotationfield = canvas['otherContent'] ? canvas['otherContent'] : canvas['annotations'];
if (annotationfield){
otherContent.push({'oc': annotationfield, 'canvas': canvas});
}
}
} else {
otherContent = shared.flatten(manifest['items'].map(element => element['annotations']));
}
for (var an=0; an<otherContent.length; an++){
var anno = otherContent[an];
var anno = otherContent[an]['oc'];
if (anno.constructor.name == 'Array') {
for (var h=0; h<anno.length; h++){
this.addToLists(anno[h], an+h, this.$props.rangeurl, canvasid);
this.addToLists(anno[h], an+h, this.$props.rangeurl, otherContent[an]['canvas']);
}
} else{
this.addToLists(anno, an, this.$props.rangeurl, canvasid);
this.addToLists(anno, an, this.$props.rangeurl, otherContent[an]['canvas']);
}
}
this.setDefaults(manifest);
},
addToLists: function(anno, an, manifesturl, canvasid, xywh) {
addToLists: function(anno, an, manifesturl, canvas) {
if(anno.resources || anno.items){
var jsonanno = anno;
} else {
var annourl = shared.getId(anno);
}
var toclabel = anno['label'] ? anno['label'] : `Page ${an + 1}`;
if (canvas){
var canvasid = shared.getId(canvas);
if (canvasid.constructor.name === 'String' && canvasid.indexOf('#xywh') > -1){
var xywh = canvasid.split("#xywh=").length > 1 ? canvasid.split("#xywh=").slice(-1)[0] : '';
}
var firstcanvas = canvas.images ? canvas.images[0] : canvas.items ? canvas.items[0].items[0] : undefined;
if (firstcanvas){
var thumbnail = shared.getImages(shared.getCanvasTile(firstcanvas)['canvas_tile'], 'full', '30,')['imageurl'];
}
}
var toclabel = anno['label'] ? anno['label'] : canvas && canvas['label'] ? canvas['label'] : `Page ${an + 1}`;
toclabel = shared.parseMetaFields(toclabel);
var description = anno['description'] ? anno['description'] : '';
this.toc.push({ 'position' :an, 'label' : toclabel, 'description': description});
this.toc.push({ 'position' :an, 'label' : toclabel, 'thumbnail': thumbnail, 'description': description});
this.rangelist.push({'canvas': canvasid, 'anno': annourl, 'jsonanno': jsonanno, 'manifest': manifesturl, 'section': xywh, 'title': toclabel});
},
setDefaults: function(data) {
Expand All @@ -140,22 +151,18 @@ export default {
this.$props.layers ? this.customlayers = this.$props.layers : '';
this.annotationurl.section ? this.settings.imagecrop = this.annotationurl.section : '';
this.getStylingString();
this.rangelist.length == 1 ? this.nextPageInactive = true : ''
this.rangelist.length == 1 ? this.nextPageInactive = true : '';
this.ready = true;
},
getRangeData: function(rangelist) {
var annos = rangelist.contentLayer.otherContent;
var canvases = rangelist.canvases ? rangelist.canvases : [];
for (var ca=0; ca<annos.length; ca++){
var canvas = canvases[ca];
var anno = annos[ca];
var xywh = '';
var manifest = canvas ? canvas['within'] : '';
manifest = shared.getId(manifest);
if (canvas){
var canvasid = shared.getId(canvas);
xywh = canvasid.constructor.name === 'String' && canvasid.split("#xywh=").length > 1 ? canvasid.split("#xywh=").slice(-1)[0] : '';
}
this.addToLists(anno, ca, manifest, canvasid, xywh);
this.addToLists(anno, ca, manifest, canvas);
}
this.setDefaults(rangelist);
},
Expand Down
42 changes: 39 additions & 3 deletions src/components/shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,9 @@ export default {
selectors = selectors.length > 0 ? selectors : canvasId.selector.filter(element => element.value.indexOf('xywh') > -1);
canvasSelector = selectors[0];
}
var parser = this.selectorParser(canvasSelector);
canvasRegion = parser['bounds'];
svg = parser['svg'];
var ciparser = this.selectorParser(canvasSelector);
canvasRegion = ciparser['bounds'];
svg = ciparser['svg'];
}
if (canvasId['source']){
canvasId = canvasId.source;
Expand Down Expand Up @@ -335,6 +335,42 @@ export default {
return array.reduce((acc, val) => acc.concat(val), []).filter(Boolean);
}
},
getCanvasTile: function(image) {
var imgResource = image.resource ? image.resource : image.body;
var canvas_tile = imgResource.service && imgResource.service.constructor.name == 'Array' ? this.getId(imgResource.service[0]).split("/full/")[0] : imgResource.service ? this.getId(imgResource.service).split("/full/")[0] :this.getId(imgResource);
canvas_tile = canvas_tile.indexOf('upload.wikimedia.org') > -1 ? 'https://tools.wmflabs.org/zoomviewer/proxy.php?iiif=' + canvas_tile.split("/").slice(-1)[0] : canvas_tile;
canvas_tile += canvas_tile.slice(-1) !== '/' ? "/" : '';
return {'canvas_tile': canvas_tile, 'img_resource': imgResource};
},
matchCanvas: function(manifest, canvas, imagetitle) {
var canvases = manifest.sequences ? manifest.sequences[0].canvases : manifest.items;
var title = imagetitle;
var images = '';
for (var i = 0; i< canvases.length; i++){
var cleancanvas = canvas.split('/canvas').slice(-1)[0];
var canvregex = new RegExp(`${cleancanvas}$`,"g");
var cleanexisting = this.getId(canvases[i]).replace("https", "http").replace('/info.json', '');
if (cleanexisting === canvas.replace("https", "http") || canvregex.test(cleanexisting)) {
images = canvases[i].images ? canvases[i].images : this.flatten(canvases[i].items.map(element => element['items']));
if (!imagetitle){
title = canvases[i].label;
title = this.getValueField(title);
title = title && title !== imagetitle && canvases.length !== 1 ? imagetitle += ': ' + title : imagetitle;
}
return {'images': images, 'title': title}
}
}
return {'images': images, 'title': title}
},
//get full image URL
getImages: function(baseImageUrl, canvasRegion, size, jpgformat='default.jpg'){
var regExp = new RegExp("/+$");
baseImageUrl = baseImageUrl.replace(regExp, "")
var extension = this.getExtension(baseImageUrl);
var imageurl = this.imageextensions.includes(extension) ? baseImageUrl : `${baseImageUrl}/${canvasRegion}/${size}/0/${jpgformat}`;
var fullImage = this.imageextensions.includes(extension) ? baseImageUrl : canvasRegion !== "full" ? `${baseImageUrl}/full/${size}/0/${jpgformat}` : '';
return {'fullImage':fullImage, 'imageurl': imageurl};
},
keyboardShortcuts: function(type, vueinfo){
var buttons = vueinfo.buttons;
var shortcuts = {
Expand Down
33 changes: 13 additions & 20 deletions src/components/storyboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,12 @@
<button class="infolink buttonlink" v-on:click="sendMessage({'function':'switchShown', 'args': 'tocshown'});" v-if="$parent.range && $parent.toc.length > 1">{{$parent.toctitle}}</button>
<div v-if="booleanitems.tocshown" class="tocinfo">
<div v-for="toc in $parent.toc" v-bind:key="toc.position" v-bind:id="'data_' + toc.position">
<div class="title"><button class="buttonlink" v-on:click="$parent.nextItemRange(toc.position);">{{toc.label}}</button></div>

<div class="title">
<button class="buttonlink" v-on:click="$parent.nextItemRange(toc.position);">
<img v-bind:src="toc.thumbnail" v-if="toc.thumbnail">{{toc.label}}
</button>
</div>
<div class="additionaltext" v-html="toc.description" v-if="toc.description"></div>
</div>
</div>
Expand Down Expand Up @@ -256,7 +261,7 @@ export default {
},
methods: {
parseAnnoData: function(annotation, annotationurl, isURL){
this.imagetitle = annotation.label ? annotation.label : this.imagetitle;
this.imagetitle = this.settings.title ? this.imagetitle : annotation.label;
var anno = shared.getAnnotations(annotation);
//Get basic annotation information
this.annoinfo.text += `<div class="listinfo">${isURL ? `<b>Annotation Url: </b><a href="${annotationurl}" target="_blank">${annotationurl}</a><br>` : ``}
Expand Down Expand Up @@ -650,20 +655,9 @@ export default {
getManifestData: function(manifestlink, canvas, canvasId){
axios.get(manifestlink).then(canvas_data => {
this.getImageInfo(canvas_data, manifestlink)
var canvases = canvas_data.data.sequences ? canvas_data.data.sequences[0].canvases : canvas_data.data.items;
for (var i = 0; i< canvases.length; i++){
var cleancanvas = canvas.split('/canvas').slice(-1)[0];
var canvregex = new RegExp(`${cleancanvas}$`,"g");
var cleanexisting = shared.getId(canvases[i]).replace("https", "http").replace('/info.json', '');
if (cleanexisting === canvas.replace("https", "http") || canvregex.test(cleanexisting)) {
var images = canvases[i].images ? canvases[i].images : shared.flatten(canvases[i].items.map(element => element['items']));
if (!this.settings.title){
var title = canvases[i].label;
title = shared.getValueField(title);
this.imagetitle = title && title !== this.imagetitle && canvases.length !== 1 ? this.imagetitle += ': ' + title : this.imagetitle;
}
}
}
var get_canvas = shared.matchCanvas(canvas_data.data, canvas, this.imagetitle);
this.imagetitle = get_canvas['title'];
var images = get_canvas['images'];
this.getLayerData(images);
this.buildseadragon(canvasId);
});
Expand Down Expand Up @@ -700,10 +694,9 @@ export default {
getLayerData: function(images) {
images = images ? images : [];
for (var i=0; i<images.length; i++){
var imgResource = images[i].resource ? images[i].resource : images[i].body;
var canvas_tile = imgResource.service && imgResource.service.constructor.name == 'Array' ?shared.getId(imgResource.service[0]).split("/full/")[0] : imgResource.service ? shared.getId(imgResource.service).split("/full/")[0] :shared.getId(imgResource);
canvas_tile = canvas_tile.indexOf('upload.wikimedia.org') > -1 ? 'https://tools.wmflabs.org/zoomviewer/proxy.php?iiif=' + canvas_tile.split("/").slice(-1)[0] : canvas_tile;
canvas_tile += canvas_tile.slice(-1) !== '/' ? "/" : '';
var get_ct = shared.getCanvasTile(images[i]);
var canvas_tile = get_ct['canvas_tile'];
var imgResource = get_ct['img_resource'];
var xywh = images[i].on ? images[i].on.split("xywh=").slice(-1)[0].split(",") : '';
var label = imgResource.label ? imgResource.label : `Layer ${i + 1}`;
canvas_tile += 'info.json';
Expand Down
6 changes: 6 additions & 0 deletions src/iiif-annotation.scss
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,12 @@ figcaption {
padding: 0px;
cursor: pointer;
font: inherit;
display: flex;
align-items:center;
}

.buttonlink img{
padding-right: 10px;
}

.infolink {
Expand Down
4 changes: 4 additions & 0 deletions test/__mocks__/axios.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions test/iiifannotation.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,18 @@ describe('Component', () => {
expect(wrapper.html()).toContain('"bees2.json" did not render. Please ensure your annotation link is correct.')
})

test('test with regular image', async () => {
const wrapper = mount(iiifAnnotation,{
propsData: {
annotationlist: 'regular.json'
}
})
await wrapper.vm.$nextTick()
await flushPromises()
const annotations = wrapper.vm.$data.annotation_items[0]
expect(annotations.image).toEqual(["<div id=\"regular0_canvas_img0\"></div>"])
expect(Object.keys(annotations).length).toBe(9)
expect(annotations.fullImage).toEqual("/annotate/assets/images/custom/spencer-davis-7ZpvOE2psxM-unsplash.jpg")
})

})
Loading

0 comments on commit 50b1b20

Please sign in to comment.