Skip to content

Commit 53a2e81

Browse files
committed
Add functionality to handle fragments in ...
... ranges when getting canvases
1 parent d0a54a6 commit 53a2e81

File tree

4 files changed

+83
-41
lines changed

4 files changed

+83
-41
lines changed

src/Manifest.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,15 @@ export class Manifest extends IIIFResource {
164164
this._parseRanges(item, path + "/" + i, range);
165165
} else if (
166166
(item["@type"] && item["@type"].toLowerCase() === "sc:canvas") ||
167-
(item["type"] && item["type"].toLowerCase() === "canvas")
167+
(item["type"] && item["type"].toLowerCase() === "canvas") ||
168+
(item["type"] && item["type"].toLowerCase() === "specificresource")
168169
) {
169170
// store the ids on the __jsonld object to be used by Range.getCanvasIds()
170171
if (!range.canvases) {
171172
range.canvases = [];
172173
}
173-
174-
const id: string = item.id || item["@id"];
174+
175+
const id: string = item.id || item["@id"] || item["source"];
175176

176177
range.canvases.push(id);
177178
}

src/Range.ts

Lines changed: 57 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export class Range extends ManifestResource {
2222
public path: string;
2323
public treeNode: TreeNode;
2424

25-
constructor(jsonld?: any, options?: IManifestoOptions) {
25+
constructor(jsonld ? : any, options ? : IManifestoOptions) {
2626
super(jsonld, options);
2727
}
2828

@@ -58,63 +58,90 @@ export class Range extends ManifestResource {
5858
).options.resource.getSequences()[0];
5959
let manifestCanvases =
6060
manifestSequence.__jsonld.canvases || manifestSequence.__jsonld.elements;
61+
6162
const canvasLength = this.canvases ? this.canvases.length : 0;
6263
let canvasItems: (Canvas | null)[] = new Array(canvasLength).fill(null);
6364

65+
const rangeItems = this.__jsonld.items;
66+
6467
if (manifestCanvases && this.canvases) {
6568
for (let i = 0; i < manifestCanvases.length; i++) {
66-
const c = manifestCanvases[i];
69+
let c = manifestCanvases[i];
70+
71+
const fragmentCanvas = rangeItems.filter(item => {
72+
return item.source === c.id;
73+
});
6774

6875
if (c.id in this.canvases) {
76+
if (fragmentCanvas) {
77+
const fragment = fragmentCanvas[0].selector.value;
78+
const fragmentCanvasId = `${c.id}#${fragment}`;
79+
c = this._updateFragmentIds(c, fragmentCanvasId);
80+
}
81+
6982
const canvas: Canvas = new Canvas(c, this.options);
7083
canvas.index = this.canvases.indexOf(c.id);
7184
canvasItems.splice(canvas.index, 1, canvas);
7285
}
7386
}
7487
} else if (manifestSequence.__jsonld && this.canvases) {
7588
for (let i = 0; i < manifestSequence.__jsonld.length; i++) {
76-
const c = manifestSequence.__jsonld[i];
89+
let c = manifestSequence.__jsonld[i];
90+
91+
const fragmentCanvas = rangeItems.filter(item => {
92+
return item.source === c.id;
93+
});
7794

7895
if (this.canvases.includes(c.id)) {
96+
const cIndex = this.canvases.indexOf(c.id);
97+
if (fragmentCanvas) {
98+
const fragment = fragmentCanvas[0].selector.value;
99+
const fragmentCanvasId = `${c.id}#${fragment}`;
100+
c = this._updateFragmentIds(c, fragmentCanvasId);
101+
}
102+
79103
const canvas: Canvas = new Canvas(c, this.options);
104+
canvas.index = cIndex;
80105

81-
canvas.index = this.canvases.indexOf(c.id);
82106
canvasItems.splice(canvas.index, 1, canvas);
83107
}
84108
}
85109
}
86110

87111
this._canvases =
88-
canvasItems.length > 0
89-
? !canvasItems.includes(null)
90-
? <Canvas[]>canvasItems
91-
: null
92-
: null;
112+
canvasItems.length > 0 ?
113+
!canvasItems.includes(null) ?
114+
< Canvas[] > canvasItems :
115+
null :
116+
null;
93117

94118
return this._canvases !== null ? this._canvases : [];
95119
}
96120

97121
// update __jsonld canvas id's because that is used by other functions in
98122
// the library when working with canvases
99-
/* _updateCanvasIds(canvasJson: any, newCanvasId: string): any {
100-
// update ids in annotations
101-
const items = canvasJson.items || canvasJson.content;
102-
const annotations = items.length && items[0].items ? items[0].items : [];
103-
if (annotations && canvasJson.items) {
104-
for (let i = 0; i < annotations.length; i++) {
105-
canvasJson["id"] = newCanvasId;
106-
// update target canvas Id in all canvas annotations
107-
canvasJson.items[0].items[i]["target"] = newCanvasId;
108-
}
109-
} else if (annotations) {
110-
for (let i = 0; i < annotations.length; i++) {
111-
canvasJson["id"] = newCanvasId;
112-
// update target canvas Id in all canvas annotations
113-
canvasJson.content[0].items[i]["target"] = newCanvasId;
114-
}
123+
_updateFragmentIds(canvasJson: any, newCanvasId: string): any {
124+
// update ids in annotations
125+
const items = canvasJson.items || canvasJson.content;
126+
const annotations = items.length && items[0].items ? items[0].items : [];
127+
128+
if (annotations && canvasJson.items) {
129+
for (let i = 0; i < annotations.length; i++) {
130+
canvasJson["id"] = newCanvasId;
131+
// update target canvas Id in all canvas annotations
132+
canvasJson.items[0].items[i]["target"] = newCanvasId;
133+
}
134+
} else if (annotations) {
135+
for (let i = 0; i < annotations.length; i++) {
136+
canvasJson["id"] = newCanvasId;
137+
// update target canvas Id in all canvas annotations
138+
// replace this with (something that looks at other contents)
139+
canvasJson.content[0].items[i]["target"] = newCanvasId;
115140
}
116-
return canvasJson;
117-
} */
141+
}
142+
143+
return canvasJson;
144+
}
118145

