@odoo/o-spreadsheet 1.0.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 (199) hide show
  1. package/.eslintrc.json +20 -0
  2. package/.husky/post-checkout +9 -0
  3. package/.husky/pre-commit +39 -0
  4. package/.prettierignore +1 -0
  5. package/astToFormula.patch +0 -0
  6. package/demo/data.js +255 -0
  7. package/demo/index.html +9 -0
  8. package/demo/libs/Chart.bundle.js +20755 -0
  9. package/demo/main.js +101 -0
  10. package/doc/readme.md +46 -0
  11. package/package.json +78 -0
  12. package/readme.md +39 -0
  13. package/rollup.config.js +23 -0
  14. package/src/base_plugin.ts +102 -0
  15. package/src/components/autofill.ts +146 -0
  16. package/src/components/bottom_bar.ts +199 -0
  17. package/src/components/color_picker.ts +150 -0
  18. package/src/components/composer/autocomplete_dropdown.ts +135 -0
  19. package/src/components/composer/composer.ts +487 -0
  20. package/src/components/composer/content_editable_helper.ts +146 -0
  21. package/src/components/figures/chart.ts +70 -0
  22. package/src/components/figures/container.ts +268 -0
  23. package/src/components/figures/text_figure.ts +36 -0
  24. package/src/components/grid.ts +635 -0
  25. package/src/components/helpers/dom_helpers.ts +7 -0
  26. package/src/components/helpers/drag_and_drop.ts +17 -0
  27. package/src/components/icons.ts +36 -0
  28. package/src/components/index.ts +1 -0
  29. package/src/components/menu.ts +288 -0
  30. package/src/components/overlay.ts +457 -0
  31. package/src/components/scrollbar.ts +22 -0
  32. package/src/components/selection_input.ts +168 -0
  33. package/src/components/side_panel/cell_is_rule_editor.ts +169 -0
  34. package/src/components/side_panel/chart_panel.ts +104 -0
  35. package/src/components/side_panel/color_scale_rule_editor.ts +145 -0
  36. package/src/components/side_panel/conditional_formatting.ts +396 -0
  37. package/src/components/side_panel/side_panel.ts +127 -0
  38. package/src/components/side_panel/translations_terms.ts +45 -0
  39. package/src/components/spreadsheet.ts +198 -0
  40. package/src/components/top_bar.ts +535 -0
  41. package/src/constants.ts +26 -0
  42. package/src/data.ts +149 -0
  43. package/src/fonts.ts +41 -0
  44. package/src/formulas/compiler.ts +258 -0
  45. package/src/formulas/composer_tokenizer.ts +70 -0
  46. package/src/formulas/index.ts +15 -0
  47. package/src/formulas/normalize.ts +52 -0
  48. package/src/formulas/parser.ts +280 -0
  49. package/src/formulas/range_tokenizer.ts +97 -0
  50. package/src/formulas/tokenizer.ts +242 -0
  51. package/src/functions/arguments.ts +114 -0
  52. package/src/functions/dates.ts +302 -0
  53. package/src/functions/helpers.ts +592 -0
  54. package/src/functions/index.ts +52 -0
  55. package/src/functions/module_database.ts +282 -0
  56. package/src/functions/module_date.ts +743 -0
  57. package/src/functions/module_info.ts +69 -0
  58. package/src/functions/module_logical.ts +208 -0
  59. package/src/functions/module_lookup.ts +185 -0
  60. package/src/functions/module_math.ts +1252 -0
  61. package/src/functions/module_operators.ts +291 -0
  62. package/src/functions/module_statistical.ts +882 -0
  63. package/src/functions/module_text.ts +370 -0
  64. package/src/helpers/color.ts +30 -0
  65. package/src/helpers/coordinates.ts +71 -0
  66. package/src/helpers/grid_manipulation.ts +68 -0
  67. package/src/helpers/index.ts +7 -0
  68. package/src/helpers/misc.ts +76 -0
  69. package/src/helpers/numbers.ts +117 -0
  70. package/src/helpers/uuid.ts +19 -0
  71. package/src/helpers/zones.ts +263 -0
  72. package/src/history.ts +186 -0
  73. package/src/index.ts +84 -0
  74. package/src/model.ts +261 -0
  75. package/src/plugins/autofill.ts +412 -0
  76. package/src/plugins/chart.ts +404 -0
  77. package/src/plugins/clipboard.ts +461 -0
  78. package/src/plugins/conditional_format.ts +445 -0
  79. package/src/plugins/core.ts +1502 -0
  80. package/src/plugins/edition.ts +157 -0
  81. package/src/plugins/evaluation.ts +428 -0
  82. package/src/plugins/figures.ts +123 -0
  83. package/src/plugins/formatting.ts +630 -0
  84. package/src/plugins/highlight.ts +187 -0
  85. package/src/plugins/index.ts +32 -0
  86. package/src/plugins/merge.ts +524 -0
  87. package/src/plugins/renderer.ts +571 -0
  88. package/src/plugins/selection.ts +562 -0
  89. package/src/plugins/selection_inputs.ts +326 -0
  90. package/src/registries/autofill_modifiers.ts +76 -0
  91. package/src/registries/autofill_rules.ts +98 -0
  92. package/src/registries/figure_registry.ts +30 -0
  93. package/src/registries/index.ts +7 -0
  94. package/src/registries/menu_items_registry.ts +110 -0
  95. package/src/registries/menus/cell_menu_registry.ts +79 -0
  96. package/src/registries/menus/col_menu_registry.ts +63 -0
  97. package/src/registries/menus/index.ts +6 -0
  98. package/src/registries/menus/menu_items_actions.ts +425 -0
  99. package/src/registries/menus/row_menu_registry.ts +63 -0
  100. package/src/registries/menus/sheet_menu_registry.ts +75 -0
  101. package/src/registries/menus/topbar_menu_registry.ts +204 -0
  102. package/src/registries/side_panel_registry.ts +26 -0
  103. package/src/registries/topbar_component_registry.ts +12 -0
  104. package/src/registry.ts +51 -0
  105. package/src/translation.ts +44 -0
  106. package/src/types/autofill.ts +48 -0
  107. package/src/types/chart.ts +26 -0
  108. package/src/types/commands.ts +716 -0
  109. package/src/types/conditional_formatting.ts +124 -0
  110. package/src/types/env.ts +13 -0
  111. package/src/types/functions.ts +35 -0
  112. package/src/types/getters.ts +103 -0
  113. package/src/types/index.ts +20 -0
  114. package/src/types/misc.ts +143 -0
  115. package/src/types/rendering.ts +41 -0
  116. package/src/types/workbook_data.ts +62 -0
  117. package/tests/__mocks__/uuid.ts +7 -0
  118. package/tests/canvas.mock.ts +34 -0
  119. package/tests/components/__mocks__/content_editable_helper.ts +79 -0
  120. package/tests/components/__mocks__/scrollbar.ts +18 -0
  121. package/tests/components/__snapshots__/autocomplete_dropdown_test.ts.snap +29 -0
  122. package/tests/components/__snapshots__/bottom_bar_test.ts.snap +75 -0
  123. package/tests/components/__snapshots__/context_menu_test.ts.snap +88 -0
  124. package/tests/components/__snapshots__/grid_test.ts.snap +60 -0
  125. package/tests/components/__snapshots__/spreadsheet_test.ts.snap +455 -0
  126. package/tests/components/__snapshots__/top_bar_test.ts.snap +705 -0
  127. package/tests/components/autocomplete_dropdown_test.ts +315 -0
  128. package/tests/components/autofill_test.ts +167 -0
  129. package/tests/components/bottom_bar_test.ts +262 -0
  130. package/tests/components/chart_side_panel_test.ts +123 -0
  131. package/tests/components/composer_test.ts +400 -0
  132. package/tests/components/context_menu_test.ts +825 -0
  133. package/tests/components/grid_manipulation_test.ts +163 -0
  134. package/tests/components/grid_test.ts +581 -0
  135. package/tests/components/overlay_test.ts +541 -0
  136. package/tests/components/selection_input_test.ts +259 -0
  137. package/tests/components/side_panel_test.ts +148 -0
  138. package/tests/components/spreadsheet_test.ts +194 -0
  139. package/tests/components/top_bar_test.ts +427 -0
  140. package/tests/data_test.ts +175 -0
  141. package/tests/dom_helper.ts +42 -0
  142. package/tests/formulas/__snapshots__/compiler_test.ts.snap +302 -0
  143. package/tests/formulas/compiler_test.ts +266 -0
  144. package/tests/formulas/composer_tokenizer_test.ts +137 -0
  145. package/tests/formulas/expressions_test.ts +57 -0
  146. package/tests/formulas/formulas_test.ts +80 -0
  147. package/tests/formulas/normalize_test.ts +82 -0
  148. package/tests/formulas/parser_test.ts +224 -0
  149. package/tests/formulas/range_tokenizer_test.ts +187 -0
  150. package/tests/formulas/tokenizer_test.ts +164 -0
  151. package/tests/functions/arguments_test.ts +141 -0
  152. package/tests/functions/dates_test.ts +1081 -0
  153. package/tests/functions/functions_test.ts +53 -0
  154. package/tests/functions/helper_test.ts +98 -0
  155. package/tests/functions/module_database_test.ts +311 -0
  156. package/tests/functions/module_date_test.ts +941 -0
  157. package/tests/functions/module_info_test.ts +139 -0
  158. package/tests/functions/module_logical_test.ts +369 -0
  159. package/tests/functions/module_lookup_test.ts +541 -0
  160. package/tests/functions/module_math_test.ts +2482 -0
  161. package/tests/functions/module_operators_test.ts +955 -0
  162. package/tests/functions/module_statistical_test.ts +2014 -0
  163. package/tests/functions/module_text_test.ts +667 -0
  164. package/tests/helpers/coordinates_test.ts +25 -0
  165. package/tests/helpers/misc_test.ts +95 -0
  166. package/tests/helpers/numbers_test.ts +196 -0
  167. package/tests/helpers/zones_test.ts +97 -0
  168. package/tests/helpers.ts +384 -0
  169. package/tests/menu_items_registry_test.ts +540 -0
  170. package/tests/model/plugins/__snapshots__/chart_test.ts.snap +90 -0
  171. package/tests/model/plugins/chart_test.ts +562 -0
  172. package/tests/model_test.ts +82 -0
  173. package/tests/plugins/__snapshots__/conditional_formatting_test.ts.snap +131 -0
  174. package/tests/plugins/__snapshots__/renderer_test.ts.snap +371 -0
  175. package/tests/plugins/autofill_test.ts +457 -0
  176. package/tests/plugins/borders_test.ts +295 -0
  177. package/tests/plugins/clipboard_test.ts +1180 -0
  178. package/tests/plugins/conditional_formatting_test.ts +1253 -0
  179. package/tests/plugins/core_test.ts +614 -0
  180. package/tests/plugins/edition_test.ts +100 -0
  181. package/tests/plugins/evaluation_async_test.ts +332 -0
  182. package/tests/plugins/evaluation_dates_test.ts +79 -0
  183. package/tests/plugins/evaluation_test.ts +901 -0
  184. package/tests/plugins/figures_test.ts +327 -0
  185. package/tests/plugins/formatting_test.ts +391 -0
  186. package/tests/plugins/grid_manipulation_test.ts +1366 -0
  187. package/tests/plugins/highlight_test.ts +413 -0
  188. package/tests/plugins/history_test.ts +142 -0
  189. package/tests/plugins/import_export_test.ts +276 -0
  190. package/tests/plugins/merges_test.ts +490 -0
  191. package/tests/plugins/navigation_test.ts +181 -0
  192. package/tests/plugins/plugins/evaluation_test.ts +111 -0
  193. package/tests/plugins/renderer_test.ts +598 -0
  194. package/tests/plugins/resizing_test.ts +152 -0
  195. package/tests/plugins/selection_input_test.ts +409 -0
  196. package/tests/plugins/selection_test.ts +442 -0
  197. package/tests/plugins/sheets_test.ts +643 -0
  198. package/tests/plugins/style_test.ts +90 -0
  199. package/tsconfig.json +22 -0
