Skip to content

Commit

Permalink
Adds level0 support for IIIF manifests fixes #2616
Browse files Browse the repository at this point in the history
  • Loading branch information
mejackreed committed Apr 16, 2020
1 parent 722d811 commit 70030ed
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 7 deletions.
34 changes: 34 additions & 0 deletions __tests__/fixtures/version-2/minimumRequired.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"@context": "http://iiif.io/api/presentation/2/context.json",
"@id": "http://iiif.io/api/presentation/2.0/example/fixtures/1/manifest.json",
"@type": "sc:Manifest",
"label": "Test 1 Manifest: Minimum Required Fields",
"within": "http://iiif.io/api/presentation/2.0/example/fixtures/collection.json",
"sequences": [
{
"@type": "sc:Sequence",
"canvases": [
{
"@id": "http://iiif.io/api/presentation/2.0/example/fixtures/canvas/1/c1.json",
"@type": "sc:Canvas",
"label": "Test 1 Canvas: 1",
"height": 1800,
"width": 1200,
"images": [
{
"@type": "oa:Annotation",
"motivation": "sc:painting",
"resource": {
"@id": "http://iiif.io/api/presentation/2.0/example/fixtures/resources/page1-full.png",
"@type": "dctypes:Image",
"height": 1800,
"width": 1200
},
"on": "http://iiif.io/api/presentation/2.0/example/fixtures/canvas/1/c1.json"
}
]
}
]
}
]
}
14 changes: 12 additions & 2 deletions __tests__/src/components/OpenSeadragonViewer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,17 +118,27 @@ describe('OpenSeadragonViewer', () => {
});
});