119146
getCanvasByIndex(canvasIndex: number): any {
120147
return this.getCanvases()[canvasIndex];
@@ -286,7 +313,7 @@ export class Range extends ManifestResource {
286313
return this._ranges;
287314
}
288315

289-
return (this._ranges = <Range[]>this.items.filter(m => m.isRange()));
316+
return (this._ranges = < Range[] > this.items.filter(m => m.isRange()));
290317
}
291318

292319
getBehavior(): Behavior | null {
@@ -344,7 +371,7 @@ export class Range extends ManifestResource {
344371
}
345372

346373
private _parseTreeNode(node: TreeNode, range: Range): void {
347-
node.label = <string>range.getLabel().getValue(this.options.locale);
374+
node.label = < string > range.getLabel().getValue(this.options.locale);
348375
node.data = range;
349376
node.data.type = Utils.normaliseType(TreeNodeType.RANGE);
350377
range.treeNode = node;
@@ -366,4 +393,4 @@ export class Range extends ManifestResource {
366393
}
367394
}
368395
}
369-
}
396+
}

test/fixtures/pres3.json

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -186,15 +186,22 @@
186186
"type": "Range",
187187
"behavior": "sequence",
188188
"items": [
189-
{
190-
"id": "http://example.org/iiif/book1/canvas/0",
191-
"type": "Canvas",
192-
"label": {
193-
"@none": [
194-
"p. 1"
195-
]
189+
{
190+
"type": "SpecificResource",
191+
"source": "http://example.org/iiif/book1/canvas/0",
192+
"selector": {
193+
"type": "FragmentSelector",
194+
"value": "xywh=0,0,750,300"
195+
}
196+
},
197+
{
198+
"type": "SpecificResource",
199+
"source": "http://example.org/iiif/book1/canvas/1",
200+
"selector": {
201+
"type": "FragmentSelector",
202+
"value": "xywh=0,0,750,300"
203+
}
196204
}
197-
}
198205
]
199206
}
200207
]

test/tests/pres3.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ describe('presentation 3', function() {
4848
/* B */
4949
});
5050

51+
it('updates canvas Id if canvas is listed as a fragment in range', function() {
52+
canvas = range.getCanvases()[1];
53+
const hasFragment = canvas.id.includes('#xywh=')
54+
expect(hasFragment).to.exist;
55+
/* B */
56+
});
57+
5158
it('has an annotation body', function() {
5259
content = canvas.getContent();
5360
annotation = content[0];

0 commit comments

Comments
 (0)