@@ -0,0 +1,384 @@
1
+ import { Component, hooks, tags, useState } from "@odoo/owl";
2
+ import { Grid } from "../src/components/grid";
3
+ import { SidePanel } from "../src/components/side_panel/side_panel";
4
+ import { TopBar } from "../src/components/top_bar";
5
+ import { functionRegistry } from "../src/functions/index";
6
+ import { toCartesian, toXC } from "../src/helpers/index";
7
+ import { Model } from "../src/model";
8
+ import {
9
+ Cell,
10
+ ColorScaleThreshold,
11
+ CommandTypes,
12
+ ConditionalFormat,
13
+ GridRenderingContext,
14
+ Sheet,
15
+ SpreadsheetEnv,
16
+ Style,
17
+ Zone,
18
+ } from "../src/types";
19
+ import "./canvas.mock";
20
+ export { setNextId as mockUuidV4To } from "./__mocks__/uuid";
21
+
22
+ const functions = functionRegistry.content;
23
+ const functionMap = functionRegistry.mapping;
24
+ const { xml } = tags;
25
+ const { useRef, useSubEnv } = hooks;
26
+
27
+ //------------------------------------------------------------------------------
28
+ // Helpers
29
+ //------------------------------------------------------------------------------
30
+
31
+ export function nextMicroTick(): Promise<void> {
32
+ return Promise.resolve();
33
+ }
34
+
35
+ const origSetTimeout = window.setTimeout;
36
+ export async function nextTick(): Promise<void> {
37
+ return new Promise(function (resolve) {
38
+ origSetTimeout(() => Component.scheduler.requestAnimationFrame(() => resolve()));
39
+ });
40
+ }
41
+
42
+ export function makeTestFixture() {
43
+ let fixture = document.createElement("div");
44
+ document.body.appendChild(fixture);
45
+ return fixture;
46
+ }
47
+
48
+ const t = (s: string): string => s;
49
+
50
+ export class MockClipboard {
51
+ private content: string = "Some random clipboard content";
52
+
53
+ readText(): Promise<string> {
54
+ return Promise.resolve(this.content);
55
+ }
56
+
57
+ writeText(content: string): Promise<void> {
58
+ this.content = content;
59
+ return Promise.resolve();
60
+ }
61
+
62
+ addEventListener() {}
63
+ removeEventListener() {}
64
+ dispatchEvent() {
65
+ return false;
66
+ }
67
+ }
68
+
69
+ export function testUndoRedo(model: Model, expect: jest.Expect, command: CommandTypes, args: any) {
70
+ const before = model.exportData();
71
+ model.dispatch(command, args);
72
+ const after = model.exportData();
73
+ model.dispatch("UNDO");
74
+ expect(model.exportData()).toEqual(before);
75
+ model.dispatch("REDO");
76
+ expect(model.exportData()).toEqual(after);
77
+ }
78
+
79
+ export class GridParent extends Component<any, SpreadsheetEnv> {
80
+ static template = xml`
81
+ <div class="parent">
82
+ <TopBar model="model" t-on-ask-confirmation="askConfirmation"/>
83
+ <Grid model="model" t-ref="grid"/>
84
+ <SidePanel t-if="sidePanel.isOpen"
85
+ t-on-close-side-panel="sidePanel.isOpen = false"
86
+ model="model"
87
+ component="sidePanel.component"
88
+ panelProps="sidePanel.panelProps" />
89
+ </div>`;
90
+
91
+ static _t = t;
92
+ static components = { Grid, SidePanel, TopBar };
93
+ model: Model;
94
+ grid: any = useRef("grid");
95
+ sidePanel = useState({ isOpen: false, panelProps: {} } as {
96
+ isOpen: boolean;
97
+ component?: string;
98
+ panelProps: any;
99
+ });
100
+
101
+ constructor(model: Model) {
102
+ super();
103
+ useSubEnv({
104
+ openSidePanel: (panel: string, panelProps: any = {}) => this.openSidePanel(panel, panelProps),
105
+ dispatch: model.dispatch,
106
+ getters: model.getters,
107
+ _t: GridParent._t,
108
+ clipboard: new MockClipboard(),
109
+ });
110
+
111
+ const drawGrid = model.drawGrid;
112
+ model.drawGrid = function (context: GridRenderingContext) {
113
+ context.viewport.width = 1000;
114
+ context.viewport.height = 1000;
115
+ drawGrid.call(this, context);
116
+ };
117
+ this.model = model;
118
+ }
119
+
120
+ mounted() {
121
+ this.model.on("update", this, this.render);
122
+ }
123
+
124
+ willUnmount() {
125
+ this.model.off("update", this);
126
+ }
127
+
128
+ openSidePanel(panel: string, panelProps: any) {
129
+ this.sidePanel.component = panel;
130
+ this.sidePanel.panelProps = panelProps;
131
+ this.sidePanel.isOpen = true;
132
+ }
133
+ }
134
+
135
+ type GridDescr = { [xc: string]: string | undefined };
136
+ type FormattedGridDescr = GridDescr;
137
+ type GridResult = { [xc: string]: any };
138
+
139
+ export function getGrid(model: Model): GridResult {
140
+ const result = {};
141
+ for (let xc in model["workbook"].activeSheet.cells) {
142
+ const cell = model["workbook"].activeSheet.cells[xc];
143
+ result[xc] = cell.value;
144
+ }
145
+ return result;
146
+ }
147
+
148
+ /**
149
+ * Evaluate the final state of a grid according to the different values ​​and
150
+ * different functions submitted in the grid cells
151
+ *
152
+ * Examples:
153
+ * {A1: "=sum(B2:B3)", B2: "2", B3: "3"} => {A1: 5, B2: 2, B3: 3}
154
+ * {B5: "5", D8: "2.6", W4: "=round(A2)"} => {B5: 5, D8: 2.6, W4: 3}
155
+ */
156
+ export function evaluateGrid(grid: GridDescr): GridResult {
157
+ const model = new Model();
158
+ for (let xc in grid) {
159
+ if (grid[xc]) {
160
+ model.dispatch("SET_VALUE", { xc, text: grid[xc]! });
161
+ }
162
+ }
163
+ const result = {};
164
+ for (let xc in grid) {
165
+ const cell = getCell(model, xc);
166
+ result[xc] = cell ? cell.value : "";
167
+ }
168
+ return result;
169
+ }
170
+
171
+ export function evaluateGridText(grid: GridDescr): FormattedGridDescr {
172
+ const model = new Model();
173
+ for (let xc in grid) {
174
+ if (grid[xc] !== undefined) {
175
+ model.dispatch("SET_VALUE", { xc, text: grid[xc]! });
176
+ }
177
+ }
178
+ const result = {};
179
+ for (let xc in grid) {
180
+ const cell = getCell(model, xc);
181
+ result[xc] = cell ? model.getters.getCellText(cell) : "";
182
+ }
183
+ return result;
184
+ }
185
+
186
+ /**
187
+ * Evaluate the final state of a cell according to the different values ​​and
188
+ * different functions submitted in a grid cells
189
+ *
190
+ * Examples:
191
+ * "A2", {A1: "41", A2: "42", A3: "43"} => 42
192
+ * "A1", {A1: "=sum(A2:A4)", A2: "2", A3: "3", "A4": "4"} => 9
193
+ */
194
+ export function evaluateCell(xc: string, grid: GridDescr): any {
195
+ const gridResult = evaluateGrid(grid);
196
+ return gridResult[xc];
197
+ }
198
+
199
+ export function evaluateCellText(xc: string, grid: GridDescr): string {
200
+ const gridResult = evaluateGridText(grid);
201
+ return gridResult[xc] || "";
202
+ }
203
+
204
+ //------------------------------------------------------------------------------
205
+ // DOM/Misc Mocks
206
+ //------------------------------------------------------------------------------
207
+
208
+ // modifies scheduler to make it faster to test components
209
+ Component.scheduler.requestAnimationFrame = function (callback: FrameRequestCallback) {
210
+ origSetTimeout(callback, 1);
211
+ return 1;
212
+ };
213
+
214
+ interface Deferred extends Promise<any> {
215
+ resolve(val?: any): void;
216
+ reject(): void;
217
+ }
218
+
219
+ export function makeDeferred(): Deferred {
220
+ let resolve, reject;
221
+ let def = new Promise((_resolve, _reject) => {
222
+ resolve = _resolve;
223
+ reject = _reject;
224
+ });
225
+ (<Deferred>def).resolve = resolve;
226
+ (<Deferred>def).reject = reject;
227
+ return <Deferred>def;
228
+ }
229
+
230
+ interface PatchResult {
231
+ calls: any[];
232
+ resolveAll: () => void;
233
+ }
234
+ export function patchWaitFunction(): PatchResult {
235
+ const result: PatchResult = {
236
+ calls: [],
237
+ resolveAll() {
238
+ result.calls.forEach((c) => c.def.resolve(c.val));
239
+ result.calls = [];
240
+ },
241
+ };
242
+ functionMap["WAIT"] = (arg) => {
243
+ const def = makeDeferred();
244
+ const call = { def, val: arg };
245
+ result.calls.push(call);
246
+ return def;
247
+ };
248
+ return result;
249
+ }
250
+
251
+ export const patch = patchWaitFunction();
252
+
253
+ let timeHandlers: Function[] = [];
254
+ (window as any).setTimeout = (cb) => {
255
+ timeHandlers.push(cb);
256
+ };
257
+
258
+ function clearTimers() {
259
+ let handlers = timeHandlers.slice();
260
+ timeHandlers = [];
261
+ for (let cb of handlers) {
262
+ cb();
263
+ }
264
+ }
265
+
266
+ export async function asyncComputations() {
267
+ clearTimers();
268
+ await nextTick();
269
+ }
270
+
271
+ export async function waitForRecompute() {
272
+ patch.resolveAll();
273
+ await nextTick();
274
+ clearTimers();
275
+ }
276
+ /*
277
+ * Remove all functions from the internal function list.
278
+ */
279
+ export function resetFunctions() {
280
+ Object.keys(functionMap).forEach((k) => {
281
+ delete functionMap[k];
282
+ });
283
+
284
+ Object.keys(functions).forEach((k) => {
285
+ delete functions[k];
286
+ });
287
+ }
288
+
289
+ export function getActiveXc(model: Model): string {
290
+ return toXC(...model.getters.getPosition());
291
+ }
292
+
293
+ export function getCell(model: Model, xc: string, sheet?: string): Cell | null {
294
+ let [col, row] = toCartesian(xc);
295
+ return model.getters.getCell(col, row, sheet);
296
+ }
297
+
298
+ export function getSheet(model: Model, index: number = 0): Sheet {
299
+ const id = model["workbook"].visibleSheets[index];
300
+ return model["workbook"].sheets[id];
301
+ }
302
+
303
+ export function zone(str: string): Zone {
304
+ let [tl, br] = str.split(":");
305
+ if (!br) {
306
+ br = tl;
307
+ }
308
+ const [left, top] = toCartesian(tl);
309
+ const [right, bottom] = toCartesian(br);
310
+ return { left, top, right, bottom };
311
+ }
312
+
313
+ export function target(str: string): Zone[] {
314
+ return str.split(",").map(zone);
315
+ }
316
+
317
+ export function createEqualCF(
318
+ ranges: string[],
319
+ value: string,
320
+ style: Style,
321
+ id: string
322
+ ): ConditionalFormat {
323
+ return {
324
+ ranges,
325
+ id,
326
+ rule: { values: [value], operator: "Equal", type: "CellIsRule", style },
327
+ };
328
+ }
329
+
330
+ export function createColorScale(
331
+ id: string,
332
+ ranges: string[],
333
+ min: ColorScaleThreshold,
334
+ max: ColorScaleThreshold,
335
+ mid?: ColorScaleThreshold
336
+ ): ConditionalFormat {
337
+ return {
338
+ ranges,
339
+ id,
340
+ rule: { type: "ColorScaleRule", minimum: min, maximum: max, midpoint: mid },
341
+ };
342
+ }
343
+
344
+ /**
345
+ * The Touch API is currently experimental (mid 2020).
346
+ * This implementation is used in test to easily trigger TouchEvents.
347
+ * (TouchEvent is not experimental and supported by all major browsers.)
348
+ *
349
+ * https://developer.mozilla.org/en-US/docs/Web/API/Touch
350
+ */
351
+ export class Touch {
352
+ readonly altitudeAngle: number;
353
+ readonly azimuthAngle: number;
354
+ readonly clientX: number;
355
+ readonly clientY: number;
356
+ readonly force: number;
357
+ readonly identifier: number;
358
+ readonly pageX: number;
359
+ readonly pageY: number;
360
+ readonly radiusX: number;
361
+ readonly radiusY: number;
362
+ readonly rotationAngle: number;
363
+ readonly screenX: number;
364
+ readonly screenY: number;
365
+ readonly target: EventTarget;
366
+ readonly touchType: TouchType;
367
+ constructor(touchInitDict: TouchInit) {
368
+ this.identifier = touchInitDict.identifier;
369
+ this.target = touchInitDict.target;
370
+ this.altitudeAngle = touchInitDict.altitudeAngle || 0;
371
+ this.azimuthAngle = touchInitDict.azimuthAngle || 0;
372
+ this.clientX = touchInitDict.clientX || 0;
373
+ this.clientY = touchInitDict.clientY || 0;
374
+ this.force = touchInitDict.force || 0;
375
+ this.pageX = touchInitDict.pageX || 0;
376
+ this.pageY = touchInitDict.pageY || 0;
377
+ this.radiusX = touchInitDict.radiusX || 0;
378
+ this.radiusY = touchInitDict.radiusY || 0;
379
+ this.rotationAngle = touchInitDict.rotationAngle || 0;
380
+ this.screenX = touchInitDict.screenX || 0;
381
+ this.screenY = touchInitDict.screenY || 0;
382
+ this.touchType = touchInitDict.touchType || "direct";
383
+ }
384
+ }