box-annotations 4.0.0-beta.8 → 4.0.1-beta.1

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 (208) hide show
  1. package/README.md +7 -57
  2. package/dist/annotations.css +1 -1
  3. package/dist/annotations.js +1 -1
  4. package/i18n/bn-IN.js +6 -0
  5. package/i18n/bn-IN.properties +12 -0
  6. package/i18n/da-DK.js +6 -0
  7. package/i18n/da-DK.properties +12 -0
  8. package/i18n/de-DE.js +6 -0
  9. package/i18n/de-DE.properties +12 -0
  10. package/i18n/en-AU.js +6 -0
  11. package/i18n/en-AU.properties +12 -0
  12. package/i18n/en-CA.js +6 -0
  13. package/i18n/en-CA.properties +12 -0
  14. package/i18n/en-GB.js +6 -0
  15. package/i18n/en-GB.properties +12 -0
  16. package/i18n/en-US.js +6 -0
  17. package/i18n/en-US.properties +12 -0
  18. package/i18n/en-x-pseudo.js +16 -9
  19. package/i18n/en-x-pseudo.properties +23 -9
  20. package/i18n/es-419.js +6 -0
  21. package/i18n/es-419.properties +12 -0
  22. package/i18n/es-ES.js +6 -0
  23. package/i18n/es-ES.properties +12 -0
  24. package/i18n/fi-FI.js +6 -0
  25. package/i18n/fi-FI.properties +12 -0
  26. package/i18n/fr-CA.js +6 -0
  27. package/i18n/fr-CA.properties +12 -0
  28. package/i18n/fr-FR.js +6 -0
  29. package/i18n/fr-FR.properties +12 -0
  30. package/i18n/hi-IN.js +6 -0
  31. package/i18n/hi-IN.properties +12 -0
  32. package/i18n/it-IT.js +6 -0
  33. package/i18n/it-IT.properties +12 -0
  34. package/i18n/ja-JP.js +6 -0
  35. package/i18n/ja-JP.properties +12 -0
  36. package/i18n/json/src/components/Popups/messages.json +1 -1
  37. package/i18n/ko-KR.js +6 -0
  38. package/i18n/ko-KR.properties +12 -0
  39. package/i18n/nb-NO.js +6 -0
  40. package/i18n/nb-NO.properties +12 -0
  41. package/i18n/nl-NL.js +6 -0
  42. package/i18n/nl-NL.properties +12 -0
  43. package/i18n/pl-PL.js +6 -0
  44. package/i18n/pl-PL.properties +12 -0
  45. package/i18n/pt-BR.js +6 -0
  46. package/i18n/pt-BR.properties +12 -0
  47. package/i18n/ru-RU.js +6 -0
  48. package/i18n/ru-RU.properties +12 -0
  49. package/i18n/sv-SE.js +6 -0
  50. package/i18n/sv-SE.properties +12 -0
  51. package/i18n/tr-TR.js +6 -0
  52. package/i18n/tr-TR.properties +12 -0
  53. package/i18n/zh-CN.js +6 -0
  54. package/i18n/zh-CN.properties +12 -0
  55. package/i18n/zh-TW.js +6 -0
  56. package/i18n/zh-TW.properties +12 -0
  57. package/package.json +29 -29
  58. package/src/@types/events.ts +8 -2
  59. package/src/@types/global.ts +1 -0
  60. package/src/@types/model.ts +20 -7
  61. package/src/BoxAnnotations.ts +16 -2
  62. package/src/common/BaseAnnotator.scss +0 -1
  63. package/src/common/BaseAnnotator.ts +125 -19
  64. package/src/common/BaseManager.ts +67 -4
  65. package/src/common/DeselectListener.tsx +21 -0
  66. package/src/common/DeselectManager.tsx +30 -0
  67. package/src/common/useIsListInteractive.ts +10 -0
  68. package/src/common/useMountId.ts +14 -0
  69. package/src/common/useOutsideEvent.ts +9 -4
  70. package/src/common/usePrevious.ts +13 -0
  71. package/src/components/ItemList/ItemList.scss +7 -2
  72. package/src/components/ItemList/ItemList.tsx +45 -26
  73. package/src/components/ItemList/ItemRow.scss +19 -7
  74. package/src/components/ItemList/ItemRow.tsx +33 -12
  75. package/src/components/PointerCapture/PointerCapture.tsx +116 -0
  76. package/src/components/PointerCapture/index.ts +2 -0
  77. package/src/components/Popups/Popper.ts +1 -0
  78. package/src/components/Popups/PopupArrow.scss +91 -0
  79. package/src/components/Popups/PopupBase.scss +12 -81
  80. package/src/components/Popups/PopupBase.tsx +0 -1
  81. package/src/components/Popups/PopupCursor.tsx +1 -1
  82. package/src/components/Popups/PopupDrawingToolbar.scss +76 -0
  83. package/src/components/Popups/PopupDrawingToolbar.tsx +109 -0
  84. package/src/components/Popups/PopupHighlight.scss +39 -0
  85. package/src/components/Popups/PopupHighlight.tsx +97 -0
  86. package/src/components/Popups/PopupHighlightError.scss +23 -0
  87. package/src/components/Popups/PopupHighlightError.tsx +74 -0
  88. package/src/components/Popups/PopupList.scss +1 -4
  89. package/src/components/Popups/PopupList.tsx +2 -2
  90. package/src/components/Popups/PopupReply.tsx +51 -6
  91. package/src/components/Popups/messages.ts +30 -0
  92. package/src/components/ReplyField/ReplyField.scss +6 -1
  93. package/src/components/ReplyField/ReplyField.tsx +43 -42
  94. package/src/components/ReplyField/ReplyFieldContainer.tsx +2 -1
  95. package/src/components/ReplyForm/ReplyButton.tsx +38 -0
  96. package/src/components/ReplyForm/ReplyForm.scss +3 -0
  97. package/src/components/ReplyForm/ReplyForm.tsx +49 -12
  98. package/src/components/ReplyForm/ReplyFormContainer.tsx +6 -4
  99. package/src/constants.js +1 -8
  100. package/src/document/DocumentAnnotator.scss +15 -0
  101. package/src/document/DocumentAnnotator.ts +110 -53
  102. package/src/document/docUtil.ts +61 -0
  103. package/src/drawing/DecoratedDrawingPath.scss +9 -0
  104. package/src/drawing/DecoratedDrawingPath.tsx +43 -0
  105. package/src/drawing/DrawingAnnotations.scss +39 -0
  106. package/src/drawing/DrawingAnnotations.tsx +157 -0
  107. package/src/drawing/DrawingAnnotationsContainer.tsx +66 -0
  108. package/src/drawing/DrawingCreator.scss +9 -0
  109. package/src/drawing/DrawingCreator.tsx +183 -0
  110. package/src/drawing/DrawingCursor.ts +23 -0
  111. package/src/drawing/DrawingList.tsx +60 -0
  112. package/src/drawing/DrawingManager.tsx +15 -0
  113. package/src/drawing/DrawingPath.tsx +17 -0
  114. package/src/drawing/DrawingPathGroup.tsx +52 -0
  115. package/src/drawing/DrawingSVG.tsx +34 -0
  116. package/src/drawing/DrawingSVGGroup.tsx +23 -0
  117. package/src/drawing/DrawingTarget.scss +11 -0
  118. package/src/drawing/DrawingTarget.tsx +100 -0
  119. package/src/drawing/SVGFilterContext.js +5 -0
  120. package/src/drawing/actions.ts +48 -0
  121. package/src/drawing/drawingUtil.ts +106 -0
  122. package/src/drawing/index.ts +2 -0
  123. package/src/highlight/HighlightAnnotations.scss +12 -0
  124. package/src/highlight/HighlightAnnotations.tsx +144 -0
  125. package/src/highlight/HighlightCanvas.scss +9 -0
  126. package/src/highlight/HighlightCanvas.tsx +109 -0
  127. package/src/highlight/HighlightContainer.tsx +64 -0
  128. package/src/highlight/HighlightCreator.scss +12 -0
  129. package/src/highlight/HighlightCreatorManager.ts +79 -0
  130. package/src/highlight/HighlightList.scss +13 -0
  131. package/src/highlight/HighlightList.tsx +92 -0
  132. package/src/highlight/HighlightListener.ts +37 -0
  133. package/src/highlight/HighlightManager.tsx +15 -0
  134. package/src/highlight/HighlightSvg.scss +7 -0
  135. package/src/highlight/HighlightSvg.tsx +18 -0
  136. package/src/highlight/HighlightTarget.scss +5 -0
  137. package/src/highlight/HighlightTarget.tsx +106 -0
  138. package/src/highlight/actions.ts +36 -0
  139. package/src/highlight/highlightUtil.ts +143 -0
  140. package/src/highlight/index.ts +4 -0
  141. package/src/image/ImageAnnotator.scss +20 -0
  142. package/src/image/ImageAnnotator.ts +137 -0
  143. package/src/polyfill.ts +19 -0
  144. package/src/popup/PopupContainer.tsx +50 -0
  145. package/src/popup/PopupLayer.scss +3 -0
  146. package/src/popup/PopupLayer.tsx +103 -0
  147. package/src/popup/PopupManager.tsx +15 -0
  148. package/src/region/RegionAnnotation.scss +4 -0
  149. package/src/region/RegionAnnotation.tsx +15 -16
  150. package/src/region/RegionAnnotations.scss +1 -15
  151. package/src/region/RegionAnnotations.tsx +14 -115
  152. package/src/region/RegionAnnotationsContainer.tsx +24 -0
  153. package/src/region/RegionCreation.scss +17 -0
  154. package/src/region/RegionCreation.tsx +79 -0
  155. package/src/region/RegionCreationContainer.tsx +43 -0
  156. package/src/region/RegionCreationManager.tsx +15 -0
  157. package/src/region/RegionCreator.scss +9 -2
  158. package/src/region/RegionCreator.tsx +50 -71
  159. package/src/region/RegionList.tsx +8 -12
  160. package/src/region/RegionManager.tsx +7 -39
  161. package/src/region/RegionRect.scss +41 -9
  162. package/src/region/RegionRect.tsx +9 -3
  163. package/src/region/index.ts +1 -0
  164. package/src/region/regionUtil.ts +1 -8
  165. package/src/region/transformUtil.ts +28 -0
  166. package/src/store/annotations/actions.ts +1 -0
  167. package/src/store/annotations/reducer.ts +9 -2
  168. package/src/store/annotations/selectors.ts +1 -0
  169. package/src/store/annotations/types.ts +1 -0
  170. package/src/store/common/actions.ts +1 -0
  171. package/src/store/common/reducer.ts +16 -10
  172. package/src/store/common/selectors.ts +1 -0
  173. package/src/store/common/types.ts +3 -0
  174. package/src/store/createRootReducer.ts +4 -0
  175. package/src/store/creator/actions.ts +2 -0
  176. package/src/store/creator/reducer.ts +22 -3
  177. package/src/store/creator/selectors.ts +9 -1
  178. package/src/store/creator/types.ts +18 -3
  179. package/src/store/drawing/actions.ts +10 -0
  180. package/src/store/drawing/index.ts +4 -0
  181. package/src/store/drawing/reducer.ts +50 -0
  182. package/src/store/drawing/selectors.ts +9 -0
  183. package/src/store/drawing/types.ts +7 -0
  184. package/src/store/eventing/active.ts +4 -2
  185. package/src/store/eventing/fetch.ts +8 -0
  186. package/src/store/eventing/init.ts +14 -0
  187. package/src/store/eventing/middleware.ts +21 -3
  188. package/src/store/eventing/mode.ts +7 -0
  189. package/src/store/eventing/staged.ts +56 -0
  190. package/src/store/eventing/status.ts +19 -0
  191. package/src/store/highlight/actions.ts +106 -0
  192. package/src/store/highlight/index.ts +4 -0
  193. package/src/store/highlight/reducer.ts +37 -0
  194. package/src/store/highlight/selectors.ts +12 -0
  195. package/src/store/highlight/types.ts +14 -0
  196. package/src/store/index.ts +2 -0
  197. package/src/store/options/actions.ts +2 -0
  198. package/src/store/options/reducer.ts +17 -1
  199. package/src/store/options/selectors.ts +8 -0
  200. package/src/store/options/types.ts +5 -0
  201. package/src/store/types.ts +5 -1
  202. package/src/store/users/actions.ts +3 -2
  203. package/src/utils/resin.ts +22 -0
  204. package/src/utils/rotate.ts +131 -0
  205. package/src/utils/scroll.ts +45 -0
  206. package/src/utils/util.ts +3 -0
  207. package/src/region/RegionContainer.tsx +0 -49
  208. package/src/utils/polyfill.js +0 -161
