Skip to content

Commit

Permalink
Merge pull request #743 from samvera-labs/thumbnail-nav
Browse files Browse the repository at this point in the history
Avoid parsing structure ranges with 'behavior=thumbnail-nav'
  • Loading branch information
Dananji authored Dec 6, 2024
2 parents e903c49 + c3f885e commit f183189
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 3 deletions.
26 changes: 26 additions & 0 deletions src/components/StructuredNavigation/StructuredNavigation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import manifestWoCanvasRefs from '@TestData/transcript-annotation';
import manifest from '@TestData/lunchroom-manners';
import singleCanvasManifest from '@TestData/single-canvas';
import invalidStructure from '@TestData/invalid-structure';
import thumbnailNavStructure from '@TestData/transcript-multiple-canvas';
import playlist from '@TestData/playlist';
import nonCollapsibleStructure from '@TestData/multiple-canvas-auto-advance';
import {
Expand Down Expand Up @@ -217,6 +218,31 @@ describe('StructuredNavigation component', () => {
});
});

describe('with structures with behavior=thumbnail-nav in the root Range', () => {
beforeEach(() => {
const NavWithPlayer = withPlayerProvider(StructuredNavigation, {
initialState: {},
});
const NavWithManifest = withManifestProvider(NavWithPlayer, {
initialState: { ...manifestState(thumbnailNavStructure) },
});
render(
<ErrorBoundary>
<NavWithManifest />
</ErrorBoundary>
);
});

test('renders component', () => {
expect(screen.queryByTestId('structured-nav')).toBeInTheDocument();
});

test('does not render any structure elements', () => {
expect(screen.queryByTestId('list')).toBeNull();
expect(screen.queryByText(/There are no structures in the manifest/)).toBeInTheDocument();
});
});

describe('without structures', () => {
test('renders no list items and a message when structures are not present in manifest', () => {
let manifestWithoutStructures = JSON.parse(JSON.stringify(manifest));
Expand Down
10 changes: 7 additions & 3 deletions src/services/iiif-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ const HTML_SANITIZE_CONFIG = {
allowedSchemesByTag: { 'a': ['http', 'https', 'mailto'] }
};

// Do not build structures for the following 'Range' behaviors:
// Reference: https://iiif.io/api/presentation/3.0/#behavior
const NO_DISPLAY_STRUCTURE_BEHAVIORS = ['no-nav', 'thumbnail-nav'];

/**
* Get all the canvases in manifest with related information
* @function IIIFParser#canvasesInManifest
Expand Down Expand Up @@ -549,7 +553,7 @@ export function getStructureRanges(manifest, canvasesInfo, isPlaylist = false) {
let subIndex = 0;
let parseItem = (range, rootNode) => {
let behavior = range.getBehavior();
if (behavior != 'no-nav') {
if (!NO_DISPLAY_STRUCTURE_BEHAVIORS.includes(behavior)) {
let label = getLabelValue(range.getLabel().getValue());
let canvases = range.getCanvasIds();

Expand Down Expand Up @@ -629,15 +633,15 @@ export function getStructureRanges(manifest, canvasesInfo, isPlaylist = false) {
const rootNode = allRanges[0];
let structures = [];
const rootBehavior = rootNode.getBehavior();
if (rootBehavior && rootBehavior == 'no-nav') {
if (rootBehavior && NO_DISPLAY_STRUCTURE_BEHAVIORS.includes(rootBehavior)) {
return { structures: [], timespans: [], hasCollapsibleStructure };
} else {
if (isPlaylist || rootBehavior === 'top') {
let canvasRanges = rootNode.getRanges();
if (canvasRanges?.length > 0) {
canvasRanges.map((range, index) => {
const behavior = range.getBehavior();
if (behavior != 'no-nav') {
if (!NO_DISPLAY_STRUCTURE_BEHAVIORS.includes(behavior)) {
// Reset the index for timespans in structure for each Canvas
subIndex = 0;
cIndex = index + 1;
Expand Down
10 changes: 10 additions & 0 deletions src/services/iiif-parser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,16 @@ describe('iiif-parser', () => {
expect(firstStructCanvas.duration).toEqual('00:32');
expect(firstStructCanvas.canvasDuration).toEqual(32);
});

it('return empty structures and timespans when behavior is set to thumbnail-nav', () => {
const { structures, timespans, markRoot, hasCollapsibleStructure } = iiifParser.getStructureRanges(
singleSrcManifest, iiifParser.canvasesInManifest(singleSrcManifest)
);
expect(structures).toHaveLength(0);
expect(timespans).toHaveLength(0);
expect(markRoot).toBeFalsy();
expect(hasCollapsibleStructure).toBeFalsy();
});
});

describe('getSearchService()', () => {
Expand Down
41 changes: 41 additions & 0 deletions src/test_data/transcript-multiple-canvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,47 @@ export default {
],
},
],
structures: [
{
id: "https://example.com/sample/manifest/range/1",
type: "Range",
items: [
{
id: "http://localhost:4000/recipe/0229-behavior-ranges/range/1.1",
type: "Range",
items: [
{
id: "http://localhost:4000/recipe/0229-behavior-ranges/canvas/1#t=0,9",
type: "Canvas"
}
],
behavior: "no-nav"
},
{
id: "http://localhost:4000/recipe/0229-behavior-ranges/range/2",
type: "Range",
items: [
{
id: "http://localhost:4000/recipe/0229-behavior-ranges/canvas/1#t=9,305",
type: "Canvas"
}
],
label: { en: ["Start – 305s"] },
thumbnail: [
{
id: "https://fixtures.iiif.io/video/indiana/donizetti-elixir/thumbnails/thumb-nav-01.png",
type: "Image",
width: "2250",
format: "image/png",
height: "1266"
}
]
}
],
label: { en: ["Behavior Property Test"] },
behavior: "thumbnail-nav"
}
],
thumbnail: [
{
id: 'https://example.com/sample/thumbnail/poster.jpg',
Expand Down

0 comments on commit f183189

Please sign in to comment.