js-draw 1.3.1 → 1.4.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 (170) hide show
  1. package/README.md +2 -2
  2. package/dist/Editor.css +55 -13
  3. package/dist/bundle.js +2 -2
  4. package/dist/bundledStyles.js +1 -1
  5. package/dist/cjs/Editor.d.ts +36 -3
  6. package/dist/cjs/Editor.js +63 -26
  7. package/dist/cjs/commands/Erase.js +1 -1
  8. package/dist/cjs/commands/UnresolvedCommand.d.ts +1 -1
  9. package/dist/cjs/components/AbstractComponent.d.ts +1 -1
  10. package/dist/cjs/components/AbstractComponent.js +1 -1
  11. package/dist/cjs/components/BackgroundComponent.d.ts +1 -1
  12. package/dist/cjs/components/BackgroundComponent.js +13 -7
  13. package/dist/cjs/components/SVGGlobalAttributesObject.d.ts +2 -2
  14. package/dist/cjs/components/SVGGlobalAttributesObject.js +10 -14
  15. package/dist/cjs/{EditorImage.d.ts → image/EditorImage.d.ts} +30 -8
  16. package/dist/cjs/{EditorImage.js → image/EditorImage.js} +51 -7
  17. package/dist/cjs/image/export/adjustExportedSVGSize.d.ts +6 -0
  18. package/dist/cjs/image/export/adjustExportedSVGSize.js +22 -0
  19. package/dist/cjs/image/export/editorImageToSVG.d.ts +8 -0
  20. package/dist/cjs/image/export/editorImageToSVG.js +63 -0
  21. package/dist/cjs/image/lib.d.ts +1 -0
  22. package/dist/cjs/image/lib.js +8 -0
  23. package/dist/cjs/lib.d.ts +1 -1
  24. package/dist/cjs/lib.js +2 -3
  25. package/dist/cjs/localizations/comments.d.ts +6 -0
  26. package/dist/cjs/localizations/comments.js +10 -0
  27. package/dist/cjs/localizations/es.js +68 -48
  28. package/dist/cjs/rendering/caching/RenderingCache.d.ts +1 -1
  29. package/dist/cjs/rendering/caching/RenderingCacheNode.d.ts +1 -1
  30. package/dist/cjs/rendering/caching/RenderingCacheNode.js +4 -3
  31. package/dist/cjs/rendering/renderers/AbstractRenderer.d.ts +1 -0
  32. package/dist/cjs/rendering/renderers/AbstractRenderer.js +8 -0
  33. package/dist/cjs/rendering/renderers/SVGRenderer.d.ts +28 -1
  34. package/dist/cjs/rendering/renderers/SVGRenderer.js +58 -7
  35. package/dist/cjs/toolbar/AbstractToolbar.d.ts +11 -3
  36. package/dist/cjs/toolbar/AbstractToolbar.js +20 -6
  37. package/dist/cjs/toolbar/EdgeToolbar.js +5 -6
  38. package/dist/cjs/toolbar/IconProvider.d.ts +1 -0
  39. package/dist/cjs/toolbar/IconProvider.js +43 -0
  40. package/dist/cjs/toolbar/widgets/ActionButtonWidget.d.ts +3 -1
  41. package/dist/cjs/toolbar/widgets/ActionButtonWidget.js +19 -1
  42. package/dist/cjs/toolbar/widgets/BaseToolWidget.d.ts +1 -0
  43. package/dist/cjs/toolbar/widgets/BaseToolWidget.js +3 -0
  44. package/dist/cjs/toolbar/widgets/BaseWidget.d.ts +5 -0
  45. package/dist/cjs/toolbar/widgets/BaseWidget.js +30 -2
  46. package/dist/cjs/toolbar/widgets/DocumentPropertiesWidget.js +1 -1
  47. package/dist/cjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
  48. package/dist/cjs/toolbar/widgets/HandToolWidget.js +6 -0
  49. package/dist/cjs/toolbar/widgets/InsertImageWidget.js +1 -1
  50. package/dist/cjs/toolbar/widgets/OverflowWidget.d.ts +1 -0
  51. package/dist/cjs/toolbar/widgets/OverflowWidget.js +3 -0
  52. package/dist/cjs/toolbar/widgets/SaveActionWidget.d.ts +1 -0
  53. package/dist/cjs/toolbar/widgets/SaveActionWidget.js +3 -0
  54. package/dist/cjs/tools/BaseTool.d.ts +3 -0
  55. package/dist/cjs/tools/BaseTool.js +13 -2
  56. package/dist/cjs/tools/FindTool.d.ts +1 -0
  57. package/dist/cjs/tools/FindTool.js +4 -1
  58. package/dist/cjs/tools/PanZoom.d.ts +1 -0
  59. package/dist/cjs/tools/PanZoom.js +4 -0
  60. package/dist/cjs/tools/Pen.d.ts +0 -1
  61. package/dist/cjs/tools/Pen.js +1 -4
  62. package/dist/cjs/tools/PipetteTool.d.ts +1 -0
  63. package/dist/cjs/tools/PipetteTool.js +3 -0
  64. package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +1 -0
  65. package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.js +3 -0
  66. package/dist/cjs/tools/SelectionTool/Selection.d.ts +2 -0
  67. package/dist/cjs/tools/SelectionTool/Selection.js +44 -8
  68. package/dist/cjs/tools/SelectionTool/SelectionHandle.d.ts +14 -6
  69. package/dist/cjs/tools/SelectionTool/SelectionHandle.js +26 -8
  70. package/dist/cjs/tools/SelectionTool/SelectionTool.js +5 -0
  71. package/dist/cjs/tools/SoundUITool.d.ts +1 -0
  72. package/dist/cjs/tools/SoundUITool.js +4 -1
  73. package/dist/cjs/tools/TextTool.js +2 -2
  74. package/dist/cjs/tools/ToolController.d.ts +2 -0
  75. package/dist/cjs/tools/ToolController.js +13 -2
  76. package/dist/cjs/tools/ToolSwitcherShortcut.d.ts +1 -0
  77. package/dist/cjs/tools/ToolSwitcherShortcut.js +3 -0
  78. package/dist/cjs/types.d.ts +9 -4
  79. package/dist/cjs/types.js +4 -3
  80. package/dist/cjs/util/ReactiveValue.d.ts +1 -1
  81. package/dist/cjs/util/ReactiveValue.js +2 -2
  82. package/dist/cjs/version.js +1 -1
  83. package/dist/mjs/Editor.d.ts +36 -3
  84. package/dist/mjs/Editor.mjs +64 -27
  85. package/dist/mjs/Editor.toSVGAsync.test.d.ts +1 -0
  86. package/dist/mjs/commands/Erase.mjs +1 -1
  87. package/dist/mjs/commands/UnresolvedCommand.d.ts +1 -1
  88. package/dist/mjs/components/AbstractComponent.d.ts +1 -1
  89. package/dist/mjs/components/AbstractComponent.mjs +1 -1
  90. package/dist/mjs/components/BackgroundComponent.d.ts +1 -1
  91. package/dist/mjs/components/BackgroundComponent.mjs +13 -7
  92. package/dist/mjs/components/SVGGlobalAttributesObject.d.ts +2 -2
  93. package/dist/mjs/components/SVGGlobalAttributesObject.mjs +10 -14
  94. package/dist/mjs/{EditorImage.d.ts → image/EditorImage.d.ts} +30 -8
  95. package/dist/mjs/{EditorImage.mjs → image/EditorImage.mjs} +51 -7
  96. package/dist/mjs/image/EditorImage.test.d.ts +1 -0
  97. package/dist/mjs/image/export/adjustExportedSVGSize.d.ts +6 -0
  98. package/dist/mjs/image/export/adjustExportedSVGSize.mjs +20 -0
  99. package/dist/mjs/image/export/editorImageToSVG.d.ts +8 -0
  100. package/dist/mjs/image/export/editorImageToSVG.mjs +55 -0
  101. package/dist/mjs/image/lib.d.ts +1 -0
  102. package/dist/mjs/image/lib.mjs +1 -0
  103. package/dist/mjs/lib.d.ts +1 -1
  104. package/dist/mjs/lib.mjs +1 -1
  105. package/dist/mjs/localizations/comments.d.ts +6 -0
  106. package/dist/mjs/localizations/comments.mjs +8 -0
  107. package/dist/mjs/localizations/es.mjs +68 -48
  108. package/dist/mjs/rendering/caching/RenderingCache.d.ts +1 -1
  109. package/dist/mjs/rendering/caching/RenderingCacheNode.d.ts +1 -1
  110. package/dist/mjs/rendering/caching/RenderingCacheNode.mjs +4 -3
  111. package/dist/mjs/rendering/renderers/AbstractRenderer.d.ts +1 -0
  112. package/dist/mjs/rendering/renderers/AbstractRenderer.mjs +8 -0
  113. package/dist/mjs/rendering/renderers/SVGRenderer.d.ts +28 -1
  114. package/dist/mjs/rendering/renderers/SVGRenderer.mjs +58 -7
  115. package/dist/mjs/toolbar/AbstractToolbar.d.ts +11 -3
  116. package/dist/mjs/toolbar/AbstractToolbar.mjs +20 -6
  117. package/dist/mjs/toolbar/EdgeToolbar.mjs +5 -6
  118. package/dist/mjs/toolbar/IconProvider.d.ts +1 -0
  119. package/dist/mjs/toolbar/IconProvider.mjs +43 -0
  120. package/dist/mjs/toolbar/widgets/ActionButtonWidget.d.ts +3 -1
  121. package/dist/mjs/toolbar/widgets/ActionButtonWidget.mjs +21 -2
  122. package/dist/mjs/toolbar/widgets/BaseToolWidget.d.ts +1 -0
  123. package/dist/mjs/toolbar/widgets/BaseToolWidget.mjs +3 -0
  124. package/dist/mjs/toolbar/widgets/BaseWidget.d.ts +5 -0
  125. package/dist/mjs/toolbar/widgets/BaseWidget.mjs +30 -2
  126. package/dist/mjs/toolbar/widgets/DocumentPropertiesWidget.mjs +1 -1
  127. package/dist/mjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
  128. package/dist/mjs/toolbar/widgets/HandToolWidget.mjs +6 -0
  129. package/dist/mjs/toolbar/widgets/InsertImageWidget.mjs +1 -1
  130. package/dist/mjs/toolbar/widgets/OverflowWidget.d.ts +1 -0
  131. package/dist/mjs/toolbar/widgets/OverflowWidget.mjs +3 -0
  132. package/dist/mjs/toolbar/widgets/SaveActionWidget.d.ts +1 -0
  133. package/dist/mjs/toolbar/widgets/SaveActionWidget.mjs +3 -0
  134. package/dist/mjs/tools/BaseTool.d.ts +3 -0
  135. package/dist/mjs/tools/BaseTool.mjs +13 -2
  136. package/dist/mjs/tools/FindTool.d.ts +1 -0
  137. package/dist/mjs/tools/FindTool.mjs +4 -1
  138. package/dist/mjs/tools/PanZoom.d.ts +1 -0
  139. package/dist/mjs/tools/PanZoom.mjs +4 -0
  140. package/dist/mjs/tools/Pen.d.ts +0 -1
  141. package/dist/mjs/tools/Pen.mjs +1 -4
  142. package/dist/mjs/tools/PipetteTool.d.ts +1 -0
  143. package/dist/mjs/tools/PipetteTool.mjs +3 -0
  144. package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +1 -0
  145. package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.mjs +3 -0
  146. package/dist/mjs/tools/SelectionTool/Selection.d.ts +2 -0
  147. package/dist/mjs/tools/SelectionTool/Selection.mjs +45 -9
  148. package/dist/mjs/tools/SelectionTool/SelectionHandle.d.ts +14 -6
  149. package/dist/mjs/tools/SelectionTool/SelectionHandle.mjs +25 -7
  150. package/dist/mjs/tools/SelectionTool/SelectionTool.mjs +5 -0
  151. package/dist/mjs/tools/SoundUITool.d.ts +1 -0
  152. package/dist/mjs/tools/SoundUITool.mjs +4 -1
  153. package/dist/mjs/tools/TextTool.mjs +2 -2
  154. package/dist/mjs/tools/ToolController.d.ts +2 -0
  155. package/dist/mjs/tools/ToolController.mjs +13 -2
  156. package/dist/mjs/tools/ToolSwitcherShortcut.d.ts +1 -0
  157. package/dist/mjs/tools/ToolSwitcherShortcut.mjs +3 -0
  158. package/dist/mjs/types.d.ts +9 -4
  159. package/dist/mjs/types.mjs +4 -3
  160. package/dist/mjs/util/ReactiveValue.d.ts +1 -1
  161. package/dist/mjs/util/ReactiveValue.mjs +2 -2
  162. package/dist/mjs/version.mjs +1 -1
  163. package/package.json +5 -5
  164. package/src/Editor.scss +6 -0
  165. package/src/toolbar/EdgeToolbar.scss +19 -2
  166. package/src/tools/SelectionTool/SelectionTool.scss +74 -0
  167. package/src/tools/tools.scss +1 -1
  168. package/src/tools/SelectionTool/SelectionTool.css +0 -35
  169. /package/dist/cjs/{EditorImage.test.d.ts → Editor.toSVGAsync.test.d.ts} +0 -0
  170. /package/dist/{mjs → cjs/image}/EditorImage.test.d.ts +0 -0
