@annotorious/annotorious 3.0.0-rc.16 → 3.0.0-rc.18

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.
Files changed (72) hide show
  1. package/dist/Annotorious.d.ts.map +1 -1
  2. package/dist/annotation/SVGAnnotationLayerPointerEvent.d.ts.map +1 -1
  3. package/dist/annotation/editors/Handle.svelte.d.ts +1 -0
  4. package/dist/annotation/editors/editorsRegistry.d.ts +1 -1
  5. package/dist/annotation/editors/editorsRegistry.d.ts.map +1 -1
  6. package/dist/annotation/editors/index.d.ts +1 -1
  7. package/dist/annotation/editors/index.d.ts.map +1 -1
  8. package/dist/annotation/tools/drawingToolsRegistry.d.ts +4 -4
  9. package/dist/annotation/tools/drawingToolsRegistry.d.ts.map +1 -1
  10. package/dist/annotation/utils/responsive.d.ts +2 -1
  11. package/dist/annotation/utils/responsive.d.ts.map +1 -1
  12. package/dist/annotation/utils/styling.d.ts +1 -1
  13. package/dist/annotation/utils/styling.d.ts.map +1 -1
  14. package/dist/annotation/utils/touch.d.ts.map +1 -1
  15. package/dist/annotorious.css +1 -1
  16. package/dist/annotorious.es.js +2373 -2072
  17. package/dist/annotorious.es.js.map +1 -1
  18. package/dist/annotorious.js +1 -1
  19. package/dist/annotorious.js.map +1 -1
  20. package/dist/index.d.ts +1 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/keyboardCommands.d.ts.map +1 -1
  23. package/dist/model/w3c/W3CImageAnnotation.d.ts +11 -0
  24. package/dist/model/w3c/W3CImageAnnotation.d.ts.map +1 -0
  25. package/dist/model/w3c/W3CImageFormatAdapter.d.ts +3 -2
  26. package/dist/model/w3c/W3CImageFormatAdapter.d.ts.map +1 -1
  27. package/dist/model/w3c/fragment/FragmentSelector.d.ts +1 -2
  28. package/dist/model/w3c/fragment/FragmentSelector.d.ts.map +1 -1
  29. package/dist/model/w3c/index.d.ts +1 -0
  30. package/dist/model/w3c/index.d.ts.map +1 -1
  31. package/dist/model/w3c/svg/SVG.d.ts.map +1 -1
  32. package/dist/model/w3c/svg/SVGSelector.d.ts +1 -2
  33. package/dist/model/w3c/svg/SVGSelector.d.ts.map +1 -1
  34. package/dist/state/spatialTree.d.ts +1 -1
  35. package/dist/state/spatialTree.d.ts.map +1 -1
  36. package/package.json +10 -10
  37. package/src/Annotorious.css +5 -5
  38. package/src/Annotorious.ts +7 -6
  39. package/src/annotation/SVGAnnotationLayer.svelte +18 -14
  40. package/src/annotation/SVGAnnotationLayerPointerEvent.ts +1 -2
  41. package/src/annotation/Transform.ts +1 -1
  42. package/src/annotation/editors/Editor.svelte +10 -11
  43. package/src/annotation/editors/EditorMount.svelte +2 -2
  44. package/src/annotation/editors/Handle.svelte +66 -0
  45. package/src/annotation/editors/index.ts +2 -2
  46. package/src/annotation/editors/polygon/PolygonEditor.svelte +16 -16
  47. package/src/annotation/editors/rectangle/RectangleEditor.svelte +46 -43
  48. package/src/annotation/shapes/Ellipse.svelte +2 -2
  49. package/src/annotation/shapes/Polygon.svelte +2 -2
  50. package/src/annotation/shapes/Rectangle.svelte +2 -2
  51. package/src/annotation/tools/ToolMount.svelte +3 -3
  52. package/src/annotation/tools/drawingToolsRegistry.ts +2 -1
  53. package/src/annotation/tools/polygon/RubberbandPolygon.svelte +34 -11
  54. package/src/annotation/tools/rectangle/RubberbandRectangle.svelte +16 -10
  55. package/src/annotation/utils/responsive.ts +1 -1
  56. package/src/annotation/utils/touch.ts +4 -1
  57. package/src/index.ts +1 -2
  58. package/src/keyboardCommands.ts +8 -4
  59. package/src/model/w3c/W3CImageAnnotation.ts +17 -0
  60. package/src/model/w3c/W3CImageFormatAdapter.ts +19 -15
  61. package/src/model/w3c/fragment/FragmentSelector.ts +5 -6
  62. package/src/model/w3c/index.ts +1 -0
  63. package/src/model/w3c/svg/SVG.ts +1 -2
  64. package/src/model/w3c/svg/SVGSelector.ts +11 -13
  65. package/src/state/ImageAnnotatorState.ts +3 -3
  66. package/src/state/spatialTree.ts +3 -2
  67. package/src/themes/dark/index.css +2 -2
  68. package/src/themes/light/index.css +2 -2
  69. package/src/themes/smart/setTheme.ts +2 -2
  70. package/dist/annotation/editors/Handle.d.ts +0 -14
  71. package/dist/annotation/editors/Handle.d.ts.map +0 -1
  72. package/src/annotation/editors/Handle.ts +0 -21