@@ -1,11 +1,21 @@
1
1
  import { createReducer } from '@reduxjs/toolkit';
2
2
  import { OptionsState } from './types';
3
- import { setFileIdAction, setFileVersionIdAction, setPermissionsAction } from './actions';
3
+ import {
4
+ setFileIdAction,
5
+ setFileVersionIdAction,
6
+ setPermissionsAction,
7
+ setRotationAction,
8
+ setScaleAction,
9
+ } from './actions';
4
10
 
5
11
  export const initialState = {
12
+ features: {},
6
13
  fileId: null,
7
14
  fileVersionId: null,
15
+ isCurrentFileVersion: true,
8
16
  permissions: {},
17
+ rotation: 0,
18
+ scale: 1,
9
19
  };
10
20
 
11
21
  export default createReducer<OptionsState>(initialState, builder =>
@@ -18,5 +28,11 @@ export default createReducer<OptionsState>(initialState, builder =>
18
28
  })
19
29
  .addCase(setPermissionsAction, (state, { payload }) => {
20
30
  state.permissions = payload;
31
+ })
32
+ .addCase(setRotationAction, (state, { payload }) => {
33
+ state.rotation = payload;
34
+ })
35
+ .addCase(setScaleAction, (state, { payload }) => {
36
+ state.scale = payload;
21
37
  }),
