@syncfusion/ej2-base 24.2.7 → 25.1.35-579988

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 (163) hide show
  1. package/.eslintrc.json +2 -1
  2. package/CHANGELOG.md +641 -677
  3. package/{README.md → ReadMe.md} +100 -100
  4. package/dist/ej2-base.umd.min.js +1 -10
  5. package/dist/ej2-base.umd.min.js.map +1 -1
  6. package/dist/es6/ej2-base.es2015.js +178 -1025
  7. package/dist/es6/ej2-base.es2015.js.map +1 -1
  8. package/dist/es6/ej2-base.es5.js +226 -934
  9. package/dist/es6/ej2-base.es5.js.map +1 -1
  10. package/dist/global/ej2-base.min.js +1 -10
  11. package/dist/global/ej2-base.min.js.map +1 -1
  12. package/dist/global/index.d.ts +0 -9
  13. package/dist/ts/ajax.ts +236 -0
  14. package/dist/ts/animation.ts +544 -0
  15. package/dist/ts/base.ts +357 -0
  16. package/dist/ts/browser.ts +387 -0
  17. package/dist/ts/child-property.ts +192 -0
  18. package/dist/ts/component.ts +519 -0
  19. package/dist/ts/dom.ts +488 -0
  20. package/dist/ts/draggable.ts +1155 -0
  21. package/dist/ts/droppable.ts +172 -0
  22. package/dist/ts/event-handler.ts +169 -0
  23. package/dist/ts/internationalization.ts +369 -0
  24. package/dist/ts/intl/date-formatter.ts +317 -0
  25. package/dist/ts/intl/date-parser.ts +426 -0
  26. package/dist/ts/intl/intl-base.ts +1104 -0
  27. package/dist/ts/intl/number-formatter.ts +411 -0
  28. package/dist/ts/intl/number-parser.ts +158 -0
  29. package/dist/ts/intl/parser-base.ts +394 -0
  30. package/dist/ts/keyboard.ts +238 -0
  31. package/dist/ts/l10n.ts +94 -0
  32. package/dist/ts/module-loader.ts +149 -0
  33. package/dist/ts/notify-property-change.ts +726 -0
  34. package/dist/ts/observer.ts +236 -0
  35. package/dist/ts/sanitize-helper.ts +224 -0
  36. package/dist/ts/template-engine.ts +191 -0
  37. package/dist/ts/template.ts +329 -0
  38. package/dist/ts/touch.ts +544 -0
  39. package/dist/ts/util.ts +523 -0
  40. package/dist/ts/validate-lic.ts +0 -0
  41. package/e2e/crypto.js +16 -16
  42. package/e2e/m.protractor.config.js +286 -286
  43. package/e2e/modified-protractor/protractor.config.js +316 -316
  44. package/e2e/protractor.config.js +389 -332
  45. package/helpers/e2e/index.js +3 -3
  46. package/license +10 -10
  47. package/package.json +225 -174
  48. package/src/ajax.d.ts +1 -1
  49. package/src/ajax.js +3 -8
  50. package/src/animation-model.d.ts +41 -41
  51. package/src/animation.d.ts +6 -6
  52. package/src/animation.js +25 -25
  53. package/src/base.d.ts +2 -1
  54. package/src/base.js +9 -7
  55. package/src/component-model.d.ts +16 -16
  56. package/src/component.d.ts +9 -3
  57. package/src/component.js +50 -38
  58. package/src/draggable-model.d.ts +113 -113
  59. package/src/draggable.d.ts +2 -0
  60. package/src/draggable.js +45 -29
  61. package/src/droppable-model.d.ts +23 -23
  62. package/src/droppable.js +19 -19
  63. package/src/event-handler.js +2 -1
  64. package/src/index.d.ts +0 -3
  65. package/src/index.js +0 -3
  66. package/src/intl/date-formatter.js +2 -6
  67. package/src/intl/date-parser.js +1 -20
  68. package/src/intl/intl-base.js +1 -164
  69. package/src/intl/number-formatter.d.ts +3 -0
  70. package/src/intl/number-formatter.js +7 -7
  71. package/src/intl/number-parser.js +1 -0
  72. package/src/keyboard-model.d.ts +16 -16
  73. package/src/keyboard.js +19 -19
  74. package/src/module-loader.d.ts +12 -0
  75. package/src/module-loader.js +11 -0
  76. package/src/notify-property-change.js +3 -2
  77. package/src/observer.js +2 -0
  78. package/src/sanitize-helper.js +5 -0
  79. package/src/template-engine.js +1 -0
  80. package/src/template.js +3 -2
  81. package/src/touch-model.d.ts +39 -39
  82. package/src/touch.js +19 -19
  83. package/src/validate-lic.d.ts +0 -11
  84. package/src/validate-lic.js +1 -259
  85. package/styles/_all.scss +2 -2
  86. package/styles/_bds-dark-definition.scss +15 -0
  87. package/styles/_bds-definition.scss +15 -0
  88. package/styles/_bootstrap-dark-definition.scss +42 -42
  89. package/styles/_bootstrap-definition.scss +42 -42
  90. package/styles/_bootstrap4-definition.scss +11 -11
  91. package/styles/_bootstrap5-dark-definition.scss +9 -9
  92. package/styles/_bootstrap5-definition.scss +8 -8
  93. package/styles/_fabric-dark-definition.scss +42 -42
  94. package/styles/_fabric-definition.scss +42 -42
  95. package/styles/_fluent-dark-definition.scss +9 -9
  96. package/styles/_fluent-definition.scss +9 -9
  97. package/styles/_fluent2-definition.scss +9 -0
  98. package/styles/_fusionnew-dark-definition.scss +8 -8
  99. package/styles/_fusionnew-definition.scss +8 -8
  100. package/styles/_highcontrast-definition.scss +42 -42
  101. package/styles/_highcontrast-light-definition.scss +42 -42
  102. package/styles/_material-dark-definition.scss +48 -48
  103. package/styles/_material-definition.scss +49 -49
  104. package/styles/_material3-dark-definition.scss +14 -14
  105. package/styles/_material3-definition.scss +15 -15
  106. package/styles/_tailwind-dark-definition.scss +15 -15
  107. package/styles/_tailwind-definition.scss +15 -15
  108. package/styles/animation/_all.scss +560 -560
  109. package/styles/bootstrap-dark.css +10 -1
  110. package/styles/bootstrap.css +10 -1
  111. package/styles/bootstrap4.css +10 -1
  112. package/styles/bootstrap5-dark.css +10 -1
  113. package/styles/bootstrap5.css +10 -1
  114. package/styles/common/_all.scss +2 -2
  115. package/styles/common/_core.scss +117 -117
  116. package/styles/common/_mixin.scss +9 -9
  117. package/styles/definition/_bds-dark.scss +1179 -0
  118. package/styles/definition/_bds.scss +1474 -0
  119. package/styles/definition/_bootstrap-dark.scss +219 -219
  120. package/styles/definition/_bootstrap.scss +215 -215
  121. package/styles/definition/_bootstrap4.scss +167 -167
  122. package/styles/definition/_bootstrap5-dark.scss +493 -493
  123. package/styles/definition/_bootstrap5.scss +494 -494
  124. package/styles/definition/_fabric-dark.scss +200 -200
  125. package/styles/definition/_fabric.scss +198 -198
  126. package/styles/definition/_fluent-dark.scss +557 -557
  127. package/styles/definition/_fluent.scss +558 -558
  128. package/styles/definition/_fluent2.scss +2198 -0
  129. package/styles/definition/_fusionnew-dark.scss +362 -362
  130. package/styles/definition/_fusionnew.scss +363 -363
  131. package/styles/definition/_highcontrast-light.scss +193 -193
  132. package/styles/definition/_highcontrast.scss +195 -195
  133. package/styles/definition/_material-dark.scss +198 -198
  134. package/styles/definition/_material.scss +192 -192
  135. package/styles/definition/_material3-dark.scss +710 -710
  136. package/styles/definition/_material3.scss +792 -792
  137. package/styles/definition/_tailwind-dark.scss +488 -488
  138. package/styles/definition/_tailwind.scss +485 -485
  139. package/styles/fabric-dark.css +10 -1
  140. package/styles/fabric.css +10 -1
  141. package/styles/fluent-dark.css +10 -1
  142. package/styles/fluent.css +10 -1
  143. package/styles/highcontrast-light.css +10 -1
  144. package/styles/highcontrast.css +10 -1
  145. package/styles/material-dark.css +10 -1
  146. package/styles/material.css +10 -1
  147. package/styles/material3-dark.css +10 -1
  148. package/styles/material3.css +10 -1
  149. package/styles/offline-theme/material-dark.css +10 -1
  150. package/styles/offline-theme/material.css +10 -1
  151. package/styles/offline-theme/tailwind-dark.css +10 -1
  152. package/styles/offline-theme/tailwind.css +10 -1
  153. package/styles/tailwind-dark.css +10 -1
  154. package/styles/tailwind.css +10 -1
  155. package/.github/PULL_REQUEST_TEMPLATE/Bug.md +0 -60
  156. package/.github/PULL_REQUEST_TEMPLATE/feature.md +0 -42
  157. package/bin/syncfusion-license.js +0 -2
  158. package/dist/ej2-base.min.js +0 -10
  159. package/e2e/index.d.ts +0 -27
  160. package/src/fetch.d.ts +0 -114
  161. package/src/fetch.js +0 -116
  162. package/src/hijri-parser.d.ts +0 -19
  163. package/src/hijri-parser.js +0 -204
