react-iiif-vault 1.0.8 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.build/types/canvas-panel/Viewer.d.ts +1 -1
- package/.build/types/canvas-panel/index.d.ts +2 -1
- package/.build/types/canvas-panel/render/Audio.d.ts +1 -1
- package/.build/types/canvas-panel/render/Canvas.d.ts +2 -2
- package/.build/types/canvas-panel/render/CanvasBackground.d.ts +1 -1
- package/.build/types/canvas-panel/render/DefaultCanvasFallback.d.ts +1 -1
- package/.build/types/canvas-panel/render/Image.d.ts +1 -1
- package/.build/types/canvas-panel/render/Model.d.ts +1 -1
- package/.build/types/canvas-panel/render/Video.d.ts +1 -1
- package/.build/types/canvas-panel/render/VideoYouTube.d.ts +1 -1
- package/.build/types/components/CanvasAnnotations.d.ts +10 -0
- package/.build/types/components/CombinedMetadata.d.ts +4 -0
- package/.build/types/components/Image.d.ts +15 -0
- package/.build/types/components/ManifestMetadata.d.ts +4 -0
- package/.build/types/components/Metadata.d.ts +39 -0
- package/.build/types/components/SequenceThumbnails.d.ts +29 -0
- package/.build/types/components/SingleCanvasThumbnail.d.ts +20 -0
- package/.build/types/context/AnnotationContext.d.ts +1 -1
- package/.build/types/context/AnnotationPageContext.d.ts +1 -1
- package/.build/types/context/CanvasContext.d.ts +1 -1
- package/.build/types/context/CollectionContext.d.ts +1 -1
- package/.build/types/context/ContextBridge.d.ts +1 -1
- package/.build/types/context/ManifestContext.d.ts +1 -1
- package/.build/types/context/MediaContext.d.ts +1 -1
- package/.build/types/context/RangeContext.d.ts +1 -1
- package/.build/types/context/ResourceContext.d.ts +2 -2
- package/.build/types/context/VaultContext.d.ts +1 -1
- package/.build/types/demo/media-controls.d.ts +1 -1
- package/.build/types/demo/viewer-controls.d.ts +1 -1
- package/.build/types/features/rendering-strategy/3d-strategy.d.ts +1 -1
- package/.build/types/features/rendering-strategy/image-strategy.d.ts +1 -1
- package/.build/types/features/rendering-strategy/resource-types.d.ts +7 -7
- package/.build/types/features/rendering-strategy/strategies.d.ts +5 -5
- package/.build/types/features/rendering-strategy/textual-content-strategy.d.ts +1 -1
- package/.build/types/hooks/useEventListener.d.ts +1 -1
- package/.build/types/hooks/useExternalResource.d.ts +1 -1
- package/.build/types/hooks/useImage.d.ts +10 -0
- package/.build/types/hooks/useLoadImageService.d.ts +1 -1
- package/.build/types/hooks/useRenderingStrategy.d.ts +3 -3
- package/.build/types/hooks/useSimpleMediaPlayer.d.ts +2 -2
- package/.build/types/hooks/useVirtualAnnotationPageContext.d.ts +81 -81
- package/.build/types/index.d.ts +8 -0
- package/.build/types/utility/i18n-utils.d.ts +8 -6
- package/.build/types/viewers/SimpleViewerContext.d.ts +2 -2
- package/.build/types/viewers/SimpleViewerContext.hooks.d.ts +2 -0
- package/.build/types/viewers/SimpleViewerContext.types.d.ts +6 -4
- package/dist/bundle/cjs/index.js +7 -6
- package/dist/bundle/cjs/index.js.map +1 -1
- package/dist/bundle/esm/index.mjs +2390 -1174
- package/dist/bundle/esm/index.mjs.map +1 -1
- package/dist/canvas-panel/cjs/canvas-panel.js +5 -5
- package/dist/canvas-panel/cjs/canvas-panel.js.map +1 -1
- package/dist/canvas-panel/esm/canvas-panel.mjs +540 -480
- package/dist/canvas-panel/esm/canvas-panel.mjs.map +1 -1
- package/dist/index.umd.js +78 -76
- package/dist/index.umd.js.map +1 -1
- package/dist/react17/cjs/index.js +7 -6
- package/dist/react17/cjs/index.js.map +1 -1
- package/dist/react17/esm/index.mjs +2390 -1174
- package/dist/react17/esm/index.mjs.map +1 -1
- package/dist/utils/cjs/utils.js +1 -1
- package/dist/utils/cjs/utils.js.map +1 -1
- package/dist/utils/esm/utils.mjs +21 -21
- package/dist/utils/esm/utils.mjs.map +1 -1
- package/package.json +24 -22
package/dist/utils/cjs/utils.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const T=require("@iiif/helpers"),w=require("@atlas-viewer/iiif-image-api"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const T=require("@iiif/helpers"),w=require("@atlas-viewer/iiif-image-api"),y=require("@iiif/helpers/annotation-targets");function I(e){return e.type==="SpecificResource"?[e.source,{selector:e.selector}]:[e,{selector:null}]}function m(e,o){const{selector:r,source:i}=T.expandTarget(o);if(i.id!==e.id)return[null,i];const t={type:"BoxSelector",spatial:{x:0,y:0,width:Number(e.width),height:Number(e.height)}};return[r?r.type==="TemporalSelector"?{type:"TemporalBoxSelector",temporal:r.temporal,spatial:t.spatial}:r:null,i]}const R={makeChoice:()=>{}},f={type:"unknown"},n=e=>({type:"unknown",reason:e,annotations:{pages:[]}}),h=(e,o)=>({type:"empty",width:e,height:o,annotations:{pages:[]},image:null,images:[]}),O=["model/gltf-binary"];function k(e,o){const i=o.items[0].resource;return i.format?O.indexOf(i.format)===-1?n(`3D format: ${i.format} is unsupported`):{type:"3d-model",model:i}:n("Unknown format")}function N(e,o){var i;if(!e.duration)return n("No duration on canvas");if(o.items.length>1)return n("Only one audio source supported");const r=(i=o.items[0])==null?void 0:i.resource;return r?r.format?{type:"media",media:{annotationId:o.items[0].annotationId,duration:e.duration,url:r.id,type:"Sound",target:{type:"TemporalSelector",temporal:{startTime:0,endTime:e.duration}},format:r.format,selector:{type:"TemporalSelector",temporal:{startTime:0,endTime:e.duration}}},annotations:{pages:[]}}:n("Audio does not have format"):n("Unknown audio")}function B(e,o,r){const i=[];for(const t of o.items){const u=t.resource&&t.resource.type==="SpecificResource"?t.resource.source:t.resource;if(!u.id)return n("No resource Identifier");let s;if(u.service){const a=w.getImageServices(u);a[0]&&(s=r(a[0],e))}const l={type:"BoxSelector",spatial:{x:0,y:0,width:Number(e.width),height:Number(e.height)}},[d,g]=m(e,t.target);if(!(g.id===e.id||decodeURIComponent(g.id||"")===(e.id||"")))continue;t.resource.width&&t.resource.height&&(t.resource.width,t.resource.height);let c=t.resource.type==="SpecificResource"?y.expandTarget(t.resource):null;if(t.selector){const a=y.expandTarget({type:"SpecificResource",source:t.resource,selector:t.selector});a&&(c=a)}const p=c&&c.selector&&(c.selector.type==="BoxSelector"||c.selector.type==="TemporalBoxSelector")?{type:"BoxSelector",spatial:{x:c.selector.spatial.x,y:c.selector.spatial.y,width:c.selector.spatial.width,height:c.selector.spatial.height}}:void 0;s&&!s.id&&(s.id=s["@id"]);const x={id:u.id,type:"Image",annotationId:t.annotationId,width:Number(d||p?u.width:e.width),height:Number(d||p?u.height:e.height),service:s,sizes:s&&s.sizes?s.sizes:u.width&&u.height?[{width:u.width,height:u.height}]:[],target:d&&d.type!=="PointSelector"?d:l,selector:p};i.push(x)}return{type:"images",image:i[0],images:i,choice:o.choice}}function S(e,o={},r){const i=e.language||r||"none";switch(e.type){case"TextualBody":{typeof e.value<"u"&&(o[i]=e.value);break}case"List":case"Composite":case"Choice":e.items&&e.items.forEach(t=>S(t,o,i))}return o}function v(e,o){const r=[];return o.items.forEach(i=>{if(i.resource){const[t]=m(e,i.target);r.push({annotationId:i.annotationId,text:S(i.resource),target:t})}}),{type:"textual-content",items:r}}const C=/^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/|shorts\/)|(?:(?:watch)?\?vi?=|&vi?=))([^#&?]*).*/;function V(e,o){var l;const r=o.items.filter(d=>d.type==="video");let i=!1;if(e.duration||(i=!0),r.length>1)return n("Only one video source supported");const t=(l=r[0])==null?void 0:l.resource,u=!!(t.service||[]).find(d=>(d.profile||"").includes("youtube.com"));if(!u&&i)return n("Video does not have duration");if(!t)return n("Unknown video");if((!t.format||t.format==="text/html")&&!u)return n("Video does not have format");const s={annotationId:o.items[0].annotationId,duration:e.duration,url:t.id,type:"Video",items:[],target:{type:"TemporalSelector",temporal:{startTime:0,endTime:e.duration}},format:t.format,selector:{type:"TemporalSelector",temporal:{startTime:0,endTime:e.duration}}};if(u){s.type="VideoYouTube";const d=t.id.match(C);if(!d[1])return n("Video is not known youtube video");s.youTubeId=d[1]}return{type:"media",media:s,annotations:{pages:[]}}}function b({canvas:e,paintables:o,supports:r,loadImageService:i}){if(!e)return console.log("No canvas"),f;if(o.types.length===0)return r.indexOf("empty")!==-1?h(e.width,e.height):(console.log("No paintables"),f);if(o.types.length!==1)if(o.types.length===2&&o.types.indexOf("text")!==-1)o.types=o.types.filter(u=>u!=="text");else return r.indexOf("complex-timeline")===-1?n("Complex timeline not supported"):n("ComplexTimelineStrategy not yet supported");const t=o.types[0];return t==="image"?r.indexOf("images")===-1?n("Image not supported"):B(e,o,i):t==="Model"||t==="model"?r.indexOf("3d-model")===-1?n("3D not supported"):k(e,o):t==="textualbody"?r.indexOf("textual-content")===-1?n("Textual content not supported"):v(e,o):t==="sound"||t==="audio"?r.indexOf("media")===-1?n("Media not supported"):N(e,o):t==="video"?r.indexOf("media")===-1?n("Media not supported"):V(e,o):f}exports.emptyActions=R;exports.emptyStrategy=h;exports.getParsedTargetSelector=m;exports.getRenderingStrategy=b;exports.parseSpecificResource=I;exports.unknownResponse=f;exports.unsupportedStrategy=n;
|
|
2
2
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../../../src/features/rendering-strategy/rendering-utils.ts","../../../src/features/rendering-strategy/3d-strategy.ts","../../../src/features/rendering-strategy/audio-strategy.ts","../../../src/features/rendering-strategy/image-strategy.ts","../../../src/features/rendering-strategy/textual-content-strategy.ts","../../../src/features/rendering-strategy/video-strategy.ts","../../../src/features/rendering-strategy/get-rendering-strategy.ts"],"sourcesContent":["import { ContentResource, PointSelector, W3CAnnotationTarget } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { UseRenderingStrategy } from '../../hooks/useRenderingStrategy';\nimport { BoxSelector, expandTarget, SupportedTarget, TemporalBoxSelector } from '@iiif/helpers';\n\n/**\n * Parse specific resource.\n *\n * This could be expanded to support pulling out more from the specific resource.\n *\n * @param resource\n */\nexport function parseSpecificResource(resource: ContentResource) {\n if (resource.type === 'SpecificResource') {\n return [resource.source, { selector: resource.selector }];\n }\n\n return [resource, { selector: null }];\n}\n\nexport function getParsedTargetSelector(\n canvas: CanvasNormalized,\n target: W3CAnnotationTarget | W3CAnnotationTarget[]\n): [TemporalBoxSelector | BoxSelector | PointSelector | null, SupportedTarget['source']] {\n const { selector: imageTarget, source } = expandTarget(target);\n\n if (source.id !== canvas.id) {\n // Skip invalid targets.\n return [null, source];\n }\n\n // Target is where it should be painted.\n const defaultTarget: BoxSelector = {\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: Number(canvas.width),\n height: Number(canvas.height),\n },\n };\n\n return [\n imageTarget\n ? imageTarget.type === 'TemporalSelector'\n ? ({\n type: 'TemporalBoxSelector',\n temporal: imageTarget.temporal,\n spatial: defaultTarget.spatial,\n } as any)\n : imageTarget\n : null,\n source,\n ];\n}\n\nexport const emptyActions = {\n makeChoice: () => {\n // no-op\n },\n};\n\nexport const unknownResponse: UseRenderingStrategy[0] = { type: 'unknown' };\n\nexport const unsupportedStrategy = (reason: string): UseRenderingStrategy[0] => {\n return { type: 'unknown', reason, annotations: { pages: [] } };\n};\n\nexport const emptyStrategy = (width: number, height: number): UseRenderingStrategy[0] => {\n return { type: 'empty', width, height, annotations: { pages: [] }, image: null, images: [] };\n};\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { AnnotationPageDescription } from './resource-types';\nimport { ExternalWebResource } from '@iiif/presentation-3';\nimport { RenderingStrategy } from './strategies';\nimport { ChoiceDescription, Paintables } from '@iiif/helpers';\n\nexport type Single3DModelStrategy = {\n type: '3d-model';\n model: ExternalWebResource;\n choice?: ChoiceDescription; // future\n annotations?: AnnotationPageDescription; // future\n};\n\nconst supportedFormats = ['model/gltf-binary'];\n\nexport function get3dStrategy(canvas: CanvasNormalized, paintables: Paintables): RenderingStrategy {\n const first = paintables.items[0];\n const resource = first.resource as ExternalWebResource;\n\n if (!resource.format) {\n return unsupportedStrategy('Unknown format');\n }\n\n if (supportedFormats.indexOf(resource.format) === -1) {\n return unsupportedStrategy(`3D format: ${resource.format} is unsupported`);\n }\n\n return {\n type: '3d-model',\n model: resource as any,\n } as Single3DModelStrategy;\n}\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { MediaStrategy } from './strategies';\nimport { Paintables } from '@iiif/helpers';\n\nexport function getAudioStrategy(canvas: CanvasNormalized, paintables: Paintables) {\n if (!canvas.duration) {\n return unsupportedStrategy('No duration on canvas');\n }\n\n if (paintables.items.length > 1) {\n return unsupportedStrategy('Only one audio source supported');\n }\n\n const audioResource = paintables.items[0]?.resource as any; // @todo stronger type for what this might be.\n\n if (!audioResource) {\n return unsupportedStrategy('Unknown audio');\n }\n\n if (!audioResource.format) {\n return unsupportedStrategy('Audio does not have format');\n }\n\n return {\n type: 'media',\n media: {\n annotationId: paintables.items[0].annotationId,\n duration: canvas.duration,\n url: audioResource.id,\n type: 'Sound',\n target: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n format: audioResource.format,\n selector: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n },\n annotations: {\n pages: [],\n },\n } as MediaStrategy;\n}\n","import { IIIFExternalWebResource } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { ImageServiceLoaderType } from '../../hooks/useLoadImageService';\nimport { AnnotationPageDescription, ImageWithOptionalService } from './resource-types';\nimport { getImageServices } from '@atlas-viewer/iiif-image-api';\nimport { getParsedTargetSelector, unsupportedStrategy } from './rendering-utils';\nimport { expandTarget } from '@iiif/helpers/annotation-targets';\nimport { BoxSelector, ChoiceDescription, Paintables } from '@iiif/helpers';\n\nexport type SingleImageStrategy = {\n type: 'images';\n image: ImageWithOptionalService;\n images: Array<ImageWithOptionalService>;\n choice?: ChoiceDescription;\n annotations?: AnnotationPageDescription;\n};\n\nexport function getImageStrategy(\n canvas: CanvasNormalized,\n paintables: Paintables,\n loadImageService: ImageServiceLoaderType\n) {\n const imageTypes: ImageWithOptionalService[] = [];\n for (const singleImage of paintables.items) {\n // SingleImageStrategy\n const resource: IIIFExternalWebResource =\n singleImage.resource && singleImage.resource.type === 'SpecificResource'\n ? singleImage.resource.source\n : singleImage.resource;\n\n // Validation.\n if (!resource.id) {\n // @todo we could skip this?\n return unsupportedStrategy('No resource Identifier');\n }\n\n let imageService = undefined;\n if (resource.service) {\n const imageServices = getImageServices(resource as any) as any[];\n if (imageServices[0]) {\n imageService = loadImageService(imageServices[0], canvas);\n }\n }\n\n // Target is where it should be painted.\n const defaultTarget: BoxSelector = {\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: Number(canvas.width),\n height: Number(canvas.height),\n },\n };\n\n const [target, source] = getParsedTargetSelector(canvas, singleImage.target);\n if (source.id !== canvas.id) {\n // Skip invalid targets.\n continue;\n }\n\n // Support for cropping before painting an annotation.\n // @todo this isn't working.\n const defaultImageSelector =\n (singleImage.resource as any).width && (singleImage.resource as any).height\n ? ({\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: (singleImage.resource as any).width,\n height: (singleImage.resource as any).height,\n },\n } as BoxSelector)\n : undefined;\n\n let imageSelector = singleImage.resource.type === 'SpecificResource' ? expandTarget(singleImage.resource) : null;\n\n if (singleImage.selector) {\n const found = expandTarget({\n type: 'SpecificResource',\n source: singleImage.resource,\n selector: singleImage.selector,\n });\n\n if (found) {\n imageSelector = found;\n }\n }\n\n const selector: undefined | BoxSelector =\n imageSelector &&\n imageSelector.selector &&\n (imageSelector.selector.type === 'BoxSelector' || imageSelector.selector.type === 'TemporalBoxSelector')\n ? {\n type: 'BoxSelector',\n spatial: {\n x: imageSelector.selector.spatial.x,\n y: imageSelector.selector.spatial.y,\n width: imageSelector.selector.spatial.width,\n height: imageSelector.selector.spatial.height,\n },\n }\n : undefined;\n\n if (imageService && !imageService.id) {\n (imageService as any).id = imageService['@id'];\n }\n\n const imageType: ImageWithOptionalService = {\n id: resource.id,\n type: 'Image',\n annotationId: (singleImage as any).annotationId,\n width: Number(target || selector ? resource.width : canvas.width),\n height: Number(target || selector ? resource.height : canvas.height),\n service: imageService,\n sizes:\n imageService && imageService.sizes\n ? imageService.sizes\n : resource.width && resource.height\n ? [{ width: resource.width, height: resource.height }]\n : [],\n target: target && target.type !== 'PointSelector' ? target : defaultTarget,\n selector: selector,\n };\n\n imageTypes.push(imageType);\n }\n\n return {\n type: 'images',\n image: imageTypes[0],\n images: imageTypes,\n choice: paintables.choice,\n } as SingleImageStrategy;\n}\n","import { InternationalString } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { AnnotationPageDescription } from './resource-types';\nimport { getParsedTargetSelector } from './rendering-utils';\nimport { RenderingStrategy } from './strategies';\nimport { ChoiceDescription, Paintables, SupportedTarget } from '@iiif/helpers';\n\nexport type TextualContentStrategy = {\n type: 'textual-content';\n items: { annotationId: string; text: InternationalString; target: SupportedTarget | null }[];\n choice?: ChoiceDescription; // future\n annotations?: AnnotationPageDescription; // future\n};\n\nfunction parseType(item: any, languageMap: InternationalString = {}, lang?: string) {\n const language = item.language || lang || 'none';\n switch (item.type) {\n case 'TextualBody': {\n if (typeof item.value !== 'undefined') {\n languageMap[language] = item.value;\n }\n break;\n }\n case 'List':\n case 'Composite':\n case 'Choice': {\n if (item.items) {\n item.items.forEach((inner: any) => parseType(inner, languageMap, language));\n }\n }\n }\n return languageMap;\n}\n\nexport function getTextualContentStrategy(canvas: CanvasNormalized, paintables: Paintables): RenderingStrategy {\n const items: TextualContentStrategy['items'] = [];\n\n paintables.items.forEach((item) => {\n if (item.resource) {\n const [target] = getParsedTargetSelector(canvas, item.target);\n items.push({ annotationId: item.annotationId, text: parseType(item.resource), target: target as any });\n }\n });\n\n return {\n type: 'textual-content',\n items,\n } as TextualContentStrategy;\n}\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { MediaStrategy } from './strategies';\nimport { Paintables } from '@iiif/helpers';\n\n// https://stackoverflow.com/a/27728417\nconst ytRegex = /^.*(?:(?:youtu\\.be\\/|v\\/|vi\\/|u\\/\\w\\/|embed\\/|shorts\\/)|(?:(?:watch)?\\?vi?=|&vi?=))([^#&?]*).*/;\n\nexport function getVideoStrategy(canvas: CanvasNormalized, paintables: Paintables) {\n const videoPaintables = paintables.items.filter((t) => t.type === 'video');\n\n let noDuration = false;\n\n if (!canvas.duration) {\n noDuration = true;\n }\n\n if (videoPaintables.length > 1) {\n return unsupportedStrategy('Only one video source supported');\n }\n\n const videoResource = videoPaintables[0]?.resource as any; // @todo stronger type for what this might be.\n const isYouTube = !!(videoResource.service || []).find((service: any) =>\n (service.profile || '').includes('youtube.com')\n );\n\n if (!isYouTube && noDuration) {\n return unsupportedStrategy('Video does not have duration');\n }\n\n if (!videoResource) {\n return unsupportedStrategy('Unknown video');\n }\n\n if (!videoResource.format || videoResource.format === 'text/html') {\n if (!isYouTube) {\n return unsupportedStrategy('Video does not have format');\n }\n }\n\n const media = {\n annotationId: (paintables.items[0] as any).annotationId,\n duration: canvas.duration,\n url: videoResource.id,\n type: 'Video',\n items: [],\n target: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n format: videoResource.format,\n selector: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n };\n\n if (isYouTube) {\n media.type = 'VideoYouTube';\n const id = videoResource.id.match(ytRegex);\n if (!id[1]) {\n return unsupportedStrategy('Video is not known youtube video');\n }\n (media as any).youTubeId = id[1];\n }\n\n // @todo support VTT\n\n return {\n type: 'media',\n media,\n annotations: {\n pages: [],\n },\n } as MediaStrategy;\n}\n","import { get3dStrategy } from './3d-strategy';\nimport { getAudioStrategy } from './audio-strategy';\nimport { getImageStrategy } from './image-strategy';\nimport { emptyStrategy, unknownResponse, unsupportedStrategy } from './rendering-utils';\nimport { getTextualContentStrategy } from './textual-content-strategy';\nimport { getVideoStrategy } from './video-strategy';\nimport type { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport type { Paintables } from '@iiif/helpers/painting-annotations';\nimport type { ImageServiceLoaderType } from '../../hooks/useLoadImageService';\n\ninterface GetRenderStrategyOptions {\n canvas: CanvasNormalized | null | undefined;\n paintables: Paintables;\n supports: string[];\n loadImageService: ImageServiceLoaderType;\n}\n\nexport function getRenderingStrategy({ canvas, paintables, supports, loadImageService }: GetRenderStrategyOptions) {\n if (!canvas) {\n console.log('No canvas');\n return unknownResponse;\n }\n\n if (paintables.types.length === 0) {\n if (supports.indexOf('empty') !== -1) {\n return emptyStrategy(canvas.width, canvas.height);\n }\n console.log('No paintables');\n return unknownResponse;\n }\n\n if (paintables.types.length !== 1) {\n if (paintables.types.length === 2 && paintables.types.indexOf('text') !== -1) {\n paintables.types = paintables.types.filter((t) => t !== 'text');\n } else {\n if (supports.indexOf('complex-timeline') === -1) {\n return unsupportedStrategy('Complex timeline not supported');\n }\n return unsupportedStrategy('ComplexTimelineStrategy not yet supported');\n }\n }\n\n const mainType = paintables.types[0];\n\n // Image\n if (mainType === 'image') {\n if (supports.indexOf('images') === -1) {\n return unsupportedStrategy('Image not supported');\n }\n\n return getImageStrategy(canvas, paintables, loadImageService);\n }\n\n // 3D\n if (mainType === 'Model' || mainType === 'model') {\n if (supports.indexOf('3d-model') === -1) {\n return unsupportedStrategy('3D not supported');\n }\n\n return get3dStrategy(canvas, paintables);\n }\n\n if (mainType === 'textualbody') {\n if (supports.indexOf('textual-content') === -1) {\n return unsupportedStrategy('Textual content not supported');\n }\n\n return getTextualContentStrategy(canvas, paintables);\n }\n\n if (mainType === 'sound' || mainType === 'audio') {\n if (supports.indexOf('media') === -1) {\n return unsupportedStrategy('Media not supported');\n }\n\n // Media Strategy with audio or audio sequence.\n return getAudioStrategy(canvas, paintables);\n }\n\n if (mainType === 'video') {\n if (supports.indexOf('media') === -1) {\n return unsupportedStrategy('Media not supported');\n }\n\n // Media Strategy with video or video sequence.\n return getVideoStrategy(canvas, paintables);\n }\n\n // Unknown fallback.\n return unknownResponse;\n}\n"],"names":["parseSpecificResource","resource","getParsedTargetSelector","canvas","target","imageTarget","source","expandTarget","defaultTarget","emptyActions","unknownResponse","unsupportedStrategy","reason","emptyStrategy","width","height","supportedFormats","get3dStrategy","paintables","getAudioStrategy","audioResource","_a","getImageStrategy","loadImageService","imageTypes","singleImage","imageService","imageServices","getImageServices","imageSelector","found","selector","imageType","parseType","item","languageMap","lang","language","inner","getTextualContentStrategy","items","ytRegex","getVideoStrategy","videoPaintables","t","noDuration","videoResource","isYouTube","service","media","id","getRenderingStrategy","supports","mainType"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../../../src/features/rendering-strategy/rendering-utils.ts","../../../src/features/rendering-strategy/3d-strategy.ts","../../../src/features/rendering-strategy/audio-strategy.ts","../../../src/features/rendering-strategy/image-strategy.ts","../../../src/features/rendering-strategy/textual-content-strategy.ts","../../../src/features/rendering-strategy/video-strategy.ts","../../../src/features/rendering-strategy/get-rendering-strategy.ts"],"sourcesContent":["import { ContentResource, PointSelector, W3CAnnotationTarget } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { UseRenderingStrategy } from '../../hooks/useRenderingStrategy';\nimport { BoxSelector, expandTarget, SupportedTarget, TemporalBoxSelector } from '@iiif/helpers';\n\n/**\n * Parse specific resource.\n *\n * This could be expanded to support pulling out more from the specific resource.\n *\n * @param resource\n */\nexport function parseSpecificResource(resource: ContentResource) {\n if (resource.type === 'SpecificResource') {\n return [resource.source, { selector: resource.selector }];\n }\n\n return [resource, { selector: null }];\n}\n\nexport function getParsedTargetSelector(\n canvas: CanvasNormalized,\n target: W3CAnnotationTarget | W3CAnnotationTarget[]\n): [TemporalBoxSelector | BoxSelector | PointSelector | null, SupportedTarget['source']] {\n const { selector: imageTarget, source } = expandTarget(target);\n\n if (source.id !== canvas.id) {\n // Skip invalid targets.\n return [null, source];\n }\n\n // Target is where it should be painted.\n const defaultTarget: BoxSelector = {\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: Number(canvas.width),\n height: Number(canvas.height),\n },\n };\n\n return [\n imageTarget\n ? imageTarget.type === 'TemporalSelector'\n ? ({\n type: 'TemporalBoxSelector',\n temporal: imageTarget.temporal,\n spatial: defaultTarget.spatial,\n } as any)\n : imageTarget\n : null,\n source,\n ];\n}\n\nexport const emptyActions = {\n makeChoice: () => {\n // no-op\n },\n};\n\nexport const unknownResponse: UseRenderingStrategy[0] = { type: 'unknown' };\n\nexport const unsupportedStrategy = (reason: string): UseRenderingStrategy[0] => {\n return { type: 'unknown', reason, annotations: { pages: [] } };\n};\n\nexport const emptyStrategy = (width: number, height: number): UseRenderingStrategy[0] => {\n return { type: 'empty', width, height, annotations: { pages: [] }, image: null, images: [] };\n};\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { AnnotationPageDescription } from './resource-types';\nimport { ExternalWebResource } from '@iiif/presentation-3';\nimport { RenderingStrategy } from './strategies';\nimport { ChoiceDescription, Paintables } from '@iiif/helpers';\n\nexport type Single3DModelStrategy = {\n type: '3d-model';\n model: ExternalWebResource;\n choice?: ChoiceDescription; // future\n annotations?: AnnotationPageDescription; // future\n};\n\nconst supportedFormats = ['model/gltf-binary'];\n\nexport function get3dStrategy(canvas: CanvasNormalized, paintables: Paintables): RenderingStrategy {\n const first = paintables.items[0];\n const resource = first.resource as ExternalWebResource;\n\n if (!resource.format) {\n return unsupportedStrategy('Unknown format');\n }\n\n if (supportedFormats.indexOf(resource.format) === -1) {\n return unsupportedStrategy(`3D format: ${resource.format} is unsupported`);\n }\n\n return {\n type: '3d-model',\n model: resource as any,\n } as Single3DModelStrategy;\n}\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { MediaStrategy } from './strategies';\nimport { Paintables } from '@iiif/helpers';\n\nexport function getAudioStrategy(canvas: CanvasNormalized, paintables: Paintables) {\n if (!canvas.duration) {\n return unsupportedStrategy('No duration on canvas');\n }\n\n if (paintables.items.length > 1) {\n return unsupportedStrategy('Only one audio source supported');\n }\n\n const audioResource = paintables.items[0]?.resource as any; // @todo stronger type for what this might be.\n\n if (!audioResource) {\n return unsupportedStrategy('Unknown audio');\n }\n\n if (!audioResource.format) {\n return unsupportedStrategy('Audio does not have format');\n }\n\n return {\n type: 'media',\n media: {\n annotationId: paintables.items[0].annotationId,\n duration: canvas.duration,\n url: audioResource.id,\n type: 'Sound',\n target: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n format: audioResource.format,\n selector: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n },\n annotations: {\n pages: [],\n },\n } as MediaStrategy;\n}\n","import { IIIFExternalWebResource } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { ImageServiceLoaderType } from '../../hooks/useLoadImageService';\nimport { AnnotationPageDescription, ImageWithOptionalService } from './resource-types';\nimport { getImageServices } from '@atlas-viewer/iiif-image-api';\nimport { getParsedTargetSelector, unsupportedStrategy } from './rendering-utils';\nimport { expandTarget } from '@iiif/helpers/annotation-targets';\nimport { BoxSelector, ChoiceDescription, Paintables } from '@iiif/helpers';\n\nexport type SingleImageStrategy = {\n type: 'images';\n image: ImageWithOptionalService;\n images: Array<ImageWithOptionalService>;\n choice?: ChoiceDescription;\n annotations?: AnnotationPageDescription;\n};\n\nexport function getImageStrategy(\n canvas: CanvasNormalized,\n paintables: Paintables,\n loadImageService: ImageServiceLoaderType\n) {\n const imageTypes: ImageWithOptionalService[] = [];\n for (const singleImage of paintables.items) {\n // SingleImageStrategy\n const resource: IIIFExternalWebResource =\n singleImage.resource && singleImage.resource.type === 'SpecificResource'\n ? singleImage.resource.source\n : singleImage.resource;\n\n // Validation.\n if (!resource.id) {\n // @todo we could skip this?\n return unsupportedStrategy('No resource Identifier');\n }\n\n let imageService = undefined;\n if (resource.service) {\n const imageServices = getImageServices(resource as any) as any[];\n if (imageServices[0]) {\n imageService = loadImageService(imageServices[0], canvas);\n }\n }\n\n // Target is where it should be painted.\n const defaultTarget: BoxSelector = {\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: Number(canvas.width),\n height: Number(canvas.height),\n },\n };\n\n const [target, source] = getParsedTargetSelector(canvas, singleImage.target);\n if (!(source.id === canvas.id || decodeURIComponent(source.id || '') === (canvas.id || ''))) {\n // Skip invalid targets.\n continue;\n }\n\n // Support for cropping before painting an annotation.\n // @todo this isn't working.\n const defaultImageSelector =\n (singleImage.resource as any).width && (singleImage.resource as any).height\n ? ({\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: (singleImage.resource as any).width,\n height: (singleImage.resource as any).height,\n },\n } as BoxSelector)\n : undefined;\n\n let imageSelector = singleImage.resource.type === 'SpecificResource' ? expandTarget(singleImage.resource) : null;\n\n if (singleImage.selector) {\n const found = expandTarget({\n type: 'SpecificResource',\n source: singleImage.resource,\n selector: singleImage.selector,\n });\n\n if (found) {\n imageSelector = found;\n }\n }\n\n const selector: undefined | BoxSelector =\n imageSelector &&\n imageSelector.selector &&\n (imageSelector.selector.type === 'BoxSelector' || imageSelector.selector.type === 'TemporalBoxSelector')\n ? {\n type: 'BoxSelector',\n spatial: {\n x: imageSelector.selector.spatial.x,\n y: imageSelector.selector.spatial.y,\n width: imageSelector.selector.spatial.width,\n height: imageSelector.selector.spatial.height,\n },\n }\n : undefined;\n\n if (imageService && !imageService.id) {\n (imageService as any).id = imageService['@id'];\n }\n\n const imageType: ImageWithOptionalService = {\n id: resource.id,\n type: 'Image',\n annotationId: (singleImage as any).annotationId,\n width: Number(target || selector ? resource.width : canvas.width),\n height: Number(target || selector ? resource.height : canvas.height),\n service: imageService,\n sizes:\n imageService && imageService.sizes\n ? imageService.sizes\n : resource.width && resource.height\n ? [{ width: resource.width, height: resource.height }]\n : [],\n target: target && target.type !== 'PointSelector' ? target : defaultTarget,\n selector: selector,\n };\n\n imageTypes.push(imageType);\n }\n\n return {\n type: 'images',\n image: imageTypes[0],\n images: imageTypes,\n choice: paintables.choice,\n } as SingleImageStrategy;\n}\n","import { InternationalString } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { AnnotationPageDescription } from './resource-types';\nimport { getParsedTargetSelector } from './rendering-utils';\nimport { RenderingStrategy } from './strategies';\nimport { ChoiceDescription, Paintables, SupportedTarget } from '@iiif/helpers';\n\nexport type TextualContentStrategy = {\n type: 'textual-content';\n items: { annotationId: string; text: InternationalString; target: SupportedTarget | null }[];\n choice?: ChoiceDescription; // future\n annotations?: AnnotationPageDescription; // future\n};\n\nfunction parseType(item: any, languageMap: InternationalString = {}, lang?: string) {\n const language = item.language || lang || 'none';\n switch (item.type) {\n case 'TextualBody': {\n if (typeof item.value !== 'undefined') {\n languageMap[language] = item.value;\n }\n break;\n }\n case 'List':\n case 'Composite':\n case 'Choice': {\n if (item.items) {\n item.items.forEach((inner: any) => parseType(inner, languageMap, language));\n }\n }\n }\n return languageMap;\n}\n\nexport function getTextualContentStrategy(canvas: CanvasNormalized, paintables: Paintables): RenderingStrategy {\n const items: TextualContentStrategy['items'] = [];\n\n paintables.items.forEach((item) => {\n if (item.resource) {\n const [target] = getParsedTargetSelector(canvas, item.target);\n items.push({ annotationId: item.annotationId, text: parseType(item.resource), target: target as any });\n }\n });\n\n return {\n type: 'textual-content',\n items,\n } as TextualContentStrategy;\n}\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { MediaStrategy } from './strategies';\nimport { Paintables } from '@iiif/helpers';\n\n// https://stackoverflow.com/a/27728417\nconst ytRegex = /^.*(?:(?:youtu\\.be\\/|v\\/|vi\\/|u\\/\\w\\/|embed\\/|shorts\\/)|(?:(?:watch)?\\?vi?=|&vi?=))([^#&?]*).*/;\n\nexport function getVideoStrategy(canvas: CanvasNormalized, paintables: Paintables) {\n const videoPaintables = paintables.items.filter((t) => t.type === 'video');\n\n let noDuration = false;\n\n if (!canvas.duration) {\n noDuration = true;\n }\n\n if (videoPaintables.length > 1) {\n return unsupportedStrategy('Only one video source supported');\n }\n\n const videoResource = videoPaintables[0]?.resource as any; // @todo stronger type for what this might be.\n const isYouTube = !!(videoResource.service || []).find((service: any) =>\n (service.profile || '').includes('youtube.com')\n );\n\n if (!isYouTube && noDuration) {\n return unsupportedStrategy('Video does not have duration');\n }\n\n if (!videoResource) {\n return unsupportedStrategy('Unknown video');\n }\n\n if (!videoResource.format || videoResource.format === 'text/html') {\n if (!isYouTube) {\n return unsupportedStrategy('Video does not have format');\n }\n }\n\n const media = {\n annotationId: (paintables.items[0] as any).annotationId,\n duration: canvas.duration,\n url: videoResource.id,\n type: 'Video',\n items: [],\n target: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n format: videoResource.format,\n selector: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n };\n\n if (isYouTube) {\n media.type = 'VideoYouTube';\n const id = videoResource.id.match(ytRegex);\n if (!id[1]) {\n return unsupportedStrategy('Video is not known youtube video');\n }\n (media as any).youTubeId = id[1];\n }\n\n // @todo support VTT\n\n return {\n type: 'media',\n media,\n annotations: {\n pages: [],\n },\n } as MediaStrategy;\n}\n","import { get3dStrategy } from './3d-strategy';\nimport { getAudioStrategy } from './audio-strategy';\nimport { getImageStrategy } from './image-strategy';\nimport { emptyStrategy, unknownResponse, unsupportedStrategy } from './rendering-utils';\nimport { getTextualContentStrategy } from './textual-content-strategy';\nimport { getVideoStrategy } from './video-strategy';\nimport type { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport type { Paintables } from '@iiif/helpers/painting-annotations';\nimport type { ImageServiceLoaderType } from '../../hooks/useLoadImageService';\n\ninterface GetRenderStrategyOptions {\n canvas: CanvasNormalized | null | undefined;\n paintables: Paintables;\n supports: string[];\n loadImageService: ImageServiceLoaderType;\n}\n\nexport function getRenderingStrategy({ canvas, paintables, supports, loadImageService }: GetRenderStrategyOptions) {\n if (!canvas) {\n console.log('No canvas');\n return unknownResponse;\n }\n\n if (paintables.types.length === 0) {\n if (supports.indexOf('empty') !== -1) {\n return emptyStrategy(canvas.width, canvas.height);\n }\n console.log('No paintables');\n return unknownResponse;\n }\n\n if (paintables.types.length !== 1) {\n if (paintables.types.length === 2 && paintables.types.indexOf('text') !== -1) {\n paintables.types = paintables.types.filter((t) => t !== 'text');\n } else {\n if (supports.indexOf('complex-timeline') === -1) {\n return unsupportedStrategy('Complex timeline not supported');\n }\n return unsupportedStrategy('ComplexTimelineStrategy not yet supported');\n }\n }\n\n const mainType = paintables.types[0];\n\n // Image\n if (mainType === 'image') {\n if (supports.indexOf('images') === -1) {\n return unsupportedStrategy('Image not supported');\n }\n\n return getImageStrategy(canvas, paintables, loadImageService);\n }\n\n // 3D\n if (mainType === 'Model' || mainType === 'model') {\n if (supports.indexOf('3d-model') === -1) {\n return unsupportedStrategy('3D not supported');\n }\n\n return get3dStrategy(canvas, paintables);\n }\n\n if (mainType === 'textualbody') {\n if (supports.indexOf('textual-content') === -1) {\n return unsupportedStrategy('Textual content not supported');\n }\n\n return getTextualContentStrategy(canvas, paintables);\n }\n\n if (mainType === 'sound' || mainType === 'audio') {\n if (supports.indexOf('media') === -1) {\n return unsupportedStrategy('Media not supported');\n }\n\n // Media Strategy with audio or audio sequence.\n return getAudioStrategy(canvas, paintables);\n }\n\n if (mainType === 'video') {\n if (supports.indexOf('media') === -1) {\n return unsupportedStrategy('Media not supported');\n }\n\n // Media Strategy with video or video sequence.\n return getVideoStrategy(canvas, paintables);\n }\n\n // Unknown fallback.\n return unknownResponse;\n}\n"],"names":["parseSpecificResource","resource","getParsedTargetSelector","canvas","target","imageTarget","source","expandTarget","defaultTarget","emptyActions","unknownResponse","unsupportedStrategy","reason","emptyStrategy","width","height","supportedFormats","get3dStrategy","paintables","getAudioStrategy","audioResource","_a","getImageStrategy","loadImageService","imageTypes","singleImage","imageService","imageServices","getImageServices","imageSelector","found","selector","imageType","parseType","item","languageMap","lang","language","inner","getTextualContentStrategy","items","ytRegex","getVideoStrategy","videoPaintables","t","noDuration","videoResource","isYouTube","service","media","id","getRenderingStrategy","supports","mainType"],"mappings":"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"}
|
package/dist/utils/esm/utils.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { expandTarget as S } from "@iiif/helpers";
|
|
2
2
|
import { getImageServices as T } from "@atlas-viewer/iiif-image-api";
|
|
3
|
-
import { expandTarget as
|
|
4
|
-
function
|
|
3
|
+
import { expandTarget as g } from "@iiif/helpers/annotation-targets";
|
|
4
|
+
function b(e) {
|
|
5
5
|
return e.type === "SpecificResource" ? [e.source, { selector: e.selector }] : [e, { selector: null }];
|
|
6
6
|
}
|
|
7
|
-
function
|
|
7
|
+
function y(e, o) {
|
|
8
8
|
const { selector: r, source: i } = S(o);
|
|
9
9
|
if (i.id !== e.id)
|
|
10
10
|
return [null, i];
|
|
@@ -26,7 +26,7 @@ function g(e, o) {
|
|
|
26
26
|
i
|
|
27
27
|
];
|
|
28
28
|
}
|
|
29
|
-
const
|
|
29
|
+
const z = {
|
|
30
30
|
makeChoice: () => {
|
|
31
31
|
}
|
|
32
32
|
}, m = { type: "unknown" }, n = (e) => ({ type: "unknown", reason: e, annotations: { pages: [] } }), w = (e, o) => ({ type: "empty", width: e, height: o, annotations: { pages: [] }, image: null, images: [] }), I = ["model/gltf-binary"];
|
|
@@ -37,7 +37,7 @@ function O(e, o) {
|
|
|
37
37
|
model: i
|
|
38
38
|
} : n("Unknown format");
|
|
39
39
|
}
|
|
40
|
-
function
|
|
40
|
+
function R(e, o) {
|
|
41
41
|
var i;
|
|
42
42
|
if (!e.duration)
|
|
43
43
|
return n("No duration on canvas");
|
|
@@ -72,7 +72,7 @@ function N(e, o) {
|
|
|
72
72
|
}
|
|
73
73
|
} : n("Audio does not have format") : n("Unknown audio");
|
|
74
74
|
}
|
|
75
|
-
function
|
|
75
|
+
function N(e, o, r) {
|
|
76
76
|
const i = [];
|
|
77
77
|
for (const t of o.items) {
|
|
78
78
|
const u = t.resource && t.resource.type === "SpecificResource" ? t.resource.source : t.resource;
|
|
@@ -91,13 +91,13 @@ function R(e, o, r) {
|
|
|
91
91
|
width: Number(e.width),
|
|
92
92
|
height: Number(e.height)
|
|
93
93
|
}
|
|
94
|
-
}, [s,
|
|
95
|
-
if (
|
|
94
|
+
}, [s, p] = y(e, t.target);
|
|
95
|
+
if (!(p.id === e.id || decodeURIComponent(p.id || "") === (e.id || "")))
|
|
96
96
|
continue;
|
|
97
97
|
t.resource.width && t.resource.height && (t.resource.width, t.resource.height);
|
|
98
|
-
let c = t.resource.type === "SpecificResource" ?
|
|
98
|
+
let c = t.resource.type === "SpecificResource" ? g(t.resource) : null;
|
|
99
99
|
if (t.selector) {
|
|
100
|
-
const a =
|
|
100
|
+
const a = g({
|
|
101
101
|
type: "SpecificResource",
|
|
102
102
|
source: t.resource,
|
|
103
103
|
selector: t.selector
|
|
@@ -134,7 +134,7 @@ function R(e, o, r) {
|
|
|
134
134
|
choice: o.choice
|
|
135
135
|
};
|
|
136
136
|
}
|
|
137
|
-
function
|
|
137
|
+
function h(e, o = {}, r) {
|
|
138
138
|
const i = e.language || r || "none";
|
|
139
139
|
switch (e.type) {
|
|
140
140
|
case "TextualBody": {
|
|
@@ -144,7 +144,7 @@ function y(e, o = {}, r) {
|
|
|
144
144
|
case "List":
|
|
145
145
|
case "Composite":
|
|
146
146
|
case "Choice":
|
|
147
|
-
e.items && e.items.forEach((t) =>
|
|
147
|
+
e.items && e.items.forEach((t) => h(t, o, i));
|
|
148
148
|
}
|
|
149
149
|
return o;
|
|
150
150
|
}
|
|
@@ -152,8 +152,8 @@ function k(e, o) {
|
|
|
152
152
|
const r = [];
|
|
153
153
|
return o.items.forEach((i) => {
|
|
154
154
|
if (i.resource) {
|
|
155
|
-
const [t] =
|
|
156
|
-
r.push({ annotationId: i.annotationId, text:
|
|
155
|
+
const [t] = y(e, i.target);
|
|
156
|
+
r.push({ annotationId: i.annotationId, text: h(i.resource), target: t });
|
|
157
157
|
}
|
|
158
158
|
}), {
|
|
159
159
|
type: "textual-content",
|
|
@@ -161,7 +161,7 @@ function k(e, o) {
|
|
|
161
161
|
};
|
|
162
162
|
}
|
|
163
163
|
const B = /^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/|shorts\/)|(?:(?:watch)?\?vi?=|&vi?=))([^#&?]*).*/;
|
|
164
|
-
function
|
|
164
|
+
function C(e, o) {
|
|
165
165
|
var f;
|
|
166
166
|
const r = o.items.filter((s) => s.type === "video");
|
|
167
167
|
let i = !1;
|
|
@@ -213,7 +213,7 @@ function v(e, o) {
|
|
|
213
213
|
}
|
|
214
214
|
};
|
|
215
215
|
}
|
|
216
|
-
function
|
|
216
|
+
function A({ canvas: e, paintables: o, supports: r, loadImageService: i }) {
|
|
217
217
|
if (!e)
|
|
218
218
|
return console.log("No canvas"), m;
|
|
219
219
|
if (o.types.length === 0)
|
|
@@ -224,14 +224,14 @@ function D({ canvas: e, paintables: o, supports: r, loadImageService: i }) {
|
|
|
224
224
|
else
|
|
225
225
|
return r.indexOf("complex-timeline") === -1 ? n("Complex timeline not supported") : n("ComplexTimelineStrategy not yet supported");
|
|
226
226
|
const t = o.types[0];
|
|
227
|
-
return t === "image" ? r.indexOf("images") === -1 ? n("Image not supported") :
|
|
227
|
+
return t === "image" ? r.indexOf("images") === -1 ? n("Image not supported") : N(e, o, i) : t === "Model" || t === "model" ? r.indexOf("3d-model") === -1 ? n("3D not supported") : O(e, o) : t === "textualbody" ? r.indexOf("textual-content") === -1 ? n("Textual content not supported") : k(e, o) : t === "sound" || t === "audio" ? r.indexOf("media") === -1 ? n("Media not supported") : R(e, o) : t === "video" ? r.indexOf("media") === -1 ? n("Media not supported") : C(e, o) : m;
|
|
228
228
|
}
|
|
229
229
|
export {
|
|
230
|
-
|
|
230
|
+
z as emptyActions,
|
|
231
231
|
w as emptyStrategy,
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
232
|
+
y as getParsedTargetSelector,
|
|
233
|
+
A as getRenderingStrategy,
|
|
234
|
+
b as parseSpecificResource,
|
|
235
235
|
m as unknownResponse,
|
|
236
236
|
n as unsupportedStrategy
|
|
237
237
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.mjs","sources":["../../../src/features/rendering-strategy/rendering-utils.ts","../../../src/features/rendering-strategy/3d-strategy.ts","../../../src/features/rendering-strategy/audio-strategy.ts","../../../src/features/rendering-strategy/image-strategy.ts","../../../src/features/rendering-strategy/textual-content-strategy.ts","../../../src/features/rendering-strategy/video-strategy.ts","../../../src/features/rendering-strategy/get-rendering-strategy.ts"],"sourcesContent":["import { ContentResource, PointSelector, W3CAnnotationTarget } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { UseRenderingStrategy } from '../../hooks/useRenderingStrategy';\nimport { BoxSelector, expandTarget, SupportedTarget, TemporalBoxSelector } from '@iiif/helpers';\n\n/**\n * Parse specific resource.\n *\n * This could be expanded to support pulling out more from the specific resource.\n *\n * @param resource\n */\nexport function parseSpecificResource(resource: ContentResource) {\n if (resource.type === 'SpecificResource') {\n return [resource.source, { selector: resource.selector }];\n }\n\n return [resource, { selector: null }];\n}\n\nexport function getParsedTargetSelector(\n canvas: CanvasNormalized,\n target: W3CAnnotationTarget | W3CAnnotationTarget[]\n): [TemporalBoxSelector | BoxSelector | PointSelector | null, SupportedTarget['source']] {\n const { selector: imageTarget, source } = expandTarget(target);\n\n if (source.id !== canvas.id) {\n // Skip invalid targets.\n return [null, source];\n }\n\n // Target is where it should be painted.\n const defaultTarget: BoxSelector = {\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: Number(canvas.width),\n height: Number(canvas.height),\n },\n };\n\n return [\n imageTarget\n ? imageTarget.type === 'TemporalSelector'\n ? ({\n type: 'TemporalBoxSelector',\n temporal: imageTarget.temporal,\n spatial: defaultTarget.spatial,\n } as any)\n : imageTarget\n : null,\n source,\n ];\n}\n\nexport const emptyActions = {\n makeChoice: () => {\n // no-op\n },\n};\n\nexport const unknownResponse: UseRenderingStrategy[0] = { type: 'unknown' };\n\nexport const unsupportedStrategy = (reason: string): UseRenderingStrategy[0] => {\n return { type: 'unknown', reason, annotations: { pages: [] } };\n};\n\nexport const emptyStrategy = (width: number, height: number): UseRenderingStrategy[0] => {\n return { type: 'empty', width, height, annotations: { pages: [] }, image: null, images: [] };\n};\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { AnnotationPageDescription } from './resource-types';\nimport { ExternalWebResource } from '@iiif/presentation-3';\nimport { RenderingStrategy } from './strategies';\nimport { ChoiceDescription, Paintables } from '@iiif/helpers';\n\nexport type Single3DModelStrategy = {\n type: '3d-model';\n model: ExternalWebResource;\n choice?: ChoiceDescription; // future\n annotations?: AnnotationPageDescription; // future\n};\n\nconst supportedFormats = ['model/gltf-binary'];\n\nexport function get3dStrategy(canvas: CanvasNormalized, paintables: Paintables): RenderingStrategy {\n const first = paintables.items[0];\n const resource = first.resource as ExternalWebResource;\n\n if (!resource.format) {\n return unsupportedStrategy('Unknown format');\n }\n\n if (supportedFormats.indexOf(resource.format) === -1) {\n return unsupportedStrategy(`3D format: ${resource.format} is unsupported`);\n }\n\n return {\n type: '3d-model',\n model: resource as any,\n } as Single3DModelStrategy;\n}\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { MediaStrategy } from './strategies';\nimport { Paintables } from '@iiif/helpers';\n\nexport function getAudioStrategy(canvas: CanvasNormalized, paintables: Paintables) {\n if (!canvas.duration) {\n return unsupportedStrategy('No duration on canvas');\n }\n\n if (paintables.items.length > 1) {\n return unsupportedStrategy('Only one audio source supported');\n }\n\n const audioResource = paintables.items[0]?.resource as any; // @todo stronger type for what this might be.\n\n if (!audioResource) {\n return unsupportedStrategy('Unknown audio');\n }\n\n if (!audioResource.format) {\n return unsupportedStrategy('Audio does not have format');\n }\n\n return {\n type: 'media',\n media: {\n annotationId: paintables.items[0].annotationId,\n duration: canvas.duration,\n url: audioResource.id,\n type: 'Sound',\n target: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n format: audioResource.format,\n selector: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n },\n annotations: {\n pages: [],\n },\n } as MediaStrategy;\n}\n","import { IIIFExternalWebResource } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { ImageServiceLoaderType } from '../../hooks/useLoadImageService';\nimport { AnnotationPageDescription, ImageWithOptionalService } from './resource-types';\nimport { getImageServices } from '@atlas-viewer/iiif-image-api';\nimport { getParsedTargetSelector, unsupportedStrategy } from './rendering-utils';\nimport { expandTarget } from '@iiif/helpers/annotation-targets';\nimport { BoxSelector, ChoiceDescription, Paintables } from '@iiif/helpers';\n\nexport type SingleImageStrategy = {\n type: 'images';\n image: ImageWithOptionalService;\n images: Array<ImageWithOptionalService>;\n choice?: ChoiceDescription;\n annotations?: AnnotationPageDescription;\n};\n\nexport function getImageStrategy(\n canvas: CanvasNormalized,\n paintables: Paintables,\n loadImageService: ImageServiceLoaderType\n) {\n const imageTypes: ImageWithOptionalService[] = [];\n for (const singleImage of paintables.items) {\n // SingleImageStrategy\n const resource: IIIFExternalWebResource =\n singleImage.resource && singleImage.resource.type === 'SpecificResource'\n ? singleImage.resource.source\n : singleImage.resource;\n\n // Validation.\n if (!resource.id) {\n // @todo we could skip this?\n return unsupportedStrategy('No resource Identifier');\n }\n\n let imageService = undefined;\n if (resource.service) {\n const imageServices = getImageServices(resource as any) as any[];\n if (imageServices[0]) {\n imageService = loadImageService(imageServices[0], canvas);\n }\n }\n\n // Target is where it should be painted.\n const defaultTarget: BoxSelector = {\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: Number(canvas.width),\n height: Number(canvas.height),\n },\n };\n\n const [target, source] = getParsedTargetSelector(canvas, singleImage.target);\n if (source.id !== canvas.id) {\n // Skip invalid targets.\n continue;\n }\n\n // Support for cropping before painting an annotation.\n // @todo this isn't working.\n const defaultImageSelector =\n (singleImage.resource as any).width && (singleImage.resource as any).height\n ? ({\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: (singleImage.resource as any).width,\n height: (singleImage.resource as any).height,\n },\n } as BoxSelector)\n : undefined;\n\n let imageSelector = singleImage.resource.type === 'SpecificResource' ? expandTarget(singleImage.resource) : null;\n\n if (singleImage.selector) {\n const found = expandTarget({\n type: 'SpecificResource',\n source: singleImage.resource,\n selector: singleImage.selector,\n });\n\n if (found) {\n imageSelector = found;\n }\n }\n\n const selector: undefined | BoxSelector =\n imageSelector &&\n imageSelector.selector &&\n (imageSelector.selector.type === 'BoxSelector' || imageSelector.selector.type === 'TemporalBoxSelector')\n ? {\n type: 'BoxSelector',\n spatial: {\n x: imageSelector.selector.spatial.x,\n y: imageSelector.selector.spatial.y,\n width: imageSelector.selector.spatial.width,\n height: imageSelector.selector.spatial.height,\n },\n }\n : undefined;\n\n if (imageService && !imageService.id) {\n (imageService as any).id = imageService['@id'];\n }\n\n const imageType: ImageWithOptionalService = {\n id: resource.id,\n type: 'Image',\n annotationId: (singleImage as any).annotationId,\n width: Number(target || selector ? resource.width : canvas.width),\n height: Number(target || selector ? resource.height : canvas.height),\n service: imageService,\n sizes:\n imageService && imageService.sizes\n ? imageService.sizes\n : resource.width && resource.height\n ? [{ width: resource.width, height: resource.height }]\n : [],\n target: target && target.type !== 'PointSelector' ? target : defaultTarget,\n selector: selector,\n };\n\n imageTypes.push(imageType);\n }\n\n return {\n type: 'images',\n image: imageTypes[0],\n images: imageTypes,\n choice: paintables.choice,\n } as SingleImageStrategy;\n}\n","import { InternationalString } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { AnnotationPageDescription } from './resource-types';\nimport { getParsedTargetSelector } from './rendering-utils';\nimport { RenderingStrategy } from './strategies';\nimport { ChoiceDescription, Paintables, SupportedTarget } from '@iiif/helpers';\n\nexport type TextualContentStrategy = {\n type: 'textual-content';\n items: { annotationId: string; text: InternationalString; target: SupportedTarget | null }[];\n choice?: ChoiceDescription; // future\n annotations?: AnnotationPageDescription; // future\n};\n\nfunction parseType(item: any, languageMap: InternationalString = {}, lang?: string) {\n const language = item.language || lang || 'none';\n switch (item.type) {\n case 'TextualBody': {\n if (typeof item.value !== 'undefined') {\n languageMap[language] = item.value;\n }\n break;\n }\n case 'List':\n case 'Composite':\n case 'Choice': {\n if (item.items) {\n item.items.forEach((inner: any) => parseType(inner, languageMap, language));\n }\n }\n }\n return languageMap;\n}\n\nexport function getTextualContentStrategy(canvas: CanvasNormalized, paintables: Paintables): RenderingStrategy {\n const items: TextualContentStrategy['items'] = [];\n\n paintables.items.forEach((item) => {\n if (item.resource) {\n const [target] = getParsedTargetSelector(canvas, item.target);\n items.push({ annotationId: item.annotationId, text: parseType(item.resource), target: target as any });\n }\n });\n\n return {\n type: 'textual-content',\n items,\n } as TextualContentStrategy;\n}\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { MediaStrategy } from './strategies';\nimport { Paintables } from '@iiif/helpers';\n\n// https://stackoverflow.com/a/27728417\nconst ytRegex = /^.*(?:(?:youtu\\.be\\/|v\\/|vi\\/|u\\/\\w\\/|embed\\/|shorts\\/)|(?:(?:watch)?\\?vi?=|&vi?=))([^#&?]*).*/;\n\nexport function getVideoStrategy(canvas: CanvasNormalized, paintables: Paintables) {\n const videoPaintables = paintables.items.filter((t) => t.type === 'video');\n\n let noDuration = false;\n\n if (!canvas.duration) {\n noDuration = true;\n }\n\n if (videoPaintables.length > 1) {\n return unsupportedStrategy('Only one video source supported');\n }\n\n const videoResource = videoPaintables[0]?.resource as any; // @todo stronger type for what this might be.\n const isYouTube = !!(videoResource.service || []).find((service: any) =>\n (service.profile || '').includes('youtube.com')\n );\n\n if (!isYouTube && noDuration) {\n return unsupportedStrategy('Video does not have duration');\n }\n\n if (!videoResource) {\n return unsupportedStrategy('Unknown video');\n }\n\n if (!videoResource.format || videoResource.format === 'text/html') {\n if (!isYouTube) {\n return unsupportedStrategy('Video does not have format');\n }\n }\n\n const media = {\n annotationId: (paintables.items[0] as any).annotationId,\n duration: canvas.duration,\n url: videoResource.id,\n type: 'Video',\n items: [],\n target: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n format: videoResource.format,\n selector: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n };\n\n if (isYouTube) {\n media.type = 'VideoYouTube';\n const id = videoResource.id.match(ytRegex);\n if (!id[1]) {\n return unsupportedStrategy('Video is not known youtube video');\n }\n (media as any).youTubeId = id[1];\n }\n\n // @todo support VTT\n\n return {\n type: 'media',\n media,\n annotations: {\n pages: [],\n },\n } as MediaStrategy;\n}\n","import { get3dStrategy } from './3d-strategy';\nimport { getAudioStrategy } from './audio-strategy';\nimport { getImageStrategy } from './image-strategy';\nimport { emptyStrategy, unknownResponse, unsupportedStrategy } from './rendering-utils';\nimport { getTextualContentStrategy } from './textual-content-strategy';\nimport { getVideoStrategy } from './video-strategy';\nimport type { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport type { Paintables } from '@iiif/helpers/painting-annotations';\nimport type { ImageServiceLoaderType } from '../../hooks/useLoadImageService';\n\ninterface GetRenderStrategyOptions {\n canvas: CanvasNormalized | null | undefined;\n paintables: Paintables;\n supports: string[];\n loadImageService: ImageServiceLoaderType;\n}\n\nexport function getRenderingStrategy({ canvas, paintables, supports, loadImageService }: GetRenderStrategyOptions) {\n if (!canvas) {\n console.log('No canvas');\n return unknownResponse;\n }\n\n if (paintables.types.length === 0) {\n if (supports.indexOf('empty') !== -1) {\n return emptyStrategy(canvas.width, canvas.height);\n }\n console.log('No paintables');\n return unknownResponse;\n }\n\n if (paintables.types.length !== 1) {\n if (paintables.types.length === 2 && paintables.types.indexOf('text') !== -1) {\n paintables.types = paintables.types.filter((t) => t !== 'text');\n } else {\n if (supports.indexOf('complex-timeline') === -1) {\n return unsupportedStrategy('Complex timeline not supported');\n }\n return unsupportedStrategy('ComplexTimelineStrategy not yet supported');\n }\n }\n\n const mainType = paintables.types[0];\n\n // Image\n if (mainType === 'image') {\n if (supports.indexOf('images') === -1) {\n return unsupportedStrategy('Image not supported');\n }\n\n return getImageStrategy(canvas, paintables, loadImageService);\n }\n\n // 3D\n if (mainType === 'Model' || mainType === 'model') {\n if (supports.indexOf('3d-model') === -1) {\n return unsupportedStrategy('3D not supported');\n }\n\n return get3dStrategy(canvas, paintables);\n }\n\n if (mainType === 'textualbody') {\n if (supports.indexOf('textual-content') === -1) {\n return unsupportedStrategy('Textual content not supported');\n }\n\n return getTextualContentStrategy(canvas, paintables);\n }\n\n if (mainType === 'sound' || mainType === 'audio') {\n if (supports.indexOf('media') === -1) {\n return unsupportedStrategy('Media not supported');\n }\n\n // Media Strategy with audio or audio sequence.\n return getAudioStrategy(canvas, paintables);\n }\n\n if (mainType === 'video') {\n if (supports.indexOf('media') === -1) {\n return unsupportedStrategy('Media not supported');\n }\n\n // Media Strategy with video or video sequence.\n return getVideoStrategy(canvas, paintables);\n }\n\n // Unknown fallback.\n return unknownResponse;\n}\n"],"names":["parseSpecificResource","resource","getParsedTargetSelector","canvas","target","imageTarget","source","expandTarget","defaultTarget","emptyActions","unknownResponse","unsupportedStrategy","reason","emptyStrategy","width","height","supportedFormats","get3dStrategy","paintables","getAudioStrategy","audioResource","_a","getImageStrategy","loadImageService","imageTypes","singleImage","imageService","imageServices","getImageServices","imageSelector","found","selector","imageType","parseType","item","languageMap","lang","language","inner","getTextualContentStrategy","items","ytRegex","getVideoStrategy","videoPaintables","t","noDuration","videoResource","isYouTube","service","media","id","getRenderingStrategy","supports","mainType"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils.mjs","sources":["../../../src/features/rendering-strategy/rendering-utils.ts","../../../src/features/rendering-strategy/3d-strategy.ts","../../../src/features/rendering-strategy/audio-strategy.ts","../../../src/features/rendering-strategy/image-strategy.ts","../../../src/features/rendering-strategy/textual-content-strategy.ts","../../../src/features/rendering-strategy/video-strategy.ts","../../../src/features/rendering-strategy/get-rendering-strategy.ts"],"sourcesContent":["import { ContentResource, PointSelector, W3CAnnotationTarget } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { UseRenderingStrategy } from '../../hooks/useRenderingStrategy';\nimport { BoxSelector, expandTarget, SupportedTarget, TemporalBoxSelector } from '@iiif/helpers';\n\n/**\n * Parse specific resource.\n *\n * This could be expanded to support pulling out more from the specific resource.\n *\n * @param resource\n */\nexport function parseSpecificResource(resource: ContentResource) {\n if (resource.type === 'SpecificResource') {\n return [resource.source, { selector: resource.selector }];\n }\n\n return [resource, { selector: null }];\n}\n\nexport function getParsedTargetSelector(\n canvas: CanvasNormalized,\n target: W3CAnnotationTarget | W3CAnnotationTarget[]\n): [TemporalBoxSelector | BoxSelector | PointSelector | null, SupportedTarget['source']] {\n const { selector: imageTarget, source } = expandTarget(target);\n\n if (source.id !== canvas.id) {\n // Skip invalid targets.\n return [null, source];\n }\n\n // Target is where it should be painted.\n const defaultTarget: BoxSelector = {\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: Number(canvas.width),\n height: Number(canvas.height),\n },\n };\n\n return [\n imageTarget\n ? imageTarget.type === 'TemporalSelector'\n ? ({\n type: 'TemporalBoxSelector',\n temporal: imageTarget.temporal,\n spatial: defaultTarget.spatial,\n } as any)\n : imageTarget\n : null,\n source,\n ];\n}\n\nexport const emptyActions = {\n makeChoice: () => {\n // no-op\n },\n};\n\nexport const unknownResponse: UseRenderingStrategy[0] = { type: 'unknown' };\n\nexport const unsupportedStrategy = (reason: string): UseRenderingStrategy[0] => {\n return { type: 'unknown', reason, annotations: { pages: [] } };\n};\n\nexport const emptyStrategy = (width: number, height: number): UseRenderingStrategy[0] => {\n return { type: 'empty', width, height, annotations: { pages: [] }, image: null, images: [] };\n};\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { AnnotationPageDescription } from './resource-types';\nimport { ExternalWebResource } from '@iiif/presentation-3';\nimport { RenderingStrategy } from './strategies';\nimport { ChoiceDescription, Paintables } from '@iiif/helpers';\n\nexport type Single3DModelStrategy = {\n type: '3d-model';\n model: ExternalWebResource;\n choice?: ChoiceDescription; // future\n annotations?: AnnotationPageDescription; // future\n};\n\nconst supportedFormats = ['model/gltf-binary'];\n\nexport function get3dStrategy(canvas: CanvasNormalized, paintables: Paintables): RenderingStrategy {\n const first = paintables.items[0];\n const resource = first.resource as ExternalWebResource;\n\n if (!resource.format) {\n return unsupportedStrategy('Unknown format');\n }\n\n if (supportedFormats.indexOf(resource.format) === -1) {\n return unsupportedStrategy(`3D format: ${resource.format} is unsupported`);\n }\n\n return {\n type: '3d-model',\n model: resource as any,\n } as Single3DModelStrategy;\n}\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { MediaStrategy } from './strategies';\nimport { Paintables } from '@iiif/helpers';\n\nexport function getAudioStrategy(canvas: CanvasNormalized, paintables: Paintables) {\n if (!canvas.duration) {\n return unsupportedStrategy('No duration on canvas');\n }\n\n if (paintables.items.length > 1) {\n return unsupportedStrategy('Only one audio source supported');\n }\n\n const audioResource = paintables.items[0]?.resource as any; // @todo stronger type for what this might be.\n\n if (!audioResource) {\n return unsupportedStrategy('Unknown audio');\n }\n\n if (!audioResource.format) {\n return unsupportedStrategy('Audio does not have format');\n }\n\n return {\n type: 'media',\n media: {\n annotationId: paintables.items[0].annotationId,\n duration: canvas.duration,\n url: audioResource.id,\n type: 'Sound',\n target: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n format: audioResource.format,\n selector: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n },\n annotations: {\n pages: [],\n },\n } as MediaStrategy;\n}\n","import { IIIFExternalWebResource } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { ImageServiceLoaderType } from '../../hooks/useLoadImageService';\nimport { AnnotationPageDescription, ImageWithOptionalService } from './resource-types';\nimport { getImageServices } from '@atlas-viewer/iiif-image-api';\nimport { getParsedTargetSelector, unsupportedStrategy } from './rendering-utils';\nimport { expandTarget } from '@iiif/helpers/annotation-targets';\nimport { BoxSelector, ChoiceDescription, Paintables } from '@iiif/helpers';\n\nexport type SingleImageStrategy = {\n type: 'images';\n image: ImageWithOptionalService;\n images: Array<ImageWithOptionalService>;\n choice?: ChoiceDescription;\n annotations?: AnnotationPageDescription;\n};\n\nexport function getImageStrategy(\n canvas: CanvasNormalized,\n paintables: Paintables,\n loadImageService: ImageServiceLoaderType\n) {\n const imageTypes: ImageWithOptionalService[] = [];\n for (const singleImage of paintables.items) {\n // SingleImageStrategy\n const resource: IIIFExternalWebResource =\n singleImage.resource && singleImage.resource.type === 'SpecificResource'\n ? singleImage.resource.source\n : singleImage.resource;\n\n // Validation.\n if (!resource.id) {\n // @todo we could skip this?\n return unsupportedStrategy('No resource Identifier');\n }\n\n let imageService = undefined;\n if (resource.service) {\n const imageServices = getImageServices(resource as any) as any[];\n if (imageServices[0]) {\n imageService = loadImageService(imageServices[0], canvas);\n }\n }\n\n // Target is where it should be painted.\n const defaultTarget: BoxSelector = {\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: Number(canvas.width),\n height: Number(canvas.height),\n },\n };\n\n const [target, source] = getParsedTargetSelector(canvas, singleImage.target);\n if (!(source.id === canvas.id || decodeURIComponent(source.id || '') === (canvas.id || ''))) {\n // Skip invalid targets.\n continue;\n }\n\n // Support for cropping before painting an annotation.\n // @todo this isn't working.\n const defaultImageSelector =\n (singleImage.resource as any).width && (singleImage.resource as any).height\n ? ({\n type: 'BoxSelector',\n spatial: {\n x: 0,\n y: 0,\n width: (singleImage.resource as any).width,\n height: (singleImage.resource as any).height,\n },\n } as BoxSelector)\n : undefined;\n\n let imageSelector = singleImage.resource.type === 'SpecificResource' ? expandTarget(singleImage.resource) : null;\n\n if (singleImage.selector) {\n const found = expandTarget({\n type: 'SpecificResource',\n source: singleImage.resource,\n selector: singleImage.selector,\n });\n\n if (found) {\n imageSelector = found;\n }\n }\n\n const selector: undefined | BoxSelector =\n imageSelector &&\n imageSelector.selector &&\n (imageSelector.selector.type === 'BoxSelector' || imageSelector.selector.type === 'TemporalBoxSelector')\n ? {\n type: 'BoxSelector',\n spatial: {\n x: imageSelector.selector.spatial.x,\n y: imageSelector.selector.spatial.y,\n width: imageSelector.selector.spatial.width,\n height: imageSelector.selector.spatial.height,\n },\n }\n : undefined;\n\n if (imageService && !imageService.id) {\n (imageService as any).id = imageService['@id'];\n }\n\n const imageType: ImageWithOptionalService = {\n id: resource.id,\n type: 'Image',\n annotationId: (singleImage as any).annotationId,\n width: Number(target || selector ? resource.width : canvas.width),\n height: Number(target || selector ? resource.height : canvas.height),\n service: imageService,\n sizes:\n imageService && imageService.sizes\n ? imageService.sizes\n : resource.width && resource.height\n ? [{ width: resource.width, height: resource.height }]\n : [],\n target: target && target.type !== 'PointSelector' ? target : defaultTarget,\n selector: selector,\n };\n\n imageTypes.push(imageType);\n }\n\n return {\n type: 'images',\n image: imageTypes[0],\n images: imageTypes,\n choice: paintables.choice,\n } as SingleImageStrategy;\n}\n","import { InternationalString } from '@iiif/presentation-3';\nimport { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { AnnotationPageDescription } from './resource-types';\nimport { getParsedTargetSelector } from './rendering-utils';\nimport { RenderingStrategy } from './strategies';\nimport { ChoiceDescription, Paintables, SupportedTarget } from '@iiif/helpers';\n\nexport type TextualContentStrategy = {\n type: 'textual-content';\n items: { annotationId: string; text: InternationalString; target: SupportedTarget | null }[];\n choice?: ChoiceDescription; // future\n annotations?: AnnotationPageDescription; // future\n};\n\nfunction parseType(item: any, languageMap: InternationalString = {}, lang?: string) {\n const language = item.language || lang || 'none';\n switch (item.type) {\n case 'TextualBody': {\n if (typeof item.value !== 'undefined') {\n languageMap[language] = item.value;\n }\n break;\n }\n case 'List':\n case 'Composite':\n case 'Choice': {\n if (item.items) {\n item.items.forEach((inner: any) => parseType(inner, languageMap, language));\n }\n }\n }\n return languageMap;\n}\n\nexport function getTextualContentStrategy(canvas: CanvasNormalized, paintables: Paintables): RenderingStrategy {\n const items: TextualContentStrategy['items'] = [];\n\n paintables.items.forEach((item) => {\n if (item.resource) {\n const [target] = getParsedTargetSelector(canvas, item.target);\n items.push({ annotationId: item.annotationId, text: parseType(item.resource), target: target as any });\n }\n });\n\n return {\n type: 'textual-content',\n items,\n } as TextualContentStrategy;\n}\n","import { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport { unsupportedStrategy } from './rendering-utils';\nimport { MediaStrategy } from './strategies';\nimport { Paintables } from '@iiif/helpers';\n\n// https://stackoverflow.com/a/27728417\nconst ytRegex = /^.*(?:(?:youtu\\.be\\/|v\\/|vi\\/|u\\/\\w\\/|embed\\/|shorts\\/)|(?:(?:watch)?\\?vi?=|&vi?=))([^#&?]*).*/;\n\nexport function getVideoStrategy(canvas: CanvasNormalized, paintables: Paintables) {\n const videoPaintables = paintables.items.filter((t) => t.type === 'video');\n\n let noDuration = false;\n\n if (!canvas.duration) {\n noDuration = true;\n }\n\n if (videoPaintables.length > 1) {\n return unsupportedStrategy('Only one video source supported');\n }\n\n const videoResource = videoPaintables[0]?.resource as any; // @todo stronger type for what this might be.\n const isYouTube = !!(videoResource.service || []).find((service: any) =>\n (service.profile || '').includes('youtube.com')\n );\n\n if (!isYouTube && noDuration) {\n return unsupportedStrategy('Video does not have duration');\n }\n\n if (!videoResource) {\n return unsupportedStrategy('Unknown video');\n }\n\n if (!videoResource.format || videoResource.format === 'text/html') {\n if (!isYouTube) {\n return unsupportedStrategy('Video does not have format');\n }\n }\n\n const media = {\n annotationId: (paintables.items[0] as any).annotationId,\n duration: canvas.duration,\n url: videoResource.id,\n type: 'Video',\n items: [],\n target: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n format: videoResource.format,\n selector: {\n type: 'TemporalSelector',\n temporal: {\n startTime: 0,\n endTime: canvas.duration,\n },\n },\n };\n\n if (isYouTube) {\n media.type = 'VideoYouTube';\n const id = videoResource.id.match(ytRegex);\n if (!id[1]) {\n return unsupportedStrategy('Video is not known youtube video');\n }\n (media as any).youTubeId = id[1];\n }\n\n // @todo support VTT\n\n return {\n type: 'media',\n media,\n annotations: {\n pages: [],\n },\n } as MediaStrategy;\n}\n","import { get3dStrategy } from './3d-strategy';\nimport { getAudioStrategy } from './audio-strategy';\nimport { getImageStrategy } from './image-strategy';\nimport { emptyStrategy, unknownResponse, unsupportedStrategy } from './rendering-utils';\nimport { getTextualContentStrategy } from './textual-content-strategy';\nimport { getVideoStrategy } from './video-strategy';\nimport type { CanvasNormalized } from '@iiif/presentation-3-normalized';\nimport type { Paintables } from '@iiif/helpers/painting-annotations';\nimport type { ImageServiceLoaderType } from '../../hooks/useLoadImageService';\n\ninterface GetRenderStrategyOptions {\n canvas: CanvasNormalized | null | undefined;\n paintables: Paintables;\n supports: string[];\n loadImageService: ImageServiceLoaderType;\n}\n\nexport function getRenderingStrategy({ canvas, paintables, supports, loadImageService }: GetRenderStrategyOptions) {\n if (!canvas) {\n console.log('No canvas');\n return unknownResponse;\n }\n\n if (paintables.types.length === 0) {\n if (supports.indexOf('empty') !== -1) {\n return emptyStrategy(canvas.width, canvas.height);\n }\n console.log('No paintables');\n return unknownResponse;\n }\n\n if (paintables.types.length !== 1) {\n if (paintables.types.length === 2 && paintables.types.indexOf('text') !== -1) {\n paintables.types = paintables.types.filter((t) => t !== 'text');\n } else {\n if (supports.indexOf('complex-timeline') === -1) {\n return unsupportedStrategy('Complex timeline not supported');\n }\n return unsupportedStrategy('ComplexTimelineStrategy not yet supported');\n }\n }\n\n const mainType = paintables.types[0];\n\n // Image\n if (mainType === 'image') {\n if (supports.indexOf('images') === -1) {\n return unsupportedStrategy('Image not supported');\n }\n\n return getImageStrategy(canvas, paintables, loadImageService);\n }\n\n // 3D\n if (mainType === 'Model' || mainType === 'model') {\n if (supports.indexOf('3d-model') === -1) {\n return unsupportedStrategy('3D not supported');\n }\n\n return get3dStrategy(canvas, paintables);\n }\n\n if (mainType === 'textualbody') {\n if (supports.indexOf('textual-content') === -1) {\n return unsupportedStrategy('Textual content not supported');\n }\n\n return getTextualContentStrategy(canvas, paintables);\n }\n\n if (mainType === 'sound' || mainType === 'audio') {\n if (supports.indexOf('media') === -1) {\n return unsupportedStrategy('Media not supported');\n }\n\n // Media Strategy with audio or audio sequence.\n return getAudioStrategy(canvas, paintables);\n }\n\n if (mainType === 'video') {\n if (supports.indexOf('media') === -1) {\n return unsupportedStrategy('Media not supported');\n }\n\n // Media Strategy with video or video sequence.\n return getVideoStrategy(canvas, paintables);\n }\n\n // Unknown fallback.\n return unknownResponse;\n}\n"],"names":["parseSpecificResource","resource","getParsedTargetSelector","canvas","target","imageTarget","source","expandTarget","defaultTarget","emptyActions","unknownResponse","unsupportedStrategy","reason","emptyStrategy","width","height","supportedFormats","get3dStrategy","paintables","getAudioStrategy","audioResource","_a","getImageStrategy","loadImageService","imageTypes","singleImage","imageService","imageServices","getImageServices","imageSelector","found","selector","imageType","parseType","item","languageMap","lang","language","inner","getTextualContentStrategy","items","ytRegex","getVideoStrategy","videoPaintables","t","noDuration","videoResource","isYouTube","service","media","id","getRenderingStrategy","supports","mainType"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-iiif-vault",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"main": "dist/bundle/cjs/index.js",
|
|
5
5
|
"module": "dist/bundle/esm/index.mjs",
|
|
6
6
|
"types": ".build/types/index.d.ts",
|
|
@@ -55,42 +55,44 @@
|
|
|
55
55
|
},
|
|
56
56
|
"license": "MIT",
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@atlas-viewer/atlas": ">=2.0.
|
|
58
|
+
"@atlas-viewer/atlas": ">=2.0.6",
|
|
59
59
|
"@atlas-viewer/iiif-image-api": ">=2.1.1",
|
|
60
|
-
"@iiif/
|
|
60
|
+
"@iiif/helpers": ">=1.0.6",
|
|
61
|
+
"@iiif/parser": ">=2.0.2",
|
|
61
62
|
"@iiif/presentation-2": ">=1.*",
|
|
62
63
|
"@iiif/presentation-3": ">=2.1.3",
|
|
63
64
|
"@iiif/presentation-3-normalized": ">=0.9.7",
|
|
64
|
-
"@iiif/helpers": ">=1.0.4",
|
|
65
65
|
"react": "^16.10.2 || ^17.0.2 || ^18.2.0",
|
|
66
66
|
"react-dom": "^16.10.2 || ^17.0.2 || ^18.2.0",
|
|
67
|
-
"react-error-boundary": "^
|
|
67
|
+
"react-error-boundary": "^4.0.12",
|
|
68
|
+
"react-lazy-load-image-component": "^1.6.0"
|
|
68
69
|
},
|
|
69
70
|
"devDependencies": {
|
|
70
|
-
"@testing-library/react": "^
|
|
71
|
-
"@testing-library/react-hooks": "^
|
|
72
|
-
"@types/react": "^18.
|
|
73
|
-
"@types/react-dom": "^18.
|
|
74
|
-
"@
|
|
75
|
-
"@typescript-eslint/
|
|
76
|
-
"@
|
|
77
|
-
"
|
|
78
|
-
"
|
|
71
|
+
"@testing-library/react": "^14.2.1",
|
|
72
|
+
"@testing-library/react-hooks": "^8.0.1",
|
|
73
|
+
"@types/react": "^18.2.55",
|
|
74
|
+
"@types/react-dom": "^18.2.19",
|
|
75
|
+
"@types/react-lazy-load-image-component": "^1.6.3",
|
|
76
|
+
"@typescript-eslint/eslint-plugin": "^7.0.1",
|
|
77
|
+
"@typescript-eslint/parser": "7.0.1",
|
|
78
|
+
"@vitejs/plugin-react": "^4.2.1",
|
|
79
|
+
"chalk": "^5.3.0",
|
|
80
|
+
"eslint": "^8.56.0",
|
|
79
81
|
"eslint-plugin-json": "^3.1.0",
|
|
80
|
-
"eslint-plugin-prettier": "^
|
|
81
|
-
"happy-dom": "^13.
|
|
82
|
-
"prettier": "^2.
|
|
83
|
-
"query-string": "^
|
|
82
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
83
|
+
"happy-dom": "^13.3.8",
|
|
84
|
+
"prettier": "^3.2.5",
|
|
85
|
+
"query-string": "^8.2.0",
|
|
84
86
|
"react-16": "npm:react@16",
|
|
85
87
|
"react-17": "npm:react@17",
|
|
86
88
|
"react-18": "npm:react@18",
|
|
87
89
|
"react-dom-16": "npm:react-dom@16",
|
|
88
90
|
"react-dom-17": "npm:react-dom@17",
|
|
89
91
|
"react-dom-18": "npm:react-dom@18",
|
|
90
|
-
"tslib": "^2.
|
|
91
|
-
"typescript": "^
|
|
92
|
-
"vite": "^5.
|
|
93
|
-
"vitest": "1.2.
|
|
92
|
+
"tslib": "^2.6.2",
|
|
93
|
+
"typescript": "^5.3.3",
|
|
94
|
+
"vite": "^5.1.2",
|
|
95
|
+
"vitest": "^1.2.2",
|
|
94
96
|
"zustand": "^4.5.0"
|
|
95
97
|
},
|
|
96
98
|
"publishConfig": {
|