@@ -1,19 +1,18 @@
1
- <script type="ts">
2
- import type { Rectangle } from '../../../model';
1
+ <script lang="ts">
2
+ import Handle from '../Handle.svelte';
3
+ import type { Rectangle, Shape } from '../../../model';
3
4
  import type { Transform } from '../../Transform';
4
- import { Editor, Handle } from '..';
5
+ import { Editor } from '..';
5
6
 
6
7
  /** Props */
7
8
  export let shape: Rectangle;
8
- export let computedStyle: string = undefined;
9
+ export let computedStyle: string | undefined;
9
10
  export let transform: Transform;
10
11
  export let viewportScale: number = 1;
11
12
 
12
13
  $: geom = shape.geometry;
13
14
 
14
- $: handleSize = 10 / viewportScale;
15
-
16
- const editor = (rectangle: Rectangle, handle: Handle, delta: [number, number]) => {
15
+ const editor = (rectangle: Shape, handle: string, delta: [number, number]) => {
17
16
  const initialBounds = rectangle.geometry.bounds;
18
17
 
19
18
  let [x0, y0] = [initialBounds.minX, initialBounds.minY];
@@ -21,39 +20,39 @@
21
20
 
22
21
  const [dx, dy] = delta;
23
22
 
24
- if (handle === Handle.SHAPE) {
23
+ if (handle === 'SHAPE') {
25
24
  x0 += dx;
26
25
  x1 += dx;
27
26
  y0 += dy;
28
27
  y1 += dy;
29
28
  } else {
30
29
  switch (handle) {
31
- case Handle.TOP:
32
- case Handle.TOP_LEFT:
33
- case Handle.TOP_RIGHT: {
30
+ case 'TOP':
31
+ case 'TOP_LEFT':
32
+ case 'TOP_RIGHT': {
34
33
  y0 += dy;
35
34
  break;
36
35
  }
37
36
 
38
- case Handle.BOTTOM:
39
- case Handle.BOTTOM_LEFT:
40
- case Handle.BOTTOM_RIGHT: {
37
+ case 'BOTTOM':
38
+ case 'BOTTOM_LEFT':
39
+ case 'BOTTOM_RIGHT': {
41
40
  y1 += dy;
42
41
  break;
43
42
  }
44
43
  }
45
44
 
46
45
  switch (handle) {
47
- case Handle.LEFT:
48
- case Handle.TOP_LEFT:
49
- case Handle.BOTTOM_LEFT: {
46
+ case 'LEFT':
47
+ case 'TOP_LEFT':
48
+ case 'BOTTOM_LEFT': {
50
49
  x0 += dx;
51
50
  break;
52
51
  }
53
52
 
54
- case Handle.RIGHT:
55
- case Handle.TOP_RIGHT:
56
- case Handle.BOTTOM_RIGHT: {
53
+ case 'RIGHT':
54
+ case 'TOP_RIGHT':
55
+ case 'BOTTOM_RIGHT': {
57
56
  x1 += dx;
58
57
  break;
59
58
  }
@@ -92,52 +91,56 @@
92
91
  <rect
93
92
  class="a9s-outer"
94
93
  style={computedStyle ? 'display:none;' : undefined}
95
- on:pointerdown={grab(Handle.SHAPE)}
94
+ on:pointerdown={grab('SHAPE')}
96
95
  x={geom.x} y={geom.y} width={geom.w} height={geom.h} />
97
96
 
98
97
  <rect
99
98
  class="a9s-inner a9s-shape-handle"
100
99
  style={computedStyle}
101
- on:pointerdown={grab(Handle.SHAPE)}
100
+ on:pointerdown={grab('SHAPE')}
102
101
  x={geom.x} y={geom.y} width={geom.w} height={geom.h} />
103
102
 
104
103
  <rect
105
104
  class="a9s-edge-handle a9s-edge-handle-top"
106
- on:pointerdown={grab(Handle.TOP)}
105
+ on:pointerdown={grab('TOP')}
107
106
  x={geom.x} y={geom.y} height={1} width={geom.w} />
108
107
 
109
108
  <rect
110
109
  class="a9s-edge-handle a9s-edge-handle-right"
111
- on:pointerdown={grab(Handle.RIGHT)}
110
+ on:pointerdown={grab('RIGHT')}
112
111
  x={geom.x + geom.w} y={geom.y} height={geom.h} width={1}/>
113
112
 
114
113
  <rect
115
114
  class="a9s-edge-handle a9s-edge-handle-bottom"
116
- on:pointerdown={grab(Handle.BOTTOM)}
115
+ on:pointerdown={grab('BOTTOM')}
117
116
  x={geom.x} y={geom.y + geom.h} height={1} width={geom.w} />
118
117
 
119
118
  <rect
120
119
  class="a9s-edge-handle a9s-edge-handle-left"
121
- on:pointerdown={grab(Handle.LEFT)}
120
+ on:pointerdown={grab('LEFT')}
122
121
  x={geom.x} y={geom.y} height={geom.h} width={1} />
123
122
 
124
- <rect
125
- class="a9s-corner-handle a9s-corner-handle-topleft"
126
- on:pointerdown={grab(Handle.TOP_LEFT)}
127
- x={geom.x - handleSize / 2} y={geom.y - handleSize / 2} height={handleSize} width={handleSize} />
128
-
129
- <rect
130
- class="a9s-corner-handle a9s-corner-handle-topright"
131
- on:pointerdown={grab(Handle.TOP_RIGHT)}
132
- x={geom.x + geom.w - handleSize / 2} y={geom.y - handleSize / 2} height={handleSize} width={handleSize} />
123
+ <Handle
124
+ class="a9s-corner-handle-topleft"
125
+ on:pointerdown={grab('TOP_LEFT')}
126
+ x={geom.x} y={geom.y}
127
+ scale={viewportScale} />
128
+
129
+ <Handle
130
+ class="a9s-corner-handle-topright"
131
+ on:pointerdown={grab('TOP_RIGHT')}
132
+ x={geom.x + geom.w} y={geom.y}
133
+ scale={viewportScale} />
133
134
 
134
- <rect
135
- class="a9s-corner-handle a9s-corner-handle-bottomright"
136
- on:pointerdown={grab(Handle.BOTTOM_RIGHT)}
137
- x={geom.x + geom.w - handleSize / 2} y={geom.y + geom.h - handleSize / 2} height={handleSize} width={handleSize} />
135
+ <Handle
136
+ class="a9s-corner-handle-bottomright"
137
+ on:pointerdown={grab('BOTTOM_RIGHT')}
138
+ x={geom.x + geom.w} y={geom.y + geom.h}
139
+ scale={viewportScale} />
138
140
 
139
- <rect
140
- class="a9s-corner-handle a9s-corner-handle-bottomleft"
141
- on:pointerdown={grab(Handle.BOTTOM_LEFT)}
142
- x={geom.x - handleSize / 2} y={geom.y + geom.h - handleSize / 2} height={handleSize} width={handleSize} />
141
+ <Handle
142
+ class="a9s-corner-handle-bottomleft"
143
+ on:pointerdown={grab('BOTTOM_LEFT')}
144
+ x={geom.x} y={geom.y + geom.h}
145
+ scale={viewportScale} />
143
146
  </Editor>
@@ -1,4 +1,4 @@
1
- <script type="ts">
1
+ <script lang="ts">
2
2
  import type { DrawingStyle } from '@annotorious/core';
3
3
  import type { Geometry, EllipseGeometry, ImageAnnotation } from '../../model';
4
4
  import { computeStyle } from '../utils/styling';
@@ -6,7 +6,7 @@
6
6
  /** Props */
7
7
  export let annotation: ImageAnnotation;
8
8
  export let geom: Geometry;
9
- export let style: DrawingStyle | ((annotation: ImageAnnotation) => DrawingStyle) = undefined;
9
+ export let style: DrawingStyle | ((annotation: ImageAnnotation) => DrawingStyle) | undefined;
10
10
 
11
11
  $: computedStyle = computeStyle(annotation, style);
12
12
 
@@ -1,4 +1,4 @@
1
- <script type="ts">
1
+ <script lang="ts">
2
2
  import type { DrawingStyle } from '@annotorious/core';
3
3
  import type { Geometry, ImageAnnotation, PolygonGeometry } from '../../model';
4
4
  import { computeStyle } from '../utils/styling';
@@ -6,7 +6,7 @@
6
6
  /** Props **/
7
7
  export let annotation: ImageAnnotation;
8
8
  export let geom: Geometry;
9
- export let style: DrawingStyle | ((annotation: ImageAnnotation) => DrawingStyle) = undefined;
9
+ export let style: DrawingStyle | ((annotation: ImageAnnotation) => DrawingStyle) | undefined;
10
10
 
11
11
  $: computedStyle = computeStyle(annotation, style);
12
12
 
@@ -1,4 +1,4 @@
1
- <script type="ts">
1
+ <script lang="ts">
2
2
  import type { DrawingStyle } from '@annotorious/core';
3
3
  import type { Geometry, ImageAnnotation, RectangleGeometry } from '../../model';
4
4
  import { computeStyle } from '../utils/styling';
@@ -6,7 +6,7 @@
6
6
  /** Props **/
7
7
  export let annotation: ImageAnnotation;
8
8
  export let geom: Geometry;
9
- export let style: DrawingStyle | ((annotation: ImageAnnotation) => DrawingStyle) = undefined;
9
+ export let style: DrawingStyle | ((annotation: ImageAnnotation) => DrawingStyle) | undefined;
10
10
 
11
11
  $: computedStyle = computeStyle(annotation, style);
12
12
 
@@ -23,9 +23,9 @@
23
23
 
24
24
  const cleanup: Function[] = [];
25
25
 
26
- const addEventListener = (name: string, handler: (evt: PointerEvent) => void, capture?: boolean) => {
27
- svg.addEventListener(name, handler, capture);
28
- cleanup.push(() => svg.removeEventListener(name, handler, capture));
26
+ const addEventListener = (name: keyof SVGSVGElementEventMap, handler: EventListenerOrEventListenerObject, capture?: boolean) => {
27
+ svg?.addEventListener(name, handler, capture);
28
+ cleanup.push(() => svg?.removeEventListener(name, handler, capture));
29
29
  }
30
30
 
31
31
  toolComponent = new tool({
@@ -9,10 +9,11 @@ export type DrawingToolOpts = {
9
9
 
10
10
  drawingMode?: DrawingMode;
11
11
 
12
- [key: string]: string;
12
+ [key: string]: any;
13
13
 
14
14
  }
15
15
 
16
+ // @ts-ignore
16
17
  const REGISTERED = new Map<DrawingTool, { tool: typeof SvelteComponent, opts?: DrawingToolOpts }>([
17
18
  ['rectangle', { tool: RubberbandRectangle }],
18
19
  ['polygon', { tool: RubberbandPolygon }]
@@ -1,4 +1,4 @@
1
- <script type="ts">
1
+ <script lang="ts">
2
2
  import { onMount, createEventDispatcher } from 'svelte';
3
3
  import type { DrawingMode } from '../../../AnnotoriousOpts';
4
4
  import { boundsFromPoints, computeArea, ShapeType, type Polygon } from '../../../model';
@@ -17,15 +17,24 @@
17
17
 
18
18
  let points: [number, number][] = [];
19
19
 
20
- let cursor: [number, number] = null;
20
+ let cursor: [number, number] | undefined;
21
+
22
+ // Keep track of the user keeping the finger
23
+ // in place. Long pauses will be interpreted like a
24
+ // double click and close the shape.
25
+ let touchPauseTimer: number | undefined;
21
26
 
22
27
  let isClosable: boolean = false;
23
28
 
24
29
  const CLOSE_DISTANCE = 20;
25
30
 
31
+ const TOUCH_PAUSE_LIMIT = 1500;
32
+
26
33
  $: handleSize = 10 / viewportScale;
27
34
 
28
- const onPointerDown = (evt: PointerEvent) => {
35
+ const onPointerDown = (event: Event) => {
36
+ const evt = event as PointerEvent;
37
+
29
38
  // Note that the event itself is ephemeral!
30
39
  const { timeStamp, offsetX, offsetY } = evt;
31
40
  lastPointerDown = { timeStamp, offsetX, offsetY };
@@ -40,7 +49,11 @@
40
49
  }
41
50
  }
42
51
 
43
- const onPointerMove = (evt: PointerEvent) => {
52
+ const onPointerMove = (event: Event) => {
53
+ const evt = event as PointerEvent;
54
+
55
+ if (touchPauseTimer) clearTimeout(touchPauseTimer);
56
+
44
57
  if (points.length > 0) {
45
58
  cursor = transform.elementToImage(evt.offsetX, evt.offsetY);
46
59
 
@@ -48,10 +61,18 @@
48
61
  const d = distance(cursor, points[0]) * viewportScale;
49
62
  isClosable = d < CLOSE_DISTANCE;
50
63
  }
64
+
65
+ if (evt.pointerType === 'touch') {
66
+ touchPauseTimer = setTimeout(() => {
67
+ onDblClick();
68
+ }, TOUCH_PAUSE_LIMIT);
69
+ }
51
70
  }
52
71
  }
53
72
 
54
- const onPointerUp = (evt: PointerEvent) => {
73
+ const onPointerUp = (event: Event) => {
74
+ const evt = event as PointerEvent;
75
+
55
76
  if (drawingMode === 'click') {
56
77
  const timeDifference = evt.timeStamp - lastPointerDown.timeStamp;
57
78
 
@@ -71,17 +92,17 @@
71
92
 
72
93
  cursor = point;
73
94
  } else {
74
- points.push(cursor);
95
+ points.push(cursor!);
75
96
  }
76
97
  } else {
77
98
  // Require minimum drag of 4px
78
99
  if (points.length === 1) {
79
- const dist = distance(points[0], cursor);
100
+ const dist = distance(points[0], cursor!);
80
101
 
81
102
  if (dist <= 4) {
82
103
  // Cancel
83
104
  points = [];
84
- cursor = null;
105
+ cursor = undefined;
85
106
 
86
107
  return;
87
108
  }
@@ -93,12 +114,14 @@
93
114
  if (isClosable) {
94
115
  stopDrawing();
95
116
  } else {
96
- points.push(cursor);
117
+ points.push(cursor!);
97
118
  }
98
119
  }
99
120
  }
100
121
 
101
122
  const onDblClick = () => {
123
+ if (!cursor) return;
124
+
102
125
  // Require min 3 points (incl. cursor) and minimum
103
126
  // polygon area
104
127
  const p = [...points, cursor];
@@ -114,7 +137,7 @@
114
137
  const area = computeArea(shape);
115
138
  if (area > 4) {
116
139
  points = [];
117
- cursor = null;
140
+ cursor = undefined;
118
141
 
119
142
  dispatch('create', shape);
120
143
  }
@@ -130,7 +153,7 @@
130
153
  }
131
154
 
132
155
  points = [];
133
- cursor = null;
156
+ cursor = undefined;
134
157
 
135
158
  dispatch('create', shape);
136
159
  }
@@ -1,4 +1,4 @@
1
- <script type="ts">
1
+ <script lang="ts">
2
2
  import { createEventDispatcher, onMount } from 'svelte';
3
3
  import type { DrawingMode } from '../../../AnnotoriousOpts';
4
4
  import { ShapeType, type Rectangle } from '../../../model';
@@ -13,13 +13,15 @@
13
13
 
14
14
  let lastPointerDown: number;
15
15
 
16
- let origin: [x: number, y: number];
16
+ let origin: [x: number, y: number] | undefined;
17
17
 
18
- let anchor: [number, number];
18
+ let anchor: [number, number] | undefined;
19
19
 
20
20
  let x: number, y: number, w: number, h: number;
21
21
 
22
- const onPointerDown = (evt: PointerEvent) => {
22
+ const onPointerDown = (event: Event) => {
23
+ const evt = event as PointerEvent;
24
+
23
25
  lastPointerDown = performance.now();
24
26
 
25
27
  if (drawingMode === 'drag') {
@@ -33,7 +35,9 @@
33
35
  }
34
36
  }
35
37
 
36
- const onPointerMove = (evt: PointerEvent) => {
38
+ const onPointerMove = (event: Event) => {
39
+ const evt = event as PointerEvent;
40
+
37
41
  if (origin) {
38
42
  anchor = transform.elementToImage(evt.offsetX, evt.offsetY);
39
43
 
@@ -44,7 +48,9 @@
44
48
  }
45
49
  }
46
50
 
47
- const onPointerUp = (evt: PointerEvent) => {
51
+ const onPointerUp = (event: Event) => {
52
+ const evt = event as PointerEvent;
53
+
48
54
  const timeDifference = performance.now() - lastPointerDown;
49
55
 
50
56
  if (drawingMode === 'click') {
@@ -71,8 +77,8 @@
71
77
  evt.stopPropagation();
72
78
  stopDrawing();
73
79
  } else {
74
- origin = null;
75
- anchor = null;
80
+ origin = undefined;
81
+ anchor = undefined;
76
82
  }
77
83
  }
78
84
  }
@@ -96,8 +102,8 @@
96
102
  dispatch('create', shape);
97
103
  }
98
104
 
99
- origin = null;
100
- anchor = null;
105
+ origin = undefined;
106
+ anchor = undefined;
101
107
  }
102
108
 
103
109
  onMount(() => {
@@ -42,7 +42,7 @@ export const enableResponsive = (image: HTMLImageElement | HTMLCanvasElement, sv
42
42
  set(scale);
43
43
  });
44
44
 
45
- resizeObserver.observe(svg.parentElement);
45
+ resizeObserver.observe(svg.parentElement!);
46
46
  }
47
47
 
48
48
  const destroy = () => {
@@ -1 +1,4 @@
1
- export const isTouch = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
1
+ export const isTouch = 'ontouchstart' in window
2
+ || navigator.maxTouchPoints > 0
3
+ // @ts-ignore
4
+ || navigator.msMaxTouchPoints > 0;
package/src/index.ts CHANGED
@@ -33,6 +33,5 @@ export type {
33
33
  User,
34
34
  W3CAnnotation,
35
35
  W3CAnnotationBody,
36
- W3CAnnotationTarget,
37
- W3CSelector
36
+ W3CAnnotationTarget
38
37
  } from '@annotorious/core';
@@ -9,15 +9,19 @@ export const initKeyboardCommands = <T extends Annotation>(
9
9
 
10
10
  const el = container || document;
11
11
 
12
- const onWinKeyDown = (event: KeyboardEvent) => {
13
- if (event.key === 'Z' && event.ctrlKey) {
12
+ const onWinKeyDown = (evt: Event) => {
13
+ const event = evt as KeyboardEvent;
14
+
15
+ if (event.key === 'z' && event.ctrlKey) {
14
16
  undoStack.undo();
15
- } else if (event.key === 'Y' && event.ctrlKey) {
17
+ } else if (event.key === 'y' && event.ctrlKey) {
16
18
  undoStack.redo()
17
19
  }
18
20
  };
19
21
 
20
- const onMacKeyDown = (event: KeyboardEvent) => {
22
+ const onMacKeyDown = (evt: Event) => {
23
+ const event = evt as KeyboardEvent;
24
+
21
25
  if (event.key === 'z' && event.metaKey) {
22
26
  if (event.shiftKey) {
23
27
  undoStack.redo()
@@ -0,0 +1,17 @@
1
+ import type { W3CAnnotation, W3CAnnotationTarget } from '@annotorious/core';
2
+ import type { FragmentSelector } from './fragment';
3
+ import type { SVGSelector } from './svg';
4
+
5
+ export interface W3CImageAnnotation extends W3CAnnotation {
6
+
7
+ target: W3CImageAnnotationTarget | W3CImageAnnotationTarget[];
8
+
9
+ }
10
+
11
+ export interface W3CImageAnnotationTarget extends W3CAnnotationTarget {
12
+
13
+ selector: W3CImageSelector | W3CImageSelector[];
14
+
15
+ }
16
+
17
+ export type W3CImageSelector = FragmentSelector | SVGSelector;
@@ -3,12 +3,13 @@ import { parseW3CUser, parseW3CBodies, serializeW3CBodies } from '@annotorious/c
3
3
  import type { FormatAdapter, ParseResult, W3CAnnotation } from '@annotorious/core';
4
4
  import { ShapeType } from '../core';
5
5
  import type { ImageAnnotation, RectangleGeometry } from '../core';
6
- import type { FragmentSelector } from './fragment';
6
+ import type {FragmentSelector } from './fragment';
7
7
  import { parseFragmentSelector, serializeFragmentSelector } from './fragment';
8
8
  import type { SVGSelector } from './svg';
9
9
  import { parseSVGSelector, serializeSVGSelector } from './svg';
10
+ import type { W3CImageAnnotation } from './W3CImageAnnotation';
10
11
 
11
- export type W3CImageFormatAdapter = FormatAdapter<ImageAnnotation, W3CAnnotation>;
12
+ export type W3CImageFormatAdapter = FormatAdapter<ImageAnnotation, W3CImageAnnotation>;
12
13
 
13
14
  export const W3CImageFormat = (
14
15
  source: string,
@@ -33,22 +34,23 @@ export const parseW3CImageAnnotation = (
33
34
  const {
34
35
  creator,
35
36
  created,
36
- updatedBy,
37
- updated,
37
+ modified,
38
38
  body,
39
39
  ...rest
40
40
  } = annotation;
41
41
 
42
42
  const bodies = parseW3CBodies(body, annotationId);
43
43
 
44
- const target = Array.isArray(annotation.target) ? annotation.target[0] : annotation.target;
44
+ const w3cTarget = Array.isArray(annotation.target)
45
+ ? annotation.target[0] : annotation.target;
45
46
 
46
- const w3cSelector = Array.isArray(target.selector) ? target.selector[0] : target.selector;
47
+ const w3cSelector = Array.isArray(w3cTarget.selector)
48
+ ? w3cTarget.selector[0] : w3cTarget.selector;
47
49
 
48
50
  const selector =
49
- w3cSelector.type === 'FragmentSelector' ?
51
+ w3cSelector?.type === 'FragmentSelector' ?
50
52
  parseFragmentSelector(w3cSelector as FragmentSelector, invertY) :
51
- w3cSelector.type === 'SvgSelector' ?
53
+ w3cSelector?.type === 'SvgSelector' ?
52
54
  parseSVGSelector(w3cSelector as SVGSelector) : undefined;
53
55
 
54
56
  return selector ? {
@@ -59,13 +61,14 @@ export const parseW3CImageAnnotation = (
59
61
  target: {
60
62
  created: created ? new Date(created) : undefined,
61
63
  creator: parseW3CUser(creator),
64
+ updated: modified ? new Date(modified) : undefined,
62
65
  ...rest.target,
63
66
  annotation: annotationId,
64
67
  selector
65
68
  }
66
69
  }
67
70
  } : {
68
- error: Error(`Unknown selector type: ${w3cSelector.type}`)
71
+ error: Error(`Invalid selector: ${JSON.stringify(w3cSelector)}`)
69
72
  };
70
73
 
71
74
  }
@@ -73,13 +76,13 @@ export const parseW3CImageAnnotation = (
73
76
  export const serializeW3CImageAnnotation = (
74
77
  annotation: ImageAnnotation,
75
78
  source: string
76
- ): W3CAnnotation => {
79
+ ): W3CImageAnnotation => {
77
80
  const {
78
81
  selector,
79
82
  creator,
80
83
  created,
81
- updated,
82
- updatedBy,
84
+ updated,
85
+ updatedBy, // Excluded from serialization
83
86
  ...rest
84
87
  } = annotation.target;
85
88
 
@@ -94,12 +97,13 @@ export const serializeW3CImageAnnotation = (
94
97
  id: annotation.id,
95
98
  type: 'Annotation',
96
99
  body: serializeW3CBodies(annotation.bodies),
97
- creator,
98
100
  created: created?.toISOString(),
101
+ creator,
102
+ modified: updated?.toISOString(),
99
103
  target: {
100
104
  ...rest,
101
105
  source,
102
106
  selector: w3CSelector
103
107
  }
104
- };
105
- };
108
+ }
109
+ }
@@ -1,15 +1,14 @@
1
- import type { W3CSelector } from '@annotorious/core';
2
- import { ShapeType } from '../../core';
3
1
  import type { Rectangle, RectangleGeometry } from '../../core';
2
+ import { ShapeType } from '../../core';
4
3
 
5
- export interface FragmentSelector extends W3CSelector {
4
+ export interface FragmentSelector {
6
5
 
7
6
  type: 'FragmentSelector';
8
7
 
9
8
  conformsTo: 'http://www.w3.org/TR/media-frags/',
10
9
 
11
10
  value: string;
12
-
11
+
13
12
  }
14
13
 
15
14
  export const parseFragmentSelector = (
@@ -46,7 +45,7 @@ export const parseFragmentSelector = (
46
45
  }
47
46
  }
48
47
  }
49
- };
48
+ }
50
49
 
51
50
  export const serializeFragmentSelector = (geometry: RectangleGeometry): FragmentSelector => {
52
51
  const { x, y, w, h } = geometry;
@@ -56,4 +55,4 @@ export const serializeFragmentSelector = (geometry: RectangleGeometry): Fragment
56
55
  conformsTo: 'http://www.w3.org/TR/media-frags/',
57
56
  value: `xywh=pixel:${x},${y},${w},${h}`
58
57
  };
59
- };
58
+ }
@@ -1,3 +1,4 @@
1
1
  export * from './fragment';
2
2
  export * from './svg';
3
+ export * from './W3CImageAnnotation';
3
4
  export * from './W3CImageFormatAdapter';
@@ -13,8 +13,7 @@ export const sanitize = (doc: Element | Document) => {
13
13
  // Remove script tags
14
14
  const scripts = doc.getElementsByTagName('script');
15
15
 
16
- Array.from(scripts).reverse().forEach(el =>
17
- el.parentNode.removeChild(el));
16
+ Array.from(scripts).reverse().forEach(el => el.parentNode!.removeChild(el));
18
17
 
19
18
  Array.from(doc.querySelectorAll('*')).forEach(cleanEl);
20
19