jpf 4.2.15 → 4.2.17

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 (124) hide show
  1. package/dist/controls/codeMirror/HtmlEditor/HtmlEditor.d.ts +2 -1
  2. package/dist/controls/codeMirror/HtmlEditor/HtmlEditor.js +4 -0
  3. package/dist/controls/codeMirror/HtmlEditor/HtmlEditor.js.map +1 -1
  4. package/dist/controls/codeMirror/JsonEditor/JsonEditor.d.ts +2 -1
  5. package/dist/controls/codeMirror/JsonEditor/JsonEditor.js +4 -0
  6. package/dist/controls/codeMirror/JsonEditor/JsonEditor.js.map +1 -1
  7. package/dist/controls/custom/FileSelector/FileSelector.d.ts +2 -1
  8. package/dist/controls/custom/FileSelector/FileSelector.js +4 -0
  9. package/dist/controls/custom/FileSelector/FileSelector.js.map +1 -1
  10. package/dist/controls/custom/LabeledControl/LabeledControl.d.ts +2 -1
  11. package/dist/controls/custom/LabeledControl/LabeledControl.js +4 -0
  12. package/dist/controls/custom/LabeledControl/LabeledControl.js.map +1 -1
  13. package/dist/controls/custom/ListItem/ListItem.d.ts +4 -2
  14. package/dist/controls/custom/ListItem/ListItem.js +8 -0
  15. package/dist/controls/custom/ListItem/ListItem.js.map +1 -1
  16. package/dist/controls/html/Button/Button.d.ts +2 -1
  17. package/dist/controls/html/Button/Button.js +4 -0
  18. package/dist/controls/html/Button/Button.js.map +1 -1
  19. package/dist/controls/html/Div/Div.d.ts +2 -1
  20. package/dist/controls/html/Div/Div.js +4 -0
  21. package/dist/controls/html/Div/Div.js.map +1 -1
  22. package/dist/controls/html/Image/Image.d.ts +2 -1
  23. package/dist/controls/html/Image/Image.js +4 -0
  24. package/dist/controls/html/Image/Image.js.map +1 -1
  25. package/dist/controls/html/Input/Input.d.ts +2 -1
  26. package/dist/controls/html/Input/Input.js +4 -0
  27. package/dist/controls/html/Input/Input.js.map +1 -1
  28. package/dist/controls/html/Select/Select.d.ts +2 -1
  29. package/dist/controls/html/Select/Select.js +4 -0
  30. package/dist/controls/html/Select/Select.js.map +1 -1
  31. package/dist/controls/html/Span/Span.d.ts +2 -1
  32. package/dist/controls/html/Span/Span.js +4 -0
  33. package/dist/controls/html/Span/Span.js.map +1 -1
  34. package/dist/controls/jsonViewAwesome/jsonFormatter/JsonFormatter.d.ts +2 -1
  35. package/dist/controls/jsonViewAwesome/jsonFormatter/JsonFormatter.js +4 -0
  36. package/dist/controls/jsonViewAwesome/jsonFormatter/JsonFormatter.js.map +1 -1
  37. package/dist/controls/kendo/Editor/Editor.d.ts +2 -1
  38. package/dist/controls/kendo/Editor/Editor.js +4 -0
  39. package/dist/controls/kendo/Editor/Editor.js.map +1 -1
  40. package/dist/controls/kendo/Grid/Grid.d.ts +2 -1
  41. package/dist/controls/kendo/Grid/Grid.js +4 -0
  42. package/dist/controls/kendo/Grid/Grid.js.map +1 -1
  43. package/dist/controls/kendo/Menu/Menu.js.map +1 -1
  44. package/dist/controls/leaflet/Map/Map.d.ts +2 -1
  45. package/dist/controls/leaflet/Map/Map.js +4 -0
  46. package/dist/controls/leaflet/Map/Map.js.map +1 -1
  47. package/dist/framework/ViewModel.d.ts +2 -2
  48. package/dist/framework/ViewModel.js +2 -2
  49. package/dist/framework/ViewModel.js.map +1 -1
  50. package/package.json +3 -2
  51. package/src/controls/codeMirror/HtmlEditor/HtmlEditor.ts +153 -0
  52. package/src/controls/codeMirror/JsonEditor/JsonEditor.ts +136 -0
  53. package/src/controls/codeMirror/index.ts +2 -0
  54. package/src/controls/custom/FileSelector/FileSelector.ts +74 -0
  55. package/src/controls/custom/LabeledControl/LabeledControl.ts +58 -0
  56. package/src/controls/custom/ListItem/ListItem.ts +99 -0
  57. package/src/controls/custom/index.ts +3 -0
  58. package/src/controls/html/Button/Button.ts +70 -0
  59. package/src/controls/html/Div/Div.ts +41 -0
  60. package/src/controls/html/Image/Image.ts +46 -0
  61. package/src/controls/html/Input/Input.ts +228 -0
  62. package/src/controls/html/Select/Select.ts +146 -0
  63. package/src/controls/html/Span/Span.ts +38 -0
  64. package/src/controls/html/index.ts +6 -0
  65. package/src/controls/index.ts +15 -0
  66. package/src/controls/jsonViewAwesome/index.ts +1 -0
  67. package/src/controls/jsonViewAwesome/jsonFormatter/JsonFormatter.ts +91 -0
  68. package/src/controls/kendo/Chart/Chart.ts +97 -0
  69. package/src/controls/kendo/Culture/Culture.ts +32 -0
  70. package/src/controls/kendo/DataSource/DataSource.ts +4 -0
  71. package/src/controls/kendo/Dialog/Dialog.ts +64 -0
  72. package/src/controls/kendo/Editor/Editor.ts +142 -0
  73. package/src/controls/kendo/Grid/Grid.ts +291 -0
  74. package/src/controls/kendo/Menu/Menu.ts +125 -0
  75. package/src/controls/kendo/ObservableObject/ObservableObject.ts +45 -0
  76. package/src/controls/kendo/Tree/Tree.ts +147 -0
  77. package/src/controls/kendo/index.ts +9 -0
  78. package/src/controls/leaflet/LabelControl/LabelControl.ts +42 -0
  79. package/src/controls/leaflet/Map/Map.ts +180 -0
  80. package/src/controls/leaflet/OpenStreetMapTileLayer/OpenStreetMapTileLayer.ts +19 -0
  81. package/src/controls/leaflet/PointerEvent/PointerEvent.ts +9 -0
  82. package/src/controls/leaflet/index.ts +4 -0
  83. package/src/controls/svg/Circle/Circle.ts +34 -0
  84. package/src/controls/svg/Ellipse/Ellipse.ts +36 -0
  85. package/src/controls/svg/ForeignObject/ForeignObject.ts +38 -0
  86. package/src/controls/svg/Group/Group.ts +38 -0
  87. package/src/controls/svg/Line/Line.ts +36 -0
  88. package/src/controls/svg/Pattern/Pattern.ts +49 -0
  89. package/src/controls/svg/Polygon/Polygon.ts +31 -0
  90. package/src/controls/svg/Polyline/Polyline.ts +31 -0
  91. package/src/controls/svg/Rectangle/Rectangle.ts +36 -0
  92. package/src/controls/svg/Svg/Svg.ts +43 -0
  93. package/src/controls/svg/Text/Text.ts +38 -0
  94. package/src/controls/svg/Title/Title.ts +28 -0
  95. package/src/controls/svg/index.ts +13 -0
  96. package/src/controls/svg/svg.ts +20 -0
  97. package/src/framework/View.ts +213 -0
  98. package/src/framework/ViewModel.ts +525 -0
  99. package/src/framework/attributes.ts +92 -0
  100. package/src/framework/event.ts +98 -0
  101. package/src/framework/observable.ts +80 -0
  102. package/src/framework/style.ts +3271 -0
  103. package/src/framework/types.ts +277 -0
  104. package/src/framework/userAgent.ts +51 -0
  105. package/src/index.ts +14 -0
  106. package/src/utilities/blob/blob.ts +19 -0
  107. package/src/utilities/cookie/cookie.ts +28 -0
  108. package/src/utilities/dataReaderTable/dataReaderTable.ts +34 -0
  109. package/src/utilities/fetch/fetch.ts +179 -0
  110. package/src/utilities/float/float.ts +3 -0
  111. package/src/utilities/formData/formData.ts +12 -0
  112. package/src/utilities/html/html.ts +8 -0
  113. package/src/utilities/htmlElement/htmlElement.ts +15 -0
  114. package/src/utilities/image/image.ts +1 -0
  115. package/src/utilities/index.ts +37 -0
  116. package/src/utilities/integer/integer.ts +31 -0
  117. package/src/utilities/key/key.ts +7 -0
  118. package/src/utilities/navigator/navigator.ts +7 -0
  119. package/src/utilities/notification/notification.ts +88 -0
  120. package/src/utilities/querystring/querystring.ts +61 -0
  121. package/src/utilities/router/router.ts +124 -0
  122. package/src/utilities/stylesheet/stylesheet.ts +58 -0
  123. package/src/utilities/uniqueId/uniqueId.ts +5 -0
  124. package/src/utilities/webSocket/webSocket.ts +72 -0
