Add canvas functions to ranges rebase - #181
Conversation
- Create getCanvases, getCanvasById, getCanvasByIndex functions for the range type
sequence to range as well - Add test for getCanvasById range
... index to each canvas in range
... ranges when getting canvases
Review or Edit in CodeSandboxOpen the branch in Web Editor • VS Code • Insiders |
demiankatz
left a comment
There was a problem hiding this comment.
Thanks, @marlo-longley -- I didn't fully review all of the code (some of the new logic in Range.ts is pretty complex, and it will take me more time than I have available today to thoroughly study it), but please see below for a few comments and suggestions that I hope will be helpful!
| (item["type"] && item["type"].toLowerCase() === "canvas") || | ||
| (item["type"] && item["type"].toLowerCase() === "specificresource") |
There was a problem hiding this comment.
Maybe slightly more concise/efficient?
| (item["type"] && item["type"].toLowerCase() === "canvas") || | |
| (item["type"] && item["type"].toLowerCase() === "specificresource") | |
| (item["type"] && ["canvas", "specificresource"].includes(item["type"].toLowerCase())) |
|
|
||
| const id: string = item.id || item["@id"]; | ||
| const id: string = item.id || item["@id"] || item["source"]; |
There was a problem hiding this comment.
Does it make sense to treat a specificResource as a canvas, and to accept id and source interchangeably like this? Or should we do different things based on type for tighter validation? (I confess that I know very little about the use case here, so I'm just asking in general terms).
There was a problem hiding this comment.
Specific resource might be a canvas with a selector: https://iiif.io/api/cookbook/recipe/0025-newspaper-article-index/
{
"type": "SpecificResource",
"source": {
"id": "https://iiif.io/api/cookbook/recipe/0025-newspaper-article-index/canvas/p2",
"type": "Canvas"
},
"selector": {
"type": "FragmentSelector",
"value": "xywh=553,1157,470,1103"
}
}But worth noting that source can be a string or a record with id/type
| } from "@iiif/vocabulary/dist-commonjs"; | ||
|
|
||
| export class Range extends ManifestResource { | ||
| private _canvases: Canvas[] | null = null; |
There was a problem hiding this comment.
It's not ideal to have _canvases and canvases as two distinct things. I think the "most correct" thing would be to rename canvases to canvasIds`, but that would be a breaking change, so we probably shouldn't do it for now. I wonder if there's something else we can do to make this less potentially confusing, though.
| getTopRange(range) { | ||
| let parentRange = range.parentRange; | ||
| if (parentRange) { | ||
| this.getTopRange(parentRange); |
There was a problem hiding this comment.
Should there be a return here? Do we need to worry about malformed data causing an infinite loop?
| // Alternative solution can be this | ||
| /* getTopLevelCanvases(): Canvas[] { | ||
| if(this._canvases){ | ||
| return this._canvases; | ||
| } | ||
|
|
||
| if (this.items.length) { | ||
| let canvasItems: Canvas[] = []; | ||
| for (let i = 0; i < this.items.length; i++) { | ||
| if (this.items[i].isCanvas()) { | ||
| canvasItems.push(<Canvas>this.items[i]); | ||
| } | ||
| } | ||
| return this._canvases = canvasItems; | ||
| } | ||
|
|
||
| let items = this.__jsonld.items || this.__jsonld.elements; | ||
|
|
||
| if (items) { | ||
| for (let i = 0; i < items.length; i++) { | ||
| if (items[i].type.includes("Canvas")) { | ||
| const c = items[i]; | ||
| const canvas: Canvas = new Canvas(c, this.options); | ||
| canvas.index = i; | ||
| this.items.push(canvas); | ||
| } | ||
| } | ||
| } else if (this.__jsonld) { | ||
| for (let i = 0; i < this.__jsonld.length; i++) { | ||
| if (items[i].type.includes("Canvas")) { | ||
| const c = this.__jsonld[i]; | ||
| const canvas: Canvas = new Canvas(c, this.options); | ||
| canvas.index = i; | ||
| this.items.push(canvas); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return this._canvases = <Canvas[]>this.items; | ||
| } | ||
| */ | ||
|
|
There was a problem hiding this comment.
I don't think we want to put all of this commented-out code in the finished product. Do we need to weigh options and make choices?
| } | ||
|
|
||
| const items = this.__jsonld.canvases || this.__jsonld.elements; | ||
|
|
There was a problem hiding this comment.
Maybe it's worth undoing this whitespace-only change to avoid a superfluous file change in the PR.
|
@demiankatz thanks for looking! |
|
Sounds like we're all in the same boat, @marlo-longley! :-) |
|
|
||
| private _parseTreeNode(node: TreeNode, range: Range): void { | ||
| node.label = <string>range.getLabel().getValue(this.options.locale); | ||
| node.label = < string > range.getLabel().getValue(this.options.locale); |
There was a problem hiding this comment.
There are a few formatting issues like this, although valid we should be consistent.
This rebases #79