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.
- package/dist/controls/codeMirror/HtmlEditor/HtmlEditor.d.ts +2 -1
- package/dist/controls/codeMirror/HtmlEditor/HtmlEditor.js +4 -0
- package/dist/controls/codeMirror/HtmlEditor/HtmlEditor.js.map +1 -1
- package/dist/controls/codeMirror/JsonEditor/JsonEditor.d.ts +2 -1
- package/dist/controls/codeMirror/JsonEditor/JsonEditor.js +4 -0
- package/dist/controls/codeMirror/JsonEditor/JsonEditor.js.map +1 -1
- package/dist/controls/custom/FileSelector/FileSelector.d.ts +2 -1
- package/dist/controls/custom/FileSelector/FileSelector.js +4 -0
- package/dist/controls/custom/FileSelector/FileSelector.js.map +1 -1
- package/dist/controls/custom/LabeledControl/LabeledControl.d.ts +2 -1
- package/dist/controls/custom/LabeledControl/LabeledControl.js +4 -0
- package/dist/controls/custom/LabeledControl/LabeledControl.js.map +1 -1
- package/dist/controls/custom/ListItem/ListItem.d.ts +4 -2
- package/dist/controls/custom/ListItem/ListItem.js +8 -0
- package/dist/controls/custom/ListItem/ListItem.js.map +1 -1
- package/dist/controls/html/Button/Button.d.ts +2 -1
- package/dist/controls/html/Button/Button.js +4 -0
- package/dist/controls/html/Button/Button.js.map +1 -1
- package/dist/controls/html/Div/Div.d.ts +2 -1
- package/dist/controls/html/Div/Div.js +4 -0
- package/dist/controls/html/Div/Div.js.map +1 -1
- package/dist/controls/html/Image/Image.d.ts +2 -1
- package/dist/controls/html/Image/Image.js +4 -0
- package/dist/controls/html/Image/Image.js.map +1 -1
- package/dist/controls/html/Input/Input.d.ts +2 -1
- package/dist/controls/html/Input/Input.js +4 -0
- package/dist/controls/html/Input/Input.js.map +1 -1
- package/dist/controls/html/Select/Select.d.ts +2 -1
- package/dist/controls/html/Select/Select.js +4 -0
- package/dist/controls/html/Select/Select.js.map +1 -1
- package/dist/controls/html/Span/Span.d.ts +2 -1
- package/dist/controls/html/Span/Span.js +4 -0
- package/dist/controls/html/Span/Span.js.map +1 -1
- package/dist/controls/jsonViewAwesome/jsonFormatter/JsonFormatter.d.ts +2 -1
- package/dist/controls/jsonViewAwesome/jsonFormatter/JsonFormatter.js +4 -0
- package/dist/controls/jsonViewAwesome/jsonFormatter/JsonFormatter.js.map +1 -1
- package/dist/controls/kendo/Editor/Editor.d.ts +2 -1
- package/dist/controls/kendo/Editor/Editor.js +4 -0
- package/dist/controls/kendo/Editor/Editor.js.map +1 -1
- package/dist/controls/kendo/Grid/Grid.d.ts +2 -1
- package/dist/controls/kendo/Grid/Grid.js +4 -0
- package/dist/controls/kendo/Grid/Grid.js.map +1 -1
- package/dist/controls/kendo/Menu/Menu.js.map +1 -1
- package/dist/controls/leaflet/Map/Map.d.ts +2 -1
- package/dist/controls/leaflet/Map/Map.js +4 -0
- package/dist/controls/leaflet/Map/Map.js.map +1 -1
- package/dist/framework/ViewModel.d.ts +2 -2
- package/dist/framework/ViewModel.js +2 -2
- package/dist/framework/ViewModel.js.map +1 -1
- package/package.json +3 -2
- package/src/controls/codeMirror/HtmlEditor/HtmlEditor.ts +153 -0
- package/src/controls/codeMirror/JsonEditor/JsonEditor.ts +136 -0
- package/src/controls/codeMirror/index.ts +2 -0
- package/src/controls/custom/FileSelector/FileSelector.ts +74 -0
- package/src/controls/custom/LabeledControl/LabeledControl.ts +58 -0
- package/src/controls/custom/ListItem/ListItem.ts +99 -0
- package/src/controls/custom/index.ts +3 -0
- package/src/controls/html/Button/Button.ts +70 -0
- package/src/controls/html/Div/Div.ts +41 -0
- package/src/controls/html/Image/Image.ts +46 -0
- package/src/controls/html/Input/Input.ts +228 -0
- package/src/controls/html/Select/Select.ts +146 -0
- package/src/controls/html/Span/Span.ts +38 -0
- package/src/controls/html/index.ts +6 -0
- package/src/controls/index.ts +15 -0
- package/src/controls/jsonViewAwesome/index.ts +1 -0
- package/src/controls/jsonViewAwesome/jsonFormatter/JsonFormatter.ts +91 -0
- package/src/controls/kendo/Chart/Chart.ts +97 -0
- package/src/controls/kendo/Culture/Culture.ts +32 -0
- package/src/controls/kendo/DataSource/DataSource.ts +4 -0
- package/src/controls/kendo/Dialog/Dialog.ts +64 -0
- package/src/controls/kendo/Editor/Editor.ts +142 -0
- package/src/controls/kendo/Grid/Grid.ts +291 -0
- package/src/controls/kendo/Menu/Menu.ts +125 -0
- package/src/controls/kendo/ObservableObject/ObservableObject.ts +45 -0
- package/src/controls/kendo/Tree/Tree.ts +147 -0
- package/src/controls/kendo/index.ts +9 -0
- package/src/controls/leaflet/LabelControl/LabelControl.ts +42 -0
- package/src/controls/leaflet/Map/Map.ts +180 -0
- package/src/controls/leaflet/OpenStreetMapTileLayer/OpenStreetMapTileLayer.ts +19 -0
- package/src/controls/leaflet/PointerEvent/PointerEvent.ts +9 -0
- package/src/controls/leaflet/index.ts +4 -0
- package/src/controls/svg/Circle/Circle.ts +34 -0
- package/src/controls/svg/Ellipse/Ellipse.ts +36 -0
- package/src/controls/svg/ForeignObject/ForeignObject.ts +38 -0
- package/src/controls/svg/Group/Group.ts +38 -0
- package/src/controls/svg/Line/Line.ts +36 -0
- package/src/controls/svg/Pattern/Pattern.ts +49 -0
- package/src/controls/svg/Polygon/Polygon.ts +31 -0
- package/src/controls/svg/Polyline/Polyline.ts +31 -0
- package/src/controls/svg/Rectangle/Rectangle.ts +36 -0
- package/src/controls/svg/Svg/Svg.ts +43 -0
- package/src/controls/svg/Text/Text.ts +38 -0
- package/src/controls/svg/Title/Title.ts +28 -0
- package/src/controls/svg/index.ts +13 -0
- package/src/controls/svg/svg.ts +20 -0
- package/src/framework/View.ts +213 -0
- package/src/framework/ViewModel.ts +525 -0
- package/src/framework/attributes.ts +92 -0
- package/src/framework/event.ts +98 -0
- package/src/framework/observable.ts +80 -0
- package/src/framework/style.ts +3271 -0
- package/src/framework/types.ts +277 -0
- package/src/framework/userAgent.ts +51 -0
- package/src/index.ts +14 -0
- package/src/utilities/blob/blob.ts +19 -0
- package/src/utilities/cookie/cookie.ts +28 -0
- package/src/utilities/dataReaderTable/dataReaderTable.ts +34 -0
- package/src/utilities/fetch/fetch.ts +179 -0
- package/src/utilities/float/float.ts +3 -0
- package/src/utilities/formData/formData.ts +12 -0
- package/src/utilities/html/html.ts +8 -0
- package/src/utilities/htmlElement/htmlElement.ts +15 -0
- package/src/utilities/image/image.ts +1 -0
- package/src/utilities/index.ts +37 -0
- package/src/utilities/integer/integer.ts +31 -0
- package/src/utilities/key/key.ts +7 -0
- package/src/utilities/navigator/navigator.ts +7 -0
- package/src/utilities/notification/notification.ts +88 -0
- package/src/utilities/querystring/querystring.ts +61 -0
- package/src/utilities/router/router.ts +124 -0
- package/src/utilities/stylesheet/stylesheet.ts +58 -0
- package/src/utilities/uniqueId/uniqueId.ts +5 -0
- 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
|
+
}
|