@@ -0,0 +1,1155 @@
1
+ import { Base } from './base';
2
+ import { Browser } from './browser';
3
+ import { isVisible } from './dom';
4
+ import { Property, Complex, NotifyPropertyChanges, INotifyPropertyChanged, Event } from './notify-property-change';
5
+ import { EventHandler } from './event-handler';
6
+ import { ChildProperty } from './child-property';
7
+ import { PositionModel, DraggableModel } from './draggable-model';
8
+ import { select, closest, setStyleAttribute, addClass, createElement } from './dom';
9
+ import { extend, isUndefined, isNullOrUndefined, compareElementParent, isBlazor } from './util';
10
+ const defaultPosition: PositionCoordinates = { left: 0, top: 0, bottom: 0, right: 0 };
11
+ const isDraggedObject: DragObject = { isDragged: false };
12
+
13
+ /**
14
+ * Specifies the Direction in which drag movement happen.
15
+ */
16
+ export type DragDirection = 'x' | 'y';
17
+
18
+ interface PositionCoordinates {
19
+ left?: number;
20
+ top?: number;
21
+ bottom?: number;
22
+ right?: number;
23
+ }
24
+
25
+ interface DragObject {
26
+ isDragged: boolean;
27
+ }
28
+ /**
29
+ * Specifies the position coordinates
30
+ */
31
+ export class Position extends ChildProperty<Position> {
32
+ /**
33
+ * Specifies the left position of cursor in draggable.
34
+ */
35
+ @Property(0)
36
+ public left: number;
37
+ /**
38
+ * Specifies the left position of cursor in draggable.
39
+ */
40
+ @Property(0)
41
+ public top: number;
42
+
43
+ }
44
+ interface PageInfo {
45
+ x: number;
46
+ y: number;
47
+ }
48
+ /**
49
+ * Coordinates for element position
50
+ *
51
+ * @private
52
+ */
53
+ export interface Coordinates {
54
+ /**
55
+ * Defines the x Coordinate of page.
56
+ */
57
+ pageX: number;
58
+ /**
59
+ * Defines the y Coordinate of page.
60
+ */
61
+ pageY: number;
62
+ /**
63
+ * Defines the x Coordinate of client.
64
+ */
65
+ clientX: number;
66
+ /**
67
+ * Defines the y Coordinate of client.
68
+ */
69
+ clientY: number;
70
+ }
71
+ /**
72
+ * Interface to specify the drag data in the droppable.
73
+ */
74
+ export interface DropInfo {
75
+ /**
76
+ * Specifies the current draggable element
77
+ */
78
+ draggable?: HTMLElement;
79
+ /**
80
+ * Specifies the current helper element.
81
+ */
82
+ helper?: HTMLElement;
83
+ /**
84
+ * Specifies the drag target element
85
+ */
86
+ draggedElement?: HTMLElement;
87
+ }
88
+
89
+ export interface DropObject {
90
+ target: HTMLElement;
91
+ instance: DropOption;
92
+ }
93
+
94
+ /**
95
+ * Used to access values
96
+ *
97
+ * @private
98
+ */
99
+ export interface DragPosition {
100
+ left?: string;
101
+ top?: string;
102
+ }
103
+
104
+ /**
105
+ * Used for accessing the interface.
106
+ *
107
+ * @private
108
+ */
109
+ export interface Instance extends HTMLElement {
110
+ /**
111
+ * Specifies current instance collection in element
112
+ */
113
+ // eslint-disable-next-line
114
+ ej2_instances: { [key: string]: Object }[];
115
+ }
116
+ /**
117
+ * Droppable function to be invoked from draggable
118
+ *
119
+ * @private
120
+ */
121
+ export interface DropOption {
122
+ /**
123
+ * Used to triggers over function while draggable element is over the droppable element.
124
+ */
125
+ intOver: Function;
126
+ /**
127
+ * Used to triggers out function while draggable element is out of the droppable element.
128
+ */
129
+ intOut: Function;
130
+ /**
131
+ * Used to triggers out function while draggable element is dropped on the droppable element.
132
+ */
133
+ intDrop: Function;
134
+ /**
135
+ * Specifies the information about the drag element.
136
+ */
137
+ dragData: DropInfo;
138
+ /**
139
+ * Specifies the status of the drag of drag stop calling.
140
+ */
141
+ dragStopCalled: boolean;
142
+ }
143
+ /**
144
+ * Drag Event arguments
145
+ */
146
+ export interface DragEventArgs {
147
+ /**
148
+ * Specifies the actual event.
149
+ */
150
+ event?: MouseEvent & TouchEvent;
151
+ /**
152
+ * Specifies the current drag element.
153
+ */
154
+ element?: HTMLElement;
155
+ /**
156
+ * Specifies the current target element.
157
+ */
158
+ target?: HTMLElement;
159
+ /**
160
+ * 'true' if the drag or drop action is to be prevented; otherwise false.
161
+ */
162
+ cancel?: boolean;
163
+ }
164
+
165
+ /**
166
+ * Used for accessing the BlazorEventArgs.
167
+ *
168
+ * @private
169
+ */
170
+ export interface BlazorDragEventArgs {
171
+ /**
172
+ * bind draggable element for Blazor Components
173
+ */
174
+ bindEvents: Function;
175
+ /**
176
+ * Draggable element to which draggable events are to be binded in Blazor.
177
+ */
178
+ dragElement: HTMLElement;
179
+ }
180
+
181
+ /**
182
+ * Draggable Module provides support to enable draggable functionality in Dom Elements.
183
+ * ```html
184
+ * <div id='drag'>Draggable</div>
185
+ * <script>
186
+ * var ele = document.getElementById('drag');
187
+ * var drag:Draggable = new Draggable(ele,{
188
+ * clone:false,
189
+ * drag: function(e) {
190
+ * //drag handler code.
191
+ * },
192
+ * handle:'.class'
193
+ * });
194
+ * </script>
195
+ * ```
196
+ */
197
+ @NotifyPropertyChanges
198
+ export class Draggable extends Base<HTMLElement> implements INotifyPropertyChanged {
199
+ /**
200
+ * Defines the distance between the cursor and the draggable element.
201
+ */
202
+ @Complex<PositionModel>({}, Position)
203
+ public cursorAt: PositionModel;
204
+ /**
205
+ * If `clone` set to true, drag operations are performed in duplicate element of the draggable element.
206
+ *
207
+ * @default true
208
+ */
209
+ @Property(true)
210
+ public clone: boolean;
211
+ /**
212
+ * Defines the parent element in which draggable element movement will be restricted.
213
+ */
214
+ @Property()
215
+ public dragArea: HTMLElement | string;
216
+ /**
217
+ * Defines the dragArea is scrollable or not.
218
+ */
219
+ @Property()
220
+ public isDragScroll: boolean;
221
+ /**
222
+ * Defines wheather need to replace drag element by currentstateTarget.
223
+ *
224
+ * @private
225
+ */
226
+ @Property()
227
+ public isReplaceDragEle: boolean;
228
+ /**
229
+ * Defines wheather need to add prevent select class to body or not.
230
+ *
231
+ * @private
232
+ */
233
+ @Property(true)
234
+ public isPreventSelect: boolean;
235
+ /**
236
+ * Specifies the callback function for drag event.
237
+ *
238
+ * @event drag
239
+ */
240
+ @Event()
241
+ public drag: Function;
242
+ /**
243
+ * Specifies the callback function for dragStart event.
244
+ *
245
+ * @event dragStart
246
+ */
247
+ @Event()
248
+ public dragStart: Function;
249
+ /**
250
+ * Specifies the callback function for dragStop event.
251
+ *
252
+ * @event dragStop
253
+ */
254
+ @Event()
255
+ public dragStop: Function;
256
+ /**
257
+ * Defines the minimum distance draggable element to be moved to trigger the drag operation.
258
+ *
259
+ * @default 1
260
+ */
261
+ @Property(1)
262
+ public distance: number;
263
+ /**
264
+ * Defines the child element selector which will act as drag handle.
265
+ */
266
+ @Property()
267
+ public handle: string;
268
+ /**
269
+ * Defines the child element selector which will prevent dragging of element.
270
+ */
271
+ @Property()
272
+ public abort: string | string[];
273
+ /**
274
+ * Defines the callback function for customizing the cloned element.
275
+ */
276
+ @Property()
277
+ public helper: Function;
278
+ /**
279
+ * Defines the scope value to group sets of draggable and droppable items.
280
+ * A draggable with the same scope value will be accepted by the droppable.
281
+ */
282
+ @Property('default')
283
+ public scope: string;
284
+ /**
285
+ * Specifies the dragTarget by which the clone element is positioned if not given current context element will be considered.
286
+ *
287
+ * @private
288
+ */
289
+ @Property('')
290
+ public dragTarget: string;
291
+ /**
292
+ * Defines the axis to limit the draggable element drag path.The possible axis path values are
293
+ * * `x` - Allows drag movement in horizontal direction only.
294
+ * * `y` - Allows drag movement in vertical direction only.
295
+ */
296
+ @Property()
297
+ public axis: DragDirection;
298
+ /**
299
+ * Defines the function to change the position value.
300
+ *
301
+ * @private
302
+ */
303
+ @Property()
304
+ public queryPositionInfo: Function;
305
+ /**
306
+ * Defines whether the drag clone element will be split form the cursor pointer.
307
+ *
308
+ * @private
309
+ */
310
+ @Property(false)
311
+ public enableTailMode: boolean;
312
+ /**
313
+ * Defines whether to skip the previous drag movement comparison.
314
+ *
315
+ * @private
316
+ */
317
+ @Property(false)
318
+ public skipDistanceCheck: boolean;
319
+ /**
320
+ * @private
321
+ */
322
+ @Property(true)
323
+ public preventDefault: boolean;
324
+ /**
325
+ * Defines whether to enable autoscroll on drag movement of draggable element.
326
+ * enableAutoScroll
327
+ *
328
+ * @private
329
+ */
330
+ @Property(false)
331
+ public enableAutoScroll: boolean;
332
+ /**
333
+ * Defines whether to enable taphold on mobile devices.
334
+ * enableAutoScroll
335
+ *
336
+ * @private
337
+ */
338
+ @Property(false)
339
+ public enableTapHold: boolean;
340
+ /**
341
+ * Specifies the time delay for tap hold.
342
+ *
343
+ * @default 750
344
+ * @private
345
+ */
346
+ @Property(750)
347
+ public tapHoldThreshold: number;
348
+ /**
349
+ * @private
350
+ */
351
+ @Property(false)
352
+ public enableScrollHandler: boolean;
353
+ private target: HTMLElement;
354
+ /**
355
+ * @private
356
+ */
357
+ public initialPosition: PageInfo;
358
+ private relativeXPosition: number;
359
+ private relativeYPosition: number;
360
+ private margin: PositionCoordinates;
361
+ private offset: PositionCoordinates;
362
+ private position: PositionCoordinates;
363
+ private dragLimit: PositionCoordinates = Draggable.getDefaultPosition();
364
+ private borderWidth: PositionCoordinates = Draggable.getDefaultPosition();
365
+ private padding: PositionCoordinates = Draggable.getDefaultPosition();
366
+ private left: number;
367
+ private top: number;
368
+ private width: number;
369
+ private height: number;
370
+ private pageX: number;
371
+ private diffX: number = 0;
372
+ private prevLeft: number = 0;
373
+ private prevTop: number = 0;
374
+ private dragProcessStarted: boolean = false;
375
+ private eleTop: number = 0;
376
+ /* eslint-disable @typescript-eslint/no-explicit-any */
377
+ private tapHoldTimer: any = 0;
378
+ private dragElePosition: any;
379
+ public currentStateTarget: any;
380
+ private externalInitialize: boolean = false;
381
+ private diffY: number = 0;
382
+ private pageY: number;
383
+ private helperElement: HTMLElement;
384
+ private hoverObject: DropObject;
385
+ private parentClientRect: PositionModel;
386
+ private parentScrollX: number = 0;
387
+ private parentScrollY: number = 0;
388
+ private tempScrollHeight: number;
389
+ private tempScrollWidth: number;
390
+ public droppables: { [key: string]: DropInfo } = {};
391
+ constructor(element: HTMLElement, options?: DraggableModel) {
392
+ super(options, element);
393
+ this.bind();
394
+ }
395
+ protected bind(): void {
396
+ this.toggleEvents();
397
+ if (Browser.isIE) {
398
+ addClass([this.element], 'e-block-touch');
399
+ }
400
+ this.droppables[this.scope] = {};
401
+ }
402
+ private static getDefaultPosition(): PositionCoordinates {
403
+ return extend({}, defaultPosition);
404
+ }
405
+ private toggleEvents(isUnWire?: boolean): void {
406
+ let ele: Element;
407
+ if (!isUndefined(this.handle)) {
408
+ ele = select(this.handle, this.element);
409
+ }
410
+ const handler: Function = (this.enableTapHold && Browser.isDevice && Browser.isTouch) ? this.mobileInitialize : this.initialize;
411
+ if (isUnWire) {
412
+ EventHandler.remove(ele || this.element, Browser.isSafari() ? 'touchstart' : Browser.touchStartEvent, handler);
413
+ } else {
414
+ EventHandler.add(ele || this.element, Browser.isSafari() ? 'touchstart' : Browser.touchStartEvent, handler, this);
415
+ }
416
+ }
417
+ /* istanbul ignore next */
418
+ private mobileInitialize(evt: MouseEvent & TouchEvent): void {
419
+ const target: EventTarget = evt.currentTarget;
420
+ this.tapHoldTimer = setTimeout(
421
+ () => {
422
+ this.externalInitialize = true;
423
+ this.removeTapholdTimer();
424
+ this.initialize(evt, target);
425
+ },
426
+ this.tapHoldThreshold);
427
+ EventHandler.add(document, Browser.isSafari() ? 'touchmove' : Browser.touchMoveEvent, this.removeTapholdTimer, this);
428
+ EventHandler.add(document, Browser.isSafari() ? 'touchend' : Browser.touchEndEvent, this.removeTapholdTimer, this);
429
+ }
430
+ /* istanbul ignore next */
431
+ private removeTapholdTimer(): void {
432
+ clearTimeout(this.tapHoldTimer);
433
+ EventHandler.remove(document, Browser.isSafari() ? 'touchmove' : Browser.touchMoveEvent, this.removeTapholdTimer);
434
+ EventHandler.remove(document, Browser.isSafari() ? 'touchend' : Browser.touchEndEvent, this.removeTapholdTimer);
435
+ }
436
+ /* istanbul ignore next */
437
+ private getScrollableParent(element: HTMLElement, axis: string): HTMLElement {
438
+ const scroll: Object = { 'vertical': 'scrollHeight', 'horizontal': 'scrollWidth' };
439
+ const client: Object = { 'vertical': 'clientHeight', 'horizontal': 'clientWidth' };
440
+ if (isNullOrUndefined(element)) {
441
+ return null;
442
+ }
443
+ if (element[scroll[`${axis}`]] > element[client[`${axis}`]]) {
444
+ if (axis === 'vertical' ? element.scrollTop > 0 : element.scrollLeft > 0) {
445
+ if (axis === 'vertical') {
446
+ this.parentScrollY = this.parentScrollY +
447
+ (this.parentScrollY === 0 ? element.scrollTop : element.scrollTop - this.parentScrollY);
448
+ this.tempScrollHeight = element.scrollHeight;
449
+ } else {
450
+ this.parentScrollX = this.parentScrollX +
451
+ (this.parentScrollX === 0 ? element.scrollLeft : element.scrollLeft - this.parentScrollX);
452
+ this.tempScrollWidth = element.scrollWidth;
453
+ }
454
+ if (!isNullOrUndefined(element)) {
455
+ return this.getScrollableParent(element.parentNode as HTMLElement, axis);
456
+ } else {
457
+ return element;
458
+ }
459
+ } else {
460
+ return this.getScrollableParent(element.parentNode as HTMLElement, axis);
461
+ }
462
+ } else {
463
+ return this.getScrollableParent(element.parentNode as HTMLElement, axis);
464
+ }
465
+ }
466
+ /* eslint-disable */
467
+ private getScrollableValues(): void {
468
+ this.parentScrollX = 0;
469
+ this.parentScrollY = 0;
470
+ const isModalDialog: boolean = this.element.classList.contains('e-dialog') && this.element.classList.contains('e-dlg-modal');
471
+ const verticalScrollParent: HTMLElement = this.getScrollableParent(this.element.parentNode as HTMLElement, 'vertical');
472
+ const horizontalScrollParent: HTMLElement = this.getScrollableParent(this.element.parentNode as HTMLElement, 'horizontal');
473
+ }
474
+ /* eslint-enable */
475
+ private initialize(evt: MouseEvent & TouchEvent, curTarget?: EventTarget): void {
476
+ this.currentStateTarget = evt.target;
477
+ if (this.isDragStarted()) {
478
+ return;
479
+ } else {
480
+ this.isDragStarted(true);
481
+ this.externalInitialize = false;
482
+ }
483
+ this.target = <HTMLElement>(evt.currentTarget || curTarget);
484
+ this.dragProcessStarted = false;
485
+ if (this.abort) {
486
+ /* tslint:disable no-any */
487
+ // eslint-disable-next-line
488
+ let abortSelectors: any = this.abort;
489
+ if (typeof abortSelectors === 'string') {
490
+ abortSelectors = [abortSelectors];
491
+ }
492
+ for (let i: number = 0; i < abortSelectors.length; i++) {
493
+ if (!isNullOrUndefined(closest((evt.target as Element), abortSelectors[parseInt(i.toString(), 10)]))) {
494
+ /* istanbul ignore next */
495
+ if (this.isDragStarted()) {
496
+ this.isDragStarted(true);
497
+ }
498
+ return;
499
+ }
500
+ }
501
+ }
502
+ if (this.preventDefault && !isUndefined(evt.changedTouches) && evt.type !== 'touchstart') {
503
+ evt.preventDefault();
504
+ }
505
+ this.element.setAttribute('aria-grabbed', 'true');
506
+ const intCoord: Coordinates = this.getCoordinates(evt);
507
+ this.initialPosition = { x: intCoord.pageX, y: intCoord.pageY };
508
+ if (!this.clone) {
509
+ const pos: PositionModel = this.element.getBoundingClientRect();
510
+ this.getScrollableValues();
511
+ if (evt.clientX === evt.pageX) { this.parentScrollX = 0; }
512
+ if (evt.clientY === evt.pageY) { this.parentScrollY = 0; }
513
+ this.relativeXPosition = intCoord.pageX - (pos.left + this.parentScrollX);
514
+ this.relativeYPosition = intCoord.pageY - (pos.top + this.parentScrollY);
515
+ }
516
+ if (this.externalInitialize) {
517
+ this.intDragStart(evt);
518
+ } else {
519
+ EventHandler.add(document, Browser.isSafari() ? 'touchmove' : Browser.touchMoveEvent, this.intDragStart, this);
520
+ EventHandler.add(document, Browser.isSafari() ? 'touchend' : Browser.touchEndEvent, this.intDestroy, this);
521
+ }
522
+ this.toggleEvents(true);
523
+ if (evt.type !== 'touchstart' && this.isPreventSelect) {
524
+ document.body.classList.add('e-prevent-select');
525
+ }
526
+ this.externalInitialize = false;
527
+ EventHandler.trigger(document.documentElement, Browser.isSafari() ? 'touchstart' : Browser.touchStartEvent, evt);
528
+ }
529
+ private intDragStart(evt: MouseEvent & TouchEvent): void {
530
+ this.removeTapholdTimer();
531
+ const isChangeTouch: boolean = !isUndefined(evt.changedTouches);
532
+ if (isChangeTouch && (evt.changedTouches.length !== 1)) {
533
+ return;
534
+ }
535
+ const intCordinate: Coordinates = this.getCoordinates(evt);
536
+ let pos: PositionModel;
537
+ const styleProp: CSSStyleDeclaration = getComputedStyle(this.element);
538
+ this.margin = {
539
+ left: parseInt(styleProp.marginLeft, 10),
540
+ top: parseInt(styleProp.marginTop, 10),
541
+ right: parseInt(styleProp.marginRight, 10),
542
+ bottom: parseInt(styleProp.marginBottom, 10)
543
+ };
544
+ let element: HTMLElement = this.element;
545
+ if (this.clone && this.dragTarget) {
546
+ const intClosest: HTMLElement = <HTMLElement>closest(evt.target as Element, this.dragTarget);
547
+ if (!isNullOrUndefined(intClosest)) {
548
+ element = intClosest;
549
+ }
550
+ }
551
+ /* istanbul ignore next */
552
+ if (this.isReplaceDragEle) {
553
+ // eslint-disable-next-line
554
+ element = this.currentStateCheck(evt.target as any, element);
555
+ }
556
+ this.offset = this.calculateParentPosition(element);
557
+ this.position = this.getMousePosition(evt, this.isDragScroll);
558
+ const x: number = this.initialPosition.x - intCordinate.pageX;
559
+ const y: number = this.initialPosition.y - intCordinate.pageY;
560
+ const distance: number = Math.sqrt((x * x) + (y * y));
561
+ if ((distance >= this.distance || this.externalInitialize)) {
562
+ const ele: HTMLElement = this.getHelperElement(evt);
563
+ if (!ele || isNullOrUndefined(ele)) {
564
+ return;
565
+ }
566
+ if (isChangeTouch) {
567
+ evt.preventDefault();
568
+ }
569
+ const dragTargetElement: HTMLElement = this.helperElement = ele;
570
+ this.parentClientRect = this.calculateParentPosition(dragTargetElement.offsetParent);
571
+ if (this.dragStart) {
572
+ const curTarget: Element = this.getProperTargetElement(evt);
573
+ const args: { [key: string]: object } = {
574
+ event: evt,
575
+ element: element,
576
+ target: curTarget,
577
+ bindEvents: isBlazor() ? this.bindDragEvents.bind(this) : null,
578
+ dragElement: dragTargetElement
579
+ };
580
+ this.trigger('dragStart', args);
581
+ }
582
+ if (this.dragArea) {
583
+ this.setDragArea();
584
+ } else {
585
+ this.dragLimit = { left: 0, right: 0, bottom: 0, top: 0 };
586
+ this.borderWidth = { top: 0, left: 0 };
587
+ }
588
+ pos = { left: this.position.left - this.parentClientRect.left, top: this.position.top - this.parentClientRect.top };
589
+ if (this.clone && !this.enableTailMode) {
590
+ this.diffX = this.position.left - this.offset.left;
591
+ this.diffY = this.position.top - this.offset.top;
592
+ }
593
+ this.getScrollableValues();
594
+ // when drag element has margin-top
595
+ const styles: CSSStyleDeclaration = getComputedStyle(element);
596
+ const marginTop: number = parseFloat(styles.marginTop);
597
+ /* istanbul ignore next */
598
+ if (this.clone && marginTop !== 0) {
599
+ pos.top += marginTop;
600
+ }
601
+ this.eleTop = !isNaN(parseFloat(styles.top)) ? parseFloat(styles.top) - this.offset.top : 0;
602
+ /* istanbul ignore next */
603
+ // if (this.eleTop > 0) {
604
+ // pos.top += this.eleTop;
605
+ // }
606
+ if (this.enableScrollHandler && !this.clone) {
607
+ pos.top -= this.parentScrollY;
608
+ pos.left -= this.parentScrollX;
609
+ }
610
+ const posValue: DragPosition = this.getProcessedPositionValue({
611
+ top: (pos.top - this.diffY) + 'px',
612
+ left: (pos.left - this.diffX) + 'px'
613
+ });
614
+ if (this.dragArea && typeof this.dragArea !== 'string' && this.dragArea.classList.contains('e-kanban-content') && this.dragArea.style.position === 'relative') {
615
+ pos.top += this.dragArea.scrollTop;
616
+ }
617
+ this.dragElePosition = { top: pos.top, left: pos.left };
618
+ setStyleAttribute(dragTargetElement, this.getDragPosition({ position: 'absolute', left: posValue.left, top: posValue.top }));
619
+ EventHandler.remove(document, Browser.isSafari() ? 'touchmove' : Browser.touchMoveEvent, this.intDragStart);
620
+ EventHandler.remove(document, Browser.isSafari() ? 'touchend' : Browser.touchEndEvent, this.intDestroy);
621
+ if (!isBlazor()) {
622
+ this.bindDragEvents(dragTargetElement);
623
+ }
624
+ }
625
+ }
626
+
627
+ private bindDragEvents(dragTargetElement: HTMLElement): void {
628
+ if (isVisible(dragTargetElement)) {
629
+ EventHandler.add(document, Browser.isSafari() ? 'touchmove' : Browser.touchMoveEvent, this.intDrag, this);
630
+ EventHandler.add(document, Browser.isSafari() ? 'touchend' : Browser.touchEndEvent, this.intDragStop, this);
631
+ this.setGlobalDroppables(false, this.element, dragTargetElement);
632
+ } else {
633
+ this.toggleEvents();
634
+ document.body.classList.remove('e-prevent-select');
635
+ }
636
+ }
637
+
638
+ private elementInViewport(el: HTMLElement): boolean {
639
+ this.top = el.offsetTop;
640
+ this.left = el.offsetLeft;
641
+ this.width = el.offsetWidth;
642
+ this.height = el.offsetHeight;
643
+
644
+ while (el.offsetParent) {
645
+ el = <HTMLElement>el.offsetParent;
646
+ this.top += el.offsetTop;
647
+ this.left += el.offsetLeft;
648
+ }
649
+
650
+ return (
651
+ this.top >= window.pageYOffset &&
652
+ this.left >= window.pageXOffset &&
653
+ (this.top + this.height) <= (window.pageYOffset + window.innerHeight) &&
654
+ (this.left + this.width) <= (window.pageXOffset + window.innerWidth)
655
+ );
656
+ }
657
+
658
+ private getProcessedPositionValue(value: DragPosition): DragPosition {
659
+ if (this.queryPositionInfo) {
660
+ return this.queryPositionInfo(value);
661
+ }
662
+ return value;
663
+ }
664
+
665
+ private calculateParentPosition(ele: Element): PositionModel {
666
+ if (isNullOrUndefined(ele)) {
667
+ return { left: 0, top: 0 };
668
+ }
669
+ const rect: ClientRect = ele.getBoundingClientRect();
670
+ const style: CSSStyleDeclaration = getComputedStyle(ele);
671
+ return {
672
+ left: (rect.left + window.pageXOffset) - parseInt(style.marginLeft, 10),
673
+ top: (rect.top + window.pageYOffset) - parseInt(style.marginTop, 10)
674
+ };
675
+ }
676
+ // tslint:disable-next-line:max-func-body-length
677
+ private intDrag(evt: MouseEvent & TouchEvent): void {
678
+ if (!isUndefined(evt.changedTouches) && (evt.changedTouches.length !== 1)) {
679
+ return;
680
+ }
681
+ if (this.clone && evt.changedTouches && Browser.isDevice && Browser.isTouch) {
682
+ evt.preventDefault();
683
+ }
684
+ let left: number;
685
+ let top: number;
686
+ this.position = this.getMousePosition(evt, this.isDragScroll);
687
+ const docHeight: number = this.getDocumentWidthHeight('Height');
688
+ if (docHeight < this.position.top) {
689
+ this.position.top = docHeight;
690
+ }
691
+ const docWidth: number = this.getDocumentWidthHeight('Width');
692
+ if (docWidth < this.position.left) {
693
+ this.position.left = docWidth;
694
+ }
695
+ if (this.drag) {
696
+ const curTarget: HTMLElement = this.getProperTargetElement(evt);
697
+ this.trigger('drag', { event: evt, element: this.element, target: curTarget });
698
+ }
699
+ const eleObj: DropObject = this.checkTargetElement(evt);
700
+ if (eleObj.target && eleObj.instance) {
701
+ /* tslint:disable no-any */
702
+ let flag: boolean = true;
703
+ if (this.hoverObject) {
704
+ if (this.hoverObject.instance !== eleObj.instance) {
705
+ this.triggerOutFunction(evt, eleObj);
706
+ } else {
707
+ flag = false;
708
+ }
709
+ }
710
+ if (flag) {
711
+ // eslint-disable-next-line
712
+ (<any>eleObj).instance.dragData[this.scope] = this.droppables[this.scope];
713
+ eleObj.instance.intOver(evt, eleObj.target);
714
+ this.hoverObject = eleObj;
715
+ }
716
+ } else if (this.hoverObject) {
717
+ this.triggerOutFunction(evt, eleObj);
718
+ }
719
+ const helperElement: HTMLElement = this.droppables[this.scope].helper;
720
+ this.parentClientRect = this.calculateParentPosition(this.helperElement.offsetParent);
721
+ const tLeft: number = this.parentClientRect.left;
722
+ const tTop: number = this.parentClientRect.top;
723
+ const intCoord: Coordinates = this.getCoordinates(evt);
724
+ const pagex: number = intCoord.pageX;
725
+ const pagey: number = intCoord.pageY;
726
+ const dLeft: number = this.position.left - this.diffX;
727
+ const dTop: number = this.position.top - this.diffY;
728
+ const styles: CSSStyleDeclaration = getComputedStyle(helperElement);
729
+ if (this.dragArea) {
730
+ if (this.enableAutoScroll) {
731
+ this.setDragArea();
732
+ }
733
+ if (this.pageX !== pagex || this.skipDistanceCheck) {
734
+ const helperWidth: number = helperElement.offsetWidth + (parseFloat(styles.marginLeft)
735
+ + parseFloat(styles.marginRight));
736
+ if (this.dragLimit.left > dLeft && dLeft > 0) {
737
+ left = this.dragLimit.left;
738
+ } else if (this.dragLimit.right + window.pageXOffset < dLeft + helperWidth && dLeft > 0) {
739
+ left = dLeft - (dLeft - this.dragLimit.right) + window.pageXOffset - helperWidth;
740
+ } else {
741
+ left = dLeft < 0 ? this.dragLimit.left : dLeft;
742
+ }
743
+ }
744
+ if (this.pageY !== pagey || this.skipDistanceCheck) {
745
+ const helperHeight: number = helperElement.offsetHeight + (parseFloat(styles.marginTop)
746
+ + parseFloat(styles.marginBottom));
747
+ if (this.dragLimit.top > dTop && dTop > 0) {
748
+ top = this.dragLimit.top;
749
+ } else if (this.dragLimit.bottom + window.pageYOffset < dTop + helperHeight && dTop > 0) {
750
+ top = dTop - (dTop - this.dragLimit.bottom) + window.pageYOffset - helperHeight;
751
+ } else {
752
+ top = dTop < 0 ? this.dragLimit.top : dTop;
753
+ }
754
+ }
755
+ } else {
756
+ left = dLeft;
757
+ top = dTop;
758
+ }
759
+ const iTop: number = tTop + this.borderWidth.top;
760
+ const iLeft: number = tLeft + this.borderWidth.left;
761
+ if (this.dragProcessStarted) {
762
+ if (isNullOrUndefined(top)) {
763
+ top = this.prevTop;
764
+ }
765
+ if (isNullOrUndefined(left)) {
766
+ left = this.prevLeft;
767
+ }
768
+ }
769
+ let draEleTop: number;
770
+ let draEleLeft: number;
771
+ if (this.helperElement.classList.contains('e-treeview')){
772
+ if (this.dragArea) {
773
+ this.dragLimit.top = this.clone ? this.dragLimit.top : 0;
774
+ draEleTop = (top - iTop) < 0 ? this.dragLimit.top : (top - this.borderWidth.top);
775
+ draEleLeft = (left - iLeft) < 0 ? this.dragLimit.left : (left - this.borderWidth.left);
776
+ } else {
777
+ draEleTop = top - this.borderWidth.top;
778
+ draEleLeft = left - this.borderWidth.left;
779
+ }
780
+ } else {
781
+ if (this.dragArea) {
782
+ const isDialogEle: boolean = this.helperElement.classList.contains('e-dialog');
783
+ this.dragLimit.top = this.clone ? this.dragLimit.top : 0;
784
+ draEleTop = (top - iTop) < 0 ? this.dragLimit.top : (top - iTop);
785
+ draEleLeft = (left - iLeft) < 0 ? isDialogEle ? (left - (iLeft - this.borderWidth.left)) :
786
+ this.dragElePosition.left : (left - iLeft);
787
+ } else {
788
+ draEleTop = top - iTop;
789
+ draEleLeft = left - iLeft;
790
+ }
791
+ }
792
+ const marginTop: number = parseFloat(getComputedStyle(this.element).marginTop);
793
+ // when drag-element has margin-top
794
+ /* istanbul ignore next */
795
+ if (marginTop > 0) {
796
+ if (this.clone) {
797
+ draEleTop += marginTop;
798
+ if (dTop < 0) {
799
+ if ((marginTop + dTop) >= 0) {
800
+ draEleTop = marginTop + dTop;
801
+ } else {
802
+ draEleTop -= marginTop;
803
+ }
804
+ }
805
+ if (this.dragArea) {
806
+ draEleTop = (this.dragLimit.bottom < draEleTop) ? this.dragLimit.bottom : draEleTop;
807
+ }
808
+ }
809
+ if ((top - iTop) < 0) {
810
+ if (dTop + marginTop + (helperElement.offsetHeight - iTop) >= 0) {
811
+ const tempDraEleTop: number = this.dragLimit.top + dTop - iTop;
812
+ if ((tempDraEleTop + marginTop + iTop) < 0) {
813
+ draEleTop -= marginTop + iTop;
814
+ } else {
815
+ draEleTop = tempDraEleTop;
816
+ }
817
+ } else {
818
+ draEleTop -= marginTop + iTop;
819
+ }
820
+ }
821
+ }
822
+
823
+ if (this.dragArea && this.helperElement.classList.contains('e-treeview')) {
824
+ const helperHeight: number = helperElement.offsetHeight + (parseFloat(styles.marginTop)
825
+ + parseFloat(styles.marginBottom));
826
+ draEleTop = (draEleTop + helperHeight) > this.dragLimit.bottom ? (this.dragLimit.bottom - helperHeight) : draEleTop;
827
+ }
828
+ /* istanbul ignore next */
829
+ // if(this.eleTop > 0) {
830
+ // draEleTop += this.eleTop;
831
+ // }
832
+ if (this.enableScrollHandler && !this.clone) {
833
+ draEleTop -= this.parentScrollY;
834
+ draEleLeft -= this.parentScrollX;
835
+ }
836
+ if (this.dragArea && typeof this.dragArea !== 'string' && this.dragArea.classList.contains('e-kanban-content') && this.dragArea.style.position === 'relative') {
837
+ draEleTop += this.dragArea.scrollTop;
838
+ }
839
+ const dragValue: DragPosition = this.getProcessedPositionValue({ top: draEleTop + 'px', left: draEleLeft + 'px' });
840
+ setStyleAttribute(helperElement, this.getDragPosition(dragValue));
841
+ if (!this.elementInViewport(helperElement) && this.enableAutoScroll && !this.helperElement.classList.contains('e-treeview')) {
842
+ this.helperElement.scrollIntoView();
843
+ }
844
+
845
+ let elements: NodeList | Element[] = document.querySelectorAll(':hover');
846
+ if (this.enableAutoScroll && this.helperElement.classList.contains('e-treeview')) {
847
+ if (elements.length === 0) {
848
+ elements = this.getPathElements(evt);
849
+ }
850
+ /* tslint:disable no-any */
851
+ // eslint-disable-next-line
852
+ let scrollParent: any = this.getScrollParent(elements, false);
853
+ if (this.elementInViewport(this.helperElement)) {
854
+ this.getScrollPosition(scrollParent, draEleTop);
855
+ }
856
+ else if (!this.elementInViewport(this.helperElement)) {
857
+ elements = [].slice.call(document.querySelectorAll(':hover'));
858
+ if (elements.length === 0) {
859
+ elements = this.getPathElements(evt);
860
+ }
861
+ scrollParent = this.getScrollParent(elements, true);
862
+ this.getScrollPosition(scrollParent, draEleTop);
863
+ }
864
+ }
865
+
866
+ this.dragProcessStarted = true;
867
+ this.prevLeft = left;
868
+ this.prevTop = top;
869
+ this.position.left = left;
870
+ this.position.top = top;
871
+ this.pageX = pagex;
872
+ this.pageY = pagey;
873
+ }
874
+ /* tslint:disable no-any */
875
+ // eslint-disable-next-line
876
+ private getScrollParent(node: any, reverse: boolean): any {
877
+ /* tslint:disable no-any */
878
+ // eslint-disable-next-line
879
+ const nodeEl: any = reverse ? node.reverse() : node;
880
+ let hasScroll: string;
881
+ for (let i: number = nodeEl.length - 1; i >= 0; i--) {
882
+ hasScroll = window.getComputedStyle(nodeEl[parseInt(i.toString(), 10)])['overflow-y'];
883
+ if ((hasScroll === 'auto' || hasScroll === 'scroll')
884
+ && nodeEl[parseInt(i.toString(), 10)].scrollHeight > nodeEl[parseInt(i.toString(), 10)].clientHeight) {
885
+ return nodeEl[parseInt(i.toString(), 10)];
886
+ }
887
+ }
888
+ hasScroll = window.getComputedStyle(document.scrollingElement)['overflow-y'];
889
+ if (hasScroll === 'visible') {
890
+ (document.scrollingElement as HTMLElement).style.overflow = 'auto';
891
+ return document.scrollingElement;
892
+ }
893
+ }
894
+ private getScrollPosition(nodeEle: HTMLElement, draEleTop: number): void {
895
+ if (nodeEle && nodeEle === document.scrollingElement) {
896
+ if ((nodeEle.clientHeight + document.scrollingElement.scrollTop - this.helperElement.clientHeight) < draEleTop
897
+ && nodeEle.getBoundingClientRect().height + this.parentClientRect.top > draEleTop) {
898
+ nodeEle.scrollTop += this.helperElement.clientHeight;
899
+ }else if (nodeEle.scrollTop > draEleTop - this.helperElement.clientHeight) {
900
+ nodeEle.scrollTop -= this.helperElement.clientHeight;
901
+ }
902
+ }else if (nodeEle && nodeEle !== document.scrollingElement) {
903
+ const docScrollTop: number = document.scrollingElement.scrollTop;
904
+ const helperClientHeight: number = this.helperElement.clientHeight;
905
+ if ((nodeEle.clientHeight + nodeEle.getBoundingClientRect().top - helperClientHeight + docScrollTop ) < draEleTop) {
906
+ nodeEle.scrollTop += this.helperElement.clientHeight;
907
+ } else if (nodeEle.getBoundingClientRect().top > (draEleTop - helperClientHeight - docScrollTop )) {
908
+ nodeEle.scrollTop -= this.helperElement.clientHeight;
909
+ }
910
+ }
911
+ }
912
+ private getPathElements(evt: MouseEvent & TouchEvent): Element[] {
913
+ const elementTop: number = evt.clientX > 0 ? evt.clientX : 0;
914
+ const elementLeft: number = evt.clientY > 0 ? evt.clientY : 0;
915
+ return document.elementsFromPoint(elementTop, elementLeft);
916
+ }
917
+ private triggerOutFunction(evt: MouseEvent & TouchEvent, eleObj: DropObject): void {
918
+ this.hoverObject.instance.intOut(evt, eleObj.target);
919
+ this.hoverObject.instance.dragData[this.scope] = null;
920
+ this.hoverObject = null;
921
+ }
922
+ private getDragPosition(dragValue: DragPosition & { position?: string }): {
923
+ [key: string]: Object;
924
+ } {
925
+ const temp: {
926
+ [key: string]: Object;
927
+ } = extend({}, dragValue) as {
928
+ [key: string]: Object;
929
+ };
930
+ if (this.axis) {
931
+ if (this.axis === 'x') {
932
+ delete temp.top;
933
+ } else if (this.axis === 'y') {
934
+ delete temp.left;
935
+ }
936
+ }
937
+ return temp;
938
+ }
939
+ private getDocumentWidthHeight(str: string): number {
940
+ const docBody: HTMLElement | null = document.body;
941
+ const docEle: HTMLElement | null = document.documentElement;
942
+ const returnValue: number = Math.max(
943
+ docBody['scroll' + str], docEle['scroll' + str],
944
+ docBody['offset' + str], docEle['offset' + str], docEle['client' + str]);
945
+ return returnValue;
946
+ }
947
+ private intDragStop(evt: MouseEvent & TouchEvent): void {
948
+ this.dragProcessStarted = false;
949
+ if (!isUndefined(evt.changedTouches) && (evt.changedTouches.length !== 1)) {
950
+ return;
951
+ }
952
+ const type: string[] = ['touchend', 'pointerup', 'mouseup'];
953
+ if (type.indexOf(evt.type) !== -1) {
954
+ if (this.dragStop) {
955
+ const curTarget: Element = this.getProperTargetElement(evt);
956
+ this.trigger('dragStop', { event: evt, element: this.element, target: curTarget, helper: this.helperElement });
957
+ }
958
+ this.intDestroy(evt);
959
+ } else {
960
+ this.element.setAttribute('aria-grabbed', 'false');
961
+ }
962
+ const eleObj: DropObject = this.checkTargetElement(evt);
963
+ if (eleObj.target && eleObj.instance) {
964
+ eleObj.instance.dragStopCalled = true;
965
+ // eslint-disable-next-line
966
+ (<any>eleObj).instance.dragData[this.scope] = this.droppables[this.scope];
967
+ eleObj.instance.intDrop(evt, eleObj.target);
968
+ }
969
+ this.setGlobalDroppables(true);
970
+ document.body.classList.remove('e-prevent-select');
971
+ }
972
+ /**
973
+ * @param {MouseEvent | TouchEvent} evt ?
974
+ * @returns {void}
975
+ * @private
976
+ */
977
+ // eslint-disable-next-line
978
+ public intDestroy(evt: MouseEvent & TouchEvent): void {
979
+ this.dragProcessStarted = false;
980
+ this.toggleEvents();
981
+ document.body.classList.remove('e-prevent-select');
982
+ this.element.setAttribute('aria-grabbed', 'false');
983
+ EventHandler.remove(document, Browser.isSafari() ? 'touchmove' : Browser.touchMoveEvent, this.intDragStart);
984
+ EventHandler.remove(document, Browser.isSafari() ? 'touchend' : Browser.touchEndEvent, this.intDragStop);
985
+ EventHandler.remove(document, Browser.isSafari() ? 'touchend' : Browser.touchEndEvent, this.intDestroy);
986
+ EventHandler.remove(document, Browser.isSafari() ? 'touchmove' : Browser.touchMoveEvent, this.intDrag);
987
+ if (this.isDragStarted()) {
988
+ this.isDragStarted(true);
989
+ }
990
+ }
991
+ // triggers when property changed
992
+ // eslint-disable-next-line
993
+ public onPropertyChanged(newProp: DraggableModel, oldProp: DraggableModel): void {
994
+ //No Code to handle
995
+ }
996
+ public getModuleName(): string {
997
+ return 'draggable';
998
+ }
999
+
1000
+ private isDragStarted(change?: boolean): boolean {
1001
+ if (change) { isDraggedObject.isDragged = !isDraggedObject.isDragged; }
1002
+ return isDraggedObject.isDragged;
1003
+ }
1004
+
1005
+ private setDragArea(): void {
1006
+ let eleWidthBound: number;
1007
+ let eleHeightBound: number;
1008
+ let top: number = 0;
1009
+ let left: number = 0;
1010
+ let ele: HTMLElement;
1011
+ const type: string = typeof this.dragArea;
1012
+ if (type === 'string') {
1013
+ ele = <HTMLElement>select(<string>this.dragArea);
1014
+ } else {
1015
+ ele = <HTMLElement>this.dragArea;
1016
+ }
1017
+ if (ele) {
1018
+ const elementArea: ClientRect = ele.getBoundingClientRect();
1019
+ eleWidthBound = ele.scrollWidth ? ele.scrollWidth : elementArea.right - elementArea.left;
1020
+ eleHeightBound = ele.scrollHeight ? (this.dragArea && !isNullOrUndefined(this.helperElement) && this.helperElement.classList.contains('e-treeview')) ? ele.clientHeight : ele.scrollHeight : elementArea.bottom - elementArea.top;
1021
+ const keys: string[] = ['Top', 'Left', 'Bottom', 'Right'];
1022
+ /* eslint-disable */
1023
+ const styles: any = getComputedStyle(ele);
1024
+ for (let i: number = 0; i < keys.length; i++) {
1025
+ const key: string = keys[parseInt(i.toString(), 10)];
1026
+ const tborder: string = styles['border' + key + 'Width'];
1027
+ const tpadding: string = styles['padding' + key];
1028
+ const lowerKey: string = key.toLowerCase();
1029
+ (<any>this.borderWidth)[`${lowerKey}`] = isNaN(parseFloat(tborder)) ? 0 : parseFloat(tborder);
1030
+ (<any>this.padding)[`${lowerKey}`] = isNaN(parseFloat(tpadding)) ? 0 : parseFloat(tpadding);
1031
+ }
1032
+ /* eslint-enable */
1033
+ if (this.dragArea && !isNullOrUndefined(this.helperElement) && this.helperElement.classList.contains('e-treeview')) {
1034
+ top = elementArea.top + document.scrollingElement.scrollTop;
1035
+ } else {
1036
+ top = elementArea.top;
1037
+ }
1038
+ left = elementArea.left;
1039
+ this.dragLimit.left = left + this.borderWidth.left + this.padding.left;
1040
+ this.dragLimit.top = ele.offsetTop + this.borderWidth.top + this.padding.top;
1041
+ this.dragLimit.right = left + eleWidthBound - (this.borderWidth.right + this.padding.right);
1042
+ this.dragLimit.bottom = top + eleHeightBound - (this.borderWidth.bottom + this.padding.bottom);
1043
+ }
1044
+ }
1045
+ private getProperTargetElement(evt: MouseEvent & TouchEvent): HTMLElement {
1046
+ const intCoord: Coordinates = this.getCoordinates(evt);
1047
+ let ele: HTMLElement;
1048
+ const prevStyle: string = this.helperElement.style.pointerEvents || '';
1049
+ const isPointer: boolean = evt.type.indexOf('pointer') !== -1 && Browser.info.name === 'safari' && parseInt(Browser.info.version, 10) > 12 ;
1050
+ if (compareElementParent(evt.target as Element, this.helperElement) || evt.type.indexOf('touch') !== -1 || isPointer) {
1051
+ this.helperElement.style.pointerEvents = 'none';
1052
+ ele = <HTMLElement>document.elementFromPoint(intCoord.clientX, intCoord.clientY);
1053
+ this.helperElement.style.pointerEvents = prevStyle;
1054
+ } else {
1055
+ ele = <HTMLElement>evt.target;
1056
+ }
1057
+ return ele;
1058
+ }
1059
+ /* istanbul ignore next */
1060
+ private currentStateCheck(ele: HTMLElement, oldEle?: HTMLElement): HTMLElement {
1061
+ let elem: HTMLElement;
1062
+ if (!isNullOrUndefined(this.currentStateTarget) && this.currentStateTarget !== ele) {
1063
+ elem = this.currentStateTarget;
1064
+ } else {
1065
+ elem = !isNullOrUndefined(oldEle) ? oldEle : ele;
1066
+ }
1067
+ return elem;
1068
+ }
1069
+ private getMousePosition(evt: MouseEvent & TouchEvent, isdragscroll?: boolean): PositionModel {
1070
+ /* tslint:disable no-any */
1071
+ // eslint-disable-next-line
1072
+ const dragEle: any = evt.srcElement !== undefined ? evt.srcElement : evt.target;
1073
+ const intCoord: Coordinates = this.getCoordinates(evt);
1074
+ let pageX: number;
1075
+ let pageY: number;
1076
+ const isOffsetParent: boolean = isNullOrUndefined(dragEle.offsetParent);
1077
+ /* istanbul ignore next */
1078
+ if (isdragscroll) {
1079
+ pageX = this.clone ? intCoord.pageX :
1080
+ (intCoord.pageX + (isOffsetParent ? 0 : dragEle.offsetParent.scrollLeft)) - this.relativeXPosition;
1081
+ pageY = this.clone ? intCoord.pageY :
1082
+ (intCoord.pageY + (isOffsetParent ? 0 : dragEle.offsetParent.scrollTop)) - this.relativeYPosition;
1083
+ } else {
1084
+ pageX = this.clone ? intCoord.pageX : (intCoord.pageX + window.pageXOffset) - this.relativeXPosition;
1085
+ pageY = this.clone ? intCoord.pageY : (intCoord.pageY + window.pageYOffset) - this.relativeYPosition;
1086
+ }
1087
+ if (document.scrollingElement && (!isdragscroll && !this.clone)) {
1088
+ const ele: Element = document.scrollingElement;
1089
+ const isVerticalScroll: boolean = ele.scrollHeight > 0 && ele.scrollHeight > ele.clientHeight && ele.scrollTop > 0;
1090
+ const isHorrizontalScroll: boolean = ele.scrollWidth > 0 && ele.scrollWidth > ele.clientWidth && ele.scrollLeft > 0;
1091
+ pageX = isHorrizontalScroll ? pageX - ele.scrollLeft : pageX;
1092
+ pageY = isVerticalScroll ? pageY - ele.scrollTop : pageY;
1093
+ }
1094
+ return {
1095
+ left: pageX - (this.margin.left + this.cursorAt.left),
1096
+ top: pageY - (this.margin.top + this.cursorAt.top)
1097
+ };
1098
+ }
1099
+ private getCoordinates(evt: MouseEvent & TouchEvent): Coordinates {
1100
+ if (evt.type.indexOf('touch') > -1) {
1101
+ return evt.changedTouches[0];
1102
+ }
1103
+ return evt;
1104
+ }
1105
+ private getHelperElement(evt: MouseEvent & TouchEvent): HTMLElement {
1106
+ let element: HTMLElement;
1107
+ if (this.clone) {
1108
+ if (this.helper) {
1109
+ element = this.helper({ sender: evt, element: this.target });
1110
+ } else {
1111
+ element = createElement('div', { className: 'e-drag-helper e-block-touch', innerHTML: 'Draggable' });
1112
+ document.body.appendChild(element);
1113
+ }
1114
+ } else {
1115
+ element = this.element;
1116
+ }
1117
+ return element;
1118
+ }
1119
+ private setGlobalDroppables(reset: boolean, drag?: HTMLElement, helper?: HTMLElement): void {
1120
+ this.droppables[this.scope] = reset ? null : {
1121
+ draggable: drag,
1122
+ helper: helper,
1123
+ draggedElement: this.element
1124
+ };
1125
+ }
1126
+ private checkTargetElement(evt: MouseEvent & TouchEvent): DropObject {
1127
+ const target: Element = this.getProperTargetElement(evt);
1128
+ let dropIns: DropOption = this.getDropInstance(target);
1129
+ if (!dropIns && target && !isNullOrUndefined(target.parentNode)) {
1130
+ const parent: Element = closest(target.parentNode, '.e-droppable') || target.parentElement;
1131
+ if (parent) {
1132
+ dropIns = this.getDropInstance(parent);
1133
+ }
1134
+ }
1135
+ return { target: (<HTMLElement>target), instance: dropIns };
1136
+ }
1137
+ private getDropInstance(ele: Element): DropOption {
1138
+ const name: string = 'getModuleName';
1139
+ let drop: Object;
1140
+ const eleInst: { [key: string]: Object }[] = ele && (<Instance>ele).ej2_instances;
1141
+ if (eleInst) {
1142
+ for (const inst of eleInst) {
1143
+ if ((<Function>inst[`${name}`])() === 'droppable') {
1144
+ drop = inst;
1145
+ break;
1146
+ }
1147
+ }
1148
+ }
1149
+ return <DropOption>drop;
1150
+ }
1151
+ public destroy(): void {
1152
+ this.toggleEvents(true);
1153
+ super.destroy();
1154
+ }
1155
+ }