describe('addAllTileSources', () => {
describe('addAllImageSources', () => {
it('calls addTileSource for every tileSources and then zoomsToWorld', () => {
wrapper.instance().viewer = {
close: () => {},
};
wrapper.setProps({ tileSources: [1, 2, 3, 4] });
const mockAddTileSource = jest.fn();
wrapper.instance().addTileSource = mockAddTileSource;
wrapper.instance().addAllTileSources();
wrapper.instance().addAllImageSources();
expect(mockAddTileSource).toHaveBeenCalledTimes(4);
});
it('calls addNonTileSource for every nonTiledImage and then zoomsToWorld', () => {
wrapper.instance().viewer = {
close: () => {},
};
wrapper.setProps({ nonTiledImages: [1, 2, 3, 4] });
const mockAddNonTiledImage = jest.fn();
wrapper.instance().addNonTiledImage = mockAddNonTiledImage;
wrapper.instance().addAllImageSources();
expect(mockAddNonTiledImage).toHaveBeenCalledTimes(4);
});
});

describe('addTileSource', () => {
Expand Down
25 changes: 25 additions & 0 deletions __tests__/src/selectors/canvases.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import manifestFixture001 from '../../fixtures/version-2/001.json';
import manifestFixture019 from '../../fixtures/version-2/019.json';
import minimumRequired from '../../fixtures/version-2/minimumRequired.json';

import {
getVisibleCanvases,
getNextCanvasGrouping,
Expand All @@ -9,6 +11,7 @@ import {
selectCanvasAuthService,
selectNextAuthService,
selectInfoResponse,
getVisibleCanvasNonTiledResources,
} from '../../../src/state/selectors/canvases';

describe('getVisibleCanvases', () => {
Expand Down Expand Up @@ -391,3 +394,25 @@ describe('selectInfoResponse', () => {
expect(selectInfoResponse(state, { canvasId: 'some-canvas-without-services', manifestId: 'a' })).toBe(undefined);
});
});

describe('getVisibleCanvasNonTiledResources', () => {
it('returns canvases resources without services', () => {
const state = {
manifests: {
'http://iiif.io/api/presentation/2.0/example/fixtures/1/manifest.json': {
id: 'http://iiif.io/api/presentation/2.0/example/fixtures/1/manifest.json',
json: minimumRequired,
},
},
windows: {
a: {
canvasId: 'http://iiif.io/api/presentation/2.0/example/fixtures/canvas/1/c1.json',
manifestId: 'http://iiif.io/api/presentation/2.0/example/fixtures/1/manifest.json',
},
},
};
expect(getVisibleCanvasNonTiledResources(
state, { windowId: 'a' },
)[0].id).toBe('http://iiif.io/api/presentation/2.0/example/fixtures/resources/page1-full.png');
});
});
31 changes: 26 additions & 5 deletions src/components/OpenSeadragonViewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export class OpenSeadragonViewer extends Component {
this.viewer.viewport.panTo(viewer, true);
this.viewer.viewport.zoomTo(viewer.zoom, viewer, true);
}
this.addAllTileSources();
this.addAllImageSources();
}

/**
Expand Down Expand Up @@ -125,7 +125,7 @@ export class OpenSeadragonViewer extends Component {

if (!this.tileSourcesMatch(prevProps.tileSources)) {
this.viewer.close();
this.addAllTileSources();
this.addAllImageSources();
} else if (viewer && !this.osdUpdating) {
const { viewport } = this.viewer;

Expand Down Expand Up @@ -197,17 +197,36 @@ export class OpenSeadragonViewer extends Component {
}

/** */
addAllTileSources() {
const { tileSources } = this.props;
addAllImageSources() {
const { nonTiledImages, tileSources } = this.props;
Promise.all(
tileSources.map((tileSource, i) => this.addTileSource(tileSource, i)),
nonTiledImages.map((image, i) => this.addNonTiledImage(image, i)),
).then(() => {
if (tileSources[0]) {
if (tileSources[0] || nonTiledImages[0]) {
this.zoomToWorld();
}
});
}

/** */
addNonTiledImage(image, i = 0) {
const { canvasWorld } = this.props;
return new Promise((resolve, reject) => {
if (!this.viewer) {
return;
}
this.viewer.addSimpleImage({
error: event => reject(event),
fitBounds: new OpenSeadragon.Rect(
...canvasWorld.canvasToWorldCoordinates(i),
),
success: event => resolve(event),
url: image.id,
});
});
}

/**
*/
addTileSource(tileSource, i = 0) {
Expand Down Expand Up @@ -321,6 +340,7 @@ OpenSeadragonViewer.defaultProps = {
children: null,
highlightedAnnotations: [],
label: null,
nonTiledImages: [],
osdConfig: {},
palette: {},
searchAnnotations: [],
Expand All @@ -336,6 +356,7 @@ OpenSeadragonViewer.propTypes = {
classes: PropTypes.objectOf(PropTypes.string).isRequired,
highlightedAnnotations: PropTypes.arrayOf(PropTypes.object),
label: PropTypes.string,
nonTiledImages: PropTypes.array, // eslint-disable-line react/forbid-prop-types
osdConfig: PropTypes.object, // eslint-disable-line react/forbid-prop-types
palette: PropTypes.object, // eslint-disable-line react/forbid-prop-types
searchAnnotations: PropTypes.arrayOf(PropTypes.object),
Expand Down
2 changes: 2 additions & 0 deletions src/containers/OpenSeadragonViewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { OpenSeadragonViewer } from '../components/OpenSeadragonViewer';
import * as actions from '../state/actions';
import CanvasWorld from '../lib/CanvasWorld';
import {
getVisibleCanvasNonTiledResources,
getCurrentCanvas,
getSelectedAnnotationsOnCanvases,
getHighlightedAnnotationsOnCanvases,
Expand Down Expand Up @@ -34,6 +35,7 @@ const mapStateToProps = (state, { companionWindowId, windowId }) => ({
canvasId: (getCurrentCanvas(state, { windowId }) || {}).id,
windowId,
}),
nonTiledImages: getVisibleCanvasNonTiledResources(state, { windowId }),
osdConfig: state.config.osdConfig,
palette: getTheme(state).palette,
searchAnnotations: getSearchAnnotationsForWindow(
Expand Down
11 changes: 11 additions & 0 deletions src/state/selectors/canvases.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createSelector } from 'reselect';
import { Utils } from 'manifesto.js/dist-esmodule/Utils';
import flatten from 'lodash/flatten';
import CanvasGroupings from '../../lib/CanvasGroupings';
import { getManifestoInstance } from './manifests';
import { getWindow, getWindowViewType } from './windows';
Expand Down Expand Up @@ -170,6 +171,16 @@ export const getCanvasDescription = createSelector(
/** */
export const selectInfoResponses = state => state.infoResponses;

export const getVisibleCanvasNonTiledResources = createSelector(
[
getVisibleCanvases,
],
canvases => canvases && flatten(canvases
.map(canvas => canvas.getImages()
.map(image => image.getResource())))
.filter(resource => resource.getServices().length < 1),
);

export const selectInfoResponse = createSelector(
[
getCanvas,
Expand Down

0 comments on commit 70030ed

Please sign in to comment.