@componyx/ui 0.0.0-stage → 1.0.4

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 (169) hide show
  1. package/AppSkin/AppSkin.css +1268 -0
  2. package/AppSkin/AppSkin.js +2748 -0
  3. package/AppSkin/Themes/Default.css +241 -0
  4. package/Base/Base.js +3407 -0
  5. package/Base/ComponentIcons.css +66 -0
  6. package/Base/Font/ComponentIcons.woff +0 -0
  7. package/Base/Font/UI.woff +0 -0
  8. package/Base/Library.js +8432 -0
  9. package/Base/NavigationManager.js +462 -0
  10. package/Base/ResponsiveTemplates.js +371 -0
  11. package/Base/Sanitizer.js +288 -0
  12. package/Base/Themes/Default.css +255 -0
  13. package/Base/UI.css +618 -0
  14. package/Base/UIResourcePath.js +6 -0
  15. package/Bindary/Bindary.js +2011 -0
  16. package/Bindary/Modules/Connection.js +216 -0
  17. package/Bindary/Modules/Core.js +854 -0
  18. package/Bindary/Modules/DataUpdater.js +351 -0
  19. package/Bindary/Modules/ExpressionEngine.js +347 -0
  20. package/Bindary/Modules/ProxyManager.js +482 -0
  21. package/Bindary/Modules/Renderer.js +605 -0
  22. package/Bindary/Modules/Router.js +291 -0
  23. package/Bindary/Modules/Scroller.js +89 -0
  24. package/Bindary/Modules/Template.js +1273 -0
  25. package/BookmarkSpy/BookmarkSpy.js +430 -0
  26. package/Box/Box.css +36 -0
  27. package/Box/Box.js +1685 -0
  28. package/Button/Button.css +470 -0
  29. package/Button/Button.js +1398 -0
  30. package/Button/Themes/Default.css +200 -0
  31. package/Carousel/Carousel.css +273 -0
  32. package/Carousel/Carousel.js +607 -0
  33. package/ColorButton/ColorButton.css +39 -0
  34. package/ColorButton/ColorButton.js +336 -0
  35. package/ColorPicker/ColorPicker.css +359 -0
  36. package/ColorPicker/ColorPicker.js +972 -0
  37. package/ComboBox/ComboBox.css +357 -0
  38. package/ComboBox/ComboBox.js +2342 -0
  39. package/ComboBox/Themes/Default.css +23 -0
  40. package/DataPager/DataPager.css +72 -0
  41. package/DataPager/DataPager.js +674 -0
  42. package/DatePicker/DatePicker.css +227 -0
  43. package/DatePicker/DatePicker.js +1531 -0
  44. package/DatePicker/Themes/Default.css +26 -0
  45. package/Dialog/Dialog.css +106 -0
  46. package/Dialog/Dialog.js +572 -0
  47. package/Dialog/Themes/Default.css +10 -0
  48. package/Editor/Data/Emoji.json +8285 -0
  49. package/Editor/Data/Special.json +1042 -0
  50. package/Editor/Editor.css +1562 -0
  51. package/Editor/Editor.js +4058 -0
  52. package/Editor/Font/Editor.woff +0 -0
  53. package/Editor/Modules/ComponentFactory.js +565 -0
  54. package/Editor/Modules/ContentManager.js +748 -0
  55. package/Editor/Modules/DialogManager.js +1234 -0
  56. package/Editor/Modules/EventManager.js +458 -0
  57. package/Editor/Modules/Format.js +950 -0
  58. package/Editor/Modules/History.js +191 -0
  59. package/Editor/Modules/LayoutState.js +379 -0
  60. package/Editor/Modules/ListManager.js +296 -0
  61. package/Editor/Modules/MenuManager.js +388 -0
  62. package/Editor/Modules/NodeManager.js +681 -0
  63. package/Editor/Modules/ParagraphButtons.js +122 -0
  64. package/Editor/Modules/Resizer.js +176 -0
  65. package/Editor/Modules/SelectionRange.js +564 -0
  66. package/Editor/Modules/SourceViewBuilder.js +212 -0
  67. package/Editor/Modules/SymbolPicker.js +208 -0
  68. package/Editor/Modules/Table.js +2327 -0
  69. package/Editor/Modules/TableDialog.js +757 -0
  70. package/Editor/Modules/Toolbar.js +375 -0
  71. package/Editor/Modules/TooltipMenu.js +125 -0
  72. package/Editor/Modules/Utility.js +131 -0
  73. package/Editor/Themes/Default.css +204 -0
  74. package/FileUpload/FileUpload.css +156 -0
  75. package/FileUpload/FileUpload.js +898 -0
  76. package/FileUpload/Themes/Default.css +17 -0
  77. package/Form/Form.css +1934 -0
  78. package/Form/Form.js +4943 -0
  79. package/Form/Modules/ActionManager.js +368 -0
  80. package/Form/Modules/BuildPanelManager.js +319 -0
  81. package/Form/Modules/ComponentFactory.js +468 -0
  82. package/Form/Modules/ComponentPanel.js +265 -0
  83. package/Form/Modules/ConfigPanelManager.js +685 -0
  84. package/Form/Modules/DataBinder.js +602 -0
  85. package/Form/Modules/DataObserver.js +717 -0
  86. package/Form/Modules/Draggable.js +756 -0
  87. package/Form/Modules/OptionsPanel.js +342 -0
  88. package/Form/Modules/Renderer.js +1889 -0
  89. package/Form/Modules/RuleEngine.js +585 -0
  90. package/Form/Modules/RulesPanel.js +1158 -0
  91. package/Form/Modules/Types.js +1709 -0
  92. package/Form/Modules/ValidationManager.js +194 -0
  93. package/Form/Themes/Default.css +216 -0
  94. package/FormField/FormField.css +468 -0
  95. package/FormField/FormField.js +576 -0
  96. package/FormField/Themes/Default.css +99 -0
  97. package/Grid/Grid.css +544 -0
  98. package/Grid/Grid.js +3761 -0
  99. package/Grid/Themes/Default.css +43 -0
  100. package/LICENSE +126 -0
  101. package/MaskedTextBox/MaskedTextBox.css +28 -0
  102. package/MaskedTextBox/MaskedTextBox.js +642 -0
  103. package/MaskedTextBox/Themes/Default.css +6 -0
  104. package/Menu/Menu.css +328 -0
  105. package/Menu/Menu.js +2386 -0
  106. package/Menu/Themes/Default.css +24 -0
  107. package/NumericBox/NumericBox.css +120 -0
  108. package/NumericBox/NumericBox.js +984 -0
  109. package/PanelBar/PanelBar.css +123 -0
  110. package/PanelBar/PanelBar.js +505 -0
  111. package/PanelBar/Themes/Default.css +51 -0
  112. package/PieChart/PieChart.css +95 -0
  113. package/PieChart/PieChart.js +820 -0
  114. package/PieChart/Themes/Default.css +9 -0
  115. package/README.md +178 -3
  116. package/Slider/Slider.css +348 -0
  117. package/Slider/Slider.js +1306 -0
  118. package/Slider/Themes/Default.css +44 -0
  119. package/TabStrip/TabStrip.css +52 -0
  120. package/TabStrip/TabStrip.js +362 -0
  121. package/TabStrip/Themes/Default.css +35 -0
  122. package/TimePicker/Themes/Default.css +30 -0
  123. package/TimePicker/TimePicker.css +253 -0
  124. package/TimePicker/TimePicker.js +1485 -0
  125. package/TooltipManager/Themes/Default.css +21 -0
  126. package/TooltipManager/TooltipManager.css +227 -0
  127. package/TooltipManager/TooltipManager.js +791 -0
  128. package/Validator/Validator.css +54 -0
  129. package/Validator/Validator.js +2508 -0
  130. package/componyx.html-data.json +619 -0
  131. package/index.js +27 -0
  132. package/package.json +43 -4
  133. package/types/AppSkin.d.ts +842 -0
  134. package/types/Base.d.ts +1034 -0
  135. package/types/Bindary.d.ts +1196 -0
  136. package/types/BookmarkSpy.d.ts +112 -0
  137. package/types/Box.d.ts +374 -0
  138. package/types/Button.d.ts +455 -0
  139. package/types/Carousel.d.ts +136 -0
  140. package/types/ColorButton.d.ts +120 -0
  141. package/types/ColorPicker.d.ts +225 -0
  142. package/types/ComboBox.d.ts +507 -0
  143. package/types/DataPager.d.ts +152 -0
  144. package/types/DatePicker.d.ts +354 -0
  145. package/types/Dialog.d.ts +160 -0
  146. package/types/Editor.d.ts +1289 -0
  147. package/types/FileUpload.d.ts +206 -0
  148. package/types/Form.d.ts +3078 -0
  149. package/types/FormField.d.ts +204 -0
  150. package/types/Grid.d.ts +911 -0
  151. package/types/Library.d.ts +1899 -0
  152. package/types/MaskedTextBox.d.ts +91 -0
  153. package/types/Menu.d.ts +577 -0
  154. package/types/NumericBox.d.ts +310 -0
  155. package/types/PanelBar.d.ts +223 -0
  156. package/types/PieChart.d.ts +224 -0
  157. package/types/ResponsiveTemplates.d.ts +108 -0
  158. package/types/Slider.d.ts +227 -0
  159. package/types/TabStrip.d.ts +185 -0
  160. package/types/TimePicker.d.ts +265 -0
  161. package/types/TooltipManager.d.ts +178 -0
  162. package/types/UI.d.ts +29 -0
  163. package/types/Validator.d.ts +653 -0
  164. package/types/index.d.ts +59 -0
  165. package/ui.css +11783 -0
  166. package/ui.js +79477 -0
  167. package/ui.min.css +138 -0
  168. package/ui.min.js +264 -0
  169. package/ui.min.js.map +1 -0