@@ -0,0 +1,525 @@
1
+ import { unwrap, Subscribable, isSubscribable, Subscription, isObservable } from "knockout";
2
+ import { CssProperty } from "./types";
3
+ import { userAgent } from "./userAgent";
4
+ import { EventListeners, UiElementEventMap, IEventListenerOptions, IGenericEventListener, IMouseEventListener, MouseEventListeners, mouseEvents, touchEvents, isGlobalEvent } from "./event";
5
+ import { Attributes, AttributesSubscribable } from "./attributes";
6
+ import { extend } from "jquery";
7
+ import { Style, StyleSubscribable, defaultStyle } from "./style"
8
+
9
+ export interface WebSocketMessageHandler {
10
+ handleWebSocketMessage: (message: any) => void;
11
+ }
12
+
13
+ export function handleWebSocketMessage(object: object, message: any) {
14
+ bubbleDownObjectTreeAndExecuteHandler(
15
+ object,
16
+ (object) => {
17
+ const webSocketMessageHandler = object as WebSocketMessageHandler;
18
+ if (webSocketMessageHandler.handleWebSocketMessage && typeof webSocketMessageHandler.handleWebSocketMessage === "function") {
19
+ //Call the handleWebSocketMessage method
20
+ webSocketMessageHandler.handleWebSocketMessage(message);
21
+ }
22
+ }
23
+ );
24
+ }
25
+
26
+ //This function bubbles down an object tree
27
+ //The given handler is executed on the given object and all its child properties of type object
28
+ export function bubbleDownObjectTreeAndExecuteHandler(object: object, handler: (object) => void) {
29
+ //Find out if the object is an array
30
+ if (object.constructor === Array) {
31
+ for (const arrayEntry of object as Array<any>) {
32
+ if (typeof arrayEntry === "object") {
33
+ bubbleDownObjectTreeAndExecuteHandler(arrayEntry, handler);
34
+ }
35
+ }
36
+ } else {
37
+ //Find out if the object implements the WebSocketMessageHandler interface
38
+ if (isSubscribable(object)) {
39
+ var unwrapped = unwrap(object);
40
+ if (typeof unwrapped === "object") {
41
+ bubbleDownObjectTreeAndExecuteHandler(unwrapped, handler);
42
+ }
43
+ } else {
44
+ handler(object);
45
+ //Find out if the object has properties of type object
46
+ for (const key in Object.keys(object)) {
47
+ const property = object[key];
48
+ if (property && typeof property === "object") {
49
+ //Call handleWebSocketMessage method on the property to bubble down the object tree.
50
+ bubbleDownObjectTreeAndExecuteHandler(property, handler);
51
+ }
52
+ }
53
+ }
54
+ }
55
+ }
56
+
57
+ //#region Null check
58
+ export function isNullOrUndefined(value): boolean {
59
+ return value === null || typeof value === "undefined";
60
+ }
61
+
62
+ export interface Properties {
63
+ attributes?: Attributes | AttributesSubscribable;
64
+ classNames?: Array<string> | Subscribable<Array<string>>;
65
+ style?: Style | StyleSubscribable;
66
+ visible?: boolean | Subscribable<boolean>;
67
+ disabled?: boolean | Subscribable<boolean>;
68
+ innerHtml?: any | Subscribable<any>;
69
+ textContent?: string | Subscribable<string>;
70
+ addViewModelToDataObject?: boolean;
71
+ userSelectable?: boolean;
72
+ eventListeners?: EventListeners;
73
+ viewType?: string;
74
+ focused?: boolean | Subscribable<boolean>;
75
+ }
76
+
77
+ export abstract class ViewModel implements Properties {
78
+ setProperties<TProperties>(object: object, properties: TProperties) {
79
+ if (properties) {
80
+ Object.keys(properties).forEach((property) => {
81
+ object[property] = properties[property];
82
+ });
83
+ }
84
+ }
85
+
86
+ attributes?: Attributes | AttributesSubscribable;
87
+ classNames?: Array<string> | Subscribable<Array<string>>;
88
+ style?: Style | StyleSubscribable;
89
+ visible?: boolean | Subscribable<boolean>;
90
+ disabled?: boolean | Subscribable<boolean>;
91
+ innerHtml?: any | Subscribable<any>;
92
+ textContent?: string | Subscribable<string>;
93
+ addViewModelToDataObject?: boolean;
94
+ userSelectable?: boolean;
95
+ eventListeners?: EventListeners;
96
+ viewType?: string;
97
+ focused?: boolean | Subscribable<boolean>;
98
+
99
+ //protected getStyle(...cssProperties: Array<CssProperty>): Style {
100
+ // if (cssProperties && this.style) {
101
+ // const style: Style = {};
102
+ // cssProperties.forEach((cssProperty) => {
103
+ // style[cssProperty] = this.style[cssProperty] as never;
104
+ // });
105
+ // return style;
106
+ // }
107
+
108
+ // return null as Style;
109
+ //}
110
+ //protected getStyleValue(cssProperty: CssProperty): any {
111
+ // if (this.style) {
112
+ // return unwrap(this.style[cssProperty]);
113
+ // }
114
+ // return null;
115
+ //}
116
+
117
+ //addMouseEventListener(event: keyof MouseEventListeners, mouseEventListener: IMouseEventListener) {
118
+ // if (!this.eventListeners[event]) {
119
+ // this.eventListeners[event] = mouseEventListener;
120
+ // }
121
+ //}
122
+
123
+ //addEventListener(event: keyof EventListeners, genericEventListener: IGenericEventListener) {
124
+ // if (!this.eventListeners[event]) {
125
+ // this.eventListeners[event] = genericEventListener;
126
+ // }
127
+ //}
128
+
129
+ //setClasses(classNames: string[], replace: boolean) {
130
+ // if (isSubscribable(this.classNames)) {
131
+
132
+ // var currentClassNames = unwrap(this.classNames);
133
+ // if (replace) {
134
+ // currentClassNames = new Array<string>();
135
+ // }
136
+
137
+ // if (classNames) {
138
+ // classNames.forEach((className) => {
139
+ // currentClassNames.push(className);
140
+ // });
141
+ // }
142
+ // const observable = this.classNames;
143
+ // if (isObservable(observable)) {
144
+ // observable(currentClassNames);
145
+ // }
146
+ // }
147
+ //}
148
+ //setAttributes(attributes: Attributes) {
149
+ // if (attributes) {
150
+ // Object.keys(attributes).forEach((key) => {
151
+ // let newValue = attributes[key];
152
+ // if (newValue === null || newValue === undefined) {
153
+ // newValue = null;
154
+ // }
155
+
156
+ // if (isSubscribable(this.attributes[key])) {
157
+ // this.attributes[key](unwrap(newValue));
158
+ // } else {
159
+ // this.attributes[key] = newValue;
160
+ // }
161
+ // });
162
+ // }
163
+ //}
164
+ //setStyle(style: Style): void {
165
+ // if (style) {
166
+ // Object.keys(style).forEach((key: string) => {
167
+ // let newValue = style[key];
168
+ // if (newValue === null || newValue === undefined) {
169
+ // if (userAgent.browser.isInternetExplorer) {
170
+ // //Setting a css style property to null does not work for internet explorer
171
+ // //so we reset to the default value for the given property.
172
+ // newValue = defaultStyle[key];
173
+ // } else {
174
+ // newValue = null;
175
+ // }
176
+ // }
177
+
178
+ // if (isSubscribable(this.style[key])) {
179
+ // this.style[key](unwrap(newValue));
180
+ // } else {
181
+ // this.style[key] = newValue;
182
+ // }
183
+ // });
184
+ // }
185
+ //}
186
+ //setVisible(visible: boolean) {
187
+ // const visibleObservable = this.visible;
188
+ // if (isSubscribable(visibleObservable)) {
189
+ // visibleObservable(visible);
190
+ // }
191
+ //}
192
+ //setDisabled(disabled: boolean) {
193
+ // const disableObservable = this.disabled;
194
+ // if (isSubscribable(disableObservable)) {
195
+ // disableObservable(disabled);
196
+ // }
197
+ //}
198
+ //setInnerHtml(innerHtml: string) {
199
+ // const innerHtmlObservable = this.innerHtml;
200
+ // if (isSubscribable(innerHtmlObservable)) {
201
+ // innerHtmlObservable(innerHtml);
202
+ // }
203
+ //}
204
+
205
+ //setTextContent(textContent: string) {
206
+ // const textContentObservable = this.textContent;
207
+ // if (isSubscribable(textContentObservable)) {
208
+ // textContentObservable(textContent);
209
+ // }
210
+ //}
211
+
212
+ //removeClasses(classNames: string[]) {
213
+ // const classNamesObservable = this.classNames;
214
+ // if (isSubscribable(classNamesObservable)) {
215
+ // const currentClassNames = unwrap(classNamesObservable);
216
+ // for (let i = 0; i < currentClassNames.length; i++) {
217
+ // if (classNames.includes(currentClassNames[i])) {
218
+ // currentClassNames.splice(i, 1);
219
+ // }
220
+ // }
221
+ // classNamesObservable(currentClassNames);
222
+ // }
223
+ //}
224
+ }
225
+
226
+ //#region ViewModel helper functions
227
+
228
+ //Function to merge two viewModels. The source is applied to the target. Corresponding properties are overwritten in the target.
229
+ export function extendProperties<TResult = Properties, TTarget = Properties, TSource = Properties>(target: TTarget, source: TSource): TResult {
230
+ return extend(true, target, source) as any as TResult;
231
+ }
232
+
233
+ //Functions to bind the viewModel to a html element
234
+ export function applyBindings(properties: Properties, element: HTMLElement, subscriptions: Array<Subscription>) {
235
+ element.setAttribute("viewtype", properties.viewType || "View");
236
+
237
+ if (properties.classNames) {
238
+ applyClassesToElement(unwrap<string[]>(properties.classNames), true, element);
239
+
240
+ if (isSubscribable(properties.classNames)) {
241
+ const subscription = properties.classNames.subscribe((classNames: Array<string>) => {
242
+ applyClassesToElement(classNames, true, element);
243
+ });
244
+
245
+ if (subscriptions) {
246
+ subscriptions.push(subscription);
247
+ }
248
+ }
249
+ }
250
+
251
+ if (properties.attributes) {
252
+ Object.keys(properties.attributes).forEach((key) => {
253
+ var value = properties.attributes[key];
254
+ applyAttributeToElement(key as keyof Attributes, unwrap(value), element);
255
+ if (isSubscribable(value)) {
256
+ const subscription = value.subscribe((newValue: string) => {
257
+ applyAttributeToElement(key as keyof Attributes, newValue, element);
258
+ });
259
+
260
+ if (subscriptions) {
261
+ subscriptions.push(subscription);
262
+ }
263
+ }
264
+ });
265
+ }
266
+
267
+ if (properties.style) {
268
+ Object.keys(properties.style).forEach((key) => {
269
+ const style = properties.style[key];
270
+ element.style[key] = unwrap(style);
271
+ if (isSubscribable(style)) {
272
+ const subscription = style.subscribe((newStyle) => {
273
+ element.style[key] = newStyle;
274
+ });
275
+
276
+ if (subscriptions) {
277
+ subscriptions.push(subscription);
278
+ }
279
+ }
280
+ });
281
+ }
282
+
283
+ if (!isNullOrUndefined(properties.innerHtml)) {
284
+ element.innerHTML = unwrap(properties.innerHtml);
285
+ if (isSubscribable(properties.innerHtml)) {
286
+ const subscription = properties.innerHtml.subscribe((innerHtml: string) => {
287
+ element.innerHTML = innerHtml;
288
+ });
289
+
290
+ if (subscriptions) {
291
+ subscriptions.push(subscription);
292
+ }
293
+ }
294
+ }
295
+
296
+ if (!isNullOrUndefined(properties.textContent)) {
297
+ element.textContent = unwrap(properties.textContent);
298
+ if (isSubscribable(properties.textContent)) {
299
+ const subscription = properties.textContent.subscribe((textContent: string) => {
300
+ if (element.hasChildNodes() && element.childNodes.length === 1 && element.childNodes[0].nodeType === 3) {
301
+ //The first child is a text node so the most efficient way is to use the nodeValue property
302
+ element.firstChild.nodeValue = textContent;
303
+ } else {
304
+ element.textContent = textContent;
305
+ }
306
+ });
307
+
308
+ if (subscriptions) {
309
+ subscriptions.push(subscription);
310
+ }
311
+ }
312
+ }
313
+
314
+ //Find out if the element is none selectable
315
+ if (properties.userSelectable === false) {
316
+ applyEventListenerToElement("selectstart", () => { return false; }, { passive: true }, element);
317
+ element.style.userSelect = "none";
318
+ }
319
+
320
+ if (properties.addViewModelToDataObject) {
321
+ if (!element["data"]) {
322
+ element["data"] = {};
323
+ }
324
+ element["data"].viewModel = properties;
325
+ }
326
+
327
+ if (properties.eventListeners) {
328
+ applyEventListenersToElement(properties, element);
329
+ }
330
+
331
+ applyVisibilityToElement(unwrap(properties.visible), element);
332
+ if (isSubscribable(properties.visible)) {
333
+ const subscription = properties.visible.subscribe((visible) => {
334
+ applyVisibilityToElement(visible, element);
335
+ });
336
+
337
+ if (subscriptions) {
338
+ subscriptions.push(subscription);
339
+ }
340
+ }
341
+
342
+ applyDisabledToElement(unwrap(properties.disabled), element);
343
+ if (isSubscribable(properties.disabled)) {
344
+ const subscription = properties.disabled.subscribe((disabled) => {
345
+ applyDisabledToElement(disabled, element);
346
+ });
347
+
348
+ if (subscriptions) {
349
+ subscriptions.push(subscription);
350
+ }
351
+ }
352
+
353
+ applyFocusToElement(unwrap(properties.focused), element);
354
+ if (isSubscribable(properties.focused)) {
355
+ const subscription = properties.focused.subscribe((focused) => {
356
+ applyFocusToElement(focused, element);
357
+ });
358
+
359
+ if (subscriptions) {
360
+ subscriptions.push(subscription);
361
+ }
362
+ }
363
+ }
364
+
365
+ function applyVisibilityToElement(visible: boolean, element: HTMLElement) {
366
+ if (visible === false) {
367
+ element.classList.add("hidden");
368
+ } else {
369
+ element.classList.remove("hidden");
370
+ }
371
+ }
372
+
373
+ function applyDisabledToElement(disabled: boolean, element: HTMLElement) {
374
+ if (disabled) {
375
+ element.setAttribute("disabled", "disabled");
376
+ } else {
377
+ element.removeAttribute("disabled");
378
+ }
379
+ }
380
+
381
+ function applyEventListenersToElement(viewModel: Properties, element: HTMLElement) {
382
+ //Add the eventListeners to the element
383
+ const clickEventListeners = new Array<IGenericEventListener>();
384
+ const doubleClickEventListeners = new Array<IGenericEventListener>();
385
+
386
+ Object.entries(viewModel.eventListeners).forEach((entry) => {
387
+ var eventName = entry[0] as keyof UiElementEventMap;
388
+ var eventListener = entry[1] as IGenericEventListener;
389
+
390
+ if (eventName === "click") {
391
+ clickEventListeners.push(eventListener);
392
+ return;
393
+ }
394
+ if (eventName === "dblclick") {
395
+ doubleClickEventListeners.push(eventListener);
396
+ return;
397
+ }
398
+
399
+ if (eventName === "dragstart") {
400
+ element.setAttribute("draggable", "true");
401
+ }
402
+
403
+ if (isGlobalEvent(eventName)) {
404
+ applyEventListenerToElement(
405
+ eventName,
406
+ (event: Event) => {
407
+ if (eventListener.options) {
408
+ const options = eventListener.options as IEventListenerOptions;
409
+ const keyEvent = event as KeyboardEvent;
410
+ if (options.altKey && !keyEvent.altKey) {
411
+ return;
412
+ }
413
+ if (options.shiftKey && !keyEvent.shiftKey) {
414
+ return;
415
+ }
416
+ if (options.ctrlKey && !keyEvent.ctrlKey) {
417
+ return;
418
+ }
419
+ if (options.eventKey && options.eventKey !== keyEvent.key) {
420
+ return;
421
+ }
422
+ }
423
+
424
+ eventListener.listener.call(viewModel, event);
425
+ },
426
+ eventListener.options,
427
+ element
428
+ );
429
+ }
430
+ else if (mouseEvents[eventName] && userAgent.device.supportsMouseEvents) {
431
+ applyEventListenerToElement(eventName, eventListener.listener, eventListener.options, element);
432
+ }
433
+ else if (touchEvents[eventName] && userAgent.device.supportsTouchEvents) {
434
+ applyEventListenerToElement(eventName, eventListener.listener, eventListener.options, element);
435
+ }
436
+ });
437
+
438
+ clickEventListeners.forEach((clickEventListener) => {
439
+ if (userAgent.device.supportsTouchEvents) {
440
+ // ReSharper disable once Html.EventNotResolved
441
+ applyEventListenerToElement("tap", clickEventListener.listener, clickEventListener.options, element);
442
+ }
443
+ if (userAgent.device.supportsMouseEvents) {
444
+ applyEventListenerToElement("click", clickEventListener.listener, clickEventListener.options, element);
445
+ }
446
+ });
447
+
448
+ doubleClickEventListeners.forEach((doubleClickEventListener) => {
449
+ if (userAgent.device.supportsTouchEvents) {
450
+ // ReSharper disable once Html.EventNotResolved
451
+ applyEventListenerToElement("dbltap", doubleClickEventListener.listener, doubleClickEventListener.options, element);
452
+ }
453
+ if (userAgent.device.supportsMouseEvents) {
454
+ applyEventListenerToElement("dblclick", doubleClickEventListener.listener, doubleClickEventListener.options, element);
455
+ }
456
+ });
457
+ }
458
+
459
+ function applyEventListenerToElement(type: keyof UiElementEventMap, listener: (event: any) => any, options: IEventListenerOptions, element: HTMLElement) {
460
+ if (!type) {
461
+ throw new Error("type is mandatory");
462
+ }
463
+ if (!listener) {
464
+ throw new Error("listener is mandatory");
465
+ }
466
+ if (!options) {
467
+ options = {};
468
+ }
469
+ if (!options.passive) {
470
+ options.passive = false;
471
+ }
472
+ if (!options.once) {
473
+ options.once = false;
474
+ }
475
+
476
+ if (element.addEventListener) {
477
+ element.addEventListener(
478
+ type,
479
+ (event) => {
480
+ listener(event);
481
+ },
482
+ {
483
+ passive: options.passive,
484
+ once: options.once
485
+ });
486
+ } else if (element["attachEvent"]) {
487
+ element["attachEvent"](
488
+ type,
489
+ (event) => {
490
+ listener(event);
491
+ }
492
+ );
493
+ } else {
494
+ throw "Your browser does not support 'addEventListener'";
495
+ }
496
+ }
497
+
498
+ function applyClassesToElement(classNames: string[], replace: boolean, element: HTMLElement) {
499
+ //If all existing classes need to be replace we reset the classes object to an empty object
500
+ if (replace) {
501
+ element.className = "";
502
+ }
503
+
504
+ //Add all the classNames to the classes object
505
+ if (classNames) {
506
+ classNames.forEach((className) => {
507
+ element.classList.add(className);
508
+ });
509
+ }
510
+ }
511
+
512
+ function applyAttributeToElement(name: keyof Attributes, value: string, element: HTMLElement) {
513
+ if (isNullOrUndefined(value)) {
514
+ element.removeAttribute(name);
515
+ } else {
516
+ element.setAttribute(name, value);
517
+ }
518
+ }
519
+
520
+ function applyFocusToElement(focused: boolean, element: HTMLElement) {
521
+ if (focused) {
522
+ element.focus();
523
+ }
524
+ }
525
+ //#endregion
@@ -0,0 +1,92 @@
1
+ import { Subscribable } from "knockout";
2
+ import { PreserveAspectRatio } from "./types";
3
+
4
+ export interface Attributes {
5
+ alt?: string,
6
+ disabled?: string,
7
+ href?: string,
8
+ target?: string,
9
+ id?: string,
10
+ src?: string,
11
+ title?: string,
12
+ class?: string,
13
+ tabindex?: number,
14
+ draggable?: string,
15
+ placeholder?: string,
16
+ for?: string,
17
+ type?: string,
18
+ value?: string,
19
+ view?: string,
20
+ checked?: string;
21
+ enctype?: string;
22
+ name?: string;
23
+ multiple?: boolean;
24
+ ["aria-label"]?: string;
25
+ cx?: number | string;
26
+ cy?: number | string;
27
+ r?: number | string;
28
+ rx?: number | string;
29
+ ry?: number | string;
30
+ x?: number | string;
31
+ x1?: number | string;
32
+ x2?: number | string;
33
+ y?: number | string;
34
+ y1?: number | string;
35
+ y2?: number | string;
36
+ width?: number | string;
37
+ height?: number | string;
38
+ patternUnits?: string;
39
+ patternTransform?: string;
40
+ points?: string;
41
+ viewBox?: string;
42
+ dx?: number | string;
43
+ dy?: number | string;
44
+ rotate?: string;
45
+ preserveAspectRatio?: PreserveAspectRatio;
46
+ xmlns?: string;
47
+ }
48
+
49
+ export interface AttributesSubscribable {
50
+ alt?: string | Subscribable<string>,
51
+ disabled?: string | Subscribable<string>,
52
+ href?: string | Subscribable<string>,
53
+ target?: string | Subscribable<string>,
54
+ id?: string | Subscribable<string>,
55
+ src?: string | Subscribable<string>,
56
+ title?: string | Subscribable<string>,
57
+ class?: string | Subscribable<string>,
58
+ tabindex?: number | Subscribable<number>,
59
+ draggable?: string | Subscribable<string>,
60
+ placeholder?: string | Subscribable<string>,
61
+ for?: string | Subscribable<string>,
62
+ type?: string | Subscribable<string>,
63
+ value?: string | Subscribable<string>,
64
+ view?: string | Subscribable<string>,
65
+ checked?: string | Subscribable<string>;
66
+ enctype?: string | Subscribable<string>;
67
+ name?: string | Subscribable<string>;
68
+ multiple?: boolean | Subscribable<boolean>;
69
+ ["aria-label"]?: string | Subscribable<string>;
70
+ cx?: number | string | Subscribable<number | string>;
71
+ cy?: number | string | Subscribable<number | string>;
72
+ r?: number | string | Subscribable<number | string>;
73
+ rx?: number | string | Subscribable<number | string>;
74
+ ry?: number | string | Subscribable<number | string>;
75
+ x?: number | string | Subscribable<number | string>;
76
+ x1?: number | string | Subscribable<number | string>;
77
+ x2?: number | string | Subscribable<number | string>;
78
+ y?: number | string | Subscribable<number | string>;
79
+ y1?: number | string | Subscribable<number | string>;
80
+ y2?: number | string | Subscribable<number | string>;
81
+ width?: number | string | Subscribable<number | string>;
82
+ height?: number | string | Subscribable<number | string>;
83
+ patternUnits?: string | Subscribable<string>;
84
+ patternTransform?: string | Subscribable<string>;
85
+ points?: string | Subscribable<string>;
86
+ viewBox?: string | Subscribable<string>;
87
+ dx?: number | string | Subscribable<number | string>;
88
+ dy?: number | string | Subscribable<number | string>;
89
+ rotate?: string | Subscribable<string>;
90
+ preserveAspectRatio?: PreserveAspectRatio | Subscribable<PreserveAspectRatio>;
91
+ xmlns?: string| Subscribable<string>;
92
+ }