IIIF-Commons / manifesto

IIIF Presentation API client and server utility library.
MIT License
46 stars 31 forks source link

Canvas.getContent() cannot get content on second and later AnnotationPage #86

Open 2SC1815J opened 3 years ago

2SC1815J commented 3 years ago

In the recipe provided at https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/, one Canvas has two AnnotationPage objects.

{
  "id": "https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/canvas/1",
  "type": "Canvas",
  "width": 1920,
  "height": 1080,
  "duration": 7278.422,
  "items": [
    {
      "id": "https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/canvas/1/annotation_page/1",
      "type": "AnnotationPage",
      "items": [
        {
          "id": "https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/canvas/1/annotation_page/1/annotation/1",
          "type": "Annotation",
          "motivation": "painting",
          "target": "https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/canvas/1#t=0",
          "body": {
            "id": "https://fixtures.iiif.io/video/indiana/donizetti-elixir/vae0637_accessH264_low.mp4",
            "type": "Video",
            "format": "video/mp4",
            "height": 1080,
            "width": 1920,
            "duration": 3971.24
          }
        }
      ]
    },
    {
      "id": "https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/canvas/1/annotation_page/1",
      "type": "AnnotationPage",
      "items": [
        {
          "id": "https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/canvas/1/annotation_page/1/annotation/2",
          "type": "Annotation",
          "motivation": "painting",
          "target": "https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/canvas/1#t=3971.24",
          "body": {
            "id": "https://fixtures.iiif.io/video/indiana/donizetti-elixir/vae0637_accessH264_low_act_2.mp4",
            "type": "Video",
            "format": "video/mp4",
            "height": 1080,
            "width": 1920,
            "duration": 3307.22
          }
        }
      ]
    }
  ]
}

Canvas.getContent() does not seem to be able to get the second AnnotationPage content.

const manifesto = require('manifesto.js/dist-commonjs/');

manifesto.loadManifest('https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/manifest.json').then((data) => {
  const manifest = manifesto.parseManifest(data);
  const sequence = manifest.getSequenceByIndex(0);
  const canvas = sequence.getCanvasByIndex(0);
  const content = canvas.getContent();
  console.log(content);
});

Currently, this output goes as follows.

// The Annotation in the second AnnotationPage object is missing.
[
  Annotation {
    __jsonld: {
      id: 'https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/canvas/1/annotation_page/1/annotation/1',
      type: 'Annotation',
      motivation: 'painting',
      target: 'https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/canvas/1#t=0',
      body: [Object]
    },
    context: undefined,
    id: 'https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/canvas/1/annotation_page/1/annotation/1',
    options: {
      defaultLabel: '-',
      locale: 'en-GB',
      resource: [Manifest],
      pessimisticAccessControl: false
    }
  }
]

This seems to be because only the first element is processed in the line shown below. https://github.com/IIIF-Commons/manifesto/blob/master/src/Canvas.ts#L150

I don't know if this is an issue that the recipe needs to be fixed or Canvas.getContent() needs to be improved. If the modification of Canvas.getContent() causes backward compatibility issues, you might consider creating new methods, such as Canvas.getContents(), Canvas.getContentByIndex(), etc. If the recipe should be modified, please let me know. I'll report it to the recipe repository.

stephenwf commented 3 years ago

Canvas.getContent(page: number | string) could return either the index or by id. Did that recipe come from the cookbook? Looks like both pages have the same Identifier, which could cause issues!

Would be interested to know the desired user interface when a viewer comes across more than one annotation page associated with a canvas. Is this to be interpreted in a similar way to layers?

2SC1815J commented 3 years ago

Thanks for your comment and for adding the feature so quickly #87 !

That recipe comes from the cookbook, https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/. As far as I read the intent of the recipe, I don't know why they didn't make it like this.

{
  "id": "https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/canvas/1",
  "type": "Canvas",
  "width": 1920,
  "height": 1080,
  "duration": 7278.46,
  "items": [
    {
      "id": "https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/canvas/1/annotation_page/1",
      "type": "AnnotationPage",
      "items": [
        {
          "id": "https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/canvas/1/annotation_page/1/annotation/1",
          "type": "Annotation",
          "motivation": "painting",
          "target": "https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/canvas/1#t=0,3971.24",
          "body": {
            "id": "https://fixtures.iiif.io/video/indiana/donizetti-elixir/vae0637_accessH264_low.mp4",
            "type": "Video",
            "format": "video/mp4",
            "height": 1080,
            "width": 1920,
            "duration": 3971.24
          }
        },
        {
          "id": "https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/canvas/1/annotation_page/1/annotation/2",
          "type": "Annotation",
          "motivation": "painting",
          "target": "https://iiif.io/api/cookbook/recipe/0064-opera-one-canvas/canvas/1#t=3971.24",
          "body": {
            "id": "https://fixtures.iiif.io/video/indiana/donizetti-elixir/vae0637_accessH264_low_act_2.mp4",
            "type": "Video",
            "format": "video/mp4",
            "height": 1080,
            "width": 1920,
            "duration": 3307.22
          }
        }
      ]
    }
  ]
}

Aside from that recipe's appropriateness, the specification allows for Canvas to have multiple AnnotaionPage, so it would be interesting to know if what kind of behavior the people who set up the specification had in mind as desirable.