js-draw 0.21.0 → 0.22.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 (78) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/dist/bundle.js +3 -3
  3. package/dist/bundledStyles.js +1 -1
  4. package/dist/cjs/src/Color4.js +2 -2
  5. package/dist/cjs/src/Editor.d.ts +1 -3
  6. package/dist/cjs/src/EditorImage.js +8 -2
  7. package/dist/cjs/src/Viewport.js +1 -1
  8. package/dist/cjs/src/commands/Command.js +1 -1
  9. package/dist/cjs/src/commands/SerializableCommand.js +1 -1
  10. package/dist/cjs/src/commands/uniteCommands.js +5 -0
  11. package/dist/cjs/src/components/AbstractComponent.js +6 -1
  12. package/dist/cjs/src/components/ImageComponent.d.ts +6 -6
  13. package/dist/cjs/src/components/ImageComponent.js +17 -12
  14. package/dist/cjs/src/components/TextComponent.js +1 -1
  15. package/dist/cjs/src/localizations/de.js +1 -1
  16. package/dist/cjs/src/math/Mat33.js +1 -1
  17. package/dist/cjs/src/math/Path.js +1 -1
  18. package/dist/cjs/src/math/Rect2.js +1 -1
  19. package/dist/cjs/src/math/Vec3.js +1 -1
  20. package/dist/cjs/src/rendering/Display.d.ts +1 -1
  21. package/dist/cjs/src/rendering/Display.js +1 -2
  22. package/dist/cjs/src/toolbar/HTMLToolbar.d.ts +2 -0
  23. package/dist/cjs/src/toolbar/HTMLToolbar.js +71 -12
  24. package/dist/cjs/src/toolbar/localization.d.ts +1 -0
  25. package/dist/cjs/src/toolbar/localization.js +1 -0
  26. package/dist/cjs/src/toolbar/makeColorInput.js +8 -0
  27. package/dist/cjs/src/toolbar/widgets/BaseToolWidget.d.ts +0 -1
  28. package/dist/cjs/src/toolbar/widgets/BaseToolWidget.js +0 -1
  29. package/dist/cjs/src/toolbar/widgets/BaseWidget.d.ts +5 -0
  30. package/dist/cjs/src/toolbar/widgets/BaseWidget.js +24 -7
  31. package/dist/cjs/src/toolbar/widgets/DocumentPropertiesWidget.js +1 -1
  32. package/dist/cjs/src/toolbar/widgets/EraserToolWidget.js +1 -1
  33. package/dist/cjs/src/toolbar/widgets/InsertImageWidget.js +1 -1
  34. package/dist/cjs/src/toolbar/widgets/PenToolWidget.js +1 -1
  35. package/dist/cjs/src/toolbar/widgets/TextToolWidget.js +1 -1
  36. package/dist/cjs/src/tools/SelectionTool/Selection.js +5 -2
  37. package/dist/cjs/src/tools/SelectionTool/SelectionTool.js +1 -1
  38. package/dist/cjs/src/types.d.ts +2 -0
  39. package/dist/mjs/src/Color4.mjs +2 -1
  40. package/dist/mjs/src/Editor.d.ts +1 -3
  41. package/dist/mjs/src/EditorImage.mjs +10 -2
  42. package/dist/mjs/src/Viewport.mjs +2 -1
  43. package/dist/mjs/src/commands/Command.mjs +2 -1
  44. package/dist/mjs/src/commands/SerializableCommand.mjs +2 -1
  45. package/dist/mjs/src/commands/uniteCommands.mjs +5 -0
  46. package/dist/mjs/src/components/AbstractComponent.mjs +7 -1
  47. package/dist/mjs/src/components/ImageComponent.d.ts +6 -6
  48. package/dist/mjs/src/components/ImageComponent.mjs +17 -12
  49. package/dist/mjs/src/components/TextComponent.mjs +2 -1
  50. package/dist/mjs/src/localizations/de.mjs +1 -1
  51. package/dist/mjs/src/math/Mat33.mjs +2 -1
  52. package/dist/mjs/src/math/Path.mjs +2 -1
  53. package/dist/mjs/src/math/Rect2.mjs +2 -1
  54. package/dist/mjs/src/math/Vec3.mjs +2 -1
  55. package/dist/mjs/src/rendering/Display.d.ts +1 -1
  56. package/dist/mjs/src/rendering/Display.mjs +1 -2
  57. package/dist/mjs/src/toolbar/HTMLToolbar.d.ts +2 -0
  58. package/dist/mjs/src/toolbar/HTMLToolbar.mjs +72 -12
  59. package/dist/mjs/src/toolbar/localization.d.ts +1 -0
  60. package/dist/mjs/src/toolbar/localization.mjs +1 -0
  61. package/dist/mjs/src/toolbar/makeColorInput.mjs +8 -0
  62. package/dist/mjs/src/toolbar/widgets/BaseToolWidget.d.ts +0 -1
  63. package/dist/mjs/src/toolbar/widgets/BaseToolWidget.mjs +0 -1
  64. package/dist/mjs/src/toolbar/widgets/BaseWidget.d.ts +5 -0
  65. package/dist/mjs/src/toolbar/widgets/BaseWidget.mjs +24 -7
  66. package/dist/mjs/src/toolbar/widgets/DocumentPropertiesWidget.mjs +2 -1
  67. package/dist/mjs/src/toolbar/widgets/EraserToolWidget.mjs +2 -1
  68. package/dist/mjs/src/toolbar/widgets/InsertImageWidget.mjs +2 -1
  69. package/dist/mjs/src/toolbar/widgets/PenToolWidget.mjs +2 -1
  70. package/dist/mjs/src/toolbar/widgets/TextToolWidget.mjs +2 -1
  71. package/dist/mjs/src/tools/SelectionTool/Selection.mjs +6 -2
  72. package/dist/mjs/src/tools/SelectionTool/SelectionTool.mjs +2 -1
  73. package/dist/mjs/src/types.d.ts +2 -0
  74. package/package.json +13 -13
  75. package/src/toolbar/toolbar.css +7 -0
  76. package/tsconfig-typedoc.json +7 -0
  77. package/tsconfig.json +2 -0
  78. package/typedoc.json +1 -0
