@componyx/ui 0.0.0-stage → 1.0.3

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/DataObserver.js +717 -0
  85. package/Form/Modules/Databinder.js +602 -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,854 @@
1
+ /*! Componyx.UI | (c) E.H. Daanen / Componyx | BUSL-1.1 | componyx.com/license */
2
+ await (async function ()
3
+ {
4
+ componyx.bindary_modules = componyx.bindary_modules || {};
5
+ const core = componyx.bindary_modules.core =
6
+ {
7
+ liveBindTimers: new WeakMap(),
8
+ cache: null,
9
+ data: null,
10
+ routeRdy: {},
11
+ useShorthand: true,
12
+ prefix: null,
13
+ longPrefix: 'data-bindary-',
14
+ shortPrefix: 'b-',
15
+ hyphenatedAttributes: true,
16
+ dksc: '.',
17
+ ipc: '@',
18
+ dataLabel: ['appData', 'routeData', 'viewData'],
19
+ viewContainer: null,
20
+ xhr: [],
21
+ dataWS: null,
22
+ dataXHR: null,
23
+ viewURL: null,
24
+ controllerURL: null,
25
+ dataChanges: {},
26
+ modelDataChanges: new Map(),
27
+ dataLocks: {},
28
+ repItemClones: {},
29
+ launchRoutePath: null,
30
+ liveBindTimerId: null,
31
+ scrollTimerId: null,
32
+ historyTimerId: null,
33
+ scrollPos: {},
34
+ historyLength: null,
35
+ historyAction: null,
36
+ allowHistoryScroll: null,
37
+ secure: null,
38
+ viewTree: null,
39
+ tempViewContainer: null,
40
+ callbacks: {},
41
+ scrollableRoot: null,
42
+ autoUpdateView: true,
43
+ observing: true,
44
+ observed: null,
45
+ busy: false,
46
+ rendering: false,
47
+ linkRegEx: /^((ftp|http)*s*:\/\/)|^([a-zA-Z]+\:)|^(\.\.\/)|^(\/\/)|^(\#)/gi, // match protocol, protocol-relative, relative URL or hash
48
+ escapeRegEx: /\\\${1}(parent)*$/, // match escaped $parent
49
+ methodRegEx: /(^\${1}(component|context)+.)/, // match $component or $context
50
+ dataKeyRegEx: /\{\{([^\{\}\s]+)\}\}/gm, // match {{dataKey}}
51
+ hasBindingRegEx: /\{\{([\s\S]*?)\}\}/,
52
+ singleWord: /^(\${0,1}\w+)$/,
53
+ attrRegEx: /((,+\s*|^)([^=\s]+))\s*=+\s*(?=(?:[^'"]*('|")[^\4]*\4)*[^'"]*$)/gm, // match (, )attribute= not within single or double quotes.
54
+ quoteRegEx: /"/g, // find quotes
55
+ timeRegEx: /t|\s?hh|\s?h|:mm|:m|:ss|:s/gi,
56
+ valueKey: '$value',
57
+ parentKey: '$parent',
58
+ key: '$key',
59
+ postRenderFlag: false,
60
+ waiters: [],
61
+ valueHandlers: [],
62
+ templateUpdate: null,
63
+ templateList: null,
64
+ routeCallbackId: null,
65
+ rendered: [],
66
+ components: {},
67
+ pendingUpdate: false, // a full (non-viewTree-scoped) update is queued for the next microtask flush
68
+ pendingFullRender: false, // escalates to true if any queued caller in this batch asked for a full rebuild
69
+ pendingPartialUpdate: false, // a viewTree-scoped (partial) update is queued for the next microtask flush
70
+ pendingPartialFullRender: false,
71
+ pendingTreeItems: new WeakSet(), // items already included in the pending viewTree batch, to dedupe repeat calls
72
+ pendingTreeBatch: [], // accumulates items across multiple calls within the same tick before the batch flushes
73
+ dataBindTrigger: null,
74
+ dataBindLive: false,
75
+ renderPass: 0,
76
+ omit:
77
+ {
78
+ root: '',
79
+ parent: '',
80
+ children: '',
81
+ context: '',
82
+ repeatValue: '',
83
+ value: '',
84
+ element: '',
85
+ repeatElements: '',
86
+ isRendered: '',
87
+ livePath: ''
88
+ },
89
+ attr: {
90
+ id: '',
91
+ view: '',
92
+ context: '',
93
+ value: '',
94
+ html: '',
95
+ bind: '',
96
+ live: '',
97
+ type: '',
98
+ attributes: '',
99
+ hasValue: '',
100
+ repeat: '',
101
+ repeatItemId: '',
102
+ itemId: '',
103
+ filter: '',
104
+ viewFormatter: '',
105
+ dataFormatter: '',
106
+ includable: '',
107
+ include: '',
108
+ component: '',
109
+ observe: '',
110
+ load: '',
111
+ preRender: '',
112
+ postRender: '',
113
+ "if": '',
114
+ "elseIf": '',
115
+ "else": '',
116
+ on: '',
117
+ updateId: '',
118
+ keep: '',
119
+ ignore: ''
120
+ },
121
+ scroller: null,
122
+ sanitizer: null,
123
+ expressionEngine: null,
124
+
125
+ getId()
126
+ {
127
+ return $bindary.idPrefix + $lib.guid();
128
+ },
129
+
130
+ clearPendingUpdate()
131
+ {
132
+ const complete = core.pendingFullRender;
133
+ core.pendingUpdate = false;
134
+ core.pendingFullRender = false;
135
+ return complete;
136
+ },
137
+
138
+ clearPendingPartialUpdate()
139
+ {
140
+ const batch = core.pendingTreeBatch;
141
+ const complete = core.pendingPartialFullRender;
142
+
143
+ core.pendingPartialUpdate = false;
144
+ core.pendingTreeBatch = [];
145
+ core.pendingPartialFullRender = false;
146
+ batch.forEach(item => core.pendingTreeItems.delete(item));
147
+
148
+ return { batch, complete };
149
+ },
150
+
151
+ fireEvent(name, args = [], excludeController)
152
+ {
153
+ let ucase = name.charAt(0).toUpperCase() + name.slice(1),
154
+ eventName = 'on' + ucase,
155
+ ctrlResult,
156
+ cancelToken = { cancel: false };
157
+
158
+ if (!args)
159
+ args = [];
160
+
161
+ args.push(cancelToken);
162
+
163
+ if ($bindary.route && !excludeController)
164
+ {
165
+ let route = $bindary.route,
166
+ controller = $bindary.controller,
167
+ method = core.parseExp(route, core.getRoutePath(), route['controller' + ucase]) || name;
168
+
169
+ if (controller && controller[method])
170
+ ctrlResult = controller[method].apply(controller, args);
171
+ }
172
+
173
+ if ($bindary[eventName])
174
+ $bindary[eventName].fire($bindary, args);
175
+
176
+ if (ctrlResult === false || cancelToken.cancel === true) // cancelToken.cancel is prefered, others are for backwards compatibility
177
+ return false;
178
+ },
179
+
180
+ srcState(url, ready)
181
+ {
182
+ core.cache.srcReady[url] = ready;
183
+ },
184
+
185
+ preLoad()
186
+ {
187
+ core.fireEvent('preLoad', null, true);
188
+ },
189
+
190
+ load()
191
+ {
192
+ if (core.viewURL)
193
+ core.setTitle(core.cache.view[core.viewURL].title);
194
+
195
+ core.fireEvent('load');
196
+ },
197
+
198
+ preRender(triggerElement)
199
+ {
200
+ core.dataBindTrigger = triggerElement;
201
+ core.busy = true;
202
+ core.rendering = true;
203
+ core.fireEvent('preRender');
204
+ },
205
+
206
+ postRender()
207
+ {
208
+ // if includes are loading set ready flag and call from finished include
209
+ if (core.hasLoadingIncludes())
210
+ {
211
+ core.postRenderFlag = true;
212
+ return;
213
+ }
214
+
215
+ core.dataBindTrigger = null;
216
+ core.dataBindLive = false;
217
+ core.postRenderFlag = false;
218
+ core.busy = false;
219
+ core.rendering = false;
220
+ core.setRenderStates();
221
+
222
+ if ($bindary.linkDispatching)
223
+ core.dispatchLinks();
224
+
225
+ core.dataChanges = {}; // clear data changes
226
+ core.modelDataChanges = new Map();
227
+
228
+ core.fireEvent('postRender');
229
+
230
+ if (core.routeCallbackId)
231
+ core.postLoad();
232
+ },
233
+
234
+ postLoad()
235
+ {
236
+ core.scroller.init(undefined, $bindary.routePath);
237
+
238
+ core.routeCallbackId = null;
239
+ core.routeRdy[$bindary.routeIndex] = true;
240
+ core.data = undefined;
241
+ core.fireEvent('postLoad');
242
+ },
243
+
244
+ setTitle(title)
245
+ {
246
+ let baseTitle = $bindary.baseTitle || '';
247
+
248
+ if (title)
249
+ document.title = baseTitle + title;
250
+ else if (!document.title)
251
+ document.title = baseTitle;
252
+ },
253
+
254
+ setRenderStates()
255
+ {
256
+ $lib.each(core.rendered, function (item)
257
+ {
258
+ item.isRendered = true;
259
+ }); // set rendered state for elements within repeat when all repeat-elements are rendered
260
+ core.rendered = [];
261
+ },
262
+
263
+ hasLoadingIncludes()
264
+ {
265
+ let loading = false;
266
+
267
+ $lib.each(core.cache.include, function (include)
268
+ {
269
+ return !(loading = include.loading);
270
+ });
271
+
272
+ return loading;
273
+ },
274
+
275
+ createTempViewContainer()
276
+ {
277
+ if (!core.tempViewContainer)
278
+ {
279
+ core.tempViewContainer = document.createElement('div');
280
+ }
281
+ },
282
+
283
+ getViewContainer()
284
+ {
285
+ if (!core.viewContainer)
286
+ {
287
+ core.viewContainer = $lib(function (el)
288
+ {
289
+ return (el.hasAttribute(core.attr.view));
290
+ }, null, '', true);
291
+ }
292
+
293
+ return core.viewContainer;
294
+ },
295
+
296
+ isRouteCallback(dataMsg)
297
+ {
298
+ return (core.routeCallbackId && !$lib.isEmpty(dataMsg) && (dataMsg.callbackId === core.routeCallbackId || $lib.indexOf(dataMsg, function (msg) { return (core.routeCallbackId == msg.callbackId); }) > -1));
299
+ },
300
+
301
+ parseExp(route, routePath, text)
302
+ {
303
+ if (!route || !route.pathExp || !text || text.search(/\$\d/) == -1)
304
+ return text;
305
+
306
+ let exp = route.path,
307
+ match = exp.exec(routePath);
308
+
309
+ for (let index = 0; index < match.length; ++index)
310
+ {
311
+ text = text.replace($lib.format('${0}', index), match[index] || '');
312
+ }
313
+
314
+ route.path.lastIndex = 0; // always reset
315
+ return text;
316
+ },
317
+
318
+ getTemplateFlags(el, flags)
319
+ {
320
+ const result = Object.fromEntries(flags.map(key => [key, undefined]));
321
+
322
+ for (let parent = el; parent; parent = parent.parentElement)
323
+ {
324
+ for (const key of flags)
325
+ {
326
+ if (result[key] !== undefined) continue;
327
+
328
+ const attrValue = parent.getAttribute(core.attr[key]);
329
+ if (attrValue !== null)
330
+ {
331
+ if (attrValue === 'true') result[key] = true;
332
+ else if (attrValue === 'false') result[key] = false;
333
+ else if (attrValue === '' || attrValue === 'null') result[key] = null;
334
+ else
335
+ {
336
+ const num = Number(attrValue);
337
+ result[key] = isNaN(num) ? null : num;
338
+ }
339
+ }
340
+ }
341
+
342
+ if (flags.every(key => result[key] !== undefined)) // Exit early if all flags have been resolved
343
+ break;
344
+ }
345
+
346
+ return result;
347
+ },
348
+
349
+ keepAttributes(el)
350
+ {
351
+ const { keep } = core.getTemplateFlags(el, ['keep']);
352
+
353
+ if (keep !== undefined && keep !== null)
354
+ {
355
+ return keep;
356
+ }
357
+
358
+ return $bindary.keepAttributes;
359
+ },
360
+
361
+ setItemPlaceHolder(item, element)
362
+ {
363
+ core.createPlaceHolder(item, element.parentElement, element);
364
+
365
+ if (!item.inRepeat && !item.repeatDataKey)
366
+ item.isRendered = false;
367
+
368
+ if (!item.repeatDataKey || element != item.repeatPlaceHolder)
369
+ $lib.remove(element);
370
+ },
371
+
372
+ createPlaceHolder(item, parent, before)
373
+ {
374
+ let node = item.sourceElement.nodeName,
375
+ placeHolder = document.createElement(node);
376
+ placeHolder.style.display = 'none';
377
+ placeHolder.setAttribute(core.attr.id, item.id);
378
+
379
+ if (!item.inRepeat)
380
+ placeHolder.id = item.id;
381
+
382
+ placeHolder._bindaryPlaceholder = true;
383
+
384
+ if (before)
385
+ parent.insertBefore(placeHolder, before);
386
+ else
387
+ parent.appendChild(placeHolder);
388
+
389
+ return placeHolder;
390
+ },
391
+
392
+ dispatchLinks(container)
393
+ {
394
+ let baseHref = core.getBaseHref();
395
+
396
+ if (baseHref.match(core.linkRegEx)) // links are not dispatchable because of base href
397
+ return;
398
+
399
+ $lib(core.dispatchLink, container || document, 'a');
400
+ },
401
+
402
+ dispatchLink(a)
403
+ {
404
+ if (!core.dispatchable(a))
405
+ return;
406
+
407
+ if ($bindary.prettyURL && !$lib.has(a, 'click', core.dispatch))
408
+ $lib.on(a, 'click', core.dispatch);
409
+ else if (!$bindary.prettyURL)
410
+ a.href = '#' + a.href;
411
+ },
412
+
413
+ dispatch(e)
414
+ {
415
+ let href = this.getAttribute('href');
416
+ this.getAttribute('target');
417
+ let baseHref = core.getBaseHref(),
418
+ routePath = baseHref + href.replace(/^\//, '');
419
+
420
+ if (!core.dispatchable(this) || baseHref.match(core.linkRegEx))
421
+ return;
422
+
423
+ if (core.isBookmarkJump(routePath))
424
+ return;
425
+
426
+ this.href = 'javascript:void(0);';
427
+ setTimeout(function (href) { this.href = href; }.bind(this, href), 0);
428
+ $bindary.loadRoute(routePath);
429
+ },
430
+
431
+ dispatchable(a)
432
+ {
433
+ let href = a.getAttribute('href'),
434
+ target = a.getAttribute('target');
435
+ return (!$lib.isEmpty(href) && $lib.isEmpty(target) && !href.match(core.linkRegEx))
436
+ },
437
+
438
+ getBaseHref()
439
+ {
440
+ let head = $lib(null, document, 'head', true),
441
+ base = $lib(null, head, 'base', true),
442
+ href = (base) ? base.getAttribute('href') : '';
443
+
444
+ return (href === '/') ? '' : href;
445
+ },
446
+
447
+ getRoutePath()
448
+ {
449
+ let rootPath = $bindary.rootPath || '/',
450
+ routePath = null;
451
+
452
+ if ($bindary.prettyURL)
453
+ routePath = location.pathname.replace(rootPath, '');
454
+ else
455
+ routePath = core.getHashtag();
456
+
457
+ return ($lib.isEmpty(routePath)) ? '' : decodeURIComponent(routePath);
458
+ },
459
+
460
+ getLocationOrigin()
461
+ {
462
+ if (window.location.origin)
463
+ return window.location.origin;
464
+ else
465
+ return window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port : '');
466
+ },
467
+
468
+ getHashtag()
469
+ {
470
+ let hash = window.location.hash.split('#')[1];
471
+
472
+ if ($lib.isEmpty(hash))
473
+ return null;
474
+
475
+ if (hash.indexOf('!') == 0) // hash-bang
476
+ hash = hash.substr(1);
477
+
478
+ return hash;
479
+ },
480
+
481
+ getAnchor()
482
+ {
483
+ let anchor, hash,
484
+ href = window.location.href, index = href.lastIndexOf('#');
485
+
486
+ if ($bindary.prettyURL && window.location.hash)
487
+ anchor = window.location.hash.substr(1);
488
+ else if (!$bindary.prettyURL && index > -1)
489
+ {
490
+ hash = href.substr(index + 1);
491
+
492
+ if (href.substr(href.indexOf('#') + 1) !== hash)
493
+ anchor = hash;
494
+ }
495
+
496
+ return anchor;
497
+ },
498
+
499
+ removeAnchor(routePath)
500
+ {
501
+ let hashIndex;
502
+
503
+ if ((hashIndex = routePath.indexOf('#')) > -1)
504
+ routePath = routePath.substr(0, hashIndex);
505
+
506
+ return routePath;
507
+ },
508
+
509
+ isBookmarkJump(routePath)
510
+ {
511
+ return (core.removeAnchor(routePath) === $bindary.routePath && (($bindary.prettyURL && routePath.indexOf('#') > -1) || (!$bindary.prettyURL && core.getAnchor())));
512
+ },
513
+
514
+ getFullPath(routePath)
515
+ {
516
+ return core.getLocationOrigin() + $bindary.rootPath + routePath;
517
+ },
518
+
519
+ initCache()
520
+ {
521
+ core.cache = { srcReady: {}, view: {}, controller: {}, routeData: {}, viewData: {}, include: {} };
522
+ },
523
+
524
+ clearCache(keepControllers, keepExternalScripts, keepExternalCSS, keepInternalScripts, keepInternalCSS)
525
+ {
526
+ let clear = function (item)
527
+ {
528
+ let tags = (keepExternalScripts && keepInternalScripts) ? [] : item.script;
529
+ tags = (keepExternalCSS && keepInternalCSS) ? tags : tags.concat(item.css);
530
+
531
+ $lib.each(tags, function (tag)
532
+ {
533
+ let nodeName = tag.nodeName.toLowerCase();
534
+
535
+ if ((nodeName == 'style' && !keepInternalCSS)
536
+ || (nodeName == 'link' && !keepExternalCSS)
537
+ || (nodeName == 'script' && tag.src && !keepExternalScripts)
538
+ || (nodeName == 'script' && tag.text && !keepInternalScripts))
539
+ {
540
+ $lib.remove(tag);
541
+ }
542
+ });
543
+ };
544
+
545
+ if (!keepControllers)
546
+ {
547
+ $lib.each(core.cache.controller, function (tag)
548
+ {
549
+ $lib.remove(tag);
550
+ });
551
+ }
552
+
553
+ if (!(keepExternalScripts && keepExternalCSS && keepInternalScripts && keepInternalCSS))
554
+ {
555
+ $lib.each(core.cache.view, function (item) { clear(item); });
556
+ $lib.each(core.cache.include, function (item) { clear(item); });
557
+ }
558
+
559
+ if (!keepControllers && !keepExternalScripts && !keepExternalCSS && !keepInternalScripts && !keepInternalCSS)
560
+ core.initCache();
561
+ },
562
+
563
+ initializePrefix(prefix, hyphenatedAttributes=true)
564
+ {
565
+ core.prefix = prefix;
566
+ core.hyphenatedAttributes = hyphenatedAttributes;
567
+ Object.keys(core.attr).forEach((key) =>
568
+ {
569
+ core.attr[key] = prefix + (core.hyphenatedAttributes ? core.camelToKebab(key) : key.toLowerCase());
570
+ });
571
+ },
572
+
573
+ camelToKebab(text)
574
+ {
575
+ return text.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
576
+ },
577
+
578
+ clearWaiters()
579
+ {
580
+ let index = core.waiters.length, waiter;
581
+
582
+ if (index == 0)
583
+ return;
584
+
585
+ while (--index)
586
+ {
587
+ waiter = core.waiters[index];
588
+
589
+ if (!waiter.waiting)
590
+ core.waiters.splice(index, 1);
591
+ }
592
+ },
593
+
594
+ useWS()
595
+ {
596
+ return ($bindary.useWebSocket && $bindary.websocketSupport);
597
+ },
598
+
599
+ formatDate(date, format)
600
+ {
601
+ format = format || $bindary.dateFormat;
602
+ return $lib.formatDate(date, format);
603
+ },
604
+
605
+ customEventHandler()
606
+ {
607
+ core.eventHandler.apply(this, arguments);
608
+ },
609
+
610
+ eventHandler(method, item, treeState, args, internal, context, e)
611
+ {
612
+ item.restoreContext(treeState);
613
+
614
+ if (!internal)
615
+ core.call(method, [item, e], context);
616
+ else
617
+ {
618
+ let methodArgs = [];
619
+ methodArgs.unshift(item);
620
+ args.push(e);
621
+ method.apply(this, methodArgs.concat(args));
622
+ }
623
+ },
624
+
625
+ call(method, args, context)
626
+ {
627
+ if (!method)
628
+ return;
629
+
630
+ let item = args[0];
631
+
632
+ if (!context)
633
+ context = core.getMethodContext(method, item);
634
+
635
+ method = core.methodName(method);
636
+
637
+ let contextTree = method.split('.'), length = contextTree.length;
638
+
639
+ $lib.each(contextTree, function (name, index)
640
+ {
641
+ if (!context && $bindary.controller && $bindary.controller[name])
642
+ context = $bindary.controller;
643
+ else if (!context)
644
+ context = window;
645
+
646
+ method = context[name];
647
+
648
+ if (index != length - 1)
649
+ context = context[name];
650
+ });
651
+
652
+ return method.apply(context, args);
653
+ },
654
+
655
+ methodName(method)
656
+ {
657
+ let p = '$component', c = '$context';
658
+
659
+ method = method.replace(core.methodRegEx, ''); // replace $component. and $context.
660
+ return method.replace('\\' + p, p).replace('\\' + c, c) // replace escaped keys
661
+ },
662
+
663
+ getMethodContext(method, item)
664
+ {
665
+ if (!method)
666
+ return null;
667
+
668
+ let keys = method.split('.');
669
+
670
+ if (core.isKey(keys[0], '$context'))
671
+ return item.context;
672
+
673
+ if (!item.isComponent || !core.isKey(keys[0], '$component'))
674
+ return null;
675
+
676
+ while (!item.component)
677
+ item = item.parent;
678
+
679
+ return item.context;
680
+ },
681
+
682
+ resolveContentExpression(el)
683
+ {
684
+ const nodes = el.childNodes;
685
+ let hasElementChild = false;
686
+ const candidates = [];
687
+
688
+ for (let i = 0; i < nodes.length; i++)
689
+ {
690
+ const n = nodes[i];
691
+
692
+ if (n.nodeType === 1)
693
+ hasElementChild = true;
694
+ else if (n.nodeType === 3 && n.data.includes('{{'))
695
+ candidates.push(n);
696
+ }
697
+
698
+ if (candidates.length === 0)
699
+ return false; // nothing to do
700
+
701
+ if (!hasElementChild)
702
+ return true; // pure-text, existing whole-content path handles it, unchanged
703
+
704
+ for (const textNode of candidates)
705
+ {
706
+ const span = document.createElement('span');
707
+ span.textContent = textNode.data;
708
+ textNode.replaceWith(span);
709
+ }
710
+
711
+ return false; // this element itself is no longer a content-expression node; the new spans get discovered independently below
712
+ },
713
+
714
+ hasContentExpression(el)
715
+ {
716
+ const nodes = el.childNodes;
717
+ let index = nodes.length;
718
+
719
+ while (index--)
720
+ {
721
+ const n = nodes[index];
722
+
723
+ if (n.nodeType === 1) // ELEMENT_NODE
724
+ return false;
725
+
726
+ if (n.nodeType === 3 && n.data.includes('{{'))
727
+ return true;
728
+ }
729
+
730
+ return false;
731
+ },
732
+
733
+ hasExpression(text)
734
+ {
735
+ return (text.indexOf('{{') > -1 && text.match(core.hasBindingRegEx) !== null);
736
+ },
737
+
738
+ isKey(text, key)
739
+ {
740
+ return (text && text.indexOf(key) == 0);
741
+ },
742
+
743
+ dataKeyMatch(key, startKey)
744
+ {
745
+ return (key && startKey && $lib.startsWith(key, startKey + core.dksc));
746
+ },
747
+
748
+ literalContainsKey(value)
749
+ {
750
+ let left = (value.match(/\{/g) || []).length,
751
+ right = (value.match(/\}/g) || []).length;
752
+
753
+ return ((left >= 1 && left % 2 == 0) && (right >= 1 && right % 2 == 0));
754
+ },
755
+
756
+ escapeDataKey(dataKey)
757
+ {
758
+ $lib.each(dataKey, function (item, index) { dataKey[index] = item.replace(core.escapeRegEx, '$$1'); });
759
+ },
760
+
761
+ toBoolean(text)
762
+ {
763
+ if (!text)
764
+ return false;
765
+
766
+ switch (text.toLowerCase().trim())
767
+ {
768
+ case "false": case "no": case "0": return false;
769
+ default: return true;
770
+ }
771
+ },
772
+
773
+ getElementValue(item)
774
+ {
775
+ const el = item.element;
776
+
777
+ for (const handler of core.valueHandlers)
778
+ {
779
+ if (handler.matcher(item) && handler.getValue)
780
+ {
781
+ return handler.getValue(el);
782
+ }
783
+ }
784
+
785
+ return (el.contentEditable == 'true') ? el.innerHTML : el.value;
786
+ },
787
+
788
+ setElementValue(item, value, isHTML)
789
+ {
790
+ const el = item.element;
791
+
792
+ for (const handler of core.valueHandlers)
793
+ {
794
+ if (handler.matcher(item) && handler.setValue)
795
+ {
796
+ return handler.setValue(el, value);
797
+ }
798
+ }
799
+
800
+ if (isHTML && el.innerHTML != value)
801
+ el.innerHTML = value;
802
+ else if (!isHTML)
803
+ $lib.setText(el, value);
804
+ },
805
+
806
+ createJSON(text)
807
+ {
808
+ return text.replace(core.quoteRegEx, '\\"').replace(core.attrRegEx, '"$2"$3":"').substr(1) + '"'; // first escape all double-quotes, than replace attribute matches and finally remove extra double-quote at beginning and add one at the end
809
+ },
810
+
811
+ addDataContainer(dataKey, isRoot)
812
+ {
813
+ if (!dataKey)
814
+ return null;
815
+
816
+ let container, index = 0, root = dataKey[0], addSymbol;
817
+
818
+ if (root == core.parentKey || root == core.valueKey || root == core.key)
819
+ {
820
+ isRoot = false;
821
+ }
822
+ else if (root == '$')
823
+ {
824
+ isRoot = true;
825
+ root = dataKey[1] || root;
826
+ ++index;
827
+ }
828
+ else if (isRoot)
829
+ addSymbol = true;
830
+
831
+ if (isRoot && $lib.indexOf(core.dataLabel, root) == -1)
832
+ {
833
+ if (root in $bindary.viewData)
834
+ container = core.dataLabel[2];
835
+ else if (root in $bindary.routeData)
836
+ container = core.dataLabel[1];
837
+ else if (root in $bindary.appData)
838
+ container = core.dataLabel[0];
839
+
840
+ if (container)
841
+ dataKey.splice(index, 0, container);
842
+ }
843
+
844
+ if (addSymbol)
845
+ dataKey.splice(0, 0, '$');
846
+
847
+ return dataKey;
848
+ }
849
+ };
850
+ })();
851
+
852
+ var Core = componyx.bindary_modules.core;
853
+
854
+ export { Core as default };