js-draw 1.0.1 → 1.0.2

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 (182) hide show
  1. package/LICENSE +21 -0
  2. package/dist/bundle.js +1 -1
  3. package/dist/cjs/version.js +1 -1
  4. package/dist/mjs/version.mjs +1 -1
  5. package/docs/img/readme-images/js-draw.jpg +0 -0
  6. package/docs/img/readme-images/unsupported-elements--in-editor.png +0 -0
  7. package/package.json +5 -4
  8. package/dist-test/test_imports/package-lock.json +0 -13
  9. package/dist-test/test_imports/package.json +0 -12
  10. package/dist-test/test_imports/test-imports.js +0 -11
  11. package/dist-test/test_imports/test-require.cjs +0 -14
  12. package/src/Editor.loadFrom.test.ts +0 -24
  13. package/src/Editor.test.ts +0 -107
  14. package/src/Editor.toSVG.test.ts +0 -294
  15. package/src/Editor.ts +0 -1443
  16. package/src/EditorImage.test.ts +0 -117
  17. package/src/EditorImage.ts +0 -609
  18. package/src/EventDispatcher.test.ts +0 -123
  19. package/src/EventDispatcher.ts +0 -72
  20. package/src/Pointer.ts +0 -183
  21. package/src/SVGLoader.test.ts +0 -114
  22. package/src/SVGLoader.ts +0 -672
  23. package/src/UndoRedoHistory.test.ts +0 -34
  24. package/src/UndoRedoHistory.ts +0 -102
  25. package/src/Viewport.ts +0 -322
  26. package/src/bundle/bundled.ts +0 -7
  27. package/src/commands/Command.ts +0 -45
  28. package/src/commands/Duplicate.ts +0 -75
  29. package/src/commands/Erase.ts +0 -95
  30. package/src/commands/SerializableCommand.ts +0 -49
  31. package/src/commands/UnresolvedCommand.ts +0 -37
  32. package/src/commands/invertCommand.ts +0 -58
  33. package/src/commands/lib.ts +0 -16
  34. package/src/commands/localization.ts +0 -47
  35. package/src/commands/uniteCommands.test.ts +0 -23
  36. package/src/commands/uniteCommands.ts +0 -140
  37. package/src/components/AbstractComponent.transformBy.test.ts +0 -23
  38. package/src/components/AbstractComponent.ts +0 -383
  39. package/src/components/BackgroundComponent.test.ts +0 -44
  40. package/src/components/BackgroundComponent.ts +0 -348
  41. package/src/components/ImageComponent.ts +0 -176
  42. package/src/components/RestylableComponent.ts +0 -161
  43. package/src/components/SVGGlobalAttributesObject.ts +0 -79
  44. package/src/components/Stroke.test.ts +0 -137
  45. package/src/components/Stroke.ts +0 -294
  46. package/src/components/TextComponent.test.ts +0 -202
  47. package/src/components/TextComponent.ts +0 -429
  48. package/src/components/UnknownSVGObject.test.ts +0 -10
  49. package/src/components/UnknownSVGObject.ts +0 -60
  50. package/src/components/builders/ArrowBuilder.ts +0 -106
  51. package/src/components/builders/CircleBuilder.ts +0 -100
  52. package/src/components/builders/FreehandLineBuilder.test.ts +0 -24
  53. package/src/components/builders/FreehandLineBuilder.ts +0 -210
  54. package/src/components/builders/LineBuilder.ts +0 -77
  55. package/src/components/builders/PressureSensitiveFreehandLineBuilder.ts +0 -453
  56. package/src/components/builders/RectangleBuilder.ts +0 -73
  57. package/src/components/builders/types.ts +0 -15
  58. package/src/components/lib.ts +0 -31
  59. package/src/components/localization.ts +0 -24
  60. package/src/components/util/StrokeSmoother.ts +0 -302
  61. package/src/components/util/describeComponentList.ts +0 -18
  62. package/src/dialogs/makeAboutDialog.ts +0 -82
  63. package/src/inputEvents.ts +0 -143
  64. package/src/lib.ts +0 -91
  65. package/src/localization.ts +0 -34
  66. package/src/localizations/de.ts +0 -146
  67. package/src/localizations/en.ts +0 -8
  68. package/src/localizations/es.ts +0 -74
  69. package/src/localizations/getLocalizationTable.test.ts +0 -27
  70. package/src/localizations/getLocalizationTable.ts +0 -74
  71. package/src/rendering/Display.ts +0 -247
  72. package/src/rendering/RenderablePathSpec.ts +0 -88
  73. package/src/rendering/RenderingStyle.test.ts +0 -68
  74. package/src/rendering/RenderingStyle.ts +0 -55
  75. package/src/rendering/TextRenderingStyle.ts +0 -55
  76. package/src/rendering/caching/CacheRecord.test.ts +0 -48
  77. package/src/rendering/caching/CacheRecord.ts +0 -76
  78. package/src/rendering/caching/CacheRecordManager.ts +0 -71
  79. package/src/rendering/caching/RenderingCache.test.ts +0 -43
  80. package/src/rendering/caching/RenderingCache.ts +0 -66
  81. package/src/rendering/caching/RenderingCacheNode.ts +0 -404
  82. package/src/rendering/caching/testUtils.ts +0 -35
  83. package/src/rendering/caching/types.ts +0 -34
  84. package/src/rendering/lib.ts +0 -8
  85. package/src/rendering/localization.ts +0 -20
  86. package/src/rendering/renderers/AbstractRenderer.ts +0 -232
  87. package/src/rendering/renderers/CanvasRenderer.ts +0 -312
  88. package/src/rendering/renderers/DummyRenderer.test.ts +0 -41
  89. package/src/rendering/renderers/DummyRenderer.ts +0 -142
  90. package/src/rendering/renderers/SVGRenderer.ts +0 -434
  91. package/src/rendering/renderers/TextOnlyRenderer.test.ts +0 -34
  92. package/src/rendering/renderers/TextOnlyRenderer.ts +0 -68
  93. package/src/shortcuts/KeyBinding.test.ts +0 -61
  94. package/src/shortcuts/KeyBinding.ts +0 -257
  95. package/src/shortcuts/KeyboardShortcutManager.test.ts +0 -95
  96. package/src/shortcuts/KeyboardShortcutManager.ts +0 -163
  97. package/src/shortcuts/lib.ts +0 -3
  98. package/src/testing/createEditor.ts +0 -11
  99. package/src/testing/getUniquePointerId.ts +0 -18
  100. package/src/testing/lib.ts +0 -3
  101. package/src/testing/sendPenEvent.ts +0 -36
  102. package/src/testing/sendTouchEvent.ts +0 -71
  103. package/src/toolbar/AbstractToolbar.ts +0 -542
  104. package/src/toolbar/DropdownToolbar.ts +0 -220
  105. package/src/toolbar/EdgeToolbar.test.ts +0 -54
  106. package/src/toolbar/EdgeToolbar.ts +0 -543
  107. package/src/toolbar/IconProvider.ts +0 -861
  108. package/src/toolbar/constants.ts +0 -1
  109. package/src/toolbar/lib.ts +0 -6
  110. package/src/toolbar/localization.ts +0 -136
  111. package/src/toolbar/types.ts +0 -13
  112. package/src/toolbar/widgets/ActionButtonWidget.ts +0 -39
  113. package/src/toolbar/widgets/BaseToolWidget.ts +0 -81
  114. package/src/toolbar/widgets/BaseWidget.ts +0 -495
  115. package/src/toolbar/widgets/DocumentPropertiesWidget.ts +0 -250
  116. package/src/toolbar/widgets/EraserToolWidget.ts +0 -84
  117. package/src/toolbar/widgets/HandToolWidget.ts +0 -239
  118. package/src/toolbar/widgets/InsertImageWidget.ts +0 -248
  119. package/src/toolbar/widgets/OverflowWidget.ts +0 -92
  120. package/src/toolbar/widgets/PenToolWidget.ts +0 -369
  121. package/src/toolbar/widgets/SelectionToolWidget.ts +0 -195
  122. package/src/toolbar/widgets/TextToolWidget.ts +0 -149
  123. package/src/toolbar/widgets/components/makeColorInput.ts +0 -184
  124. package/src/toolbar/widgets/components/makeFileInput.ts +0 -128
  125. package/src/toolbar/widgets/components/makeGridSelector.ts +0 -179
  126. package/src/toolbar/widgets/components/makeSeparator.ts +0 -17
  127. package/src/toolbar/widgets/components/makeThicknessSlider.ts +0 -62
  128. package/src/toolbar/widgets/keybindings.ts +0 -19
  129. package/src/toolbar/widgets/layout/DropdownLayoutManager.ts +0 -262
  130. package/src/toolbar/widgets/layout/EdgeToolbarLayoutManager.ts +0 -71
  131. package/src/toolbar/widgets/layout/types.ts +0 -74
  132. package/src/toolbar/widgets/lib.ts +0 -13
  133. package/src/tools/BaseTool.ts +0 -169
  134. package/src/tools/Eraser.test.ts +0 -103
  135. package/src/tools/Eraser.ts +0 -173
  136. package/src/tools/FindTool.test.ts +0 -67
  137. package/src/tools/FindTool.ts +0 -153
  138. package/src/tools/InputFilter/FunctionMapper.ts +0 -17
  139. package/src/tools/InputFilter/InputMapper.ts +0 -41
  140. package/src/tools/InputFilter/InputPipeline.test.ts +0 -41
  141. package/src/tools/InputFilter/InputPipeline.ts +0 -34
  142. package/src/tools/InputFilter/InputStabilizer.ts +0 -254
  143. package/src/tools/InputFilter/StrokeKeyboardControl.ts +0 -104
  144. package/src/tools/PanZoom.test.ts +0 -339
  145. package/src/tools/PanZoom.ts +0 -525
  146. package/src/tools/PasteHandler.ts +0 -94
  147. package/src/tools/Pen.test.ts +0 -260
  148. package/src/tools/Pen.ts +0 -284
  149. package/src/tools/PipetteTool.ts +0 -84
  150. package/src/tools/SelectionTool/SelectAllShortcutHandler.ts +0 -29
  151. package/src/tools/SelectionTool/Selection.ts +0 -647
  152. package/src/tools/SelectionTool/SelectionHandle.ts +0 -142
  153. package/src/tools/SelectionTool/SelectionTool.test.ts +0 -370
  154. package/src/tools/SelectionTool/SelectionTool.ts +0 -510
  155. package/src/tools/SelectionTool/TransformMode.ts +0 -112
  156. package/src/tools/SelectionTool/types.ts +0 -11
  157. package/src/tools/SoundUITool.ts +0 -221
  158. package/src/tools/TextTool.ts +0 -339
  159. package/src/tools/ToolController.ts +0 -224
  160. package/src/tools/ToolEnabledGroup.ts +0 -14
  161. package/src/tools/ToolSwitcherShortcut.ts +0 -39
  162. package/src/tools/ToolbarShortcutHandler.ts +0 -39
  163. package/src/tools/UndoRedoShortcut.test.ts +0 -62
  164. package/src/tools/UndoRedoShortcut.ts +0 -24
  165. package/src/tools/keybindings.ts +0 -85
  166. package/src/tools/lib.ts +0 -22
  167. package/src/tools/localization.ts +0 -76
  168. package/src/types.ts +0 -151
  169. package/src/util/ReactiveValue.test.ts +0 -168
  170. package/src/util/ReactiveValue.ts +0 -241
  171. package/src/util/assertions.ts +0 -55
  172. package/src/util/fileToBase64.ts +0 -18
  173. package/src/util/guessKeyCodeFromKey.ts +0 -36
  174. package/src/util/listPrefixMatch.ts +0 -19
  175. package/src/util/stopPropagationOfScrollingWheelEvents.ts +0 -20
  176. package/src/util/untilNextAnimationFrame.ts +0 -9
  177. package/src/util/waitForAll.ts +0 -18
  178. package/src/util/waitForTimeout.ts +0 -9
  179. package/src/version.test.ts +0 -12
  180. package/src/version.ts +0 -3
  181. package/tools/allLocales.js +0 -4
  182. package/tools/copyREADME.ts +0 -62