@@ -26,6 +26,7 @@ export interface ToolbarLocalization {
26
26
  duplicateSelection: string;
27
27
  pickColorFromScreen: string;
28
28
  clickToPickColorAnnouncement: string;
29
+ colorSelectionCanceledAnnouncement: string;
29
30
  reformatSelection: string;
30
31
  undo: string;
31
32
  redo: string;
@@ -26,6 +26,7 @@ exports.defaultToolbarLocalization = {
26
26
  selectPenType: 'Pen type: ',
27
27
  pickColorFromScreen: 'Pick color from screen',
28
28
  clickToPickColorAnnouncement: 'Click on the screen to pick a color',
29
+ colorSelectionCanceledAnnouncement: 'Color selection canceled',
29
30
  selectionToolKeyboardShortcuts: 'Selection tool: Use arrow keys to move selected items, lowercase/uppercase ‘i’ and ‘o’ to resize.',
30
31
  documentProperties: 'Page',
31
32
  backgroundColor: 'Background Color: ',
@@ -48,6 +48,11 @@ const makeColorInput = (editor, onColorChange) => {
48
48
  open: true,
49
49
  });
50
50
  pipetteController.cancel();
51
+ // Focus the Coloris color picker, if it exists.
52
+ // Don't focus the text input within the color picker, however,
53
+ // as this displays a keyboard on mobile devices.
54
+ const colorPickerElem = document.querySelector('#clr-picker #clr-hue-slider');
55
+ colorPickerElem === null || colorPickerElem === void 0 ? void 0 : colorPickerElem.focus();
51
56
  });