22
38
  );
@@ -1,8 +1,16 @@
1
+ import getProp from 'lodash/get';
1
2
  import { AppState } from '../types';
2
3
  import { Permissions } from '../../@types';
4
+ import { Features } from '../../BoxAnnotations';
3
5
 
4
6
  type State = Pick<AppState, 'options'>;
5
7
 
8
+ export const getFeatures = (state: State): Features => state.options.features;
6
9
  export const getFileId = (state: State): string | null => state.options.fileId;
7
10
  export const getFileVersionId = (state: State): string | null => state.options.fileVersionId;
11
+ export const getIsCurrentFileVersion = (state: State): boolean => state.options.isCurrentFileVersion;
8
12
  export const getPermissions = (state: State): Permissions => state.options.permissions;
13
+ export const getRotation = (state: State): number => state.options.rotation;
14
+ export const getScale = (state: State): number => state.options.scale;
15
+ export const isFeatureEnabled = (state: State, featurename: string): boolean =>
16
+ getProp(getFeatures(state), featurename, false);
@@ -1,7 +1,12 @@
1
+ import { Features } from '../../BoxAnnotations';
1
2
  import { Permissions } from '../../@types';
2
3
 
3
4
  export type OptionsState = {
5
+ features: Features;
4
6
  fileId: string | null;
5
7
  fileVersionId: string | null;
8
+ isCurrentFileVersion: boolean;
6
9
  permissions: Permissions;
10
+ rotation: number;
11
+ scale: number;
7
12
  };