@@ -8,6 +8,10 @@ export interface SpacerOptions {
8
8
  minSize: string;
9
9
  maxSize: string;
10
10
  }
11
+ export type ToolbarActionButtonOptions = {
12
+ mustBeToplevel?: boolean;
13
+ autoDisableInReadOnlyEditors?: boolean;
14
+ };
11
15
  export default abstract class AbstractToolbar {
12
16
  #private;
13
17
  protected editor: Editor;
@@ -91,18 +95,22 @@ export default abstract class AbstractToolbar {
91
95
  * @see
92
96
  * {@link addActionButton}
93
97
  */
94
- protected makeActionButton(title: string | ActionButtonIcon, command: () => void, mustBeToplevel?: boolean): BaseWidget;
98
+ protected makeActionButton(title: string | ActionButtonIcon, command: () => void, options?: ToolbarActionButtonOptions | boolean): BaseWidget;
95
99
  /**
96
100
  * Adds an action button with `title` to this toolbar (or to the given `parent` element).
97
101
  *
102
+ * `options` can either be an object with properties `mustBeToplevel` and/or
103
+ * `autoDisableInReadOnlyEditors` or a boolean value. If a boolean, it is interpreted
104
+ * as being the value of `mustBeToplevel`.
105
+ *
98
106
  * @return The added button.
99
107
  */
100
- addActionButton(title: string | ActionButtonIcon, command: () => void, mustBeToplevel?: boolean): BaseWidget;
108
+ addActionButton(title: string | ActionButtonIcon, command: () => void, options?: ToolbarActionButtonOptions | boolean): BaseWidget;
101
109
  /**
102
110
  * Like {@link addActionButton}, except associates `tags` with the button that allow
103
111
  * different toolbar styles to give the button tag-dependent styles.
104
112
  */
105
- addTaggedActionButton(tags: (ToolbarWidgetTag | string)[], title: string | ActionButtonIcon, command: () => void, mustBeToplevel?: boolean): BaseWidget;
113
+ addTaggedActionButton(tags: (ToolbarWidgetTag | string)[], title: string | ActionButtonIcon, command: () => void, options?: ToolbarActionButtonOptions | boolean): BaseWidget;
106
114
  /**
107
115
  * Adds a save button that, when clicked, calls `saveCallback`.
108
116
  *
@@ -235,7 +235,15 @@ class AbstractToolbar {
235
235
  * @see
236
236
  * {@link addActionButton}
237
237
  */
238
- makeActionButton(title, command, mustBeToplevel = true) {
238
+ makeActionButton(title, command, options = true) {
239
+ // Parse options
240
+ if (typeof options === 'boolean') {
241
+ options = {
242
+ mustBeToplevel: options,
243
+ };
244
+ }
245
+ const mustBeToplevel = options.mustBeToplevel ?? true;
246
+ const autoDisableInReadOnlyEditors = options.autoDisableInReadOnlyEditors ?? true;
239
247
  const titleString = typeof title === 'string' ? title : title.label;
240
248
  const widgetId = 'action-button';
241
249
  const makeIcon = () => {
@@ -244,16 +252,20 @@ class AbstractToolbar {
244
252
  }
245
253
  return title.icon;
246
254
  };
247
- const widget = new ActionButtonWidget_1.default(this.editor, widgetId, makeIcon, titleString, command, this.editor.localization, mustBeToplevel);
255
+ const widget = new ActionButtonWidget_1.default(this.editor, widgetId, makeIcon, titleString, command, this.editor.localization, mustBeToplevel, autoDisableInReadOnlyEditors);
248
256
  return widget;
249
257
  }
250
258
  /**
251
259
  * Adds an action button with `title` to this toolbar (or to the given `parent` element).
252
260
  *
261
+ * `options` can either be an object with properties `mustBeToplevel` and/or
262
+ * `autoDisableInReadOnlyEditors` or a boolean value. If a boolean, it is interpreted
263
+ * as being the value of `mustBeToplevel`.
264
+ *
253
265
  * @return The added button.
254
266
  */
255
- addActionButton(title, command, mustBeToplevel = true) {
256
- const widget = this.makeActionButton(title, command, mustBeToplevel);
267
+ addActionButton(title, command, options = true) {
268
+ const widget = this.makeActionButton(title, command, options);
257
269
  this.addWidget(widget);
258
270
  return widget;
259
271
  }
@@ -261,8 +273,8 @@ class AbstractToolbar {
261
273
  * Like {@link addActionButton}, except associates `tags` with the button that allow
262
274
  * different toolbar styles to give the button tag-dependent styles.
263
275
  */
264
- addTaggedActionButton(tags, title, command, mustBeToplevel = true) {
265
- const widget = this.makeActionButton(title, command, mustBeToplevel);
276
+ addTaggedActionButton(tags, title, command, options = true) {
277
+ const widget = this.makeActionButton(title, command, options);
266
278
  widget.setTags(tags);
267
279
  this.addWidget(widget);
268
280
  return widget;
@@ -308,6 +320,8 @@ class AbstractToolbar {
308
320
  icon: this.editor.icons.makeCloseIcon(),
309
321
  }, () => {
310
322
  exitCallback();
323
+ }, {
324
+ autoDisableInReadOnlyEditors: false,
311
325
  });
312
326
  }
313
327
  /**
@@ -198,7 +198,6 @@ class EdgeToolbar extends AbstractToolbar_1.default {
198
198
  };
199
199
  const actionRowBBox = this.toolbarActionRow.getBoundingClientRect();
200
200
  const toolbarRowBBox = this.toolbarToolRow.getBoundingClientRect();
201
- const inSameRow = actionRowBBox.y === toolbarRowBBox.y;
202
201
  const onDifferentRows = actionRowBBox.y + actionRowBBox.height <= toolbarRowBBox.y;
203
202
  if (onDifferentRows) {
204
203
  this.toolbarContainer.classList.remove('one-row');
@@ -208,11 +207,11 @@ class EdgeToolbar extends AbstractToolbar_1.default {
208
207
  }
209
208
  if (this.toolbarToolRow.clientWidth < this.toolbarToolRow.scrollWidth) {
210
209
  this.toolbarToolRow.classList.add('has-scroll');
211
- // If both button areas are in the same row, don't change the padding --
212
- // it could lead to an endless loop of reseize events.
213
- if (!inSameRow) {
214
- setExtraPadding();
215
- }
210
+ // Note: This can potentially change the size of the tool row.
211
+ // Because this is run inside of a ResizeObserver callback, special
212
+ // care must be taken to ensure that this change doesn't re-trigger
213
+ // the resize observer.
214
+ setExtraPadding();
216
215
  }
217
216
  else {
218
217
  this.toolbarToolRow.classList.remove('has-scroll', 'extra-padding');
@@ -38,6 +38,7 @@ export default class IconProvider {
38
38
  makeDropdownIcon(): IconElemType;
39
39
  makeEraserIcon(eraserSize?: number): IconElemType;
40
40
  makeSelectionIcon(): IconElemType;
41
+ makeRotateIcon(): IconElemType;
41
42
  makeHandToolIcon(): IconElemType;
42
43
  makeTouchPanningIcon(): IconElemType;
43
44
  /** Unused by js-draw. @deprecated */
@@ -169,6 +169,49 @@ class IconProvider {
169
169
  icon.setAttribute('viewBox', '0 0 100 100');
170
170
  return icon;
171
171
  }
172
+ makeRotateIcon() {
173
+ const icon = document.createElementNS(svgNamespace, 'svg');
174
+ icon.innerHTML = `
175
+ <defs>
176
+ <marker
177
+ id="arrow-marker"
178
+ viewBox="0 0 10 10"
179
+ refX="3" refY="5"
180
+ markerWidth="3" markerHeight="3"
181
+ orient="auto-start-reverse"
182
+ >
183
+ <path
184
+ d="M0,0 L8,5 L0,10z"
185
+ fill="var(--icon-color)"
186
+ />
187
+ </marker>
188
+ </defs>
189
+
190
+ <path
191
+ marker-start="url(#arrow-marker)"
192
+ d="
193
+ M20,20
194
+ A30,30 0 1 1 80 80
195
+ "
196
+ fill="none"
197
+ stroke="var(--icon-color)"
198
+ stroke-width="12"
199
+ />
200
+ <path
201
+ d="
202
+ M80,80
203
+ A30,30 0 1 1 20 20
204
+ "
205
+ fill="none"
206
+ stroke="var(--icon-color)"
207
+ stroke-width="12"
208
+ stroke-dasharray="30 10 20 10 20 10 10"
209
+ style="stroke-linecap: butt;"
210
+ />
211
+ `;
212
+ icon.setAttribute('viewBox', '-5 -5 110 110');
213
+ return icon;
214
+ }
172
215
  makeHandToolIcon() {
173
216
  const fill = 'none';
174
217
  const strokeColor = 'var(--icon-color)';
@@ -2,11 +2,13 @@ import Editor from '../../Editor';
2
2
  import { ToolbarLocalization } from '../localization';
3
3
  import BaseWidget from './BaseWidget';
4
4
  export default class ActionButtonWidget extends BaseWidget {
5
+ #private;
5
6
  protected makeIcon: () => Element | null;
6
7
  protected title: string;
7
8
  protected clickAction: () => void;
8
9
  protected mustBeToplevel: boolean;
9
- constructor(editor: Editor, id: string, makeIcon: () => Element | null, title: string, clickAction: () => void, localizationTable?: ToolbarLocalization, mustBeToplevel?: boolean);
10
+ constructor(editor: Editor, id: string, makeIcon: () => Element | null, title: string, clickAction: () => void, localizationTable?: ToolbarLocalization, mustBeToplevel?: boolean, autoDisableInReadOnlyEditors?: boolean);
11
+ protected shouldAutoDisableInReadOnlyEditor(): boolean;
10
12
  protected handleClick(): void;
11
13
  protected getTitle(): string;
12
14
  protected createIcon(): Element | null;
@@ -1,16 +1,33 @@
1
1
  "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
2
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
15
  };
16
+ var _ActionButtonWidget_autoDisableInReadOnlyEditors;
5
17
  Object.defineProperty(exports, "__esModule", { value: true });
6
18
  const BaseWidget_1 = __importDefault(require("./BaseWidget"));
7
19
  class ActionButtonWidget extends BaseWidget_1.default {
8
- constructor(editor, id, makeIcon, title, clickAction, localizationTable, mustBeToplevel = false) {
20
+ constructor(editor, id, makeIcon, title, clickAction, localizationTable, mustBeToplevel = false, autoDisableInReadOnlyEditors = true) {
9
21
  super(editor, id, localizationTable);
10
22
  this.makeIcon = makeIcon;
11
23
  this.title = title;
12
24
  this.clickAction = clickAction;
13
25
  this.mustBeToplevel = mustBeToplevel;
26
+ _ActionButtonWidget_autoDisableInReadOnlyEditors.set(this, void 0);
27
+ __classPrivateFieldSet(this, _ActionButtonWidget_autoDisableInReadOnlyEditors, autoDisableInReadOnlyEditors, "f");
28
+ }
29
+ shouldAutoDisableInReadOnlyEditor() {
30
+ return __classPrivateFieldGet(this, _ActionButtonWidget_autoDisableInReadOnlyEditors, "f");
14
31
  }
15
32
  handleClick() {
16
33
  this.clickAction();
@@ -28,4 +45,5 @@ class ActionButtonWidget extends BaseWidget_1.default {
28
45
  return this.mustBeToplevel;
29
46
  }
30
47
  }
48
+ _ActionButtonWidget_autoDisableInReadOnlyEditors = new WeakMap();
31
49
  exports.default = ActionButtonWidget;
@@ -6,6 +6,7 @@ import BaseWidget from './BaseWidget';
6
6
  export default abstract class BaseToolWidget extends BaseWidget {
7
7
  protected targetTool: BaseTool;
8
8
  constructor(editor: Editor, targetTool: BaseTool, id: string, localizationTable?: ToolbarLocalization);
9
+ protected shouldAutoDisableInReadOnlyEditor(): boolean;
9
10
  protected handleClick(): void;
10
11
  protected onKeyPress(event: KeyPressEvent): boolean;
11
12
  addTo(parent: HTMLElement): HTMLElement;
@@ -39,6 +39,9 @@ class BaseToolWidget extends BaseWidget_1.default {
39
39
  }
40
40
  });
41
41
  }
42
+ shouldAutoDisableInReadOnlyEditor() {
43
+ return !this.targetTool.canReceiveInputInReadOnlyEditor();
44
+ }
42
45
  handleClick() {
43
46
  if (this.hasDropdown) {
44
47
  if (!this.targetTool.isEnabled()) {
@@ -29,6 +29,11 @@ export default abstract class BaseWidget {
29
29
  private toplevel;
30
30
  protected readonly localizationTable: ToolbarLocalization;
31
31
  constructor(editor: Editor, id: string, localizationTable?: ToolbarLocalization);
32
+ /**
33
+ * Should return a constant true or false value. If true (the default),
34
+ * this widget must be automatically disabled when its editor is read-only.
35
+ */
36
+ protected shouldAutoDisableInReadOnlyEditor(): boolean;
32
37
  getId(): string;
33
38
  /**
34
39
  * Note: Tags should be set *before* a tool widget is added to a toolbar.
@@ -13,7 +13,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
13
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
15
  };
16
- var _BaseWidget_hasDropdown, _BaseWidget_tags;
16
+ var _BaseWidget_hasDropdown, _BaseWidget_disabledDueToReadOnlyEditor, _BaseWidget_tags, _BaseWidget_readOnlyListener;
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.ToolbarWidgetTag = void 0;
19
19
  const ToolbarShortcutHandler_1 = __importDefault(require("../../tools/ToolbarShortcutHandler"));
@@ -36,11 +36,16 @@ class BaseWidget {
36
36
  this.id = id;
37
37
  this.dropdown = null;
38
38
  _BaseWidget_hasDropdown.set(this, void 0);
39
+ // True iff this widget is disabled.
39
40
  this.disabled = false;
41
+ // True iff this widget is currently disabled because the editor is read only
42
+ _BaseWidget_disabledDueToReadOnlyEditor.set(this, false);
40
43
  _BaseWidget_tags.set(this, []);
41
44
  // Maps subWidget IDs to subWidgets.
42
45
  this.subWidgets = {};
43
46
  this.toplevel = true;
47
+ // Listens for changes in whether the editor is read-only
48
+ _BaseWidget_readOnlyListener.set(this, null);
44
49
  this.localizationTable = localizationTable ?? editor.localization;
45
50
  // Default layout manager
46
51
  const defaultLayoutManager = new DropdownLayoutManager_1.default((text) => this.editor.announceForAccessibility(text), this.localizationTable);
@@ -68,6 +73,13 @@ class BaseWidget {
68
73
  toolbarShortcutHandlers[0].registerListener(event => this.onKeyPress(event));
69
74
  }
70
75
  }
76
+ /**
77
+ * Should return a constant true or false value. If true (the default),
78
+ * this widget must be automatically disabled when its editor is read-only.
79
+ */
80
+ shouldAutoDisableInReadOnlyEditor() {
81
+ return true;
82
+ }
71
83
  getId() {
72
84
  return this.id;
73
85
  }
@@ -262,6 +274,19 @@ class BaseWidget {
262
274
  if (this.container.parentElement) {
263
275
  this.container.remove();
264
276
  }
277
+ __classPrivateFieldSet(this, _BaseWidget_readOnlyListener, this.editor.isReadOnlyReactiveValue().onUpdateAndNow(readOnly => {
278
+ if (readOnly && this.shouldAutoDisableInReadOnlyEditor() && !this.disabled) {
279
+ this.setDisabled(true);
280
+ __classPrivateFieldSet(this, _BaseWidget_disabledDueToReadOnlyEditor, true, "f");
281
+ if (__classPrivateFieldGet(this, _BaseWidget_hasDropdown, "f")) {
282
+ this.dropdown?.requestHide();
283
+ }
284
+ }
285
+ else if (!readOnly && __classPrivateFieldGet(this, _BaseWidget_disabledDueToReadOnlyEditor, "f")) {
286
+ __classPrivateFieldSet(this, _BaseWidget_disabledDueToReadOnlyEditor, false, "f");
287
+ this.setDisabled(false);
288
+ }
289
+ }), "f");
265
290
  parent.appendChild(this.container);
266
291
  return this.container;
267
292
  }
@@ -279,6 +304,8 @@ class BaseWidget {
279
304
  }
280
305
  remove() {
281
306
  this.container.remove();
307
+ __classPrivateFieldGet(this, _BaseWidget_readOnlyListener, "f")?.remove();
308
+ __classPrivateFieldSet(this, _BaseWidget_readOnlyListener, null, "f");
282
309
  }
283
310
  updateIcon() {
284
311
  let newIcon = this.createIcon();
@@ -295,6 +322,7 @@ class BaseWidget {
295
322
  }
296
323
  setDisabled(disabled) {
297
324
  this.disabled = disabled;
325
+ __classPrivateFieldSet(this, _BaseWidget_disabledDueToReadOnlyEditor, false, "f");
298
326
  if (this.disabled) {
299
327
  this.button.classList.add('disabled');
300
328
  this.button.setAttribute('aria-disabled', 'true');
@@ -415,5 +443,5 @@ class BaseWidget {
415
443
  }
416
444
  }
417
445
  }
418
- _BaseWidget_hasDropdown = new WeakMap(), _BaseWidget_tags = new WeakMap();
446
+ _BaseWidget_hasDropdown = new WeakMap(), _BaseWidget_disabledDueToReadOnlyEditor = new WeakMap(), _BaseWidget_tags = new WeakMap(), _BaseWidget_readOnlyListener = new WeakMap();
419
447
  exports.default = BaseWidget;
@@ -29,7 +29,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
29
29
  const Erase_1 = __importDefault(require("../../commands/Erase"));
30
30
  const uniteCommands_1 = __importDefault(require("../../commands/uniteCommands"));
31
31
  const BackgroundComponent_1 = __importStar(require("../../components/BackgroundComponent"));
32
- const EditorImage_1 = require("../../EditorImage");
32
+ const EditorImage_1 = require("../../image/EditorImage");
33
33
  const math_1 = require("@js-draw/math");
34
34
  const types_1 = require("../../types");
35
35
  const constants_1 = require("../constants");
@@ -7,6 +7,7 @@ export default class HandToolWidget extends BaseToolWidget {
7
7
  protected overridePanZoomTool: PanZoom;
8
8
  private allowTogglingBaseTool;
9
9
  constructor(editor: Editor, overridePanZoomTool: PanZoom, localizationTable: ToolbarLocalization);
10
+ protected shouldAutoDisableInReadOnlyEditor(): boolean;
10
11
  private static getPrimaryHandTool;
11
12
  protected getTitle(): string;
12
13
  protected createIcon(): Element;
@@ -103,6 +103,9 @@ class HandModeWidget extends BaseWidget_1.default {
103
103
  });
104
104
  this.setSelected(false);
105
105
  }
106
+ shouldAutoDisableInReadOnlyEditor() {
107
+ return false;
108
+ }
106
109
  setModeFlag(enabled) {
107
110
  this.tool.setModeEnabled(this.flag, enabled);
108
111
  }
@@ -141,6 +144,9 @@ class HandToolWidget extends BaseToolWidget_1.default {
141
144
  this.addSubWidget(touchPanningWidget);
142
145
  this.addSubWidget(rotationLockWidget);
143
146
  }
147
+ shouldAutoDisableInReadOnlyEditor() {
148
+ return false;
149
+ }
144
150
  static getPrimaryHandTool(toolController) {
145
151
  const primaryPanZoomToolList = toolController.getPrimaryTools().filter(tool => tool instanceof PanZoom_1.default);
146
152
  const primaryPanZoomTool = primaryPanZoomToolList[0];
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const ImageComponent_1 = __importDefault(require("../../components/ImageComponent"));
7
7
  const Erase_1 = __importDefault(require("../../commands/Erase"));
8
- const EditorImage_1 = __importDefault(require("../../EditorImage"));
8
+ const EditorImage_1 = __importDefault(require("../../image/EditorImage"));
9
9
  const uniteCommands_1 = __importDefault(require("../../commands/uniteCommands"));
10
10
  const SelectionTool_1 = __importDefault(require("../../tools/SelectionTool/SelectionTool"));
11
11
  const math_1 = require("@js-draw/math");
@@ -5,6 +5,7 @@ export default class OverflowWidget extends BaseWidget {
5
5
  private overflowChildren;
6
6
  private overflowContainer;
7
7
  constructor(editor: Editor, localizationTable?: ToolbarLocalization);
8
+ protected shouldAutoDisableInReadOnlyEditor(): boolean;
8
9
  protected getTitle(): string;
9
10
  protected createIcon(): Element | null;
10
11
  protected handleClick(): void;
@@ -13,6 +13,9 @@ class OverflowWidget extends BaseWidget_1.default {
13
13
  this.container.classList.add('dropdownShowable');
14
14
  this.overflowContainer ??= document.createElement('div');
15
15
  }
16
+ shouldAutoDisableInReadOnlyEditor() {
17
+ return false;
18
+ }
16
19
  getTitle() {
17
20
  return this.localizationTable.toggleOverflow;
18
21
  }
@@ -4,6 +4,7 @@ import { ToolbarLocalization } from '../localization';
4
4
  import ActionButtonWidget from './ActionButtonWidget';
5
5
  declare class SaveActionWidget extends ActionButtonWidget {
6
6
  constructor(editor: Editor, localization: ToolbarLocalization, saveCallback: () => void);
7
+ protected shouldAutoDisableInReadOnlyEditor(): boolean;
7
8
  protected onKeyPress(event: KeyPressEvent): boolean;
8
9
  mustBeInToplevelMenu(): boolean;
9
10
  }
@@ -11,6 +11,9 @@ class SaveActionWidget extends ActionButtonWidget_1.default {
11
11
  super(editor, 'save-button', editor.icons.makeSaveIcon, localization.save, saveCallback);
12
12
  this.setTags([BaseWidget_1.ToolbarWidgetTag.Save]);
13
13
  }
14
+ shouldAutoDisableInReadOnlyEditor() {
15
+ return false;
16
+ }
14
17
  onKeyPress(event) {
15
18
  if (this.editor.shortcuts.matchesShortcut(keybindings_1.saveKeyboardShortcut, event)) {
16
19
  this.clickAction();
@@ -8,6 +8,8 @@ export default abstract class BaseTool implements InputEventListener {
8
8
  private notifier;
9
9
  readonly description: string;
10
10
  protected constructor(notifier: EditorNotifier, description: string);
11
+ /** Override this to allow this tool to be enabled in a read-only editor */
12
+ canReceiveInputInReadOnlyEditor(): boolean;
11
13
  setInputMapper(mapper: InputMapper | null): void;
12
14
  getInputMapper(): InputMapper | null;
13
15
  private dispatchEventToCallback;
@@ -54,4 +56,5 @@ export default abstract class BaseTool implements InputEventListener {
54
56
  enabledValue(): ReactiveValue<boolean>;
55
57
  setToolGroup(group: ToolEnabledGroup): void;
56
58
  getToolGroup(): ToolEnabledGroup | null;
59
+ onDestroy(): void;
57
60
  }
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- var _BaseTool_enabled, _BaseTool_group, _BaseTool_inputMapper;
13
+ var _BaseTool_enabled, _BaseTool_group, _BaseTool_inputMapper, _BaseTool_readOnlyEditorChangeListener;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const types_1 = require("../types");
16
16
  const inputEvents_1 = require("../inputEvents");
@@ -22,6 +22,7 @@ class BaseTool {
22
22
  _BaseTool_enabled.set(this, void 0);
23
23
  _BaseTool_group.set(this, null);
24
24
  _BaseTool_inputMapper.set(this, null);
25
+ _BaseTool_readOnlyEditorChangeListener.set(this, null);
25
26
  __classPrivateFieldSet(this, _BaseTool_enabled, ReactiveValue_1.ReactiveValue.fromInitialValue(true), "f");
26
27
  __classPrivateFieldGet(this, _BaseTool_enabled, "f").onUpdate(enabled => {
27
28
  // Ensure that at most one tool in the group is enabled.
@@ -40,6 +41,10 @@ class BaseTool {
40
41
  }
41
42
  });
42
43
  }
44
+ /** Override this to allow this tool to be enabled in a read-only editor */
45
+ canReceiveInputInReadOnlyEditor() {
46
+ return false;
47
+ }
43
48
  setInputMapper(mapper) {
44
49
  __classPrivateFieldSet(this, _BaseTool_inputMapper, mapper, "f");
45
50
  if (mapper) {
@@ -157,6 +162,12 @@ class BaseTool {
157
162
  }
158
163
  return null;
159
164
  }
165
+ // Called when the tool is removed/when the editor is destroyed.
166
+ // Subclasses that override this method **must call super.onDestroy()**.
167
+ onDestroy() {
168
+ __classPrivateFieldGet(this, _BaseTool_readOnlyEditorChangeListener, "f")?.remove();
169
+ __classPrivateFieldSet(this, _BaseTool_readOnlyEditorChangeListener, null, "f");
170
+ }
160
171
  }
161
- _BaseTool_enabled = new WeakMap(), _BaseTool_group = new WeakMap(), _BaseTool_inputMapper = new WeakMap();
172
+ _BaseTool_enabled = new WeakMap(), _BaseTool_group = new WeakMap(), _BaseTool_inputMapper = new WeakMap(), _BaseTool_readOnlyEditorChangeListener = new WeakMap();
162
173
  exports.default = BaseTool;
@@ -7,6 +7,7 @@ export default class FindTool extends BaseTool {
7
7
  private searchInput;
8
8
  private currentMatchIdx;
9
9
  constructor(editor: Editor);
10
+ canReceiveInputInReadOnlyEditor(): boolean;
10
11
  private getMatches;
11
12
  private focusCurrentMatch;
12
13
  private toNextMatch;
@@ -21,6 +21,9 @@ class FindTool extends BaseTool_1.default {
21
21
  this.overlay.style.display = 'none';
22
22
  this.overlay.classList.add(`${cssPrefix}-overlay`);
23
23
  }
24
+ canReceiveInputInReadOnlyEditor() {
25
+ return true;
26
+ }
24
27
  getMatches(searchFor) {
25
28
  searchFor = searchFor.toLocaleLowerCase();
26
29
  const allTextComponents = this.editor.image.getAllElements()
@@ -113,7 +116,7 @@ class FindTool extends BaseTool_1.default {
113
116
  }
114
117
  setEnabled(enabled) {
115
118
  super.setEnabled(enabled);
116
- if (enabled) {
119
+ if (this.isEnabled()) {
117
120
  this.setVisible(false);
118
121
  }
119
122
  }
@@ -32,6 +32,7 @@ export default class PanZoom extends BaseTool {
32
32
  private inertialScroller;
33
33
  private velocity;
34
34
  constructor(editor: Editor, mode: PanZoomMode, description: string);
35
+ canReceiveInputInReadOnlyEditor(): boolean;
35
36
  computePinchData(p1: Pointer, p2: Pointer): PinchData;
36
37
  private allPointersAreOfType;
37
38
  onPointerDown({ allPointers: pointers, current: currentPointer }: PointerEvt): boolean;
@@ -80,6 +80,10 @@ class PanZoom extends BaseTool_1.default {
80
80
  this.inertialScroller = null;
81
81
  this.velocity = null;
82
82
  }
83
+ // The pan/zoom tool can be used in a read-only editor.
84
+ canReceiveInputInReadOnlyEditor() {
85
+ return true;
86
+ }
83
87
  // Returns information about the pointers in a gesture
84
88
  computePinchData(p1, p2) {
85
89
  // Swap the pointers to ensure consistent ordering.
@@ -40,6 +40,5 @@ export default class Pen extends BaseTool {
40
40
  getColor(): Color4;
41
41
  getStrokeFactory(): ComponentBuilderFactory;
42
42
  getStyleValue(): MutableReactiveValue<PenStyle>;
43
- setEnabled(enabled: boolean): void;
44
43
  onKeyPress(event: KeyPressEvent): boolean;
45
44
  }
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const math_1 = require("@js-draw/math");
7
- const EditorImage_1 = __importDefault(require("../EditorImage"));
7
+ const EditorImage_1 = __importDefault(require("../image/EditorImage"));
8
8
  const Pointer_1 = require("../Pointer");
9
9
  const FreehandLineBuilder_1 = require("../components/builders/FreehandLineBuilder");
10
10
  const types_1 = require("../types");
@@ -205,9 +205,6 @@ class Pen extends BaseTool_1.default {
205
205
  getColor() { return this.style.color; }
206
206
  getStrokeFactory() { return this.style.factory; }
207
207
  getStyleValue() { return this.styleValue; }
208
- setEnabled(enabled) {
209
- super.setEnabled(enabled);
210
- }
211
208
  onKeyPress(event) {
212
209
  const shortcuts = this.editor.shortcuts;
213
210
  // Ctrl+Z: End the stroke so that it can be undone/redone.
@@ -16,6 +16,7 @@ export default class PipetteTool extends BaseTool {
16
16
  private colorPreviewListener;
17
17
  private colorSelectListener;
18
18
  constructor(editor: Editor, description: string);
19
+ canReceiveInputInReadOnlyEditor(): boolean;
19
20
  private updateSelectingStatus;
20
21
  setColorListener(colorPreviewListener: ColorListener, colorSelectListener: ColorListener): void;
21
22
  clearColorListener(): void;
@@ -23,6 +23,9 @@ class PipetteTool extends BaseTool_1.default {
23
23
  this.updateSelectingStatus();
24
24
  });
25
25
  }
26
+ canReceiveInputInReadOnlyEditor() {
27
+ return true;
28
+ }
26
29
  // Ensures that the root editor element correctly reflects whether color selection
27
30
  // is in progress.
28
31
  updateSelectingStatus() {
@@ -4,5 +4,6 @@ import BaseTool from '../BaseTool';
4
4
  export default class SelectAllShortcutHandler extends BaseTool {
5
5
  private editor;
6
6
  constructor(editor: Editor);
7
+ canReceiveInputInReadOnlyEditor(): boolean;
7
8
  onKeyPress(event: KeyPressEvent): boolean;
8
9
  }
@@ -12,6 +12,9 @@ class SelectAllShortcutHandler extends BaseTool_1.default {
12
12
  super(editor.notifier, editor.localization.selectAllTool);
13
13
  this.editor = editor;
14
14
  }
15
+ canReceiveInputInReadOnlyEditor() {
16
+ return true;
17
+ }
15
18
  // @internal
16
19
  onKeyPress(event) {
17
20
  if (this.editor.shortcuts.matchesShortcut(keybindings_1.selectAllKeyboardShortcut, event)) {
@@ -11,6 +11,7 @@ export default class Selection {
11
11
  private editor;
12
12
  private handles;
13
13
  private originalRegion;
14
+ private selectionTightBoundingBox;
14
15
  private transformers;
15
16
  private transform;
16
17
  private selectedElems;
@@ -39,6 +40,7 @@ export default class Selection {
39
40
  private previewTransformCmds;
40
41
  resolveToObjects(): boolean;
41
42
  recomputeRegion(): boolean;
43
+ padRegion(): void;
42
44
  getMinCanvasSize(): number;
43
45
  getSelectedItemCount(): number;
44
46
  updateUI(): void;