52
57
  colorInput.addEventListener('close', () => {
53
58
  editor.notifier.dispatch(types_1.EditorEventType.ColorPickerToggled, {
@@ -55,6 +60,8 @@ const makeColorInput = (editor, onColorChange) => {
55
60
  open: false,
56
61
  });
57
62
  onInputEnd();
63
+ // Restore focus to the input that opened the color picker
64
+ colorInput.focus();
58
65
  });
59
66
  const setColorInputValue = (color) => {
60
67
  if (typeof color === 'object') {
@@ -101,6 +108,7 @@ const addPipetteTool = (editor, container, onColorChange) => {
101
108
  // If already picking, cancel it.
102
109
  if (pipetteButton.classList.contains('active')) {
103
110
  endColorSelectMode();
111
+ editor.announceForAccessibility(editor.localization.colorSelectionCanceledAnnouncement);
104
112
  return;
105
113
  }
106
114
  pipetteTool === null || pipetteTool === void 0 ? void 0 : pipetteTool.setColorListener(pipetteColorPreview, pipetteColorSelect);
@@ -3,7 +3,6 @@ import BaseTool from '../../tools/BaseTool';
3
3
  import { ToolbarLocalization } from '../localization';
4
4
  import BaseWidget from './BaseWidget';
5
5
  export default abstract class BaseToolWidget extends BaseWidget {
6
- protected editor: Editor;
7
6
  protected targetTool: BaseTool;
8
7
  constructor(editor: Editor, targetTool: BaseTool, id: string, localizationTable?: ToolbarLocalization);
9
8
  protected handleClick(): void;
@@ -8,7 +8,6 @@ const BaseWidget_1 = __importDefault(require("./BaseWidget"));
8
8
  class BaseToolWidget extends BaseWidget_1.default {
9
9
  constructor(editor, targetTool, id, localizationTable) {
10
10
  super(editor, id, localizationTable);
11
- this.editor = editor;
12
11
  this.targetTool = targetTool;
13
12
  editor.notifier.on(types_1.EditorEventType.ToolEnabled, toolEvt => {
14
13
  if (toolEvt.kind !== types_1.EditorEventType.ToolEnabled) {
@@ -37,6 +37,11 @@ export default abstract class BaseWidget {
37
37
  protected get hasDropdown(): boolean;
38
38
  protected addSubWidget(widget: BaseWidget): void;
39
39
  private toolbarWidgetToggleListener;
40
+ /**
41
+ * Adds this to `parent`. This can only be called once for each ToolbarWidget.
42
+ * Returns the element that was just added to `parent`.
43
+ * @internal
44
+ */
40
45
  addTo(parent: HTMLElement): HTMLElement;
41
46
  protected updateIcon(): void;
42
47
  setDisabled(disabled: boolean): void;
@@ -140,14 +140,26 @@ class BaseWidget {
140
140
  const id = widget.getUniqueIdIn(this.subWidgets);
141
141
  this.subWidgets[id] = widget;
142
142
  }
143
- // Adds this to [parent]. This can only be called once for each ToolbarWidget.
144
- // Returns the element that was just added to `parent`.
145
- // @internal
143
+ /**
144
+ * Adds this to `parent`. This can only be called once for each ToolbarWidget.
145
+ * Returns the element that was just added to `parent`.
146
+ * @internal
147
+ */
146
148
  addTo(parent) {
147
- this.label.innerText = this.getTitle();
148
- this.setupActionBtnClickListener(this.button);
149
+ // Update title and icon
149
150
  this.icon = null;
150
151
  this.updateIcon();
152
+ this.label.innerText = this.getTitle();
153
+ const longLabelCSSClass = 'long-label';
154
+ if (this.label.innerText.length > 7) {
155
+ this.label.classList.add(longLabelCSSClass);
156
+ }
157
+ else {
158
+ this.label.classList.remove(longLabelCSSClass);
159
+ }
160
+ // Click functionality
161
+ this.setupActionBtnClickListener(this.button);
162
+ // Clear anything already in this.container.
151
163
  this.container.replaceChildren();
152
164
  this.button.replaceChildren(this.icon, this.label);
153
165
  this.container.appendChild(this.button);
@@ -204,13 +216,18 @@ class BaseWidget {
204
216
  if (currentlySelected === selected) {
205
217
  return;
206
218
  }
219
+ // Ensure that accessibility tools check and read the value of
220
+ // aria-checked.
221
+ // TODO: Ensure that 'role' is set to 'switch' by default for selectable
222
+ // buttons.
223
+ this.button.setAttribute('role', 'switch');
207
224
  if (selected) {
208
225
  this.container.classList.add('selected');
209
- this.button.ariaSelected = 'true';
226
+ this.button.setAttribute('aria-checked', 'true');
210
227
  }
211
228
  else {
212
229
  this.container.classList.remove('selected');
213
- this.button.ariaSelected = 'false';
230
+ this.button.setAttribute('aria-checked', 'false');
214
231
  }
215
232
  }
216
233
  setDropdownVisible(visible) {
@@ -197,5 +197,5 @@ class DocumentPropertiesWidget extends BaseWidget_1.default {
197
197
  return true;
198
198
  }
199
199
  }
200
- exports.default = DocumentPropertiesWidget;
201
200
  DocumentPropertiesWidget.idCounter = 0;
201
+ exports.default = DocumentPropertiesWidget;
@@ -59,5 +59,5 @@ class EraserToolWidget extends BaseToolWidget_1.default {
59
59
  }
60
60
  }
61
61
  }
62
- exports.default = EraserToolWidget;
63
62
  EraserToolWidget.nextThicknessInputId = 0;
63
+ exports.default = EraserToolWidget;
@@ -172,5 +172,5 @@ class InsertImageWidget extends ActionButtonWidget_1.default {
172
172
  });
173
173
  }
174
174
  }
175
- exports.default = InsertImageWidget;
176
175
  InsertImageWidget.nextInputId = 0;
176
+ exports.default = InsertImageWidget;
@@ -222,5 +222,5 @@ class PenToolWidget extends BaseToolWidget_1.default {
222
222
  }
223
223
  }
224
224
  }
225
- exports.default = PenToolWidget;
226
225
  PenToolWidget.idCounter = 0;
226
+ exports.default = PenToolWidget;
@@ -111,5 +111,5 @@ class TextToolWidget extends BaseToolWidget_1.default {
111
111
  super.deserializeFrom(state);
112
112
  }
113
113
  }
114
- exports.default = TextToolWidget;
115
114
  TextToolWidget.idCounter = 0;
115
+ exports.default = TextToolWidget;
@@ -153,6 +153,9 @@ class Selection {
153
153
  this.transform = Mat33_1.default.identity;
154
154
  // Make the commands undo-able
155
155
  this.editor.dispatch(new Selection.ApplyTransformationCommand(this, selectedElems, fullTransform));
156
+ // Clear renderings of any in-progress transformations
157
+ const wetInkRenderer = this.editor.display.getWetInkRenderer();
158
+ wetInkRenderer.clear();
156
159
  }
157
160
  // Preview the effects of the current transformation on the selection
158
161
  previewTransformCmds() {
@@ -406,7 +409,6 @@ class Selection {
406
409
  return this.selectedElems;
407
410
  }
408
411
  }
409
- exports.default = Selection;
410
412
  _a = Selection;
411
413
  (() => {
412
414
  SerializableCommand_1.default.register('selection-tool-transform', (json, _editor) => {
@@ -471,7 +473,7 @@ Selection.ApplyTransformationCommand = class extends SerializableCommand_1.defau
471
473
  (_b = this.selection) === null || _b === void 0 ? void 0 : _b.setTransform(this.fullTransform.inverse(), false);
472
474
  (_c = this.selection) === null || _c === void 0 ? void 0 : _c.updateUI();
473
475
  yield editor.asyncUnapplyCommands(this.transformCommands, updateChunkSize, true);
474
- (_d = this.selection) === null || _d === void 0 ? void 0 : _d.setTransform(Mat33_1.default.identity);
476
+ (_d = this.selection) === null || _d === void 0 ? void 0 : _d.setTransform(Mat33_1.default.identity, false);
475
477
  (_e = this.selection) === null || _e === void 0 ? void 0 : _e.recomputeRegion();
476
478
  (_f = this.selection) === null || _f === void 0 ? void 0 : _f.updateUI();
477
479
  });
@@ -486,3 +488,4 @@ Selection.ApplyTransformationCommand = class extends SerializableCommand_1.defau
486
488
  return localizationTable.transformedElements(this.selectedElemIds.length);
487
489
  }
488
490
  };
491
+ exports.default = Selection;
@@ -393,7 +393,6 @@ class SelectionTool extends BaseTool_1.default {
393
393
  this.onSelectionUpdated();
394
394
  }
395
395
  }
396
- exports.default = SelectionTool;
397
396
  SelectionTool.handleableKeys = [
398
397
  'a', 'h', 'ArrowLeft',
399
398
  'd', 'l', 'ArrowRight',
@@ -403,3 +402,4 @@ SelectionTool.handleableKeys = [
403
402
  'i', 'I', 'o', 'O',
404
403
  'Control', 'Meta',
405
404
  ];
405
+ exports.default = SelectionTool;
@@ -9,6 +9,8 @@ import Pointer from './Pointer';
9
9
  import Color4 from './Color4';
10
10
  import Command from './commands/Command';
11
11
  import BaseWidget from './toolbar/widgets/BaseWidget';
12
+ export type HTMLPointerEventName = 'pointerdown' | 'pointermove' | 'pointerup' | 'pointercancel';
13
+ export type HTMLPointerEventFilter = (eventName: HTMLPointerEventName, event: PointerEvent) => boolean;
12
14
  export interface PointerEvtListener {
13
15
  onPointerDown(event: PointerEvt): boolean;
14
16
  onPointerMove(event: PointerEvt): void;
@@ -1,5 +1,5 @@
1
1
  import Vec3 from './math/Vec3.mjs';
2
- export default class Color4 {
2
+ class Color4 {
3
3
  constructor(
4
4
  /** Red component. Should be in the range [0, 1]. */
5
5
  r,
@@ -254,4 +254,5 @@ Color4.clay = Color4.ofRGB(0.8, 0.4, 0.2);
254
254
  Color4.black = Color4.ofRGB(0, 0, 0);
255
255
  Color4.gray = Color4.ofRGB(0.5, 0.5, 0.5);
256
256
  Color4.white = Color4.ofRGB(1, 1, 1);
257
+ export default Color4;
257
258
  export { Color4 };
@@ -1,6 +1,6 @@
1
1
  import EditorImage from './EditorImage';
2
2
  import ToolController from './tools/ToolController';
3
- import { InputEvtType, EditorNotifier, ImageLoader } from './types';
3
+ import { InputEvtType, EditorNotifier, ImageLoader, HTMLPointerEventFilter } from './types';
4
4
  import Command from './commands/Command';
5
5
  import UndoRedoHistory from './UndoRedoHistory';
6
6
  import Viewport from './Viewport';
@@ -14,8 +14,6 @@ import Rect2 from './math/Rect2';
14
14
  import { EditorLocalization } from './localization';
15
15
  import IconProvider from './toolbar/IconProvider';
16
16
  import AbstractComponent from './components/AbstractComponent';
17
- type HTMLPointerEventType = 'pointerdown' | 'pointermove' | 'pointerup' | 'pointercancel';
18
- type HTMLPointerEventFilter = (eventName: HTMLPointerEventType, event: PointerEvent) => boolean;
19
17
  export interface EditorSettings {
20
18
  /** Defaults to `RenderingMode.CanvasRenderer` */
21
19
  renderingMode: RenderingMode;
@@ -1,3 +1,7 @@
1
+ var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
2
+ if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
3
+ return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
4
+ };
1
5
  var _a, _b, _c;
2
6
  import Viewport from './Viewport.mjs';
3
7
  import AbstractComponent from './components/AbstractComponent.mjs';
@@ -16,7 +20,7 @@ export var EditorImageEventType;
16
20
  EditorImageEventType[EditorImageEventType["ExportViewportChanged"] = 0] = "ExportViewportChanged";
17
21
  })(EditorImageEventType || (EditorImageEventType = {}));
18
22
  // Handles lookup/storage of elements in the image
19
- export default class EditorImage {
23
+ class EditorImage {
20
24
  // @internal
21
25
  constructor() {
22
26
  this.root = new ImageNode();
@@ -194,6 +198,7 @@ EditorImage.AddElementCommand = (_b = class extends SerializableCommand {
194
198
  };
195
199
  }
196
200
  },
201
+ __setFunctionName(_b, "AddElementCommand"),
197
202
  (() => {
198
203
  SerializableCommand.register('add-element', (json, editor) => {
199
204
  const id = json.elemData.id;
@@ -241,6 +246,7 @@ EditorImage.SetImportExportRectCommand = (_c = class extends SerializableCommand
241
246
  };
242
247
  }
243
248
  },
249
+ __setFunctionName(_c, "SetImportExportRectCommand"),
244
250
  _c.commandId = 'set-import-export-rect',
245
251
  (() => {
246
252
  const commandId = _c.commandId;
@@ -261,8 +267,9 @@ EditorImage.SetImportExportRectCommand = (_c = class extends SerializableCommand
261
267
  });
262
268
  })(),
263
269
  _c);
270
+ export default EditorImage;
264
271
  /** Part of the Editor's image. @internal */
265
- export class ImageNode {
272
+ class ImageNode {
266
273
  constructor(parent = null) {
267
274
  this.parent = parent;
268
275
  this.targetChildCount = 30;
@@ -475,3 +482,4 @@ export class ImageNode {
475
482
  }
476
483
  }
477
484
  ImageNode.idCounter = 0;
485
+ export { ImageNode };
@@ -17,7 +17,7 @@ import { Vec2 } from './math/Vec2.mjs';
17
17
  import Vec3 from './math/Vec3.mjs';
18
18
  export class ViewportTransform extends Command {
19
19
  }
20
- export class Viewport {
20
+ class Viewport {
21
21
  // @internal
22
22
  constructor(onTransformChangeCallback) {
23
23
  this.onTransformChangeCallback = onTransformChangeCallback;
@@ -257,4 +257,5 @@ Viewport.ViewportTransform = (_a = class extends ViewportTransform {
257
257
  },
258
258
  _inverseTransform = new WeakMap(),
259
259
  _a);
260
+ export { Viewport };
260
261
  export default Viewport;
@@ -1,4 +1,4 @@
1
- export class Command {
1
+ class Command {
2
2
  // Called when the command is being deleted
3
3
  onDrop(_editor) { }
4
4
  static union(a, b) {
@@ -27,4 +27,5 @@ Command.empty = new class extends Command {
27
27
  apply(_editor) { }
28
28
  unapply(_editor) { }
29
29
  };
30
+ export { Command };
30
31
  export default Command;
@@ -1,5 +1,5 @@
1
1
  import Command from './Command.mjs';
2
- export default class SerializableCommand extends Command {
2
+ class SerializableCommand extends Command {
3
3
  constructor(commandTypeId) {
4
4
  super();
5
5
  this.commandTypeId = commandTypeId;
@@ -34,3 +34,4 @@ export default class SerializableCommand extends Command {
34
34
  }
35
35
  }
36
36
  SerializableCommand.deserializationCallbacks = {};
37
+ export default SerializableCommand;
@@ -68,12 +68,17 @@ class SerializableUnion extends SerializableCommand {
68
68
  this.nonserializableCommand = new NonSerializableUnion(commands, applyChunkSize);
69
69
  }
70
70
  serializeToJSON() {
71
+ if (this.serializedData) {
72
+ return this.serializedData;
73
+ }
71
74
  return {
72
75
  applyChunkSize: this.applyChunkSize,
73
76
  data: this.commands.map(command => command.serialize()),
74
77
  };
75
78
  }
76
79
  apply(editor) {
80
+ // Cache this' serialized form -- applying this may change how commands serialize.
81
+ this.serializedData = this.serializeToJSON();
77
82
  return this.nonserializableCommand.apply(editor);
78
83
  }
79
84
  unapply(editor) {
@@ -1,3 +1,7 @@
1
+ var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
2
+ if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
3
+ return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
4
+ };
1
5
  var _a;
2
6
  import SerializableCommand from '../commands/SerializableCommand.mjs';
3
7
  import EditorImage from '../EditorImage.mjs';
@@ -6,7 +10,7 @@ import UnresolvedSerializableCommand from '../commands/UnresolvedCommand.mjs';
6
10
  /**
7
11
  * A base class for everything that can be added to an {@link EditorImage}.
8
12
  */
9
- export default class AbstractComponent {
13
+ class AbstractComponent {
10
14
  constructor(
11
15
  // A unique identifier for the type of component
12
16
  componentKind, initialZIndex) {
@@ -249,6 +253,7 @@ AbstractComponent.TransformElementCommand = (_a = class extends UnresolvedSerial
249
253
  };
250
254
  }
251
255
  },
256
+ __setFunctionName(_a, "TransformElementCommand"),
252
257
  (() => {
253
258
  SerializableCommand.register(AbstractComponent.transformElementCommandId, (json, editor) => {
254
259
  var _a, _b;
@@ -260,3 +265,4 @@ AbstractComponent.TransformElementCommand = (_a = class extends UnresolvedSerial
260
265
  });
261
266
  })(),
262
267
  _a);
268
+ export default AbstractComponent;
@@ -14,6 +14,12 @@ export default class ImageComponent extends AbstractComponent {
14
14
  render(canvas: AbstractRenderer, _visibleRect?: Rect2): void;
15
15
  getProportionalRenderingTime(): number;
16
16
  intersects(lineSegment: LineSegment2): boolean;
17
+ protected applyTransformation(affineTransfm: Mat33): void;
18
+ description(localizationTable: ImageComponentLocalization): string;
19
+ getAltText(): string | undefined;
20
+ getURL(): string;
21
+ getTransformation(): Mat33;
22
+ protected createClone(): AbstractComponent;
17
23
  protected serializeToJSON(): {
18
24
  src: string;
19
25
  label: string | undefined;
@@ -21,11 +27,5 @@ export default class ImageComponent extends AbstractComponent {
21
27
  height: number;
22
28
  transform: Mat33Array;
23
29
  };
24
- protected applyTransformation(affineTransfm: Mat33): void;
25
- description(localizationTable: ImageComponentLocalization): string;
26
- getAltText(): string | undefined;
27
- getURL(): string;
28
- getTransformation(): Mat33;
29
- protected createClone(): AbstractComponent;
30
30
  static deserializeFromJSON(data: any): ImageComponent;
31
31
  }
@@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import Mat33 from '../math/Mat33.mjs';
11
11
  import Rect2 from '../math/Rect2.mjs';
12
+ import { assertIsNumber, assertIsNumberArray } from '../util/assertions.mjs';
12
13
  import AbstractComponent from './AbstractComponent.mjs';
13
14
  // Represents a raster image.
14
15
  export default class ImageComponent extends AbstractComponent {
@@ -98,16 +99,6 @@ export default class ImageComponent extends AbstractComponent {
98
99
  }
99
100
  return false;
100
101
  }
101
- serializeToJSON() {
102
- return {
103
- src: this.image.base64Url,
104
- label: this.image.label,
105
- // Store the width and height for bounding box computations while the image is loading.
106
- width: this.image.image.width,
107
- height: this.image.image.height,
108
- transform: this.image.transform.toArray(),
109
- };
110
- }
111
102
  applyTransformation(affineTransfm) {
112
103
  this.image.transform = affineTransfm.rightMul(this.image.transform);
113
104
  this.recomputeBBox();
@@ -127,19 +118,33 @@ export default class ImageComponent extends AbstractComponent {
127
118
  createClone() {
128
119
  return new ImageComponent(Object.assign({}, this.image));
129
120
  }
121
+ serializeToJSON() {
122
+ return {
123
+ src: this.image.base64Url,
124
+ label: this.image.label,
125
+ // Store the width and height for bounding box computations while the image is loading.
126
+ width: this.image.image.width,
127
+ height: this.image.image.height,
128
+ transform: this.image.transform.toArray(),
129
+ };
130
+ }
130
131
  static deserializeFromJSON(data) {
131
132
  if (!(typeof data.src === 'string')) {
132
133
  throw new Error(`${data} has invalid format! Expected src property.`);
133
134
  }
135
+ assertIsNumberArray(data.transform);
136
+ assertIsNumber(data.width);
137
+ assertIsNumber(data.height);
134
138
  const image = new Image();
135
139
  image.src = data.src;
136
140
  image.width = data.width;
137
141
  image.height = data.height;
142
+ const transform = new Mat33(...data.transform);
138
143
  return new ImageComponent({
139
144
  image: image,
140
- base64Url: image.src,
145
+ base64Url: data.src,
141
146
  label: data.label,
142
- transform: new Mat33(...data.transform),
147
+ transform,
143
148
  });
144
149
  }
145
150
  }
@@ -9,7 +9,7 @@ const componentTypeId = 'text';
9
9
  /**
10
10
  * Displays text.
11
11
  */
12
- export default class TextComponent extends AbstractComponent {
12
+ class TextComponent extends AbstractComponent {
13
13
  /**
14
14
  * Creates a new text object from a list of component text or child TextComponents.
15
15
  *
@@ -271,4 +271,5 @@ export default class TextComponent extends AbstractComponent {
271
271
  }
272
272
  }
273
273
  TextComponent.textMeasuringCtx = null;
274
+ export default TextComponent;
274
275
  AbstractComponent.registerComponent(componentTypeId, (data) => TextComponent.deserializeFromString(data));
@@ -1,4 +1,4 @@
1
1
  import { defaultEditorLocalization } from '../localization.mjs';
2
2
  // German localization
3
- const localization = Object.assign(Object.assign({}, defaultEditorLocalization), { pen: 'Stift', eraser: 'Radierer', select: 'Auswahl', handTool: 'Verschieben', zoom: 'Vergrößerung', resetView: 'Ansicht zurücksetzen', thicknessLabel: 'Dicke: ', colorLabel: 'Farbe: ', fontLabel: 'Schriftart: ', resizeImageToSelection: 'Bildgröße an Auswahl anpassen', deleteSelection: 'Auswahl löschen', duplicateSelection: 'Auswahl duplizieren', undo: 'Rückgängig', redo: 'Wiederholen', pickColorFromScreen: 'Farbe von Bildschirm auswählen', clickToPickColorAnnouncement: 'Klicke auf den Bildschirm, um eine Farbe auszuwählen', selectionToolKeyboardShortcuts: 'Auswahl-Werkzeug: Verwende die Pfeiltasten, um ausgewählte Elemente zu verschieben und ‚i‘ und ‚o‘, um ihre Größe zu ändern.', touchPanning: 'Ansicht mit Touchscreen verschieben', anyDevicePanning: 'Ansicht mit jedem Eingabegerät verschieben', selectPenType: 'Objekt-Typ: ', freehandPen: 'Freihand', arrowPen: 'Pfeil', linePen: 'Linie', outlinedRectanglePen: 'Umrissenes Rechteck', filledRectanglePen: 'Ausgefülltes Rechteck', dropdownShown: t => `Dropdown-Menü für ${t} angezeigt`, dropdownHidden: t => `Dropdown-Menü für ${t} versteckt`, zoomLevel: t => `Vergößerung: ${t}%`, colorChangedAnnouncement: t => `Farbe zu ${t} geändert`, penTool: t => `Stift ${t}`, selectionTool: 'Auswahl', eraserTool: 'Radiergummi', touchPanTool: 'Ansicht mit Touchscreen verschieben', twoFingerPanZoomTool: 'Ansicht verschieben und vergrößern', undoRedoTool: 'Rückgängig/Wiederholen', rightClickDragPanTool: 'Rechtsklick-Ziehen', pipetteTool: 'Farbe von Bildschirm auswählen', keyboardPanZoom: 'Tastaturkürzel zum Verschieben/Vergrößern der Ansicht', textTool: 'Text', enterTextToInsert: 'Einzufügender Text', toolEnabledAnnouncement: t => `${t} aktiviert`, toolDisabledAnnouncement: t => `${t} deaktiviert`, updatedViewport: 'Transformierte Ansicht', transformedElements: t => `${t} Element${1 === t ? '' : 'e'} transformiert`, resizeOutputCommand: t => `Bildgröße auf ${t.w}x${t.h} geändert`, addElementAction: t => `${t} hinzugefügt`, eraseAction: (t, e) => `${e} ${t} gelöscht`, duplicateAction: (t, e) => `${e} ${t} dupliziert`, inverseOf: t => `Umkehrung von ${t}`, elements: 'Elemente', erasedNoElements: 'Nichts entfernt', duplicatedNoElements: 'Nichts dupliziert', rotatedBy: t => `${Math.abs(t)} Grad ${t < 0 ? 'im Uhrzeigersinn' : 'gegen den Uhrzeigersinn'} gedreht`, movedLeft: 'Nacht links bewegt', movedUp: 'Nacht oben bewegt', movedDown: 'Nacht unten bewegt', movedRight: 'Nacht rechts bewegt', zoomedOut: 'Ansicht verkleinert', zoomedIn: 'Ansicht vergrößert', selectedElements: t => `${t} Element${1 === t ? '' : 'e'} ausgewählt`, stroke: 'Strich', svgObject: 'SVG-Objekt', text: t => `Text-Objekt: ${t}`, pathNodeCount: t => `Es gibt ${t} sichtbare Pfad-Objekte.`, textNodeCount: t => `Es gibt ${t} sichtbare Text-Knotenpunkte.`, textNode: t => `Text: ${t}`, rerenderAsText: 'Als Text darstellen', accessibilityInputInstructions: 'Drücke ‚t‘, um den Inhalt des Ansichtsfensters als Text zu lesen. Verwende die Pfeiltasten, um die Ansicht zu verschieben, und klicke und ziehe, um Striche zu zeichnen. Drücke ‚w‘ zum Vergrößern und ‚s‘ zum Verkleinern der Ansicht.', loading: t => `Laden ${t}%...`, doneLoading: 'Laden fertig', imageEditor: 'Bild-Editor', undoAnnouncement: t => `Rückgangig gemacht ${t}`, redoAnnouncement: t => `Wiederholt ${t}` });
3
+ const localization = Object.assign(Object.assign({}, defaultEditorLocalization), { pen: 'Stift', eraser: 'Radierer', select: 'Auswahl', handTool: 'Verschieben', zoom: 'Vergrößerung', image: 'Bild', inputAltText: 'Alt-Text: ', chooseFile: 'Wähle Datei: ', submit: 'Absenden', cancel: 'Abbrechen', resetView: 'Ansicht zurücksetzen', thicknessLabel: 'Dicke: ', colorLabel: 'Farbe: ', fontLabel: 'Schriftart: ', textSize: 'Größe: ', resizeImageToSelection: 'Bildgröße an Auswahl anpassen', deleteSelection: 'Auswahl löschen', duplicateSelection: 'Auswahl duplizieren', undo: 'Rückgängig', redo: 'Wiederholen', pickColorFromScreen: 'Farbe von Bildschirm auswählen', clickToPickColorAnnouncement: 'Klicke auf den Bildschirm, um eine Farbe auszuwählen', selectionToolKeyboardShortcuts: 'Auswahl-Werkzeug: Verwende die Pfeiltasten, um ausgewählte Elemente zu verschieben und ‚i‘ und ‚o‘, um ihre Größe zu ändern.', touchPanning: 'Ansicht mit Touchscreen verschieben', anyDevicePanning: 'Ansicht mit jedem Eingabegerät verschieben', selectPenType: 'Objekt-Typ: ', freehandPen: 'Freihand', pressureSensitiveFreehandPen: 'Stift (druckempfindlich)', arrowPen: 'Pfeil', linePen: 'Linie', outlinedRectanglePen: 'Umrissenes Rechteck', filledRectanglePen: 'Ausgefülltes Rechteck', lockRotation: 'Sperre Rotation', paste: 'Einfügen', dropdownShown: (toolName) => `Dropdown-Menü für ${toolName} angezeigt`, dropdownHidden: (toolName) => `Dropdown-Menü für ${toolName} versteckt`, zoomLevel: (zoomPercent) => `Vergößerung: ${zoomPercent}%`, colorChangedAnnouncement: (color) => `Farbe zu ${color} geändert`, imageSize: (size, units) => `Bild-Größe: ${size} ${units}`, imageLoadError: (message) => `Fehler beim Laden des Bildes: ${message}`, errorImageHasZeroSize: 'Fehler: Bild hat Größe Null', penTool: (penNumber) => `Stift ${penNumber}`, selectionTool: 'Auswahl', eraserTool: 'Radiergummi', touchPanTool: 'Ansicht mit Touchscreen verschieben', twoFingerPanZoomTool: 'Ansicht verschieben und vergrößern', undoRedoTool: 'Rückgängig/Wiederholen', rightClickDragPanTool: 'Rechtsklick-Ziehen', pipetteTool: 'Farbe von Bildschirm auswählen', keyboardPanZoom: 'Tastaturkürzel zum Verschieben/Vergrößern der Ansicht', textTool: 'Text', enterTextToInsert: 'Einzufügender Text', changeTool: 'Wechsle Werkzeug', pasteHandler: 'Copy-Paste-Handler', findLabel: 'Finde', toNextMatch: 'Nächstes', closeFindDialog: 'Schließen', findDialogShown: 'Finde-Dialog angezeigt', findDialogHidden: 'Finde-Dialog versteckt', focusedFoundText: (matchIdx, totalMatches) => `Sieh Treffer ${matchIdx} von ${totalMatches} an`, toolEnabledAnnouncement: (toolName) => `${toolName} aktiviert`, toolDisabledAnnouncement: (toolName) => `${toolName} deaktiviert`, updatedViewport: 'Transformierte Ansicht', transformedElements: (elemCount) => `${elemCount} Element${1 === elemCount ? '' : 'e'} transformiert`, resizeOutputCommand: (newSize) => `Bildgröße auf ${newSize.w}x${newSize.h} geändert`, addElementAction: (componentDescription) => `${componentDescription} hinzugefügt`, eraseAction: (elemDescription, countErased) => `${countErased} ${elemDescription} gelöscht`, duplicateAction: (elemDescription, countErased) => `${countErased} ${elemDescription} dupliziert`, inverseOf: (actionDescription) => `${actionDescription} umgekehrt`, elements: 'Elemente', erasedNoElements: 'Nichts entfernt', duplicatedNoElements: 'Nichts dupliziert', rotatedBy: (degrees) => `${Math.abs(degrees)} Grad ${degrees < 0 ? 'im Uhrzeigersinn' : 'gegen den Uhrzeigersinn'} gedreht`, movedLeft: 'Nacht links bewegt', movedUp: 'Nacht oben bewegt', movedDown: 'Nacht unten bewegt', movedRight: 'Nacht rechts bewegt', zoomedOut: 'Ansicht verkleinert', zoomedIn: 'Ansicht vergrößert', selectedElements: (count) => `${count} Element${1 === count ? '' : 'e'} ausgewählt`, stroke: 'Strich', svgObject: 'SVG-Objekt', text: (text) => `Text-Objekt: ${text}`, pathNodeCount: (count) => `Es gibt ${count} sichtbare Pfad-Objekte.`, textNodeCount: (count) => `Es gibt ${count} sichtbare Text-Knotenpunkte.`, textNode: (content) => `Text: ${content}`, imageNodeCount: (nodeCount) => `Es gibt ${nodeCount} sichtbare Bild-Knoten.`, imageNode: label => `Bild: ${label}`, unlabeledImageNode: 'Bild ohne Label', rerenderAsText: 'Als Text darstellen', accessibilityInputInstructions: 'Drücke ‚t‘, um den Inhalt des Ansichtsfensters als Text zu lesen. Verwende die Pfeiltasten, um die Ansicht zu verschieben, und klicke und ziehe, um Striche zu zeichnen. Drücke ‚w‘ zum Vergrößern und ‚s‘ zum Verkleinern der Ansicht.', loading: percentage => `Laden ${percentage}%...`, doneLoading: 'Laden fertig', imageEditor: 'Bild-Editor', undoAnnouncement: (commandDescription) => `${commandDescription} rückgängig gemacht`, redoAnnouncement: (commandDescription) => `${commandDescription} wiederholt`, reformatSelection: 'Formatiere Auswahl', documentProperties: 'Seite', backgroundColor: 'Hintergrundfarbe: ', imageWidthOption: 'Breite: ', imageHeightOption: 'Höhe: ', useGridOption: 'Gitter: ', toggleOverflow: 'Mehr', selectAllTool: 'Alle auswählen', soundExplorer: 'Klangbasierte Bilderkundung', disableAccessibilityExploreTool: 'Deaktiviere klangbasierte Erkundung', enableAccessibilityExploreTool: 'Aktiviere klangbasierte Erkundung', copied: (count, description) => `${count} ${description} kopiert`, pasted: (count, description) => `${count} ${description} eingefügt`, unionOf: (actionDescription, actionCount) => `Vereinigung: ${actionCount} ${actionDescription}`, emptyBackground: 'Leerer Hintergrund', filledBackgroundWithColor: (color) => `Gefüllter Hintergrund (${color})`, restyledElement: (elementDescription) => `${elementDescription} umgestaltet` });
4
4
  export default localization;
@@ -5,7 +5,7 @@ import Vec3 from './Vec3.mjs';
5
5
  * a two-dimensional affine transformation. (An affine transformation scales/rotates/shears
6
6
  * **and** translates while a linear transformation just scales/rotates/shears).
7
7
  */
8
- export default class Mat33 {
8
+ class Mat33 {
9
9
  /**
10
10
  * Creates a matrix from inputs in the form,
11
11
  * ```
@@ -324,3 +324,4 @@ export default class Mat33 {
324
324
  }
325
325
  }
326
326
  Mat33.identity = new Mat33(1, 0, 0, 0, 1, 0, 0, 0, 1);
327
+ export default Mat33;
@@ -29,7 +29,7 @@ const getPartBBox = (part) => {
29
29
  }
30
30
  return partBBox;
31
31
  };
32
- export default class Path {
32
+ class Path {
33
33
  constructor(startPoint, parts) {
34
34
  this.startPoint = startPoint;
35
35
  this.parts = parts;
@@ -867,3 +867,4 @@ export default class Path {
867
867
  }
868
868
  }
869
869
  Path.empty = new Path(Vec2.zero, []);
870
+ export default Path;
@@ -1,7 +1,7 @@
1
1
  import LineSegment2 from './LineSegment2.mjs';
2
2
  import { Vec2 } from './Vec2.mjs';
3
3
  // invariant: w ≥ 0, h ≥ 0.
4
- export default class Rect2 {
4
+ class Rect2 {
5
5
  constructor(x, y, w, h) {
6
6
  this.x = x;
7
7
  this.y = y;
@@ -227,3 +227,4 @@ export default class Rect2 {
227
227
  }
228
228
  Rect2.empty = new Rect2(0, 0, 0, 0);
229
229
  Rect2.unitSquare = new Rect2(0, 0, 1, 1);
230
+ export default Rect2;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * A `Vec3` is immutable.
5
5
  */
6
- export default class Vec3 {
6
+ class Vec3 {
7
7
  constructor(x, y, z) {
8
8
  this.x = x;
9
9
  this.y = y;
@@ -172,3 +172,4 @@ Vec3.unitX = Vec3.of(1, 0, 0);
172
172
  Vec3.unitY = Vec3.of(0, 1, 0);
173
173
  Vec3.unitZ = Vec3.of(0, 0, 1);
174
174
  Vec3.zero = Vec3.of(0, 0, 0);
175
+ export default Vec3;
@@ -53,7 +53,7 @@ export default class Display {
53
53
  */
54
54
  rerenderAsText(): void;
55
55
  /**
56
- * Clears the drawing surfaces and otherwise prepares for a rerender.
56
+ * Clears the main drawing surface and otherwise prepares for a rerender.
57
57
  *
58
58
  * @returns the dry ink renderer.
59
59
  */
@@ -170,14 +170,13 @@ export default class Display {
170
170
  }
171
171
  }
172
172
  /**
173
- * Clears the drawing surfaces and otherwise prepares for a rerender.
173
+ * Clears the main drawing surface and otherwise prepares for a rerender.
174
174
  *
175
175
  * @returns the dry ink renderer.
176
176
  */
177
177
  startRerender() {
178
178
  var _a;
179
179
  (_a = this.resizeSurfacesCallback) === null || _a === void 0 ? void 0 : _a.call(this);
180
- this.wetInkRenderer.clear();
181
180
  this.dryInkRenderer.clear();
182
181
  return this.dryInkRenderer;
183
182
  }
@@ -22,6 +22,8 @@ export default class HTMLToolbar {
22
22
  private updateColoris;
23
23
  /** @internal */
24
24
  constructor(editor: Editor, parent: HTMLElement, localizationTable?: ToolbarLocalization);
25
+ private closeColorPickerOverlay;
26
+ private setupCloseColorPickerOverlay;
25
27
  setupColorPickers(): void;
26
28
  private reLayoutQueued;
27
29
  private queueReLayout;