@@ -4,13 +4,17 @@ import API from '../api';
4
4
  import { AnnotationsState } from './annotations';
5
5
  import { CommonState } from './common';
6
6
  import { CreatorState } from './creator';
7
+ import { DrawingState } from './drawing';
8
+ import { HighlightState } from './highlight';
7
9
  import { OptionsState } from './options';
8
10
  import { UsersState } from './users';
9
11
 
10
12
  export type AppState = {
11
13
  annotations: AnnotationsState;
12
- creator: CreatorState;
13
14
  common: CommonState;
15
+ creator: CreatorState;
16
+ drawing: DrawingState;
17
+ highlight: HighlightState;
14
18
  options: OptionsState;
15
19
  users: UsersState;
16
20
  };
@@ -4,9 +4,9 @@ import { AppThunkAPI } from '../types';
4
4
  import { Collaborator } from '../../@types';
5
5
  import { getFileId } from '../options';
6
6
 
7
- export const fetchCollaboratorsAction = createAsyncThunk<APICollection<Collaborator>, undefined, AppThunkAPI>(
7
+ export const fetchCollaboratorsAction = createAsyncThunk<APICollection<Collaborator>, string, AppThunkAPI>(
8
8
  'FETCH_COLLABORATORS',
9
- async (arg, { extra, getState, signal }) => {
9
+ async (searchString = '', { extra, getState, signal }) => {
10
10
  // Create a new client for each request
11
11
  const client = extra.api.getCollaboratorsAPI();
12
12
  const state = getState();
@@ -20,6 +20,7 @@ export const fetchCollaboratorsAction = createAsyncThunk<APICollection<Collabora
20
20
  // Wrap the client request in a promise to allow it to be returned and cancelled
21
21
  return new Promise<APICollection<Collaborator>>((resolve, reject) => {
22
22
  client.getFileCollaborators(fileId, resolve, reject, {
23
+ filter_term: searchString, // eslint-disable-line @typescript-eslint/camelcase
23
24
  include_groups: false, // eslint-disable-line @typescript-eslint/camelcase
24
25
  include_uploader_collabs: false, // eslint-disable-line @typescript-eslint/camelcase
25
26
  });
@@ -0,0 +1,22 @@
1
+ export function stringify(value: unknown): string {
2
+ if (typeof value === 'object' || typeof value === 'function' || typeof value === 'symbol') {
3
+ return '';
4
+ }
5
+
6
+ return typeof value === 'string' ? value : String(value);
7
+ }
8
+
9
+ export function applyResinTags(element: HTMLElement, attributes: Record<string, unknown>): void {
10
+ if (!element || !Object.values(attributes).length) {
11
+ return;
12
+ }
13
+
14
+ Object.entries(attributes).forEach(([key, value]) => {
15
+ const attribute = `data-resin-${key.toLowerCase()}`;
16
+ const stringValue = stringify(value);
17
+
18
+ if (stringValue) {
19
+ element.setAttribute(attribute, stringValue);
20
+ }
21
+ });
22
+ }
@@ -0,0 +1,131 @@
1
+ import { Dimensions, Position, Shape } from '../@types';
2
+
3
+ export type Translation = {
4
+ dx?: number;
5
+ dy?: number;
6
+ };
7
+
8
+ // Possible rotation values as supplied by box-content-preview
9
+ const ROTATION_ONCE_DEG = -90;
10
+ const ROTATION_TWICE_DEG = -180;
11
+ const ROTATION_THRICE_DEG = -270;
12
+
13
+ // Annotation shapes are, by default, percentages, so a 100x100 space
14
+ const DEFAULT_DIMENSIONS = { height: 100, width: 100 };
15
+
16
+ export const invertYCoordinate = ({ x, y }: Position, height: number): Position => ({
17
+ x,
18
+ y: height > 0 ? height - y : y,
19
+ });
20
+
21
+ export const rotatePoint = ({ x, y }: Position, rotationInDegrees: number): Position => {
22
+ const radians = (rotationInDegrees * Math.PI) / 180;
23
+ const cosine = Math.cos(radians);
24
+ const sine = Math.sin(radians);
25
+
26
+ // Formula to apply a rotation to a position is:
27
+ // x' = x * cos(θ) - y * sin(θ)
28
+ // y' = x * sin(θ) + y * cos(θ)
29
+ return {
30
+ x: x * cosine - y * sine,
31
+ y: x * sine + y * cosine,
32
+ };
33
+ };
34
+
35
+ export const getPoints = (shape: Shape): [Position, Position, Position, Position] => {
36
+ const { height, width, x, y } = shape;
37
+
38
+ // Define the points from x,y and then in a clockwise fashion
39
+ // p1 p2
40
+ // +-------+
41
+ // | |
42
+ // +-------+
43
+ // p4 p3
44
+ const p1 = { x, y };
45
+ const p2 = { x: x + width, y };
46
+ const p3 = { x: x + width, y: y + height };
47
+ const p4 = { x, y: y + height };
48
+
49
+ return [p1, p2, p3, p4];
50
+ };
51
+
52
+ export const translatePoint = ({ x, y }: Position, { dx = 0, dy = 0 }: { dx?: number; dy?: number }): Position => ({
53
+ x: x + dx,
54
+ y: y + dy,
55
+ });
56
+
57
+ export function selectTransformationPoint(shape: Shape, rotation: number): Position {
58
+ const [p1, p2, p3, p4] = getPoints(shape);
59
+
60
+ // Determine which position will be the new x,y (as defined as the top left position) after rotation
61
+ // If -90deg: use p2
62
+ // If -180deg: use p3
63
+ // If -270deg: use p4
64
+ // Otherwise: use p1
65
+ switch (rotation) {
66
+ case ROTATION_ONCE_DEG:
67
+ return p2;
68
+ case ROTATION_TWICE_DEG:
69
+ return p3;
70
+ case ROTATION_THRICE_DEG:
71
+ return p4;
72
+ default:
73
+ return p1;
74
+ }
75
+ }
76
+
77
+ // Determines the translation needed to anchor the bottom left corner of the
78
+ // coordinate space at the (0, 0) origin after rotation.
79
+ export function selectTranslation(dimensions: Dimensions, rotation: number): Translation {
80
+ const { height, width } = dimensions;
81
+
82
+ switch (rotation) {
83
+ case ROTATION_ONCE_DEG:
84
+ return { dx: height };
85
+ case ROTATION_TWICE_DEG:
86
+ return { dx: width, dy: height };
87
+ case ROTATION_THRICE_DEG:
88
+ return { dy: width };
89
+ default:
90
+ }
91
+
92
+ return { dx: 0, dy: 0 };
93
+ }
94
+
95
+ export function getRotatedShape(shape: Shape, rotation: number): Shape {
96
+ const { height: shapeHeight, width: shapeWidth } = shape;
97
+ const { height: spaceHeight, width: spaceWidth } = DEFAULT_DIMENSIONS;
98
+ const isInverted = rotation % 180 === 0;
99
+ const isNoRotation = rotation % 360 === 0;
100
+ const translation = selectTranslation(DEFAULT_DIMENSIONS, rotation);
101
+ const position = selectTransformationPoint(shape, rotation);
102
+
103
+ if (isNoRotation) {
104
+ return shape;
105
+ }
106
+
107
+ // To transform from shape with 0 rotation to provided rotation:
108
+ // 1. Invert y-axis to convert from web to mathematical coordinate system
109
+ // 2. Apply rotation transformation (with inverted rotation -- again mathematical coordinate system)
110
+ // 3. Translate to align coordinate space with mathematical origin
111
+ // 4. Invert y-axis to convert back to web coordinate system
112
+ const invertedPoint = invertYCoordinate(position, spaceHeight);
113
+ const rotatedPoint = rotatePoint(invertedPoint, -rotation);
114
+ const translatedPoint = translatePoint(rotatedPoint, translation);
115
+ const { x: transformedX, y: transformedY } = invertYCoordinate(
116
+ translatedPoint,
117
+ isInverted ? spaceHeight : spaceWidth,
118
+ );
119
+
120
+ return {
121
+ height: isInverted ? shapeHeight : shapeWidth,
122
+ width: isInverted ? shapeWidth : shapeHeight,
123
+ x: transformedX,
124
+ y: transformedY,
125
+ };
126
+ }
127
+
128
+ export function getRotatedPosition({ x, y }: Position, rotation: number): Position {
129
+ const { x: rotatedX, y: rotatedY } = getRotatedShape({ height: 0, width: 0, x, y }, rotation);
130
+ return { x: rotatedX, y: rotatedY };
131
+ }
@@ -0,0 +1,45 @@
1
+ import { Position } from '../@types';
2
+
3
+ export type ScrollOptions = {
4
+ offsets?: Position;
5
+ threshold?: number;
6
+ };
7
+
8
+ const DEFAULT_OFFSETS = { x: 0, y: 0 };
9
+
10
+ export function scrollToLocation(parentEl: HTMLElement, referenceEl: HTMLElement, options: ScrollOptions = {}): void {
11
+ const { offsets = DEFAULT_OFFSETS } = options;
12
+ const { x: offsetXPercentage, y: offsetYPercentage } = offsets;
13
+ // Get the bounding client rects so that the offsetLeft of the reference element can be calculated --
14
+ // even if it has been transformed via rotation
15
+ const { left: parentLeft, top: parentTop } = parentEl.getBoundingClientRect();
16
+ const {
17
+ height: referenceHeight,
18
+ left: referenceLeft,
19
+ top: referenceTop,
20
+ width: referenceWidth,
21
+ } = referenceEl.getBoundingClientRect();
22
+
23
+ // Get the midpoint of the scrollable area (parent element)
24
+ const parentCenterX = Math.round(parentEl.clientWidth / 2);
25
+ const parentCenterY = Math.round(parentEl.clientHeight / 2);
26
+
27
+ // Get any specified offset relative to the reference element
28
+ const offsetX = Math.round(referenceWidth * (offsetXPercentage / 100)); // offsetX is assumed to be a percentage
29
+ const offsetY = Math.round(referenceHeight * (offsetYPercentage / 100)); // offsetY is assumed to be a percentage
30
+
31
+ // Get the positioning of the reference element relative to the parent and the viewport
32
+ const referenceOffsetLeft = referenceLeft - parentLeft;
33
+ const referenceOffsetTop = referenceTop - parentTop;
34
+
35
+ // Get the scroll offsets to center the parent element on the top left corner of the reference element and then apply any provided offset
36
+ const offsetScrollLeft = referenceOffsetLeft - parentCenterX + offsetX;
37
+ const offsetScrollTop = referenceOffsetTop - parentCenterY + offsetY;
38
+
39
+ // Get the absolute scroll offsets by applying the delta to the current value
40
+ const scrollLeft = Math.max(0, Math.min(parentEl.scrollLeft + offsetScrollLeft, parentEl.scrollWidth));
41
+ const scrollTop = Math.max(0, Math.min(parentEl.scrollTop + offsetScrollTop, parentEl.scrollHeight));
42
+
43
+ parentEl.scrollLeft = scrollLeft;
44
+ parentEl.scrollTop = scrollTop;
45
+ }
@@ -0,0 +1,3 @@
1
+ export function checkValue(value: number): boolean {
2
+ return value >= 0 && value <= 100; // Values cannot be negative or larger than 100%
3
+ }
@@ -1,49 +0,0 @@
1
- import { connect } from 'react-redux';
2
- import { AnnotationRegion } from '../@types';
3
- import {
4
- AppState,
5
- CreatorItem,
6
- CreatorStatus,
7
- getActiveAnnotationId,
8
- getAnnotationMode,
9
- getAnnotationsForLocation,
10
- getCreatorMessage,
11
- getCreatorStagedForLocation,
12
- getCreatorStatus,
13
- setActiveAnnotationIdAction,
14
- setMessageAction,
15
- setStagedAction,
16
- setStatusAction,
17
- } from '../store';
18
- import RegionAnnotations from './RegionAnnotations';
19
- import withProviders from '../common/withProviders';
20
- import { createRegionAction } from './actions';
21
- import { isRegion } from './regionUtil';
22
-
23
- export type Props = {
24
- activeAnnotationId: string | null;
25
- annotations: AnnotationRegion[];
26
- isCreating: boolean;
27
- message: string;
28
- staged: CreatorItem | null;
29
- status: CreatorStatus;
30
- };
31
-
32
- export const mapStateToProps = (state: AppState, { page }: { page: number }): Props => ({
33
- activeAnnotationId: getActiveAnnotationId(state),
34
- annotations: getAnnotationsForLocation(state, page).filter(isRegion),
35
- isCreating: getAnnotationMode(state) === 'region',
36
- message: getCreatorMessage(state),
37
- staged: getCreatorStagedForLocation(state, page),
38
- status: getCreatorStatus(state),
39
- });
40
-
41
- export const mapDispatchToProps = {
42
- createRegion: createRegionAction,
43
- setActiveAnnotationId: setActiveAnnotationIdAction,
44
- setMessage: setMessageAction,
45
- setStaged: setStagedAction,
46
- setStatus: setStatusAction,
47
- };
48
-
49
- export default connect(mapStateToProps, mapDispatchToProps)(withProviders(RegionAnnotations));
@@ -1,161 +0,0 @@
1
- /* eslint-disable */
2
- (function() {
3
- var testObject = {};
4
-
5
- if (!(Object.setPrototypeOf || testObject.__proto__)) {
6
- var nativeGetPrototypeOf = Object.getPrototypeOf;
7
-
8
- Object.getPrototypeOf = function(object) {
9
- if (object.__proto__) {
10
- return object.__proto__;
11
- } else {
12
- return nativeGetPrototypeOf.call(Object, object);
13
- }
14
- };
15
- }
16
- })();
17
-
18
- if (typeof Object.assign != 'function') {
19
- (function() {
20
- Object.assign = function(target) {
21
- 'use strict';
22
- if (target === undefined || target === null) {
23
- throw new TypeError('Cannot convert undefined or null to object');
24
- }
25
-
26
- var output = Object(target);
27
- for (var index = 1; index < arguments.length; index++) {
28
- var source = arguments[index];
29
- if (source !== undefined && source !== null) {
30
- for (var nextKey in source) {
31
- if (source.hasOwnProperty(nextKey)) {
32
- output[nextKey] = source[nextKey];
33
- }
34
- }
35
- }
36
- }
37
- return output;
38
- };
39
- })();
40
- }
41
-
42
- // https://tc39.github.io/ecma262/#sec-array.prototype.find
43
- if (!Array.prototype.find) {
44
- Object.defineProperty(Array.prototype, 'find', {
45
- configurable: true,
46
- enumerable: false,
47
- writable: true,
48
- value: function(predicate) {
49
- // 1. Let O be ? ToObject(this value).
50
- if (this == null) {
51
- throw new TypeError('"this" is null or not defined');
52
- }
53
-
54
- var o = Object(this);
55
-
56
- // 2. Let len be ? ToLength(? Get(O, "length")).
57
- var len = o.length >>> 0;
58
-
59
- // 3. If IsCallable(predicate) is false, throw a TypeError exception.
60
- if (typeof predicate !== 'function') {
61
- throw new TypeError('predicate must be a function');
62
- }
63
-
64
- // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
65
- var thisArg = arguments[1];
66
-
67
- // 5. Let k be 0.
68
- var k = 0;
69
-
70
- // 6. Repeat, while k < len
71
- while (k < len) {
72
- // a. Let Pk be ! ToString(k).
73
- // b. Let kValue be ? Get(O, Pk).
74
- // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
75
- // d. If testResult is true, return kValue.
76
- var kValue = o[k];
77
- if (predicate.call(thisArg, kValue, k, o)) {
78
- return kValue;
79
- }
80
- // e. Increase k by 1.
81
- k++;
82
- }
83
-
84
- // 7. Return undefined.
85
- return undefined;
86
- },
87
- });
88
- }
89
-
90
- // https://tc39.github.io/ecma262/#sec-array.prototype.includes
91
- if (!Array.prototype.includes) {
92
- Object.defineProperty(Array.prototype, 'includes', {
93
- configurable: true,
94
- enumerable: false,
95
- writable: true,
96
- value: function(searchElement, fromIndex) {
97
- // 1. Let O be ? ToObject(this value).
98
- if (this == null) {
99
- throw new TypeError('"this" is null or not defined');
100
- }
101
-
102
- var o = Object(this);
103
-
104
- // 2. Let len be ? ToLength(? Get(O, "length")).
105
- var len = o.length >>> 0;
106
-
107
- // 3. If len is 0, return false.
108
- if (len === 0) {
109
- return false;
110
- }
111
-
112
- // 4. Let n be ? ToInteger(fromIndex).
113
- // (If fromIndex is undefined, this step produces the value 0.)
114
- var n = fromIndex | 0;
115
-
116
- // 5. If n ≥ 0, then
117
- // a. Let k be n.
118
- // 6. Else n < 0,
119
- // a. Let k be len + n.
120
- // b. If k < 0, let k be 0.
121
- var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
122
-
123
- function sameValueZero(x, y) {
124
- return x === y || (typeof x === 'Number' && typeof y === 'Number' && isNaN(x) && isNaN(y));
125
- }
126
-
127
- // 7. Repeat, while k < len
128
- while (k < len) {
129
- // a. Let elementK be the result of ? Get(O, ! ToString(k)).
130
- // b. If SameValueZero(searchElement, elementK) is true, return true.
131
- // c. Increase k by 1.
132
- if (sameValueZero(o[k], searchElement)) {
133
- return true;
134
- }
135
- k++;
136
- }
137
-
138
- // 8. Return false
139
- return false;
140
- },
141
- });
142
- }
143
-
144
- // Add support for SVGElement.contains in IE11
145
- if (!SVGElement.prototype.contains) {
146
- Object.defineProperty(SVGElement.prototype, 'contains', {
147
- configurable: true,
148
- enumerable: false,
149
- writable: true,
150
- value: function contains(node) {
151
- do {
152
- if (this === node) {
153
- return true;
154
- }
155
- } while ((node = node && node.parentNode));
156
-
157
- return false;
158
- },
159
- });
160
- }
161
- /* eslint-enable */