@@ -1,495 +0,0 @@
1
- import Editor from '../../Editor';
2
- import ToolbarShortcutHandler from '../../tools/ToolbarShortcutHandler';
3
- import { KeyPressEvent, keyPressEventFromHTMLEvent, keyUpEventFromHTMLEvent } from '../../inputEvents';
4
- import { toolbarCSSPrefix } from '../constants';
5
- import { ToolbarLocalization } from '../localization';
6
- import DropdownLayoutManager from './layout/DropdownLayoutManager';
7
- import { ToolMenu, WidgetContentLayoutManager } from './layout/types';
8
-
9
- export type SavedToolbuttonState = Record<string, any>;
10
-
11
- /**
12
- * A set of labels that allow toolbar themes to treat buttons differently.
13
- */
14
- export enum ToolbarWidgetTag {
15
- Save = 'save',
16
- Exit = 'exit',
17
- Undo = 'undo',
18
- Redo = 'redo',
19
- }
20
-
21
- export default abstract class BaseWidget {
22
- protected readonly container: HTMLElement;
23
- private button: HTMLElement;
24
- private icon: Element|null;
25
- private layoutManager: WidgetContentLayoutManager;
26
- private dropdown: ToolMenu|null = null;
27
- private dropdownContent: HTMLElement;
28
- private dropdownIcon: Element;
29
- private label: HTMLLabelElement;
30
- #hasDropdown: boolean;
31
- private disabled: boolean = false;
32
-
33
- #tags: (ToolbarWidgetTag|string)[] = [];
34
-
35
- // Maps subWidget IDs to subWidgets.
36
- private subWidgets: Record<string, BaseWidget> = {};
37
-
38
- private toplevel: boolean = true;
39
- protected readonly localizationTable: ToolbarLocalization;
40
-
41
- public constructor(
42
- protected editor: Editor,
43
- protected id: string,
44
- localizationTable?: ToolbarLocalization
45
- ) {
46
- this.localizationTable = localizationTable ?? editor.localization;
47
-
48
- // Default layout manager
49
- const defaultLayoutManager = new DropdownLayoutManager(
50
- (text) => this.editor.announceForAccessibility(text),
51
- this.localizationTable
52
- );
53
- defaultLayoutManager.connectToEditorNotifier(editor.notifier);
54
- this.layoutManager = defaultLayoutManager;
55
-
56
- this.icon = null;
57
- this.container = document.createElement('div');
58
- this.container.classList.add(
59
- `${toolbarCSSPrefix}toolContainer`, `${toolbarCSSPrefix}toolButtonContainer`
60
- );
61
- this.dropdownContent = document.createElement('div');
62
- this.#hasDropdown = false;
63
-
64
- this.button = document.createElement('div');
65
- this.button.classList.add(`${toolbarCSSPrefix}button`);
66
- this.label = document.createElement('label');
67
- this.button.setAttribute('role', 'button');
68
- this.button.tabIndex = 0;
69
-
70
- const toolbarShortcutHandlers = this.editor.toolController.getMatchingTools(ToolbarShortcutHandler);
71
-
72
- // If the onKeyPress function has been extended and the editor is configured to send keypress events to
73
- // toolbar widgets,
74
- if (toolbarShortcutHandlers.length > 0 && this.onKeyPress !== BaseWidget.prototype.onKeyPress) {
75
- toolbarShortcutHandlers[0].registerListener(event => this.onKeyPress(event));
76
- }
77
- }
78
-
79
- public getId(): string {
80
- return this.id;
81
- }
82
-
83
- /**
84
- * Note: Tags should be set *before* a tool widget is added to a toolbar.
85
- *
86
- *
87
- * Associates tags with this widget that can be used by toolbar themes
88
- * to customize the layout/appearance of this button. Prefer tags in
89
- * the `ToolbarWidgetTag` enum, where possible.
90
- *
91
- * In addition to being readable from the {@link getTags} method, tags are
92
- * added to a button's main container as CSS classes with the `toolwidget-tag--` prefix.
93
- *
94
- * For example, the `undo` tag would result in `toolwidget-tag--undo`
95
- * being added to the button's container's class list.
96
- *
97
- */
98
- public setTags(tags: (string|ToolbarWidgetTag)[]) {
99
- const toClassName = (tag: string) => {
100
- return `toolwidget-tag--${tag}`;
101
- };
102
-
103
- // Remove CSS classes associated with old tags
104
- for (const tag of this.#tags) {
105
- this.container.classList.remove(toClassName(tag));
106
- }
107
-
108
- this.#tags = [...tags];
109
-
110
- // Add new CSS classes
111
- for (const tag of this.#tags) {
112
- this.container.classList.add(toClassName(tag));
113
- }
114
- }
115
-
116
- public getTags() {
117
- return [ ...this.#tags ];
118
- }
119
-
120
- /**
121
- * Returns the ID of this widget in `container`. Adds a suffix to this' ID
122
- * if an item in `container` already has this' ID.
123
- *
124
- * For example, if `this` has ID `foo` and if
125
- * `container = { 'foo': somethingNotThis, 'foo-1': somethingElseNotThis }`, this method
126
- * returns `foo-2` because elements with IDs `foo` and `foo-1` are already present in
127
- * `container`.
128
- *
129
- * If `this` is already in `container`, returns the id given to `this` in the container.
130
- */
131
- public getUniqueIdIn(container: Record<string, BaseWidget>): string {
132
- let id = this.getId();
133
- let idCounter = 0;
134
-
135
- while (id in container && container[id] !== this) {
136
- id = this.getId() + '-' + idCounter.toString();
137
- idCounter ++;
138
- }
139
-
140
- return id;
141
- }
142
-
143
- protected abstract getTitle(): string;
144
- protected abstract createIcon(): Element|null;
145
-
146
- // Add content to the widget's associated dropdown menu.
147
- // Returns true if such a menu should be created, false otherwise.
148
- protected fillDropdown(dropdown: HTMLElement): boolean {
149
- if (Object.keys(this.subWidgets).length === 0) {
150
- return false;
151
- }
152
-
153
- for (const widgetId in this.subWidgets) {
154
- const widget = this.subWidgets[widgetId];
155
-
156
- widget.addTo(dropdown);
157
- widget.setIsToplevel(false);
158
- }
159
- return true;
160
- }
161
-
162
- /** @deprecated Renamed to `setUpButtonEventListeners`. */
163
- protected setupActionBtnClickListener(button: HTMLElement) {
164
- return this.setUpButtonEventListeners(button);
165
- }
166
-
167
- protected setUpButtonEventListeners(button: HTMLElement) {
168
- const clickTriggers = { Enter: true, ' ': true, };
169
- button.onkeydown = (evt) => {
170
- let handled = false;
171
-
172
- if (evt.key in clickTriggers) {
173
- if (!this.disabled) {
174
- this.handleClick();
175
- handled = true;
176
- }
177
- }
178
-
179
- // If we didn't do anything with the event, send it to the editor.
180
- if (!handled) {
181
- const editorEvent = keyPressEventFromHTMLEvent(evt);
182
- handled = this.editor.toolController.dispatchInputEvent(editorEvent);
183
- }
184
-
185
- if (handled) {
186
- evt.preventDefault();
187
- }
188
- };
189
-
190
- button.onkeyup = htmlEvent => {
191
- if (htmlEvent.key in clickTriggers) {
192
- return;
193
- }
194
-
195
- const event = keyUpEventFromHTMLEvent(htmlEvent);
196
- const handled = this.editor.toolController.dispatchInputEvent(event);
197
-
198
- if (handled) {
199
- htmlEvent.preventDefault();
200
- }
201
- };
202
-
203
- button.onclick = () => {
204
- if (!this.disabled) {
205
- this.handleClick();
206
- }
207
- };
208
-
209
- // Prevent double-click zoom on some devices.
210
- button.ondblclick = event => {
211
- event.preventDefault();
212
- };
213
- }
214
-
215
- // Add a listener that is triggered when a key is pressed.
216
- // Listeners will fire regardless of whether this widget is selected and require that
217
- // {@link Editor.toolController} to have an enabled {@link ToolbarShortcutHandler} tool.
218
- protected onKeyPress(_event: KeyPressEvent): boolean {
219
- return false;
220
- }
221
-
222
- protected abstract handleClick(): void;
223
-
224
- protected get hasDropdown() {
225
- return this.#hasDropdown;
226
- }
227
-
228
- // Add a widget to this' dropdown. Must be called before this.addTo.
229
- protected addSubWidget(widget: BaseWidget) {
230
- // Generate a unique ID for the widget.
231
- const id = widget.getUniqueIdIn(this.subWidgets);
232
-
233
- this.subWidgets[id] = widget;
234
- }
235
-
236
- public setLayoutManager(manager: WidgetContentLayoutManager) {
237
- if (manager === this.layoutManager) {
238
- return;
239
- }
240
-
241
- this.layoutManager = manager;
242
- if (this.container.parentElement) {
243
- // Trigger a re-creation of this' content
244
- this.addTo(this.container.parentElement);
245
- }
246
- }
247
-
248
-
249
- /**
250
- * Adds this to `parent`.
251
- * Returns the element that was just added to `parent`.
252
- * @internal
253
- */
254
- public addTo(parent: HTMLElement) {
255
- // Update title and icon
256
- this.icon = null;
257
- this.updateIcon();
258
- this.label.innerText = this.getTitle();
259
-
260
- const longLabelCSSClass = 'long-label';
261
- if (this.label.innerText.length > 7) {
262
- this.label.classList.add(longLabelCSSClass);
263
- } else {
264
- this.label.classList.remove(longLabelCSSClass);
265
- }
266
-
267
- // Click functionality
268
- this.setUpButtonEventListeners(this.button);
269
-
270
- // Clear anything already in this.container.
271
- this.container.replaceChildren();
272
-
273
- this.button.replaceChildren(this.icon!, this.label);
274
- this.container.appendChild(this.button);
275
-
276
- // Clear the dropdownContainer in case this element is being moved to another
277
- // parent.
278
- this.dropdownContent.replaceChildren();
279
- this.#hasDropdown = this.fillDropdown(this.dropdownContent);
280
- if (this.#hasDropdown) {
281
- this.button.classList.add('has-dropdown');
282
-
283
- // We're re-creating the dropdown.
284
- this.dropdown?.destroy();
285
-
286
- this.dropdownIcon = this.createDropdownIcon();
287
- this.button.appendChild(this.dropdownIcon);
288
-
289
- this.dropdown = this.layoutManager.createToolMenu({
290
- target: this.button,
291
- getTitle: () => this.getTitle(),
292
- isToplevel: () => this.toplevel,
293
- });
294
-
295
- this.dropdown.visible.onUpdate(visible => {
296
- if (visible) {
297
- this.container.classList.add('dropdownVisible');
298
- } else {
299
- this.container.classList.remove('dropdownVisible');
300
- }
301
-
302
- // Auto-focus this component's button when the dropdown hides --
303
- // this ensures that keyboard focus goes to a reasonable location when
304
- // the user closes a menu.
305
- if (!visible) {
306
- this.focus();
307
- }
308
- });
309
-
310
- this.dropdown.appendChild(this.dropdownContent);
311
- }
312
-
313
- this.setDropdownVisible(false);
314
-
315
- if (this.container.parentElement) {
316
- this.container.remove();
317
- }
318
-
319
- parent.appendChild(this.container);
320
- return this.container;
321
- }
322
-
323
- public focus() {
324
- this.button.focus();
325
- }
326
-
327
- /**
328
- * @internal
329
- */
330
- public addCSSClassToContainer(className: string) {
331
- this.container.classList.add(className);
332
- }
333
-
334
- public removeCSSClassFromContainer(className: string) {
335
- this.container.classList.remove(className);
336
- }
337
-
338
- public remove() {
339
- this.container.remove();
340
- }
341
-
342
- protected updateIcon() {
343
- let newIcon = this.createIcon();
344
-
345
- if (!newIcon) {
346
- newIcon = document.createElement('div');
347
- this.container.classList.add('no-icon');
348
- } else {
349
- this.container.classList.remove('no-icon');
350
- }
351
-
352
- this.icon?.replaceWith(newIcon);
353
- this.icon = newIcon;
354
- this.icon.classList.add(`${toolbarCSSPrefix}icon`);
355
- }
356
-
357
- public setDisabled(disabled: boolean) {
358
- this.disabled = disabled;
359
-
360
- if (this.disabled) {
361
- this.button.classList.add('disabled');
362
- this.button.setAttribute('aria-disabled', 'true');
363
- } else {
364
- this.button.classList.remove('disabled');
365
- this.button.removeAttribute('aria-disabled');
366
- }
367
- }
368
-
369
- public setSelected(selected: boolean) {
370
- const currentlySelected = this.isSelected();
371
- if (currentlySelected === selected) {
372
- return;
373
- }
374
-
375
- // Ensure that accessibility tools check and read the value of
376
- // aria-checked.
377
- // TODO: Ensure that 'role' is set to 'switch' by default for selectable
378
- // buttons.
379
- this.button.setAttribute('role', 'switch');
380
-
381
- if (selected) {
382
- this.container.classList.add('selected');
383
- this.button.setAttribute('aria-checked', 'true');
384
- } else {
385
- this.container.classList.remove('selected');
386
- this.button.setAttribute('aria-checked', 'false');
387
- }
388
- }
389
-
390
-
391
- protected setDropdownVisible(visible: boolean) {
392
- if (visible) {
393
- this.dropdown?.requestShow();
394
- } else {
395
- this.dropdown?.requestHide();
396
- }
397
- }
398
-
399
- /**
400
- * Only used by some layout managers.
401
- * In those layout managers, makes this dropdown visible.
402
- */
403
- protected activateDropdown() {
404
- this.dropdown?.onActivated();
405
- }
406
-
407
- /**
408
- * Returns `true` if this widget must always be in a toplevel menu and not
409
- * in a scrolling/overflow menu.
410
- *
411
- * This method can be overidden to override the default of `true`.
412
- */
413
- public mustBeInToplevelMenu(): boolean {
414
- return false;
415
- }
416
-
417
- /**
418
- * Returns true iff this widget can be in a nontoplevel menu.
419
- *
420
- * @deprecated Use `!mustBeInToplevelMenu()` instead.
421
- */
422
- public canBeInOverflowMenu(): boolean {
423
- return !this.mustBeInToplevelMenu();
424
- }
425
-
426
- public getButtonWidth(): number {
427
- return this.button.clientWidth;
428
- }
429
-
430
- public isHidden(): boolean {
431
- return this.container.style.display === 'none';
432
- }
433
-
434
- public setHidden(hidden: boolean) {
435
- this.container.style.display = hidden ? 'none' : '';
436
- }
437
-
438
- /** Set whether the widget is contained within another. @internal */
439
- public setIsToplevel(toplevel: boolean) {
440
- this.toplevel = toplevel;
441
- }
442
-
443
- protected isDropdownVisible(): boolean {
444
- return this.dropdown?.visible?.get() ?? false;
445
- }
446
-
447
- protected isSelected(): boolean {
448
- return this.container.classList.contains('selected');
449
- }
450
-
451
- private createDropdownIcon(): Element {
452
- const icon = this.editor.icons.makeDropdownIcon();
453
- icon.classList.add(`${toolbarCSSPrefix}showHideDropdownIcon`);
454
- return icon;
455
- }
456
-
457
- /**
458
- * Serialize state associated with this widget.
459
- * Override this method to allow saving/restoring from state on application load.
460
- *
461
- * Overriders should call `super` and include the output of `super.serializeState` in
462
- * the output dictionary.
463
- *
464
- * Clients should not rely on the output from `saveState` being in any particular
465
- * format.
466
- */
467
- public serializeState(): SavedToolbuttonState {
468
- const subwidgetState: Record<string, any> = {};
469
-
470
- // Save all subwidget state.
471
- for (const subwidgetId in this.subWidgets) {
472
- subwidgetState[subwidgetId] = this.subWidgets[subwidgetId].serializeState();
473
- }
474
-
475
- return {
476
- subwidgetState,
477
- };
478
- }
479
-
480
- /**
481
- * Restore widget state from serialized data. See also `saveState`.
482
- *
483
- * Overriders must call `super`.
484
- */
485
- public deserializeFrom(state: SavedToolbuttonState): void {
486
- if (state.subwidgetState) {
487
- // Deserialize all subwidgets.
488
- for (const subwidgetId in state.subwidgetState) {
489
- if (subwidgetId in this.subWidgets) {
490
- this.subWidgets[subwidgetId].deserializeFrom(state.subwidgetState[subwidgetId]);
491
- }
492
- }
493
- }
494
- }
495
- }