@@ -0,0 +1,296 @@
1
+ /*! Componyx.UI | (c) E.H. Daanen / Componyx | BUSL-1.1 | componyx.com/license */
2
+ componyx.UI.editor_modules = componyx.UI.editor_modules || {};
3
+
4
+ /**
5
+ * ListManager module - manages list operations.
6
+ * @class ListManager
7
+ * @memberof componyx.UI.editor_modules
8
+ * @ignore
9
+ */
10
+ componyx.UI.editor_modules.ListManager = class ListManager
11
+ {
12
+ constructor(editor)
13
+ {
14
+ this.editor = editor;
15
+ this.utility = editor.utility;
16
+ }
17
+
18
+ /**
19
+ * Toggles a list item node.
20
+ * @param {string} tag
21
+ * @param {boolean} on
22
+ */
23
+ toggleListItem(tag, on)
24
+ {
25
+ this.editor.activateDocument();
26
+
27
+ if (!this.editor.contentManager.hasContent())
28
+ this.editor.contentManager.insertParagraph();
29
+
30
+ let selection = this.editor.selectionRange,
31
+ range = selection.getRange(),
32
+ nodesInRange = selection.getNodesInRange(range),
33
+ selectedListItems = selection.getListItemNodesInRange(nodesInRange),
34
+ rootNodes = selection.getRootNodesInRange(range, nodesInRange, false),
35
+ marker = selection.createRangeMarker(selection.ensureTextRange(range)),
36
+ type = this.editor.menuManager.getSelectedItemId(tag),
37
+ prop = 'list-style-type',
38
+ styles = {}, clear = false;
39
+
40
+ if (type)
41
+ type = type.replace(`${tag}_`, '');
42
+
43
+ if (type == 'disc' || type == 'decimal')
44
+ {
45
+ clear = true;
46
+ styles[prop] = null;
47
+ }
48
+ else
49
+ styles[prop] = type;
50
+
51
+ $lib.each(rootNodes, (rootNode) =>
52
+ {
53
+ if (rootNode.nodeName == tag) // list-node
54
+ {
55
+ if (on)
56
+ this.editor.format.updateNodeStyles(rootNode, styles, clear);
57
+ else
58
+ {
59
+ let listNode = rootNode, parentListNode;
60
+
61
+ while (listNode)
62
+ {
63
+ parentListNode = this.editor.nodeManager.getListNode(listNode.parentElement, this.editor.getEditorElement());
64
+ this.decreaseListIndent(listNode, selectedListItems, (parentListNode) ? false : true);
65
+ listNode = parentListNode;
66
+ }
67
+ }
68
+ }
69
+ else
70
+ {
71
+ let layoutNode = this.editor.format.updateNodeStyles($lib.element('', '', tag), styles);
72
+
73
+ if (this.utility.listFilter.indexOf(rootNode.nodeName) == -1)
74
+ layoutNode.appendChild($lib.element('', '', 'li'));
75
+
76
+ rootNode.style.removeProperty(prop);
77
+ this.editor.nodeManager.setBlockElement(rootNode, this.editor.nodeManager.getRootNode(layoutNode).cloneNode(true));
78
+ }
79
+ });
80
+
81
+ this.editor.history.addItem(range, marker);
82
+ this.editor.deactivateDocument();
83
+ }
84
+
85
+ /**
86
+ * Toggles a list item node type.
87
+ * @param {string} tag
88
+ */
89
+ toggleListItemType(tag)
90
+ {
91
+ this.toggleListItem(tag, true);
92
+ }
93
+
94
+ /**
95
+ * Increases the indent of the specified list-item node.
96
+ * @param {Node} node
97
+ */
98
+ increaseListIndent(node)
99
+ {
100
+ let nodeName = node.parentElement.nodeName,
101
+ list = node.querySelector(this.utility.listFilter),
102
+ prev = (node.previousElementSibling && node.previousElementSibling.nodeName == 'LI') ? node.previousElementSibling : null,
103
+ next = (node.nextElementSibling && node.nextElementSibling.nodeName == 'LI') ? node.nextElementSibling : null,
104
+ nextList = (next && next.firstChild && this.utility.listFilter.indexOf(next.firstChild.nodeName) > -1) ? next.firstChild : null,
105
+ removeList = (list) =>
106
+ {
107
+ let parentItem = list.parentElement;
108
+ list.remove();
109
+
110
+ if (!parentItem.childNodes.length)
111
+ parentItem.remove();
112
+ };
113
+
114
+ if (prev)
115
+ {
116
+ let prevList = prev.querySelector(this.utility.listFilter);
117
+
118
+ if (!prevList)
119
+ prevList = $lib.element(prev, '', nodeName);
120
+
121
+ prevList.appendChild(node);
122
+
123
+ if (list)
124
+ {
125
+ prevList.insertBefore($lib.extract(list), node.nextSibling);
126
+ removeList(list);
127
+ }
128
+
129
+ if (nextList)
130
+ {
131
+ prevList.appendChild($lib.extract(nextList));
132
+ removeList(nextList);
133
+ }
134
+ }
135
+ else if (nextList)
136
+ {
137
+ nextList.insertBefore(node, nextList.firstChild);
138
+
139
+ if (list)
140
+ {
141
+ nextList.insertBefore($lib.extract(list), node.nextSibling);
142
+ removeList(list);
143
+ }
144
+ }
145
+ else if (list)
146
+ {
147
+ let liBefore = node.cloneNode(false);
148
+
149
+ liBefore.appendChild(this.editor.nodeManager.getNodesBefore(node, list));
150
+ list.insertBefore(liBefore, list.firstChild);
151
+ node.style.listStyleType = 'none';
152
+
153
+ let after = this.editor.nodeManager.sibling(list, node);
154
+
155
+ if (after)
156
+ {
157
+ list.remove();
158
+
159
+ let fragmentAfter = $lib.extract(node);
160
+
161
+ if (fragmentAfter.childNodes.length)
162
+ {
163
+ let liAfter = node.cloneNode(false);
164
+ liAfter.appendChild(fragmentAfter);
165
+ list.appendChild(liAfter);
166
+ }
167
+
168
+ node.appendChild(list);
169
+ }
170
+ }
171
+ else // create deeper list
172
+ {
173
+ let li = node.cloneNode(true);
174
+
175
+ node.style.listStyleType = 'none';
176
+ node.innerHTML = '';
177
+ node.appendChild($lib.element('', '', nodeName, li));
178
+ }
179
+ }
180
+
181
+ /**
182
+ * Decreases the indent of the selected list-item nodes of the specified list node.
183
+ * @param {Node} listNode
184
+ * @param {Set<Node>} selectedListItems
185
+ * @param {boolean} removeSelected
186
+ */
187
+ decreaseListIndent(listNode, selectedListItems, removeSelected = true)
188
+ {
189
+ let li = listNode.firstElementChild,
190
+ listNodeParent = listNode.parentElement,
191
+ listNodeSibling = listNode.nextElementSibling,
192
+ fragmentSelected = this.editor.getDoc().createDocumentFragment(),
193
+ fragmentAfter = this.editor.getDoc().createDocumentFragment(),
194
+ childListNode, afterListNode, node, next, p;
195
+
196
+ while (li)
197
+ {
198
+ if (!selectedListItems.has(li))
199
+ li = (!next) ? li.nextElementSibling : null;
200
+ else
201
+ {
202
+ if (removeSelected)
203
+ selectedListItems.delete(li);
204
+
205
+ next = li.nextElementSibling;
206
+ fragmentSelected.appendChild(li);
207
+ childListNode = li.querySelector(this.utility.listFilter);
208
+ li = next;
209
+
210
+ if (childListNode) // keep same depth level
211
+ this.increaseListDepth(childListNode);
212
+ }
213
+ }
214
+
215
+ if (next) // copy to new list-node
216
+ {
217
+ node = next;
218
+
219
+ while (node)
220
+ {
221
+ next = node.nextElementSibling;
222
+ fragmentAfter.appendChild(node);
223
+ node = next;
224
+ }
225
+ }
226
+
227
+ if (listNodeParent.nodeName == 'LI') // add selected LI's to parent list-node
228
+ {
229
+ let lastItem = fragmentSelected.lastChild;
230
+ listNodeParent.parentElement.insertBefore(fragmentSelected, listNodeParent.nextElementSibling);
231
+
232
+ childListNode = listNodeParent.firstElementChild;
233
+
234
+ if (this.utility.listFilter.indexOf(childListNode.nodeName) > -1 && !childListNode.childNodes.length)
235
+ childListNode.remove();
236
+
237
+ if (fragmentAfter.childNodes.length)
238
+ {
239
+ afterListNode = lastItem.querySelector(this.utility.listFilter);
240
+
241
+ if (!afterListNode)
242
+ afterListNode = $lib.element(lastItem, '', listNode.nodeName);
243
+ }
244
+ }
245
+ else // add selected LI's as P tags
246
+ {
247
+ while (node = fragmentSelected.firstChild)
248
+ {
249
+ p = $lib.element('', '', 'p', $lib.extract(node));
250
+ listNodeParent.insertBefore(p, listNodeSibling);
251
+ node.remove();
252
+ }
253
+
254
+ if (fragmentAfter.childNodes.length)
255
+ {
256
+ afterListNode = $lib.element('', '', listNode.nodeName);
257
+ listNodeParent.insertBefore(afterListNode, listNodeSibling);
258
+ }
259
+ }
260
+
261
+ if (afterListNode)
262
+ afterListNode.appendChild(fragmentAfter); // add unselected list-item's at the bottom
263
+
264
+ if (!listNode.childNodes.length)
265
+ listNode.remove();
266
+ }
267
+
268
+ /**
269
+ * Increases the depth of the list.
270
+ * @param {Node} listNode
271
+ */
272
+ increaseListDepth(listNode)
273
+ {
274
+ let ul = $lib.element('', '', listNode.nodeName),
275
+ li = $lib.element('', '', 'li', '', { style: 'list-style-type: none' });
276
+
277
+ $lib.surround(li, listNode);
278
+ $lib.surround(ul, li);
279
+ }
280
+
281
+ /**
282
+ * Returns a value indicating if the caret is at the start of a list item (<li>).
283
+ * @param {Range} range
284
+ */
285
+ isCaretAtListItemStart(range)
286
+ {
287
+ let sContainer = range.startContainer,
288
+ el = (sContainer.nodeType == 3) ? sContainer.parentElement : sContainer;
289
+
290
+ return (range.startOffset == 0 && el.nodeName == 'LI');
291
+ }
292
+ };
293
+
294
+ var ListManager = componyx.UI.editor_modules.ListManager;
295
+
296
+ export { ListManager as default };
@@ -0,0 +1,388 @@
1
+ /*! Componyx.UI | (c) E.H. Daanen / Componyx | BUSL-1.1 | componyx.com/license */
2
+ componyx.UI.editor_modules = componyx.UI.editor_modules || {};
3
+
4
+ /**
5
+ * MenuManager module - menu and toolbar operations.
6
+ * @class MenuManager
7
+ * @memberof componyx.UI.editor_modules
8
+ * @ignore
9
+ */
10
+ componyx.UI.editor_modules.MenuManager = class MenuManager
11
+ {
12
+ constructor(editor)
13
+ {
14
+ this.editor = editor;
15
+ this.cf = editor.componentFactory;
16
+ this.utility = editor.utility;
17
+ this.menu = null;
18
+ this.defaultMenuButton = null;
19
+ }
20
+
21
+ /**
22
+ * Loads a menu item
23
+ * @param {string} menuItemId
24
+ */
25
+ loadMenuItem(menuItemId)
26
+ {
27
+ return this.menu.loadItem(menuItemId);
28
+ }
29
+
30
+ /**
31
+ * Renders a menu item
32
+ * @param {string} itemId
33
+ */
34
+ renderMenuItem(itemId)
35
+ {
36
+ let itemPath = this.loadMenuItem(itemId);
37
+ if (itemPath)
38
+ this.menu.renderItem(itemPath.item);
39
+ }
40
+
41
+ /**
42
+ * Selects a menu item
43
+ * @param {string} menuItemId
44
+ */
45
+ selectMenuItem(menuItemId)
46
+ {
47
+ this.menu.selectItem(menuItemId);
48
+ }
49
+
50
+ /**
51
+ * Deselects a menu item
52
+ * @param {string} menuItemId
53
+ */
54
+ deselectMenuItem(menuItemId)
55
+ {
56
+ this.menu.deselectItem(menuItemId);
57
+ }
58
+
59
+ /**
60
+ * Gets selected item id
61
+ * @param {string} groupId
62
+ */
63
+ getSelectedItemId(groupId)
64
+ {
65
+ return this.menu.getSelectedItemId(groupId);
66
+ }
67
+
68
+ /**
69
+ * Gets the menu
70
+ */
71
+ getMenu()
72
+ {
73
+ return this.menu;
74
+ }
75
+
76
+ /** Creates the menu. */
77
+ async createMenu()
78
+ {
79
+ this.menu = this.cf.createMenu('Menu', this.editor.menuId, this.editor.element);
80
+
81
+ let list = this.menu.itemList;
82
+
83
+ this.#createDefaultMenuButton();
84
+ list.push(this.#createMenuItem({ id: 'Block' }));
85
+ list.push(this.#createMenuItem({ id: 'FontFamily' }));
86
+ list.push(this.#createMenuItem({ id: 'FontSize' }));
87
+ list.push(this.#createMenuItem({ id: 'Style' }));
88
+ list.push(this.#createMenuItem({ id: 'Align' }));
89
+ list.push(this.#createMenuItem({ id: 'LineHeight' }));
90
+ list.push(this.#createMenuItem({ id: 'OrderedList', cssClassItemGroup: 'item-group box ordered-list' }));
91
+ list.push(this.#createMenuItem({ id: 'UnorderedList', cssClassItemGroup: 'item-group box unordered-list' }));
92
+
93
+ this.#buildBlockMenu();
94
+ this.buildFontSizeMenu(this.editor.fontSizes);
95
+ this.#buildStyleMenu();
96
+ this.#buildAlignMenu();
97
+ this.#buildLineHeightMenu();
98
+ this.#buildListItemMenu(this.menu.itemList[6], 'OL', this.editor.orderedList);
99
+ this.#buildListItemMenu(this.menu.itemList[7], 'UL', this.editor.unorderedList);
100
+ await this.#buildFontFamilyMenu();
101
+
102
+ }
103
+
104
+ /**
105
+ * Builds the font size menu
106
+ * @param {string[]} fontSizes
107
+ */
108
+ buildFontSizeMenu(fontSizes)
109
+ {
110
+ let lastUnit,
111
+ rootItem = this.menu.itemList[2],
112
+ cat = 'fontSize';
113
+
114
+ if (!rootItem.itemList.length)
115
+ rootItem.itemList.push(this.#createDefaultMenuItem(cat, this.editor.setFontSize.bind(this.editor, null)));
116
+
117
+ $lib.each(fontSizes, (f) =>
118
+ {
119
+ let unit = f.replace(/([^\d])/g, '');
120
+ let item = {
121
+ id: `${cat}_${f}`,
122
+ value: f,
123
+ text: f,
124
+ command: this.editor.setFontSize.bind(this.editor, f),
125
+ radioGroupId: cat
126
+ };
127
+
128
+ if (lastUnit && unit != lastUnit)
129
+ item.cssClass = 'first-type';
130
+
131
+ rootItem.itemList.push(this.#createMenuItem(item));
132
+ lastUnit = unit;
133
+ });
134
+
135
+ rootItem.itemList.sort((a, b) =>
136
+ {
137
+ return parseFloat(a.value) - parseFloat(b.value)
138
+ });
139
+ }
140
+
141
+ /** Creates the default menu button. */
142
+ #createDefaultMenuButton()
143
+ {
144
+ this.defaultMenuButton = $UI.createComponent(componyx.UI.Button, {
145
+ id: this.utility.getId('DefaultMenuButton'),
146
+ primary: false
147
+ });
148
+ }
149
+
150
+ /**
151
+ * Creates a default menu item
152
+ * @param {string} cat
153
+ * @param {Function} command
154
+ */
155
+ #createDefaultMenuItem(cat, command)
156
+ {
157
+ return this.#createMenuItem({
158
+ id: `${cat}_Default`,
159
+ text: this.editor.labels.default,
160
+ radioGroupId: cat,
161
+ command: command
162
+ });
163
+ }
164
+
165
+ /**
166
+ * Creates a menu item.
167
+ * @param {Object} props
168
+ */
169
+ #createMenuItem(props)
170
+ {
171
+ props.type = 2; // radio button type
172
+
173
+ if (!props.buttonId)
174
+ props.buttonId = this.defaultMenuButton.id;
175
+
176
+ return new componyx.UI.Menu.Item(props);
177
+ }
178
+
179
+ /** Builds the block menu. */
180
+ #buildBlockMenu()
181
+ {
182
+ let item = this.menu.itemList[0],
183
+ groupId = 'block',
184
+ fn = (id, text, templateId, command, groupId) =>
185
+ {
186
+ return this.#createMenuItem({
187
+ id: groupId + '_' + id,
188
+ value: id,
189
+ text: (this.editor.labels[id]) ? this.editor.labels[id] : text,
190
+ templateId: templateId,
191
+ command: command,
192
+ radioGroupId: groupId
193
+ });
194
+ };
195
+
196
+ for (let i = 1; i < 7; ++i) // add headings
197
+ {
198
+ let id = `H${i}`;
199
+ item.itemList.push(fn(id, `Heading ${i}`, id + '_Template', this.editor.setBlock.bind(this.editor, `h${i}`, null), groupId));
200
+ this.menu.addTemplate(id + '_Template', `<h${i}>{text}</h${i}>`);
201
+ }
202
+
203
+ item.itemList.push(fn('P', `Paragraph`, 'Paragraph_Template', this.editor.setBlock.bind(this.editor, 'p', null), groupId));
204
+ this.menu.addTemplate('Paragraph_Template', `<p>{text}</p>`);
205
+
206
+ item.itemList.push(fn('PRE', `Pre`, 'Pre_Template', this.editor.setBlock.bind(this.editor, 'pre', null), groupId));
207
+ this.menu.addTemplate('Pre_Template', `<pre>{text}</pre>`);
208
+ }
209
+
210
+ /** Builds the font family menu. */
211
+ async #buildFontFamilyMenu()
212
+ {
213
+ let docFonts = document.fonts;
214
+ await docFonts.ready;
215
+ let seen = new Set();
216
+
217
+ const fonts = [];
218
+
219
+ if (this.editor.detectFonts)
220
+ {
221
+ docFonts.forEach((f) =>
222
+ {
223
+ let family = f.family;
224
+
225
+ if (!seen.has(family))
226
+ {
227
+ fonts.push(family);
228
+ seen.add(family);
229
+ }
230
+ });
231
+ }
232
+
233
+ if (this.editor.includeWebSafeFonts)
234
+ {
235
+ let webFonts = this.utility.webFonts;
236
+
237
+ $lib.each(webFonts, (f) =>
238
+ {
239
+ if (!seen.has(f) && docFonts.check(`12px "${f}"`))
240
+ {
241
+ fonts.push(f);
242
+ seen.add(f);
243
+ }
244
+ });
245
+ }
246
+
247
+ $lib.each(this.editor.fonts, (f) =>
248
+ {
249
+ if (!seen.has(f))
250
+ {
251
+ fonts.push(f);
252
+ seen.add(f);
253
+ }
254
+ });
255
+
256
+ $lib.each(this.editor.excludeFonts, (f) =>
257
+ {
258
+ if (seen.has(f))
259
+ {
260
+ let index = fonts.indexOf(f);
261
+ if (index > -1)
262
+ fonts.splice(index, 1);
263
+ }
264
+ });
265
+
266
+ let rootItem = this.menu.itemList[1],
267
+ cat = 'fontFamily';
268
+
269
+ rootItem.itemList.push(this.#createDefaultMenuItem(cat, this.editor.setFontFamily.bind(this.editor, null)));
270
+
271
+ $lib.each(fonts.sort(), (f) =>
272
+ {
273
+ rootItem.itemList.push(this.#createMenuItem({
274
+ id: `${cat}_${f}`,
275
+ value: f,
276
+ text: f,
277
+ command: this.editor.setFontFamily.bind(this.editor, f),
278
+ radioGroupId: 'fontFamily'
279
+ }));
280
+ });
281
+ }
282
+
283
+ /** Builds the style menu. */
284
+ #buildStyleMenu()
285
+ {
286
+ let rootItem = this.menu.itemList[3],
287
+ templateId = 'StyleItem_Template';
288
+
289
+ this.menu.addTemplate(templateId, `<div class="style-item"><div class="preview {previewCssClass}"></div><div class="text">{text}</div></div>`);
290
+
291
+ $lib.each(this.editor.styles, (s) =>
292
+ {
293
+ rootItem.itemList.push(this.#createStyleItem(s));
294
+ });
295
+ }
296
+
297
+ /**
298
+ * Creates a style item.
299
+ * @param {Object} s
300
+ */
301
+ #createStyleItem(s)
302
+ {
303
+ let menuItem = this.#createMenuItem({
304
+ id: s.id,
305
+ text: s.name,
306
+ templateId: s.templateId || 'StyleItem_Template',
307
+ command: this.editor.setStyle.bind(this.editor, s),
308
+ radioGroupId: 'style',
309
+ isCategory: s.isCategory,
310
+ attributes: { previewCssClass: s.previewCssClass }
311
+ });
312
+
313
+ $lib.each(s.itemList, (item) =>
314
+ {
315
+ menuItem.itemList.push(this.#createStyleItem(item));
316
+ });
317
+
318
+ return menuItem;
319
+ }
320
+
321
+ /** Builds the alignment menu. */
322
+ #buildAlignMenu()
323
+ {
324
+ let rootItem = this.menu.itemList[4],
325
+ lbl = this.editor.labels,
326
+ cat = 'align',
327
+ iconPrefix = this.utility.iconPrefix;
328
+
329
+ rootItem.itemList.push(this.#createDefaultMenuItem(cat, this.editor.align.bind(this.editor, null)));
330
+
331
+ $lib.each([`${cat}Left`, `${cat}Center`, `${cat}Right`, `${cat}Justify`], (val) =>
332
+ {
333
+ let icon = `icon ${iconPrefix + val.replace('align', 'align-').toLowerCase()}`,
334
+ item = {
335
+ id: val.replace('align', 'align_').toLowerCase(),
336
+ text: `<span class="${icon}"></span>${lbl[val]}`,
337
+ command: this.editor.align.bind(this.editor, val.toLowerCase().replace('align', '')),
338
+ radioGroupId: cat
339
+ };
340
+ rootItem.itemList.push(this.#createMenuItem(item));
341
+ });
342
+ }
343
+
344
+ /** Builds the lineheight menu. */
345
+ #buildLineHeightMenu()
346
+ {
347
+ let rootItem = this.menu.itemList[5],
348
+ cat = 'lineHeight';
349
+
350
+ rootItem.itemList.push(this.#createDefaultMenuItem(cat, this.editor.lineHeight.bind(this.editor, null)));
351
+
352
+ $lib.each(this.editor.lineHeights, (val) =>
353
+ {
354
+ rootItem.itemList.push(this.#createMenuItem({
355
+ id: `${cat}_${val}`,
356
+ text: val,
357
+ command: this.editor.lineHeight.bind(this.editor, val),
358
+ radioGroupId: 'lineHeight',
359
+ }));
360
+ });
361
+ }
362
+
363
+ /**
364
+ * Builds the list-item menu.
365
+ * @param {Object} rootItem
366
+ * @param {string} prefix
367
+ * @param {Array} list
368
+ */
369
+ #buildListItemMenu(rootItem, prefix, list)
370
+ {
371
+ let iconPrefix = this.utility.iconPrefix;
372
+
373
+ $lib.each(list, (val) =>
374
+ {
375
+ rootItem.itemList.push(this.#createMenuItem({
376
+ id: `${prefix}_${val}`,
377
+ command: () => this.editor.listManager.toggleListItemType(prefix),
378
+ radioGroupId: prefix,
379
+ cssClassIcon: `icon ico-xl ${iconPrefix}list-${val.toLowerCase()}`,
380
+ hasIcon: true
381
+ }));
382
+ });
383
+ }
384
+ };
385
+
386
+ var MenuManager = componyx.UI.editor_modules.MenuManager;
387
+
388
+ export { MenuManager as default };