ngx-drag-drop 2.0.0 → 13.1.0-alpha.0
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/README.md +13 -353
- package/esm2020/lib/dnd-draggable.directive.mjs +192 -0
- package/esm2020/lib/dnd-dropzone.directive.mjs +277 -0
- package/esm2020/lib/dnd-handle.directive.mjs +30 -0
- package/esm2020/lib/dnd-state.mjs +71 -0
- package/esm2020/lib/dnd-types.mjs +2 -0
- package/esm2020/lib/dnd-utils.mjs +114 -0
- package/esm2020/lib/dnd.module.mjs +44 -0
- package/esm2020/ngx-drag-drop.mjs +5 -0
- package/esm2020/public-api.mjs +9 -0
- package/fesm2015/ngx-drag-drop.mjs +726 -0
- package/fesm2015/ngx-drag-drop.mjs.map +1 -0
- package/{fesm2015/ngx-drag-drop.js → fesm2020/ngx-drag-drop.mjs} +206 -442
- package/fesm2020/ngx-drag-drop.mjs.map +1 -0
- package/{dnd-draggable.directive.d.ts → lib/dnd-draggable.directive.d.ts} +7 -2
- package/{dnd-dropzone.directive.d.ts → lib/dnd-dropzone.directive.d.ts} +8 -3
- package/{dnd-handle.directive.d.ts → lib/dnd-handle.directive.d.ts} +3 -0
- package/{dnd-state.d.ts → lib/dnd-state.d.ts} +0 -0
- package/{dnd-types.d.ts → lib/dnd-types.d.ts} +0 -0
- package/{dnd-utils.d.ts → lib/dnd-utils.d.ts} +0 -0
- package/lib/dnd.module.d.ts +10 -0
- package/ngx-drag-drop.d.ts +2 -1
- package/package.json +24 -54
- package/public-api.d.ts +6 -0
- package/LICENSE +0 -29
- package/bundles/ngx-drag-drop.umd.js +0 -1056
- package/bundles/ngx-drag-drop.umd.js.map +0 -1
- package/bundles/ngx-drag-drop.umd.min.js +0 -2
- package/bundles/ngx-drag-drop.umd.min.js.map +0 -1
- package/dnd.module.d.ts +0 -2
- package/esm2015/dnd-draggable.directive.js +0 -314
- package/esm2015/dnd-dropzone.directive.js +0 -446
- package/esm2015/dnd-handle.directive.js +0 -40
- package/esm2015/dnd-state.js +0 -116
- package/esm2015/dnd-types.js +0 -5
- package/esm2015/dnd-utils.js +0 -199
- package/esm2015/dnd.module.js +0 -33
- package/esm2015/ngx-drag-drop.js +0 -9
- package/esm2015/public_api.js +0 -10
- package/esm5/dnd-draggable.directive.js +0 -351
- package/esm5/dnd-dropzone.directive.js +0 -500
- package/esm5/dnd-handle.directive.js +0 -43
- package/esm5/dnd-state.js +0 -116
- package/esm5/dnd-types.js +0 -5
- package/esm5/dnd-utils.js +0 -199
- package/esm5/dnd.module.js +0 -37
- package/esm5/ngx-drag-drop.js +0 -9
- package/esm5/public_api.js +0 -10
- package/fesm2015/ngx-drag-drop.js.map +0 -1
- package/fesm5/ngx-drag-drop.js +0 -1052
- package/fesm5/ngx-drag-drop.js.map +0 -1
- package/ngx-drag-drop.metadata.json +0 -1
- package/public_api.d.ts +0 -6
package/README.md
CHANGED
|
@@ -1,364 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
[](https://www.npmjs.com/package/ngx-drag-drop)
|
|
3
|
-
[](https://www.npmjs.com/package/ngx-drag-drop)
|
|
4
|
-
[](https://github.com/reppners/ngx-drag-drop/issues)
|
|
5
|
-
[](https://twitter.com/intent/tweet?text=Angular%20drag%20and%20drop%20with%20ease:&url=https://github.com/reppners/ngx-drag-drop)
|
|
1
|
+
# MyLib
|
|
6
2
|
|
|
7
|
-
|
|
3
|
+
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 13.1.0.
|
|
8
4
|
|
|
9
|
-
|
|
5
|
+
## Code scaffolding
|
|
10
6
|
|
|
11
|
-
`
|
|
7
|
+
Run `ng generate component component-name --project my-lib` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project my-lib`.
|
|
8
|
+
> Note: Don't forget to add `--project my-lib` or else it will be added to the default project in your `angular.json` file.
|
|
12
9
|
|
|
13
|
-
|
|
10
|
+
## Build
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
* nestable
|
|
17
|
-
* dropzones optionally support external/native draggables (img, txt, file)
|
|
18
|
-
* conditional drag/drop
|
|
19
|
-
* typed drag/drop
|
|
20
|
-
* utilize [EffectAllowed](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/effectAllowed)
|
|
21
|
-
* custom CSS classes
|
|
22
|
-
* touch support by using a [polyfill](#touch-support)
|
|
23
|
-
* [AOT](https://angular.io/guide/aot-compiler) compatible
|
|
12
|
+
Run `ng build my-lib` to build the project. The build artifacts will be stored in the `dist/` directory.
|
|
24
13
|
|
|
25
|
-
|
|
14
|
+
## Publishing
|
|
26
15
|
|
|
27
|
-
|
|
28
|
-
The idea is that the directive does not handle lists internally so the `dndDropzone` can be general purpose.
|
|
16
|
+
After building your library with `ng build my-lib`, go to the dist folder `cd dist/my-lib` and run `npm publish`.
|
|
29
17
|
|
|
18
|
+
## Running unit tests
|
|
30
19
|
|
|
31
|
-
|
|
20
|
+
Run `ng test my-lib` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
|
32
21
|
|
|
33
|
-
|
|
34
|
-
```HTML
|
|
35
|
-
<!--a draggable element-->
|
|
36
|
-
<div [dndDraggable]="draggable.data"
|
|
37
|
-
[dndEffectAllowed]="draggable.effectAllowed"
|
|
38
|
-
[dndDisableIf]="draggable.disable"
|
|
39
|
-
(dndStart)="onDragStart($event)"
|
|
40
|
-
(dndCopied)="onDraggableCopied($event)"
|
|
41
|
-
(dndLinked)="onDraggableLinked($event)"
|
|
42
|
-
(dndMoved)="onDraggableMoved($event)"
|
|
43
|
-
(dndCanceled)="onDragCanceled($event)"
|
|
44
|
-
(dndEnd)="onDragEnd($event)">
|
|
45
|
-
|
|
46
|
-
<!--if [dndHandle] is used inside dndDraggable drag can only start from the handle-->
|
|
47
|
-
<div *ngIf="draggable.handle"
|
|
48
|
-
dndHandle>HANDLE
|
|
49
|
-
</div>
|
|
50
|
-
|
|
51
|
-
draggable ({{draggable.effectAllowed}}) <span [hidden]="!draggable.disable">DISABLED</span>
|
|
52
|
-
|
|
53
|
-
<!--optionally select a child element as drag image-->
|
|
54
|
-
<div dndDragImageRef>DRAG_IMAGE</div>
|
|
55
|
-
|
|
56
|
-
</div>
|
|
22
|
+
## Further help
|
|
57
23
|
|
|
58
|
-
|
|
59
|
-
<!--to allow dropping content that is not [dndDraggable] set dndAllowExternal to true-->
|
|
60
|
-
<section dndDropzone
|
|
61
|
-
(dndDragover)="onDragover($event)"
|
|
62
|
-
(dndDrop)="onDrop($event)">
|
|
63
|
-
|
|
64
|
-
dropzone
|
|
65
|
-
|
|
66
|
-
<!--optional placeholder element for dropzone-->
|
|
67
|
-
<!--will be removed from DOM on init-->
|
|
68
|
-
<div style="border: 1px orangered solid; border-radius: 5px; padding: 15px;"
|
|
69
|
-
dndPlaceholderRef>
|
|
70
|
-
placeholder
|
|
71
|
-
</div>
|
|
72
|
-
|
|
73
|
-
</section>
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
`app.component`
|
|
77
|
-
```JS
|
|
78
|
-
import { Component } from '@angular/core';
|
|
79
|
-
|
|
80
|
-
import { DndDropEvent } from 'ngx-drag-drop';
|
|
81
|
-
|
|
82
|
-
@Component()
|
|
83
|
-
export class AppComponent {
|
|
84
|
-
|
|
85
|
-
draggable = {
|
|
86
|
-
// note that data is handled with JSON.stringify/JSON.parse
|
|
87
|
-
// only set simple data or POJO's as methods will be lost
|
|
88
|
-
data: "myDragData",
|
|
89
|
-
effectAllowed: "all",
|
|
90
|
-
disable: false,
|
|
91
|
-
handle: false
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
onDragStart(event:DragEvent) {
|
|
95
|
-
|
|
96
|
-
console.log("drag started", JSON.stringify(event, null, 2));
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
onDragEnd(event:DragEvent) {
|
|
100
|
-
|
|
101
|
-
console.log("drag ended", JSON.stringify(event, null, 2));
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
onDraggableCopied(event:DragEvent) {
|
|
105
|
-
|
|
106
|
-
console.log("draggable copied", JSON.stringify(event, null, 2));
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
onDraggableLinked(event:DragEvent) {
|
|
110
|
-
|
|
111
|
-
console.log("draggable linked", JSON.stringify(event, null, 2));
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
onDraggableMoved(event:DragEvent) {
|
|
115
|
-
|
|
116
|
-
console.log("draggable moved", JSON.stringify(event, null, 2));
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
onDragCanceled(event:DragEvent) {
|
|
120
|
-
|
|
121
|
-
console.log("drag cancelled", JSON.stringify(event, null, 2));
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
onDragover(event:DragEvent) {
|
|
125
|
-
|
|
126
|
-
console.log("dragover", JSON.stringify(event, null, 2));
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
onDrop(event:DndDropEvent) {
|
|
130
|
-
|
|
131
|
-
console.log("dropped", JSON.stringify(event, null, 2));
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
`app.module`
|
|
137
|
-
|
|
138
|
-
```JS
|
|
139
|
-
import { BrowserModule } from '@angular/platform-browser';
|
|
140
|
-
import { NgModule } from '@angular/core';
|
|
141
|
-
|
|
142
|
-
import { DndModule } from 'ngx-drag-drop';
|
|
143
|
-
|
|
144
|
-
import { AppComponent } from './app.component';
|
|
145
|
-
|
|
146
|
-
@NgModule({
|
|
147
|
-
declarations: [
|
|
148
|
-
AppComponent
|
|
149
|
-
],
|
|
150
|
-
imports: [
|
|
151
|
-
BrowserModule,
|
|
152
|
-
DndModule
|
|
153
|
-
],
|
|
154
|
-
providers: [],
|
|
155
|
-
bootstrap: [AppComponent]
|
|
156
|
-
})
|
|
157
|
-
export class AppModule {
|
|
158
|
-
}
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
## API
|
|
162
|
-
|
|
163
|
-
```TS
|
|
164
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/dropEffect
|
|
165
|
-
export type DropEffect = "move" | "copy" | "link" | "none";
|
|
166
|
-
|
|
167
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/effectAllowed
|
|
168
|
-
export type EffectAllowed = DropEffect | "copyMove" | "copyLink" | "linkMove" | "all";
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
```TS
|
|
172
|
-
export type DndDragImageOffsetFunction = ( event:DragEvent, dragImage:Element ) => { x:number, y:number };
|
|
173
|
-
|
|
174
|
-
@Directive( {
|
|
175
|
-
selector: "[dndDraggable]"
|
|
176
|
-
} )
|
|
177
|
-
export declare class DndDraggableDirective {
|
|
178
|
-
|
|
179
|
-
// the data attached to the drag
|
|
180
|
-
dndDraggable: any;
|
|
181
|
-
|
|
182
|
-
// the allowed drop effect
|
|
183
|
-
dndEffectAllowed: EffectAllowed;
|
|
184
|
-
|
|
185
|
-
// optionally set the type of dragged data to restrict dropping on compatible dropzones
|
|
186
|
-
dndType?: string;
|
|
187
|
-
|
|
188
|
-
// conditionally disable the draggability
|
|
189
|
-
dndDisableIf: boolean;
|
|
190
|
-
dndDisableDragIf: boolean;
|
|
191
|
-
|
|
192
|
-
// set a custom class that is applied while dragging
|
|
193
|
-
dndDraggingClass: string = "dndDragging";
|
|
194
|
-
|
|
195
|
-
// set a custom class that is applied to only the src element while dragging
|
|
196
|
-
dndDraggingSourceClass: string = "dndDraggingSource";
|
|
197
|
-
|
|
198
|
-
// set the class that is applied when draggable is disabled by [dndDisableIf]
|
|
199
|
-
dndDraggableDisabledClass = "dndDraggableDisabled";
|
|
200
|
-
|
|
201
|
-
// enables to set a function for calculating custom dragimage offset
|
|
202
|
-
dndDragImageOffsetFunction:DndDragImageOffsetFunction = calculateDragImageOffset;
|
|
203
|
-
|
|
204
|
-
// emits on drag start
|
|
205
|
-
readonly dndStart: EventEmitter<DragEvent>;
|
|
206
|
-
|
|
207
|
-
// emits on drag
|
|
208
|
-
readonly dndDrag: EventEmitter<DragEvent>;
|
|
209
|
-
|
|
210
|
-
// emits on drag end
|
|
211
|
-
readonly dndEnd: EventEmitter<DragEvent>;
|
|
212
|
-
|
|
213
|
-
// emits when the dragged item has been dropped with effect "move"
|
|
214
|
-
readonly dndMoved: EventEmitter<DragEvent>;
|
|
215
|
-
|
|
216
|
-
// emits when the dragged item has been dropped with effect "copy"
|
|
217
|
-
readonly dndCopied: EventEmitter<DragEvent>;
|
|
218
|
-
|
|
219
|
-
// emits when the dragged item has been dropped with effect "link"
|
|
220
|
-
readonly dndLinked: EventEmitter<DragEvent>;
|
|
221
|
-
|
|
222
|
-
// emits when the drag is canceled
|
|
223
|
-
readonly dndCanceled: EventEmitter<DragEvent>;
|
|
224
|
-
}
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
```TS
|
|
228
|
-
export interface DndDropEvent {
|
|
229
|
-
|
|
230
|
-
// the original drag event
|
|
231
|
-
event: DragEvent;
|
|
232
|
-
|
|
233
|
-
// the actual drop effect
|
|
234
|
-
dropEffect: DropEffect;
|
|
235
|
-
|
|
236
|
-
// true if the drag did not origin from a [dndDraggable]
|
|
237
|
-
isExternal:boolean;
|
|
238
|
-
|
|
239
|
-
// the data set on the [dndDraggable] that started the drag
|
|
240
|
-
// for external drags use the event property which contains the original drop event as this will be undefined
|
|
241
|
-
data?: any;
|
|
242
|
-
|
|
243
|
-
// the index where the draggable was dropped in a dropzone
|
|
244
|
-
// set only when using a placeholder
|
|
245
|
-
index?: number;
|
|
246
|
-
|
|
247
|
-
// if the dndType input on dndDraggable was set
|
|
248
|
-
// it will be transported here
|
|
249
|
-
type?: any;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
@Directive( {
|
|
253
|
-
selector: "[dndDropzone]"
|
|
254
|
-
} )
|
|
255
|
-
export declare class DndDropzoneDirective {
|
|
256
|
-
|
|
257
|
-
// optionally restrict the allowed types
|
|
258
|
-
dndDropzone?: string[];
|
|
259
|
-
|
|
260
|
-
// set the allowed drop effect
|
|
261
|
-
dndEffectAllowed: EffectAllowed;
|
|
262
|
-
|
|
263
|
-
// conditionally disable the dropzone
|
|
264
|
-
dndDisableIf: boolean;
|
|
265
|
-
dndDisableDropIf: boolean;
|
|
266
|
-
|
|
267
|
-
// if draggables that are not [dndDraggable] are allowed to be dropped
|
|
268
|
-
// set to true if dragged text, images or files should be handled
|
|
269
|
-
dndAllowExternal: boolean;
|
|
270
|
-
|
|
271
|
-
// if its a horizontal list this influences how the placeholder position
|
|
272
|
-
// is calculated
|
|
273
|
-
dndHorizontal: boolean;
|
|
274
|
-
|
|
275
|
-
// set the class applied to the dropzone
|
|
276
|
-
// when a draggable is dragged over it
|
|
277
|
-
dndDragoverClass: string = "dndDragover";
|
|
278
|
-
|
|
279
|
-
// set the class applied to the dropzone
|
|
280
|
-
// when the dropzone is disabled by [dndDisableIf]
|
|
281
|
-
dndDropzoneDisabledClass = "dndDropzoneDisabled";
|
|
282
|
-
|
|
283
|
-
// emits when a draggable is dragged over the dropzone
|
|
284
|
-
readonly dndDragover: EventEmitter<DragEvent>;
|
|
285
|
-
|
|
286
|
-
// emits on successful drop
|
|
287
|
-
readonly dndDrop: EventEmitter<DndDropEvent>;
|
|
288
|
-
}
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
## Touch support
|
|
292
|
-
|
|
293
|
-
Install the `mobile-drag-drop` module available on npm.
|
|
294
|
-
|
|
295
|
-
Add the following lines to your js code
|
|
296
|
-
```JS
|
|
297
|
-
import { polyfill } from 'mobile-drag-drop';
|
|
298
|
-
// optional import of scroll behaviour
|
|
299
|
-
import { scrollBehaviourDragImageTranslateOverride } from "mobile-drag-drop/scroll-behaviour";
|
|
300
|
-
|
|
301
|
-
polyfill( {
|
|
302
|
-
// use this to make use of the scroll behaviour
|
|
303
|
-
dragImageTranslateOverride: scrollBehaviourDragImageTranslateOverride
|
|
304
|
-
} );
|
|
305
|
-
|
|
306
|
-
// workaround to make scroll prevent work in iOS Safari > 10
|
|
307
|
-
try {
|
|
308
|
-
window.addEventListener( "touchmove", function() { }, { passive: false } );
|
|
309
|
-
}
|
|
310
|
-
catch(e){}
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
For more info on the polyfill check it out on GitHub
|
|
314
|
-
https://github.com/timruffles/mobile-drag-drop
|
|
315
|
-
|
|
316
|
-
## Known issues
|
|
317
|
-
|
|
318
|
-
### Firefox
|
|
319
|
-
|
|
320
|
-
* Beware that Firefox does not support dragging on `<button>` elements.
|
|
321
|
-
* `<button [dndDraggable]>` and `<button [dndHandler]>` won't work.
|
|
322
|
-
* See https://bugzilla.mozilla.org/show_bug.cgi?id=568313
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
## Why?
|
|
326
|
-
|
|
327
|
-
HTML Drag-And-Drop API implementations are not behaving the same way across browsers.
|
|
328
|
-
|
|
329
|
-
The directives contained in this module enable declarative drag and drop that "just works" across browsers in a consistent way.
|
|
330
|
-
|
|
331
|
-
Credits go to the author and contributors of [angular-drag-drop-lists](https://github.com/marceljuenemann/angular-drag-and-drop-lists).
|
|
332
|
-
|
|
333
|
-
## Maintenance
|
|
334
|
-
|
|
335
|
-
This project was generated with [Angular CLI](https://github.com/angular/angular-cli).
|
|
336
|
-
|
|
337
|
-
For the library build it uses [ng-packagr](https://github.com/dherges/ng-packagr).
|
|
338
|
-
|
|
339
|
-
#### Edit Library
|
|
340
|
-
|
|
341
|
-
* edit lib code
|
|
342
|
-
* run `npm start` (currently needs to be re-run on every lib code change)
|
|
343
|
-
|
|
344
|
-
#### Release Library
|
|
345
|
-
|
|
346
|
-
* assure correct version is set in `package.json`
|
|
347
|
-
* build library with `npm run build:lib`
|
|
348
|
-
* publish library with `npm run publish:stable` (use `npm run publish:next` for pre-releases)
|
|
349
|
-
|
|
350
|
-
#### Release Docs
|
|
351
|
-
|
|
352
|
-
* build docs site with `npm run build:docs`
|
|
353
|
-
* commit and push changes in `docs` to `master`
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
---
|
|
357
|
-
|
|
358
|
-
<p align="center">
|
|
359
|
-
Made with :heart: &
|
|
360
|
-
<a href="https://www.jetbrains.com/?from=ngx-drag-drop">
|
|
361
|
-
<img align="center" alt="jetbrains" src="jetbrains.svg" width="120px" />
|
|
362
|
-
</a>
|
|
363
|
-
& :coffee:
|
|
364
|
-
</p>
|
|
24
|
+
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { Directive, EventEmitter, HostBinding, HostListener, Input, Output } from "@angular/core";
|
|
2
|
+
import { calculateDragImageOffset, setDragData, setDragImage } from "./dnd-utils";
|
|
3
|
+
import { dndState, endDrag, startDrag } from "./dnd-state";
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
export class DndDragImageRefDirective {
|
|
6
|
+
constructor(parent, elementRef) {
|
|
7
|
+
parent.registerDragImage(elementRef);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
DndDragImageRefDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DndDragImageRefDirective, deps: [{ token: DndDraggableDirective }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
11
|
+
DndDragImageRefDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: DndDragImageRefDirective, selector: "[dndDragImageRef]", ngImport: i0 });
|
|
12
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DndDragImageRefDirective, decorators: [{
|
|
13
|
+
type: Directive,
|
|
14
|
+
args: [{
|
|
15
|
+
selector: "[dndDragImageRef]"
|
|
16
|
+
}]
|
|
17
|
+
}], ctorParameters: function () { return [{ type: DndDraggableDirective }, { type: i0.ElementRef }]; } });
|
|
18
|
+
export class DndDraggableDirective {
|
|
19
|
+
constructor(elementRef, renderer, ngZone) {
|
|
20
|
+
this.elementRef = elementRef;
|
|
21
|
+
this.renderer = renderer;
|
|
22
|
+
this.ngZone = ngZone;
|
|
23
|
+
this.dndEffectAllowed = "copy";
|
|
24
|
+
this.dndDraggingClass = "dndDragging";
|
|
25
|
+
this.dndDraggingSourceClass = "dndDraggingSource";
|
|
26
|
+
this.dndDraggableDisabledClass = "dndDraggableDisabled";
|
|
27
|
+
this.dndDragImageOffsetFunction = calculateDragImageOffset;
|
|
28
|
+
this.dndStart = new EventEmitter();
|
|
29
|
+
this.dndDrag = new EventEmitter();
|
|
30
|
+
this.dndEnd = new EventEmitter();
|
|
31
|
+
this.dndMoved = new EventEmitter();
|
|
32
|
+
this.dndCopied = new EventEmitter();
|
|
33
|
+
this.dndLinked = new EventEmitter();
|
|
34
|
+
this.dndCanceled = new EventEmitter();
|
|
35
|
+
this.draggable = true;
|
|
36
|
+
this.isDragStarted = false;
|
|
37
|
+
this.dragEventHandler = (event) => this.onDrag(event);
|
|
38
|
+
}
|
|
39
|
+
set dndDisableIf(value) {
|
|
40
|
+
this.draggable = !value;
|
|
41
|
+
if (this.draggable) {
|
|
42
|
+
this.renderer.removeClass(this.elementRef.nativeElement, this.dndDraggableDisabledClass);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
this.renderer.addClass(this.elementRef.nativeElement, this.dndDraggableDisabledClass);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
set dndDisableDragIf(value) {
|
|
49
|
+
this.dndDisableIf = value;
|
|
50
|
+
}
|
|
51
|
+
ngAfterViewInit() {
|
|
52
|
+
this.ngZone.runOutsideAngular(() => {
|
|
53
|
+
this.elementRef.nativeElement.addEventListener("drag", this.dragEventHandler);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
ngOnDestroy() {
|
|
57
|
+
this.elementRef.nativeElement.removeEventListener("drag", this.dragEventHandler);
|
|
58
|
+
if (this.isDragStarted === true) {
|
|
59
|
+
endDrag();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
onDragStart(event) {
|
|
63
|
+
if (this.draggable === false) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
// check if there is dnd handle and if the dnd handle was used to start the drag
|
|
67
|
+
if (typeof this.dndHandle !== "undefined"
|
|
68
|
+
&& typeof event._dndUsingHandle === "undefined") {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
// initialize global state
|
|
72
|
+
startDrag(event, this.dndEffectAllowed, this.dndType);
|
|
73
|
+
this.isDragStarted = true;
|
|
74
|
+
setDragData(event, { data: this.dndDraggable, type: this.dndType }, dndState.effectAllowed);
|
|
75
|
+
this.dragImage = this.determineDragImage();
|
|
76
|
+
// set dragging css class prior to setDragImage so styles are applied before
|
|
77
|
+
// TODO breaking change: add class to elementRef rather than drag image which could be another element
|
|
78
|
+
this.renderer.addClass(this.dragImage, this.dndDraggingClass);
|
|
79
|
+
// set custom dragimage if present
|
|
80
|
+
// set dragimage if drag is started from dndHandle
|
|
81
|
+
if (typeof this.dndDragImageElementRef !== "undefined"
|
|
82
|
+
|| typeof event._dndUsingHandle !== "undefined") {
|
|
83
|
+
setDragImage(event, this.dragImage, this.dndDragImageOffsetFunction);
|
|
84
|
+
}
|
|
85
|
+
// add dragging source css class on first drag event
|
|
86
|
+
const unregister = this.renderer.listen(this.elementRef.nativeElement, "drag", () => {
|
|
87
|
+
this.renderer.addClass(this.elementRef.nativeElement, this.dndDraggingSourceClass);
|
|
88
|
+
unregister();
|
|
89
|
+
});
|
|
90
|
+
this.dndStart.emit(event);
|
|
91
|
+
event.stopPropagation();
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
onDrag(event) {
|
|
95
|
+
this.dndDrag.emit(event);
|
|
96
|
+
}
|
|
97
|
+
onDragEnd(event) {
|
|
98
|
+
// get drop effect from custom stored state as its not reliable across browsers
|
|
99
|
+
const dropEffect = dndState.dropEffect;
|
|
100
|
+
let dropEffectEmitter;
|
|
101
|
+
switch (dropEffect) {
|
|
102
|
+
case "copy":
|
|
103
|
+
dropEffectEmitter = this.dndCopied;
|
|
104
|
+
break;
|
|
105
|
+
case "link":
|
|
106
|
+
dropEffectEmitter = this.dndLinked;
|
|
107
|
+
break;
|
|
108
|
+
case "move":
|
|
109
|
+
dropEffectEmitter = this.dndMoved;
|
|
110
|
+
break;
|
|
111
|
+
default:
|
|
112
|
+
dropEffectEmitter = this.dndCanceled;
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
dropEffectEmitter.emit(event);
|
|
116
|
+
this.dndEnd.emit(event);
|
|
117
|
+
// reset global state
|
|
118
|
+
endDrag();
|
|
119
|
+
this.isDragStarted = false;
|
|
120
|
+
this.renderer.removeClass(this.dragImage, this.dndDraggingClass);
|
|
121
|
+
// IE9 special hammering
|
|
122
|
+
window.setTimeout(() => {
|
|
123
|
+
this.renderer.removeClass(this.elementRef.nativeElement, this.dndDraggingSourceClass);
|
|
124
|
+
}, 0);
|
|
125
|
+
event.stopPropagation();
|
|
126
|
+
}
|
|
127
|
+
registerDragHandle(handle) {
|
|
128
|
+
this.dndHandle = handle;
|
|
129
|
+
}
|
|
130
|
+
registerDragImage(elementRef) {
|
|
131
|
+
this.dndDragImageElementRef = elementRef;
|
|
132
|
+
}
|
|
133
|
+
determineDragImage() {
|
|
134
|
+
// evaluate custom drag image existence
|
|
135
|
+
if (typeof this.dndDragImageElementRef !== "undefined") {
|
|
136
|
+
return this.dndDragImageElementRef.nativeElement;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
return this.elementRef.nativeElement;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
DndDraggableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DndDraggableDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
|
|
144
|
+
DndDraggableDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: DndDraggableDirective, selector: "[dndDraggable]", inputs: { dndDraggable: "dndDraggable", dndEffectAllowed: "dndEffectAllowed", dndType: "dndType", dndDraggingClass: "dndDraggingClass", dndDraggingSourceClass: "dndDraggingSourceClass", dndDraggableDisabledClass: "dndDraggableDisabledClass", dndDragImageOffsetFunction: "dndDragImageOffsetFunction", dndDisableIf: "dndDisableIf", dndDisableDragIf: "dndDisableDragIf" }, outputs: { dndStart: "dndStart", dndDrag: "dndDrag", dndEnd: "dndEnd", dndMoved: "dndMoved", dndCopied: "dndCopied", dndLinked: "dndLinked", dndCanceled: "dndCanceled" }, host: { listeners: { "dragstart": "onDragStart($event)", "dragend": "onDragEnd($event)" }, properties: { "attr.draggable": "this.draggable" } }, ngImport: i0 });
|
|
145
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: DndDraggableDirective, decorators: [{
|
|
146
|
+
type: Directive,
|
|
147
|
+
args: [{
|
|
148
|
+
selector: "[dndDraggable]"
|
|
149
|
+
}]
|
|
150
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }]; }, propDecorators: { dndDraggable: [{
|
|
151
|
+
type: Input
|
|
152
|
+
}], dndEffectAllowed: [{
|
|
153
|
+
type: Input
|
|
154
|
+
}], dndType: [{
|
|
155
|
+
type: Input
|
|
156
|
+
}], dndDraggingClass: [{
|
|
157
|
+
type: Input
|
|
158
|
+
}], dndDraggingSourceClass: [{
|
|
159
|
+
type: Input
|
|
160
|
+
}], dndDraggableDisabledClass: [{
|
|
161
|
+
type: Input
|
|
162
|
+
}], dndDragImageOffsetFunction: [{
|
|
163
|
+
type: Input
|
|
164
|
+
}], dndStart: [{
|
|
165
|
+
type: Output
|
|
166
|
+
}], dndDrag: [{
|
|
167
|
+
type: Output
|
|
168
|
+
}], dndEnd: [{
|
|
169
|
+
type: Output
|
|
170
|
+
}], dndMoved: [{
|
|
171
|
+
type: Output
|
|
172
|
+
}], dndCopied: [{
|
|
173
|
+
type: Output
|
|
174
|
+
}], dndLinked: [{
|
|
175
|
+
type: Output
|
|
176
|
+
}], dndCanceled: [{
|
|
177
|
+
type: Output
|
|
178
|
+
}], draggable: [{
|
|
179
|
+
type: HostBinding,
|
|
180
|
+
args: ["attr.draggable"]
|
|
181
|
+
}], dndDisableIf: [{
|
|
182
|
+
type: Input
|
|
183
|
+
}], dndDisableDragIf: [{
|
|
184
|
+
type: Input
|
|
185
|
+
}], onDragStart: [{
|
|
186
|
+
type: HostListener,
|
|
187
|
+
args: ["dragstart", ["$event"]]
|
|
188
|
+
}], onDragEnd: [{
|
|
189
|
+
type: HostListener,
|
|
190
|
+
args: ["dragend", ["$event"]]
|
|
191
|
+
}] } });
|
|
192
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG5kLWRyYWdnYWJsZS5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9kbmQvc3JjL2xpYi9kbmQtZHJhZ2dhYmxlLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsU0FBUyxFQUVULFlBQVksRUFDWixXQUFXLEVBQ1gsWUFBWSxFQUNaLEtBQUssRUFHTCxNQUFNLEVBRVAsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLHdCQUF3QixFQUF3QyxXQUFXLEVBQUUsWUFBWSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRXhILE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQzs7QUFNM0QsTUFBTSxPQUFPLHdCQUF3QjtJQUVuQyxZQUFhLE1BQTRCLEVBQzVCLFVBQXFCO1FBRWhDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBRSxVQUFVLENBQUUsQ0FBQztJQUN6QyxDQUFDOztxSEFOVSx3QkFBd0Isa0JBRWYscUJBQXFCO3lHQUY5Qix3QkFBd0I7MkZBQXhCLHdCQUF3QjtrQkFIcEMsU0FBUzttQkFBRTtvQkFDVixRQUFRLEVBQUUsbUJBQW1CO2lCQUM5QjswREFHcUIscUJBQXFCO0FBVTNDLE1BQU0sT0FBTyxxQkFBcUI7SUE2RWhDLFlBQXFCLFVBQXFCLEVBQ3JCLFFBQWtCLEVBQ2xCLE1BQWE7UUFGYixlQUFVLEdBQVYsVUFBVSxDQUFXO1FBQ3JCLGFBQVEsR0FBUixRQUFRLENBQVU7UUFDbEIsV0FBTSxHQUFOLE1BQU0sQ0FBTztRQXpFbEMscUJBQWdCLEdBQWlCLE1BQU0sQ0FBQztRQU14QyxxQkFBZ0IsR0FBRyxhQUFhLENBQUM7UUFHakMsMkJBQXNCLEdBQUcsbUJBQW1CLENBQUM7UUFHN0MsOEJBQXlCLEdBQUcsc0JBQXNCLENBQUM7UUFHbkQsK0JBQTBCLEdBQThCLHdCQUF3QixDQUFDO1FBR3hFLGFB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Z0JBQWdCO2lCQUMzQjs4SUFJQyxZQUFZO3NCQURYLEtBQUs7Z0JBSU4sZ0JBQWdCO3NCQURmLEtBQUs7Z0JBSU4sT0FBTztzQkFETixLQUFLO2dCQUlOLGdCQUFnQjtzQkFEZixLQUFLO2dCQUlOLHNCQUFzQjtzQkFEckIsS0FBSztnQkFJTix5QkFBeUI7c0JBRHhCLEtBQUs7Z0JBSU4sMEJBQTBCO3NCQUR6QixLQUFLO2dCQUlHLFFBQVE7c0JBRGhCLE1BQU07Z0JBSUUsT0FBTztzQkFEZixNQUFNO2dCQUlFLE1BQU07c0JBRGQsTUFBTTtnQkFJRSxRQUFRO3NCQURoQixNQUFNO2dCQUlFLFNBQVM7c0JBRGpCLE1BQU07Z0JBSUUsU0FBUztzQkFEakIsTUFBTTtnQkFJRSxXQUFXO3NCQURuQixNQUFNO2dCQUlQLFNBQVM7c0JBRFIsV0FBVzt1QkFBRSxnQkFBZ0I7Z0JBYzFCLFlBQVk7c0JBRGYsS0FBSztnQkFnQkYsZ0JBQWdCO3NCQURuQixLQUFLO2dCQXdCTixXQUFXO3NCQURWLFlBQVk7dUJBQUUsV0FBVyxFQUFFLENBQUUsUUFBUSxDQUFFO2dCQXVEeEMsU0FBUztzQkFEUixZQUFZO3VCQUFFLFNBQVMsRUFBRSxDQUFFLFFBQVEsQ0FBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIERpcmVjdGl2ZSxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBIb3N0QmluZGluZyxcbiAgSG9zdExpc3RlbmVyLFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgUmVuZGVyZXIyXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBjYWxjdWxhdGVEcmFnSW1hZ2VPZmZzZXQsIERuZERyYWdJbWFnZU9mZnNldEZ1bmN0aW9uLCBEbmRFdmVudCwgc2V0RHJhZ0RhdGEsIHNldERyYWdJbWFnZSB9IGZyb20gXCIuL2RuZC11dGlsc1wiO1xuaW1wb3J0IHsgRG5kSGFuZGxlRGlyZWN0aXZlIH0gZnJvbSBcIi4vZG5kLWhhbmRsZS5kaXJlY3RpdmVcIjtcbmltcG9ydCB7IGRuZFN0YXRlLCBlbmREcmFnLCBzdGFydERyYWcgfSBmcm9tIFwiLi9kbmQtc3RhdGVcIjtcbmltcG9ydCB7IEVmZmVjdEFsbG93ZWQgfSBmcm9tIFwiLi9kbmQtdHlwZXNcIjtcblxuQERpcmVjdGl2ZSgge1xuICBzZWxlY3RvcjogXCJbZG5kRHJhZ0ltYWdlUmVmXVwiXG59IClcbmV4cG9ydCBjbGFzcyBEbmREcmFnSW1hZ2VSZWZEaXJlY3RpdmUge1xuXG4gIGNvbnN0cnVjdG9yKCBwYXJlbnQ6RG5kRHJhZ2dhYmxlRGlyZWN0aXZlLFxuICAgICAgICAgICAgICAgZWxlbWVudFJlZjpFbGVtZW50UmVmICkge1xuXG4gICAgcGFyZW50LnJlZ2lzdGVyRHJhZ0ltYWdlKCBlbGVtZW50UmVmICk7XG4gIH1cbn1cblxuQERpcmVjdGl2ZSgge1xuICBzZWxlY3RvcjogXCJbZG5kRHJhZ2dhYmxlXVwiXG59IClcbmV4cG9ydCBjbGFzcyBEbmREcmFnZ2FibGVEaXJlY3RpdmUgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuXG4gIEBJbnB1dCgpXG4gIGRuZERyYWdnYWJsZTphbnk7XG5cbiAgQElucHV0KClcbiAgZG5kRWZmZWN0QWxsb3dlZDpFZmZlY3RBbGxvd2VkID0gXCJjb3B5XCI7XG5cbiAgQElucHV0KClcbiAgZG5kVHlwZT86c3RyaW5nO1xuXG4gIEBJbnB1dCgpXG4gIGRuZERyYWdnaW5nQ2xhc3MgPSBcImRuZERyYWdnaW5nXCI7XG5cbiAgQElucHV0KClcbiAgZG5kRHJhZ2dpbmdTb3VyY2VDbGFzcyA9IFwiZG5kRHJhZ2dpbmdTb3VyY2VcIjtcblxuICBASW5wdXQoKVxuICBkbmREcmFnZ2FibGVEaXNhYmxlZENsYXNzID0gXCJkbmREcmFnZ2FibGVEaXNhYmxlZFwiO1xuXG4gIEBJbnB1dCgpXG4gIGRuZERyYWdJbWFnZU9mZnNldEZ1bmN0aW9uOkRuZERyYWdJbWFnZU9mZnNldEZ1bmN0aW9uID0gY2FsY3VsYXRlRHJhZ0ltYWdlT2Zmc2V0O1xuXG4gIEBPdXRwdXQoKVxuICByZWFkb25seSBkbmRTdGFydDpFdmVudEVtaXR0ZXI8RHJhZ0V2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8RHJhZ0V2ZW50PigpO1xuXG4gIEBPdXRwdXQoKVxuICByZWFkb25seSBkbmREcmFnOkV2ZW50RW1pdHRlcjxEcmFnRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxEcmFnRXZlbnQ+KCk7XG5cbiAgQE91dHB1dCgpXG4gIHJlYWRvbmx5IGRuZEVuZDpFdmVudEVtaXR0ZXI8RHJhZ0V2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8RHJhZ0V2ZW50PigpO1xuXG4gIEBPdXRwdXQoKVxuICByZWFkb25seSBkbmRNb3ZlZDpFdmVudEVtaXR0ZXI8RHJhZ0V2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8RHJhZ0V2ZW50PigpO1xuXG4gIEBPdXRwdXQoKVxuICByZWFkb25seSBkbmRDb3BpZWQ6RXZlbnRFbWl0dGVyPERyYWdFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyPERyYWdFdmVudD4oKTtcblxuICBAT3V0cHV0KClcbiAgcmVhZG9ubHkgZG5kTGlua2VkOkV2ZW50RW1pdHRlcjxEcmFnRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxEcmFnRXZlbnQ+KCk7XG5cbiAgQE91dHB1dCgpXG4gIHJlYWRvbmx5IGRuZENhbmNlbGVkOkV2ZW50RW1pdHRlcjxEcmFnRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxEcmFnRXZlbnQ+KCk7XG5cbiAgQEhvc3RCaW5kaW5nKCBcImF0dHIuZHJhZ2dhYmxlXCIgKVxuICBkcmFnZ2FibGUgPSB0cnVlO1xuXG4gIHByaXZhdGUgZG5kSGFuZGxlPzpEbmRIYW5kbGVEaXJlY3RpdmU7XG5cbiAgcHJpdmF0ZSBkbmREcmFnSW1hZ2VFbGVtZW50UmVmPzpFbGVtZW50UmVmO1xuXG4gIHByaXZhdGUgZHJhZ0ltYWdlOkVsZW1lbnQgfCB1bmRlZmluZWQ7XG5cbiAgcHJpdmF0ZSBpc0RyYWdTdGFydGVkOmJvb2xlYW4gPSBmYWxzZTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGRyYWdFdmVudEhhbmRsZXI6KCBldmVudDpEcmFnRXZlbnQgKSA9PiB2b2lkID0gKCBldmVudDpEcmFnRXZlbnQgKSA9PiB0aGlzLm9uRHJhZyggZXZlbnQgKTtcblxuICBASW5wdXQoKVxuICBzZXQgZG5kRGlzYWJsZUlmKCB2YWx1ZTpib29sZWFuICkge1xuXG4gICAgdGhpcy5kcmFnZ2FibGUgPSAhdmFsdWU7XG5cbiAgICBpZiggdGhpcy5kcmFnZ2FibGUgKSB7XG5cbiAgICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlQ2xhc3MoIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCB0aGlzLmRuZERyYWdnYWJsZURpc2FibGVkQ2xhc3MgKTtcbiAgICB9XG4gICAgZWxzZSB7XG5cbiAgICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3MoIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCB0aGlzLmRuZERyYWdnYWJsZURpc2FibGVkQ2xhc3MgKTtcbiAgICB9XG4gIH1cblxuICBASW5wdXQoKVxuICBzZXQgZG5kRGlzYWJsZURyYWdJZiggdmFsdWU6Ym9vbGVhbiApIHtcbiAgICB0aGlzLmRuZERpc2FibGVJZiA9IHZhbHVlO1xuICB9XG5cbiAgY29uc3RydWN0b3IoIHByaXZhdGUgZWxlbWVudFJlZjpFbGVtZW50UmVmLFxuICAgICAgICAgICAgICAgcHJpdmF0ZSByZW5kZXJlcjpSZW5kZXJlcjIsXG4gICAgICAgICAgICAgICBwcml2YXRlIG5nWm9uZTpOZ1pvbmUgKSB7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKTp2b2lkIHtcbiAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhciggKCkgPT4ge1xuICAgICAgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lciggXCJkcmFnXCIsIHRoaXMuZHJhZ0V2ZW50SGFuZGxlciApO1xuICAgIH0gKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6dm9pZCB7XG4gICAgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lciggXCJkcmFnXCIsIHRoaXMuZHJhZ0V2ZW50SGFuZGxlciApO1xuICAgIGlmKHRoaXMuaXNEcmFnU3RhcnRlZCA9PT0gdHJ1ZSkge1xuICAgICAgZW5kRHJhZygpXG4gICAgfVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lciggXCJkcmFnc3RhcnRcIiwgWyBcIiRldmVudFwiIF0gKVxuICBvbkRyYWdTdGFydCggZXZlbnQ6RG5kRXZlbnQgKTogYm9vbGVhbiB7XG5cbiAgICBpZiggdGhpcy5kcmFnZ2FibGUgPT09IGZhbHNlICkge1xuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gY2hlY2sgaWYgdGhlcmUgaXMgZG5kIGhhbmRsZSBhbmQgaWYgdGhlIGRuZCBoYW5kbGUgd2FzIHVzZWQgdG8gc3RhcnQgdGhlIGRyYWdcbiAgICBpZiggdHlwZW9mIHRoaXMuZG5kSGFuZGxlICE9PSBcInVuZGVmaW5lZFwiXG4gICAgICAmJiB0eXBlb2YgZXZlbnQuX2RuZFVzaW5nSGFuZGxlID09PSBcInVuZGVmaW5lZFwiICkge1xuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gaW5pdGlhbGl6ZSBnbG9iYWwgc3RhdGVcbiAgICBzdGFydERyYWcoIGV2ZW50LCB0aGlzLmRuZEVmZmVjdEFsbG93ZWQsIHRoaXMuZG5kVHlwZSApO1xuXG4gICAgdGhpcy5pc0RyYWdTdGFydGVkID0gdHJ1ZTtcblxuICAgIHNldERyYWdEYXRhKCBldmVudCwge2RhdGE6IHRoaXMuZG5kRHJhZ2dhYmxlLCB0eXBlOiB0aGlzLmRuZFR5cGV9LCBkbmRTdGF0ZS5lZmZlY3RBbGxvd2VkISApO1xuXG4gICAgdGhpcy5kcmFnSW1hZ2UgPSB0aGlzLmRldGVybWluZURyYWdJbWFnZSgpO1xuXG4gICAgLy8gc2V0IGRyYWdnaW5nIGNzcyBjbGFzcyBwcmlvciB0byBzZXREcmFnSW1hZ2Ugc28gc3R5bGVzIGFyZSBhcHBsaWVkIGJlZm9yZVxuICAgIC8vIFRPRE8gYnJlYWtpbmcgY2hhbmdlOiBhZGQgY2xhc3MgdG8gZWxlbWVudFJlZiByYXRoZXIgdGhhbiBkcmFnIGltYWdlIHdoaWNoIGNvdWxkIGJlIGFub3RoZXIgZWxlbWVudFxuICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3MoIHRoaXMuZHJhZ0ltYWdlLCB0aGlzLmRuZERyYWdnaW5nQ2xhc3MgKTtcblxuICAgIC8vIHNldCBjdXN0b20gZHJhZ2ltYWdlIGlmIHByZXNlbnRcbiAgICAvLyBzZXQgZHJhZ2ltYWdlIGlmIGRyYWcgaXMgc3RhcnRlZCBmcm9tIGRuZEhhbmRsZVxuICAgIGlmKCB0eXBlb2YgdGhpcy5kbmREcmFnSW1hZ2VFbGVtZW50UmVmICE9PSBcInVuZGVmaW5lZFwiXG4gICAgICB8fCB0eXBlb2YgZXZlbnQuX2RuZFVzaW5nSGFuZGxlICE9PSBcInVuZGVmaW5lZFwiICkge1xuXG4gICAgICBzZXREcmFnSW1hZ2UoIGV2ZW50LCB0aGlzLmRyYWdJbWFnZSwgdGhpcy5kbmREcmFnSW1hZ2VPZmZzZXRGdW5jdGlvbiApO1xuICAgIH1cblxuICAgIC8vIGFkZCBkcmFnZ2luZyBzb3VyY2UgY3NzIGNsYXNzIG9uIGZpcnN0IGRyYWcgZXZlbnRcbiAgICBjb25zdCB1bnJlZ2lzdGVyID0gdGhpcy5yZW5kZXJlci5saXN0ZW4oIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCBcImRyYWdcIiwgKCkgPT4ge1xuXG4gICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKCB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgdGhpcy5kbmREcmFnZ2luZ1NvdXJjZUNsYXNzICk7XG4gICAgICB1bnJlZ2lzdGVyKCk7XG4gICAgfSApO1xuXG4gICAgdGhpcy5kbmRTdGFydC5lbWl0KCBldmVudCApO1xuXG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBvbkRyYWcoIGV2ZW50OkRyYWdFdmVudCApIHtcblxuICAgIHRoaXMuZG5kRHJhZy5lbWl0KCBldmVudCApO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lciggXCJkcmFnZW5kXCIsIFsgXCIkZXZlbnRcIiBdIClcbiAgb25EcmFnRW5kKCBldmVudDpEcmFnRXZlbnQgKSB7XG5cbiAgICAvLyBnZXQgZHJvcCBlZmZlY3QgZnJvbSBjdXN0b20gc3RvcmVkIHN0YXRlIGFzIGl0cyBub3QgcmVsaWFibGUgYWNyb3NzIGJyb3dzZXJzXG4gICAgY29uc3QgZHJvcEVmZmVjdCA9IGRuZFN0YXRlLmRyb3BFZmZlY3Q7XG5cbiAgICBsZXQgZHJvcEVmZmVjdEVtaXR0ZXI6RXZlbnRFbWl0dGVyPERyYWdFdmVudD47XG5cbiAgICBzd2l0Y2goIGRyb3BFZmZlY3QgKSB7XG5cbiAgICAgIGNhc2UgXCJjb3B5XCI6XG4gICAgICAgIGRyb3BFZmZlY3RFbWl0dGVyID0gdGhpcy5kbmRDb3BpZWQ7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIFwibGlua1wiOlxuICAgICAgICBkcm9wRWZmZWN0RW1pdHRlciA9IHRoaXMuZG5kTGlua2VkO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcIm1vdmVcIjpcbiAgICAgICAgZHJvcEVmZmVjdEVtaXR0ZXIgPSB0aGlzLmRuZE1vdmVkO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgZHJvcEVmZmVjdEVtaXR0ZXIgPSB0aGlzLmRuZENhbmNlbGVkO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBkcm9wRWZmZWN0RW1pdHRlci5lbWl0KCBldmVudCApO1xuICAgIHRoaXMuZG5kRW5kLmVtaXQoIGV2ZW50ICk7XG5cbiAgICAvLyByZXNldCBnbG9iYWwgc3RhdGVcbiAgICBlbmREcmFnKCk7XG5cbiAgICB0aGlzLmlzRHJhZ1N0YXJ0ZWQgPSBmYWxzZTtcblxuICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlQ2xhc3MoIHRoaXMuZHJhZ0ltYWdlLCB0aGlzLmRuZERyYWdnaW5nQ2xhc3MgKTtcblxuICAgIC8vIElFOSBzcGVjaWFsIGhhbW1lcmluZ1xuICAgIHdpbmRvdy5zZXRUaW1lb3V0KCAoKSA9PiB7XG4gICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKCB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgdGhpcy5kbmREcmFnZ2luZ1NvdXJjZUNsYXNzICk7XG4gICAgfSwgMCApO1xuXG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH1cblxuICByZWdpc3RlckRyYWdIYW5kbGUoIGhhbmRsZTpEbmRIYW5kbGVEaXJlY3RpdmUgfCB1bmRlZmluZWQgKSB7XG5cbiAgICB0aGlzLmRuZEhhbmRsZSA9IGhhbmRsZTtcbiAgfVxuXG4gIHJlZ2lzdGVyRHJhZ0ltYWdlKCBlbGVtZW50UmVmOkVsZW1lbnRSZWYgfCB1bmRlZmluZWQgKSB7XG5cbiAgICB0aGlzLmRuZERyYWdJbWFnZUVsZW1lbnRSZWYgPSBlbGVtZW50UmVmO1xuICB9XG5cbiAgcHJpdmF0ZSBkZXRlcm1pbmVEcmFnSW1hZ2UoKTpFbGVtZW50IHtcblxuICAgIC8vIGV2YWx1YXRlIGN1c3RvbSBkcmFnIGltYWdlIGV4aXN0ZW5jZVxuICAgIGlmKCB0eXBlb2YgdGhpcy5kbmREcmFnSW1hZ2VFbGVtZW50UmVmICE9PSBcInVuZGVmaW5lZFwiICkge1xuXG4gICAgICByZXR1cm4gdGhpcy5kbmREcmFnSW1hZ2VFbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQgYXMgRWxlbWVudDtcbiAgICB9XG4gICAgZWxzZSB7XG5cbiAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|