@angular/cdk 7.1.0 → 7.2.2
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/LICENSE +1 -1
- package/_a11y.scss +1 -1
- package/a11y/typings/focus-monitor/focus-monitor.d.ts +20 -5
- package/a11y/typings/focus-trap/focus-trap.d.ts +2 -0
- package/a11y/typings/index.metadata.json +1 -1
- package/bundles/cdk-a11y.umd.js +428 -197
- package/bundles/cdk-a11y.umd.js.map +1 -1
- package/bundles/cdk-a11y.umd.min.js +1 -1
- package/bundles/cdk-a11y.umd.min.js.map +1 -1
- package/bundles/cdk-accordion.umd.js +16 -9
- package/bundles/cdk-accordion.umd.js.map +1 -1
- package/bundles/cdk-accordion.umd.min.js.map +1 -1
- package/bundles/cdk-bidi.umd.js +11 -6
- package/bundles/cdk-bidi.umd.js.map +1 -1
- package/bundles/cdk-bidi.umd.min.js.map +1 -1
- package/bundles/cdk-coercion.umd.js +25 -9
- package/bundles/cdk-coercion.umd.js.map +1 -1
- package/bundles/cdk-coercion.umd.min.js +1 -1
- package/bundles/cdk-coercion.umd.min.js.map +1 -1
- package/bundles/cdk-collections.umd.js +28 -5
- package/bundles/cdk-collections.umd.js.map +1 -1
- package/bundles/cdk-collections.umd.min.js.map +1 -1
- package/bundles/cdk-drag-drop.umd.js +2297 -973
- package/bundles/cdk-drag-drop.umd.js.map +1 -1
- package/bundles/cdk-drag-drop.umd.min.js +2 -1
- package/bundles/cdk-drag-drop.umd.min.js.map +1 -1
- package/bundles/cdk-keycodes.umd.js +12 -2
- package/bundles/cdk-keycodes.umd.js.map +1 -1
- package/bundles/cdk-layout.umd.js +29 -22
- package/bundles/cdk-layout.umd.js.map +1 -1
- package/bundles/cdk-layout.umd.min.js +1 -1
- package/bundles/cdk-layout.umd.min.js.map +1 -1
- package/bundles/cdk-observers.umd.js +27 -8
- package/bundles/cdk-observers.umd.js.map +1 -1
- package/bundles/cdk-observers.umd.min.js +1 -1
- package/bundles/cdk-observers.umd.min.js.map +1 -1
- package/bundles/cdk-overlay.umd.js +586 -240
- package/bundles/cdk-overlay.umd.js.map +1 -1
- package/bundles/cdk-overlay.umd.min.js +2 -2
- package/bundles/cdk-overlay.umd.min.js.map +1 -1
- package/bundles/cdk-platform.umd.js +50 -28
- package/bundles/cdk-platform.umd.js.map +1 -1
- package/bundles/cdk-platform.umd.min.js.map +1 -1
- package/bundles/cdk-portal.umd.js +17 -10
- package/bundles/cdk-portal.umd.js.map +1 -1
- package/bundles/cdk-portal.umd.min.js.map +1 -1
- package/bundles/cdk-scrolling.umd.js +148 -50
- package/bundles/cdk-scrolling.umd.js.map +1 -1
- package/bundles/cdk-scrolling.umd.min.js +1 -1
- package/bundles/cdk-scrolling.umd.min.js.map +1 -1
- package/bundles/cdk-stepper.umd.js +69 -27
- package/bundles/cdk-stepper.umd.js.map +1 -1
- package/bundles/cdk-stepper.umd.min.js +1 -1
- package/bundles/cdk-stepper.umd.min.js.map +1 -1
- package/bundles/cdk-table.umd.js +189 -51
- package/bundles/cdk-table.umd.js.map +1 -1
- package/bundles/cdk-table.umd.min.js +1 -1
- package/bundles/cdk-table.umd.min.js.map +1 -1
- package/bundles/cdk-text-field.umd.js +76 -38
- package/bundles/cdk-text-field.umd.js.map +1 -1
- package/bundles/cdk-text-field.umd.min.js +1 -1
- package/bundles/cdk-text-field.umd.min.js.map +1 -1
- package/bundles/cdk-tree.umd.js +71 -34
- package/bundles/cdk-tree.umd.js.map +1 -1
- package/bundles/cdk-tree.umd.min.js +1 -1
- package/bundles/cdk-tree.umd.min.js.map +1 -1
- package/bundles/cdk.umd.js +5 -4
- package/bundles/cdk.umd.js.map +1 -1
- package/bundles/cdk.umd.min.js +1 -1
- package/bundles/cdk.umd.min.js.map +1 -1
- package/coercion/typings/element.d.ts +13 -0
- package/coercion/typings/index.metadata.json +1 -1
- package/coercion/typings/public-api.d.ts +1 -0
- package/drag-drop/typings/{drag-handle.d.ts → directives/drag-handle.d.ts} +6 -2
- package/drag-drop/typings/{drag-placeholder.d.ts → directives/drag-placeholder.d.ts} +0 -0
- package/drag-drop/typings/{drag-preview.d.ts → directives/drag-preview.d.ts} +0 -0
- package/drag-drop/typings/directives/drag.d.ts +110 -0
- package/{typings/esm5/drag-drop → drag-drop/typings/directives}/drop-list-group.d.ts +3 -0
- package/drag-drop/typings/{drop-list.d.ts → directives/drop-list.d.ts} +32 -72
- package/drag-drop/typings/drag-drop-registry.d.ts +8 -3
- package/drag-drop/typings/drag-events.d.ts +14 -7
- package/{typings/esm5/drag-drop/drag.d.ts → drag-drop/typings/drag-ref.d.ts} +152 -83
- package/drag-drop/typings/drop-list-container.d.ts +19 -3
- package/drag-drop/typings/drop-list-ref.d.ts +234 -0
- package/drag-drop/typings/index.d.ts +1 -0
- package/drag-drop/typings/index.metadata.json +1 -1
- package/drag-drop/typings/public-api.d.ts +13 -6
- package/esm2015/a11y.js +306 -182
- package/esm2015/a11y.js.map +1 -1
- package/esm2015/accordion.js +16 -11
- package/esm2015/accordion.js.map +1 -1
- package/esm2015/bidi.js +13 -8
- package/esm2015/bidi.js.map +1 -1
- package/esm2015/cdk.js +7 -6
- package/esm2015/cdk.js.map +1 -1
- package/esm2015/coercion.js +25 -8
- package/esm2015/coercion.js.map +1 -1
- package/esm2015/collections.js +22 -7
- package/esm2015/collections.js.map +1 -1
- package/esm2015/drag-drop.js +1774 -864
- package/esm2015/drag-drop.js.map +1 -1
- package/esm2015/keycodes.js +14 -4
- package/esm2015/keycodes.js.map +1 -1
- package/esm2015/layout.js +29 -19
- package/esm2015/layout.js.map +1 -1
- package/esm2015/observers.js +16 -11
- package/esm2015/observers.js.map +1 -1
- package/esm2015/overlay.js +373 -213
- package/esm2015/overlay.js.map +1 -1
- package/esm2015/platform.js +53 -31
- package/esm2015/platform.js.map +1 -1
- package/esm2015/portal.js +14 -10
- package/esm2015/portal.js.map +1 -1
- package/esm2015/scrolling.js +111 -51
- package/esm2015/scrolling.js.map +1 -1
- package/esm2015/stepper.js +56 -30
- package/esm2015/stepper.js.map +1 -1
- package/esm2015/table.js +96 -48
- package/esm2015/table.js.map +1 -1
- package/esm2015/text-field.js +54 -37
- package/esm2015/text-field.js.map +1 -1
- package/esm2015/tree.js +55 -36
- package/esm2015/tree.js.map +1 -1
- package/esm5/a11y.es5.js +432 -201
- package/esm5/a11y.es5.js.map +1 -1
- package/esm5/accordion.es5.js +18 -11
- package/esm5/accordion.es5.js.map +1 -1
- package/esm5/bidi.es5.js +13 -8
- package/esm5/bidi.es5.js.map +1 -1
- package/esm5/cdk.es5.js +7 -6
- package/esm5/cdk.es5.js.map +1 -1
- package/esm5/coercion.es5.js +25 -8
- package/esm5/coercion.es5.js.map +1 -1
- package/esm5/collections.es5.js +35 -7
- package/esm5/collections.es5.js.map +1 -1
- package/esm5/drag-drop.es5.js +2358 -1035
- package/esm5/drag-drop.es5.js.map +1 -1
- package/esm5/keycodes.es5.js +14 -4
- package/esm5/keycodes.es5.js.map +1 -1
- package/esm5/layout.es5.js +31 -24
- package/esm5/layout.es5.js.map +1 -1
- package/esm5/observers.es5.js +30 -11
- package/esm5/observers.es5.js.map +1 -1
- package/esm5/overlay.es5.js +590 -244
- package/esm5/overlay.es5.js.map +1 -1
- package/esm5/platform.es5.js +52 -30
- package/esm5/platform.es5.js.map +1 -1
- package/esm5/portal.es5.js +19 -12
- package/esm5/portal.es5.js.map +1 -1
- package/esm5/scrolling.es5.js +150 -52
- package/esm5/scrolling.es5.js.map +1 -1
- package/esm5/stepper.es5.js +71 -30
- package/esm5/stepper.es5.js.map +1 -1
- package/esm5/table.es5.js +191 -53
- package/esm5/table.es5.js.map +1 -1
- package/esm5/text-field.es5.js +75 -37
- package/esm5/text-field.es5.js.map +1 -1
- package/esm5/tree.es5.js +74 -37
- package/esm5/tree.es5.js.map +1 -1
- package/overlay/typings/index.metadata.json +1 -1
- package/overlay/typings/overlay-directives.d.ts +0 -2
- package/overlay/typings/overlay-ref.d.ts +1 -1
- package/package.json +4 -4
- package/portal/typings/portal.d.ts +1 -1
- package/schematics/migration.json +5 -0
- package/schematics/ng-generate/drag-drop/files/__path__/__name@dasherize@if-flat__/__name@dasherize__.component.ts +2 -2
- package/schematics/ng-update/index.d.ts +2 -0
- package/schematics/ng-update/index.js +5 -0
- package/schematics/ng-update/index.js.map +1 -1
- package/schematics/ng-update/target-version.d.ts +7 -1
- package/schematics/ng-update/target-version.js +10 -0
- package/schematics/ng-update/target-version.js.map +1 -1
- package/schematics/ng-update/upgrade-data.js +2 -1
- package/schematics/ng-update/upgrade-data.js.map +1 -1
- package/schematics/ng-update/upgrade-rules/index.js +3 -2
- package/schematics/ng-update/upgrade-rules/index.js.map +1 -1
- package/schematics/utils/ast/ng-module-imports.d.ts +1 -1
- package/schematics/utils/ast/ng-module-imports.js +25 -13
- package/schematics/utils/ast/ng-module-imports.js.map +1 -1
- package/schematics/utils/get-project.js +2 -1
- package/schematics/utils/get-project.js.map +1 -1
- package/schematics/utils/parse5-element.js +3 -2
- package/schematics/utils/parse5-element.js.map +1 -1
- package/schematics/utils/project-targets.js +2 -1
- package/schematics/utils/project-targets.js.map +1 -1
- package/schematics/utils/version-agnostic-typescript.js +3 -2
- package/schematics/utils/version-agnostic-typescript.js.map +1 -1
- package/scrolling/typings/index.metadata.json +1 -1
- package/stepper/typings/index.metadata.json +1 -1
- package/stepper/typings/stepper.d.ts +13 -1
- package/text-field/typings/autosize.d.ts +6 -0
- package/text-field/typings/index.metadata.json +1 -1
- package/tree/typings/control/base-tree-control.d.ts +1 -1
- package/tree/typings/control/nested-tree-control.d.ts +2 -2
- package/tree/typings/control/tree-control.d.ts +1 -1
- package/tree/typings/nested-node.d.ts +5 -5
- package/typings/a11y/focus-monitor/focus-monitor.d.ts +20 -5
- package/typings/a11y/focus-trap/focus-trap.d.ts +2 -0
- package/typings/a11y/index.metadata.json +1 -1
- package/typings/coercion/element.d.ts +13 -0
- package/typings/coercion/index.metadata.json +1 -1
- package/typings/coercion/public-api.d.ts +1 -0
- package/typings/drag-drop/{drag-handle.d.ts → directives/drag-handle.d.ts} +6 -2
- package/typings/drag-drop/{drag-placeholder.d.ts → directives/drag-placeholder.d.ts} +0 -0
- package/typings/drag-drop/{drag-preview.d.ts → directives/drag-preview.d.ts} +0 -0
- package/typings/drag-drop/directives/drag.d.ts +110 -0
- package/typings/drag-drop/{drop-list-group.d.ts → directives/drop-list-group.d.ts} +3 -0
- package/typings/{esm5/drag-drop → drag-drop/directives}/drop-list.d.ts +32 -72
- package/typings/drag-drop/drag-drop-registry.d.ts +8 -3
- package/typings/drag-drop/drag-events.d.ts +14 -7
- package/typings/drag-drop/{drag.d.ts → drag-ref.d.ts} +152 -83
- package/typings/drag-drop/drop-list-container.d.ts +19 -3
- package/typings/drag-drop/drop-list-ref.d.ts +234 -0
- package/typings/drag-drop/index.d.ts +1 -0
- package/typings/drag-drop/index.metadata.json +1 -1
- package/typings/drag-drop/public-api.d.ts +13 -6
- package/typings/esm5/a11y/focus-monitor/focus-monitor.d.ts +20 -5
- package/typings/esm5/a11y/focus-trap/focus-trap.d.ts +2 -0
- package/typings/esm5/a11y/index.metadata.json +1 -1
- package/typings/esm5/coercion/element.d.ts +13 -0
- package/typings/esm5/coercion/index.metadata.json +1 -1
- package/typings/esm5/coercion/public-api.d.ts +1 -0
- package/typings/esm5/drag-drop/{drag-handle.d.ts → directives/drag-handle.d.ts} +6 -2
- package/typings/esm5/drag-drop/{drag-placeholder.d.ts → directives/drag-placeholder.d.ts} +0 -0
- package/typings/esm5/drag-drop/{drag-preview.d.ts → directives/drag-preview.d.ts} +0 -0
- package/typings/esm5/drag-drop/directives/drag.d.ts +110 -0
- package/{drag-drop/typings → typings/esm5/drag-drop/directives}/drop-list-group.d.ts +3 -0
- package/typings/{drag-drop → esm5/drag-drop/directives}/drop-list.d.ts +32 -72
- package/typings/esm5/drag-drop/drag-drop-registry.d.ts +8 -3
- package/typings/esm5/drag-drop/drag-events.d.ts +14 -7
- package/{drag-drop/typings/drag.d.ts → typings/esm5/drag-drop/drag-ref.d.ts} +152 -83
- package/typings/esm5/drag-drop/drop-list-container.d.ts +19 -3
- package/typings/esm5/drag-drop/drop-list-ref.d.ts +234 -0
- package/typings/esm5/drag-drop/index.d.ts +1 -0
- package/typings/esm5/drag-drop/index.metadata.json +1 -1
- package/typings/esm5/drag-drop/public-api.d.ts +13 -6
- package/typings/esm5/index.metadata.json +1 -1
- package/typings/esm5/overlay/index.metadata.json +1 -1
- package/typings/esm5/overlay/overlay-directives.d.ts +0 -2
- package/typings/esm5/overlay/overlay-ref.d.ts +1 -1
- package/typings/esm5/portal/portal.d.ts +1 -1
- package/typings/esm5/scrolling/index.metadata.json +1 -1
- package/typings/esm5/stepper/index.metadata.json +1 -1
- package/typings/esm5/stepper/stepper.d.ts +13 -1
- package/typings/esm5/text-field/autosize.d.ts +6 -0
- package/typings/esm5/text-field/index.metadata.json +1 -1
- package/typings/esm5/tree/control/base-tree-control.d.ts +1 -1
- package/typings/esm5/tree/control/nested-tree-control.d.ts +2 -2
- package/typings/esm5/tree/control/tree-control.d.ts +1 -1
- package/typings/esm5/tree/nested-node.d.ts +5 -5
- package/typings/index.metadata.json +1 -1
- package/typings/overlay/index.metadata.json +1 -1
- package/typings/overlay/overlay-directives.d.ts +0 -2
- package/typings/overlay/overlay-ref.d.ts +1 -1
- package/typings/portal/portal.d.ts +1 -1
- package/typings/schematics/ng-update/index.d.ts +2 -0
- package/typings/schematics/ng-update/target-version.d.ts +7 -1
- package/typings/schematics/utils/ast/ng-module-imports.d.ts +1 -1
- package/typings/scrolling/index.metadata.json +1 -1
- package/typings/stepper/index.metadata.json +1 -1
- package/typings/stepper/stepper.d.ts +13 -1
- package/typings/text-field/autosize.d.ts +6 -0
- package/typings/text-field/index.metadata.json +1 -1
- package/typings/tree/control/base-tree-control.d.ts +1 -1
- package/typings/tree/control/nested-tree-control.d.ts +2 -2
- package/typings/tree/control/tree-control.d.ts +1 -1
- package/typings/tree/nested-node.d.ts +5 -5
package/esm2015/drag-drop.js
CHANGED
|
@@ -5,73 +5,136 @@
|
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
|
-
import { Injectable, NgZone, Inject, ContentChildren, ElementRef, EventEmitter, forwardRef, Input, Output, Optional, Directive, ChangeDetectorRef,
|
|
8
|
+
import { InjectionToken, Injectable, NgZone, Inject, NgModule, ContentChildren, ElementRef, EventEmitter, forwardRef, Input, Output, Optional, Directive, ChangeDetectorRef, SkipSelf, ContentChild, ViewContainerRef, TemplateRef, defineInjectable, inject } from '@angular/core';
|
|
9
9
|
import { DOCUMENT } from '@angular/common';
|
|
10
10
|
import { normalizePassiveListenerOptions } from '@angular/cdk/platform';
|
|
11
|
-
import { Subject, Observable,
|
|
12
|
-
import { coerceBooleanProperty, coerceArray } from '@angular/cdk/coercion';
|
|
11
|
+
import { Subject, Subscription, Observable, merge } from 'rxjs';
|
|
12
|
+
import { coerceBooleanProperty, coerceElement, coerceArray } from '@angular/cdk/coercion';
|
|
13
13
|
import { Directionality } from '@angular/cdk/bidi';
|
|
14
14
|
import { ViewportRuler } from '@angular/cdk/scrolling';
|
|
15
|
-
import { startWith, take } from 'rxjs/operators';
|
|
15
|
+
import { startWith, take, map, takeUntil, switchMap, tap } from 'rxjs/operators';
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* @fileoverview added by tsickle
|
|
19
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
19
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
20
20
|
*/
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* @
|
|
25
|
-
|
|
22
|
+
* Injection token that is used to provide a CdkDropList instance to CdkDrag.
|
|
23
|
+
* Used for avoiding circular imports.
|
|
24
|
+
* @type {?}
|
|
25
|
+
*/
|
|
26
|
+
const CDK_DROP_LIST = new InjectionToken('CDK_DROP_LIST');
|
|
27
|
+
/**
|
|
28
|
+
* Injection token that is used to provide a CdkDropList instance to CdkDrag.
|
|
29
|
+
* Used for avoiding circular imports.
|
|
30
|
+
* @deprecated Use `CDK_DROP_LIST` instead.
|
|
31
|
+
* \@breaking-change 8.0.0
|
|
32
|
+
* @type {?}
|
|
33
|
+
*/
|
|
34
|
+
const CDK_DROP_LIST_CONTAINER = CDK_DROP_LIST;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @fileoverview added by tsickle
|
|
38
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @fileoverview added by tsickle
|
|
43
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Moves an item one index in an array to another.
|
|
48
|
+
* @template T
|
|
49
|
+
* @param {?} array Array in which to move the item.
|
|
50
|
+
* @param {?} fromIndex Starting index of the item.
|
|
51
|
+
* @param {?} toIndex Index to which the item should be moved.
|
|
26
52
|
* @return {?}
|
|
27
53
|
*/
|
|
28
|
-
function
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
54
|
+
function moveItemInArray(array, fromIndex, toIndex) {
|
|
55
|
+
/** @type {?} */
|
|
56
|
+
const from = clamp(fromIndex, array.length - 1);
|
|
57
|
+
/** @type {?} */
|
|
58
|
+
const to = clamp(toIndex, array.length - 1);
|
|
59
|
+
if (from === to) {
|
|
60
|
+
return;
|
|
33
61
|
}
|
|
34
|
-
|
|
62
|
+
/** @type {?} */
|
|
63
|
+
const target = array[from];
|
|
64
|
+
/** @type {?} */
|
|
65
|
+
const delta = to < from ? -1 : 1;
|
|
66
|
+
for (let i = from; i !== to; i += delta) {
|
|
67
|
+
array[i] = array[i + delta];
|
|
68
|
+
}
|
|
69
|
+
array[to] = target;
|
|
35
70
|
}
|
|
36
71
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* @param {?}
|
|
40
|
-
* @param {?}
|
|
72
|
+
* Moves an item from one array to another.
|
|
73
|
+
* @template T
|
|
74
|
+
* @param {?} currentArray Array from which to transfer the item.
|
|
75
|
+
* @param {?} targetArray Array into which to put the item.
|
|
76
|
+
* @param {?} currentIndex Index of the item in its current array.
|
|
77
|
+
* @param {?} targetIndex Index at which to insert the item.
|
|
41
78
|
* @return {?}
|
|
42
79
|
*/
|
|
43
|
-
function
|
|
80
|
+
function transferArrayItem(currentArray, targetArray, currentIndex, targetIndex) {
|
|
44
81
|
/** @type {?} */
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
82
|
+
const from = clamp(currentIndex, currentArray.length - 1);
|
|
83
|
+
/** @type {?} */
|
|
84
|
+
const to = clamp(targetIndex, targetArray.length);
|
|
85
|
+
if (currentArray.length) {
|
|
86
|
+
targetArray.splice(to, 0, currentArray.splice(from, 1)[0]);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Copies an item from one array to another, leaving it in its
|
|
91
|
+
* original position in current array.
|
|
92
|
+
* @template T
|
|
93
|
+
* @param {?} currentArray Array from which to copy the item.
|
|
94
|
+
* @param {?} targetArray Array into which is copy the item.
|
|
95
|
+
* @param {?} currentIndex Index of the item in its current array.
|
|
96
|
+
* @param {?} targetIndex Index at which to insert the item.
|
|
97
|
+
*
|
|
98
|
+
* @return {?}
|
|
99
|
+
*/
|
|
100
|
+
function copyArrayItem(currentArray, targetArray, currentIndex, targetIndex) {
|
|
101
|
+
/** @type {?} */
|
|
102
|
+
const to = clamp(targetIndex, targetArray.length);
|
|
103
|
+
if (currentArray.length) {
|
|
104
|
+
targetArray.splice(to, 0, currentArray[currentIndex]);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Clamps a number between zero and a maximum.
|
|
109
|
+
* @param {?} value
|
|
110
|
+
* @param {?} max
|
|
111
|
+
* @return {?}
|
|
112
|
+
*/
|
|
113
|
+
function clamp(value, max) {
|
|
114
|
+
return Math.max(0, Math.min(max, value));
|
|
55
115
|
}
|
|
56
116
|
|
|
57
117
|
/**
|
|
58
118
|
* @fileoverview added by tsickle
|
|
59
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
119
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
60
120
|
*/
|
|
61
|
-
/**
|
|
121
|
+
/**
|
|
62
122
|
* Event options that can be used to bind an active, capturing event.
|
|
63
|
-
|
|
123
|
+
* @type {?}
|
|
124
|
+
*/
|
|
64
125
|
const activeCapturingEventOptions = normalizePassiveListenerOptions({
|
|
65
126
|
passive: false,
|
|
66
127
|
capture: true
|
|
67
128
|
});
|
|
68
|
-
// unsupported: template constraints.
|
|
69
129
|
/**
|
|
70
130
|
* Service that keeps track of all the drag item and drop container
|
|
71
131
|
* instances, and manages global event listeners on the `document`.
|
|
72
132
|
* \@docs-private
|
|
73
133
|
* @template I, C
|
|
74
134
|
*/
|
|
135
|
+
// Note: this class is generic, rather than referencing CdkDrag and CdkDropList directly, in order
|
|
136
|
+
// to avoid circular imports. If we were to reference them here, importing the registry into the
|
|
137
|
+
// classes that are registering themselves will introduce a circular import.
|
|
75
138
|
class DragDropRegistry {
|
|
76
139
|
/**
|
|
77
140
|
* @param {?} _ngZone
|
|
@@ -106,9 +169,10 @@ class DragDropRegistry {
|
|
|
106
169
|
*/
|
|
107
170
|
this.pointerUp = new Subject();
|
|
108
171
|
/**
|
|
109
|
-
*
|
|
172
|
+
* Event listener that will prevent the default browser action while the user is dragging.
|
|
173
|
+
* @param event Event whose default action should be prevented.
|
|
110
174
|
*/
|
|
111
|
-
this.
|
|
175
|
+
this._preventDefaultWhileDragging = (event) => {
|
|
112
176
|
if (this._activeDragInstances.size) {
|
|
113
177
|
event.preventDefault();
|
|
114
178
|
}
|
|
@@ -142,7 +206,7 @@ class DragDropRegistry {
|
|
|
142
206
|
this._ngZone.runOutsideAngular(() => {
|
|
143
207
|
// The event handler has to be explicitly active,
|
|
144
208
|
// because newer browsers make it passive by default.
|
|
145
|
-
this._document.addEventListener('touchmove', this.
|
|
209
|
+
this._document.addEventListener('touchmove', this._preventDefaultWhileDragging, activeCapturingEventOptions);
|
|
146
210
|
});
|
|
147
211
|
}
|
|
148
212
|
}
|
|
@@ -163,7 +227,7 @@ class DragDropRegistry {
|
|
|
163
227
|
this._dragInstances.delete(drag);
|
|
164
228
|
this.stopDragging(drag);
|
|
165
229
|
if (this._dragInstances.size === 0) {
|
|
166
|
-
this._document.removeEventListener('touchmove', this.
|
|
230
|
+
this._document.removeEventListener('touchmove', this._preventDefaultWhileDragging, activeCapturingEventOptions);
|
|
167
231
|
}
|
|
168
232
|
}
|
|
169
233
|
/**
|
|
@@ -181,26 +245,31 @@ class DragDropRegistry {
|
|
|
181
245
|
const moveEvent = isTouchEvent ? 'touchmove' : 'mousemove';
|
|
182
246
|
/** @type {?} */
|
|
183
247
|
const upEvent = isTouchEvent ? 'touchend' : 'mouseup';
|
|
184
|
-
// We need to disable the native interactions on the entire body, because
|
|
185
|
-
// the user can start marking text if they drag too far in Safari.
|
|
186
|
-
toggleNativeDragInteractions(this._document.body, false);
|
|
187
248
|
// We explicitly bind __active__ listeners here, because newer browsers will default to
|
|
188
249
|
// passive ones for `mousemove` and `touchmove`. The events need to be active, because we
|
|
189
250
|
// use `preventDefault` to prevent the page from scrolling while the user is dragging.
|
|
190
251
|
this._globalListeners
|
|
191
252
|
.set(moveEvent, {
|
|
192
|
-
handler: e => this.pointerMove.next(e),
|
|
253
|
+
handler: (e) => this.pointerMove.next((/** @type {?} */ (e))),
|
|
193
254
|
options: activeCapturingEventOptions
|
|
194
255
|
})
|
|
195
256
|
.set(upEvent, {
|
|
196
|
-
handler: e => this.pointerUp.next(e),
|
|
257
|
+
handler: (e) => this.pointerUp.next((/** @type {?} */ (e))),
|
|
197
258
|
options: true
|
|
259
|
+
})
|
|
260
|
+
// Preventing the default action on `mousemove` isn't enough to disable text selection
|
|
261
|
+
// on Safari so we need to prevent the selection event as well. Alternatively this can
|
|
262
|
+
// be done by setting `user-select: none` on the `body`, however it has causes a style
|
|
263
|
+
// recalculation which can be expensive on pages with a lot of elements.
|
|
264
|
+
.set('selectstart', {
|
|
265
|
+
handler: this._preventDefaultWhileDragging,
|
|
266
|
+
options: activeCapturingEventOptions
|
|
198
267
|
});
|
|
199
268
|
// TODO(crisbeto): prevent mouse wheel scrolling while
|
|
200
269
|
// dragging until we've set up proper scroll handling.
|
|
201
270
|
if (!isTouchEvent) {
|
|
202
271
|
this._globalListeners.set('wheel', {
|
|
203
|
-
handler: this.
|
|
272
|
+
handler: this._preventDefaultWhileDragging,
|
|
204
273
|
options: activeCapturingEventOptions
|
|
205
274
|
});
|
|
206
275
|
}
|
|
@@ -220,7 +289,6 @@ class DragDropRegistry {
|
|
|
220
289
|
this._activeDragInstances.delete(drag);
|
|
221
290
|
if (this._activeDragInstances.size === 0) {
|
|
222
291
|
this._clearGlobalListeners();
|
|
223
|
-
toggleNativeDragInteractions(this._document.body, true);
|
|
224
292
|
}
|
|
225
293
|
}
|
|
226
294
|
/**
|
|
@@ -233,6 +301,8 @@ class DragDropRegistry {
|
|
|
233
301
|
}
|
|
234
302
|
/**
|
|
235
303
|
* Gets a drop container by its id.
|
|
304
|
+
* @deprecated No longer being used. To be removed.
|
|
305
|
+
* \@breaking-change 8.0.0
|
|
236
306
|
* @param {?} id
|
|
237
307
|
* @return {?}
|
|
238
308
|
*/
|
|
@@ -251,6 +321,7 @@ class DragDropRegistry {
|
|
|
251
321
|
}
|
|
252
322
|
/**
|
|
253
323
|
* Clears out the global event listeners from the `document`.
|
|
324
|
+
* @private
|
|
254
325
|
* @return {?}
|
|
255
326
|
*/
|
|
256
327
|
_clearGlobalListeners() {
|
|
@@ -272,19 +343,60 @@ DragDropRegistry.ctorParameters = () => [
|
|
|
272
343
|
|
|
273
344
|
/**
|
|
274
345
|
* @fileoverview added by tsickle
|
|
275
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
346
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
276
347
|
*/
|
|
277
|
-
/**
|
|
348
|
+
/**
|
|
278
349
|
* Injection token that can be used for a `CdkDrag` to provide itself as a parent to the
|
|
279
350
|
* drag-specific child directive (`CdkDragHandle`, `CdkDragPreview` etc.). Used primarily
|
|
280
351
|
* to avoid circular imports.
|
|
281
352
|
* \@docs-private
|
|
282
|
-
|
|
353
|
+
* @type {?}
|
|
354
|
+
*/
|
|
283
355
|
const CDK_DRAG_PARENT = new InjectionToken('CDK_DRAG_PARENT');
|
|
284
356
|
|
|
285
357
|
/**
|
|
286
358
|
* @fileoverview added by tsickle
|
|
287
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
359
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
360
|
+
*/
|
|
361
|
+
/**
|
|
362
|
+
* Shallow-extends a stylesheet object with another stylesheet object.
|
|
363
|
+
* \@docs-private
|
|
364
|
+
* @param {?} dest
|
|
365
|
+
* @param {?} source
|
|
366
|
+
* @return {?}
|
|
367
|
+
*/
|
|
368
|
+
function extendStyles(dest, source) {
|
|
369
|
+
for (let key in source) {
|
|
370
|
+
if (source.hasOwnProperty(key)) {
|
|
371
|
+
dest[(/** @type {?} */ (key))] = source[(/** @type {?} */ (key))];
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
return dest;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Toggles whether the native drag interactions should be enabled for an element.
|
|
378
|
+
* \@docs-private
|
|
379
|
+
* @param {?} element Element on which to toggle the drag interactions.
|
|
380
|
+
* @param {?} enable Whether the drag interactions should be enabled.
|
|
381
|
+
* @return {?}
|
|
382
|
+
*/
|
|
383
|
+
function toggleNativeDragInteractions(element, enable) {
|
|
384
|
+
/** @type {?} */
|
|
385
|
+
const userSelect = enable ? '' : 'none';
|
|
386
|
+
extendStyles(element.style, {
|
|
387
|
+
touchAction: enable ? '' : 'none',
|
|
388
|
+
webkitUserDrag: enable ? '' : 'none',
|
|
389
|
+
webkitTapHighlightColor: enable ? '' : 'transparent',
|
|
390
|
+
userSelect: userSelect,
|
|
391
|
+
msUserSelect: userSelect,
|
|
392
|
+
webkitUserSelect: userSelect,
|
|
393
|
+
MozUserSelect: userSelect
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* @fileoverview added by tsickle
|
|
399
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
288
400
|
*/
|
|
289
401
|
/**
|
|
290
402
|
* Handle that can be used to drag and CdkDrag instance.
|
|
@@ -296,6 +408,10 @@ class CdkDragHandle {
|
|
|
296
408
|
*/
|
|
297
409
|
constructor(element, parentDrag) {
|
|
298
410
|
this.element = element;
|
|
411
|
+
/**
|
|
412
|
+
* Emits when the state of the handle has changed.
|
|
413
|
+
*/
|
|
414
|
+
this._stateChanges = new Subject();
|
|
299
415
|
this._disabled = false;
|
|
300
416
|
this._parentDrag = parentDrag;
|
|
301
417
|
toggleNativeDragInteractions(element.nativeElement, false);
|
|
@@ -311,6 +427,13 @@ class CdkDragHandle {
|
|
|
311
427
|
*/
|
|
312
428
|
set disabled(value) {
|
|
313
429
|
this._disabled = coerceBooleanProperty(value);
|
|
430
|
+
this._stateChanges.next(this);
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* @return {?}
|
|
434
|
+
*/
|
|
435
|
+
ngOnDestroy() {
|
|
436
|
+
this._stateChanges.complete();
|
|
314
437
|
}
|
|
315
438
|
}
|
|
316
439
|
CdkDragHandle.decorators = [
|
|
@@ -332,7 +455,7 @@ CdkDragHandle.propDecorators = {
|
|
|
332
455
|
|
|
333
456
|
/**
|
|
334
457
|
* @fileoverview added by tsickle
|
|
335
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
458
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
336
459
|
*/
|
|
337
460
|
/**
|
|
338
461
|
* Element that will be used as a template for the placeholder of a CdkDrag when
|
|
@@ -362,7 +485,7 @@ CdkDragPlaceholder.propDecorators = {
|
|
|
362
485
|
|
|
363
486
|
/**
|
|
364
487
|
* @fileoverview added by tsickle
|
|
365
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
488
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
366
489
|
*/
|
|
367
490
|
/**
|
|
368
491
|
* Element that will be used as a template for the preview
|
|
@@ -392,17 +515,7 @@ CdkDragPreview.propDecorators = {
|
|
|
392
515
|
|
|
393
516
|
/**
|
|
394
517
|
* @fileoverview added by tsickle
|
|
395
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
396
|
-
*/
|
|
397
|
-
/** *
|
|
398
|
-
* Injection token that is used to provide a CdkDropList instance to CdkDrag.
|
|
399
|
-
* Used for avoiding circular imports.
|
|
400
|
-
@type {?} */
|
|
401
|
-
const CDK_DROP_LIST_CONTAINER = new InjectionToken('CDK_DROP_LIST_CONTAINER');
|
|
402
|
-
|
|
403
|
-
/**
|
|
404
|
-
* @fileoverview added by tsickle
|
|
405
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
518
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
406
519
|
*/
|
|
407
520
|
|
|
408
521
|
/**
|
|
@@ -411,6 +524,7 @@ const CDK_DROP_LIST_CONTAINER = new InjectionToken('CDK_DROP_LIST_CONTAINER');
|
|
|
411
524
|
* @return {?}
|
|
412
525
|
*/
|
|
413
526
|
function parseCssTimeUnitsToMs(value) {
|
|
527
|
+
// Some browsers will return it in seconds, whereas others will return milliseconds.
|
|
414
528
|
/** @type {?} */
|
|
415
529
|
const multiplier = value.toLowerCase().indexOf('ms') > -1 ? 1 : 1000;
|
|
416
530
|
return parseFloat(value) * multiplier;
|
|
@@ -431,6 +545,8 @@ function getTransformTransitionDurationInMs(element) {
|
|
|
431
545
|
if (!property) {
|
|
432
546
|
return 0;
|
|
433
547
|
}
|
|
548
|
+
// Get the index of the property that we're interested in and match
|
|
549
|
+
// it up to the same index in `transition-delay` and `transition-duration`.
|
|
434
550
|
/** @type {?} */
|
|
435
551
|
const propertyIndex = transitionedProperties.indexOf(property);
|
|
436
552
|
/** @type {?} */
|
|
@@ -454,62 +570,51 @@ function parseCssPropertyValue(computedStyle, name) {
|
|
|
454
570
|
|
|
455
571
|
/**
|
|
456
572
|
* @fileoverview added by tsickle
|
|
457
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
573
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
458
574
|
*/
|
|
459
|
-
/** *
|
|
460
|
-
* Injection token that can be used to configure the behavior of `CdkDrag`.
|
|
461
|
-
@type {?} */
|
|
462
|
-
const CDK_DRAG_CONFIG = new InjectionToken('CDK_DRAG_CONFIG', {
|
|
463
|
-
providedIn: 'root',
|
|
464
|
-
factory: CDK_DRAG_CONFIG_FACTORY
|
|
465
|
-
});
|
|
466
575
|
/**
|
|
467
|
-
* \@docs-private
|
|
468
|
-
* @return {?}
|
|
469
|
-
*/
|
|
470
|
-
function CDK_DRAG_CONFIG_FACTORY() {
|
|
471
|
-
return { dragStartThreshold: 5, pointerDirectionChangeThreshold: 5 };
|
|
472
|
-
}
|
|
473
|
-
/** *
|
|
474
576
|
* Options that can be used to bind a passive event listener.
|
|
475
|
-
|
|
577
|
+
* @type {?}
|
|
578
|
+
*/
|
|
476
579
|
const passiveEventListenerOptions = normalizePassiveListenerOptions({ passive: true });
|
|
477
|
-
/**
|
|
580
|
+
/**
|
|
478
581
|
* Options that can be used to bind an active event listener.
|
|
479
|
-
|
|
582
|
+
* @type {?}
|
|
583
|
+
*/
|
|
480
584
|
const activeEventListenerOptions = normalizePassiveListenerOptions({ passive: false });
|
|
481
|
-
/**
|
|
585
|
+
/**
|
|
482
586
|
* Time in milliseconds for which to ignore mouse events, after
|
|
483
587
|
* receiving a touch event. Used to avoid doing double work for
|
|
484
588
|
* touch devices where the browser fires fake mouse events, in
|
|
485
589
|
* addition to touch events.
|
|
486
|
-
|
|
590
|
+
* @type {?}
|
|
591
|
+
*/
|
|
487
592
|
const MOUSE_EVENT_IGNORE_TIME = 800;
|
|
488
593
|
/**
|
|
489
|
-
*
|
|
594
|
+
* Reference to a draggable item. Used to manipulate or dispose of the item.
|
|
595
|
+
* \@docs-private
|
|
490
596
|
* @template T
|
|
491
597
|
*/
|
|
492
|
-
class
|
|
598
|
+
class DragRef {
|
|
493
599
|
/**
|
|
494
600
|
* @param {?} element
|
|
495
|
-
* @param {?}
|
|
496
|
-
* @param {?} document
|
|
601
|
+
* @param {?} _document
|
|
497
602
|
* @param {?} _ngZone
|
|
498
603
|
* @param {?} _viewContainerRef
|
|
499
604
|
* @param {?} _viewportRuler
|
|
500
605
|
* @param {?} _dragDropRegistry
|
|
501
606
|
* @param {?} _config
|
|
502
|
-
* @param {
|
|
607
|
+
* @param {?=} dropContainer
|
|
608
|
+
* @param {?=} _dir
|
|
503
609
|
*/
|
|
504
|
-
constructor(element,
|
|
505
|
-
|
|
506
|
-
this.element = element;
|
|
507
|
-
this.dropContainer = dropContainer;
|
|
610
|
+
constructor(element, _document, _ngZone, _viewContainerRef, _viewportRuler, _dragDropRegistry, _config, dropContainer, _dir) {
|
|
611
|
+
this._document = _document;
|
|
508
612
|
this._ngZone = _ngZone;
|
|
509
613
|
this._viewContainerRef = _viewContainerRef;
|
|
510
614
|
this._viewportRuler = _viewportRuler;
|
|
511
615
|
this._dragDropRegistry = _dragDropRegistry;
|
|
512
616
|
this._config = _config;
|
|
617
|
+
this.dropContainer = dropContainer;
|
|
513
618
|
this._dir = _dir;
|
|
514
619
|
/**
|
|
515
620
|
* CSS `transform` applied to the element when it isn't being dragged. We need a
|
|
@@ -540,35 +645,55 @@ class CdkDrag {
|
|
|
540
645
|
*/
|
|
541
646
|
this._pointerUpSubscription = Subscription.EMPTY;
|
|
542
647
|
/**
|
|
543
|
-
*
|
|
648
|
+
* Cached reference to the boundary element.
|
|
649
|
+
*/
|
|
650
|
+
this._boundaryElement = null;
|
|
651
|
+
/**
|
|
652
|
+
* Whether the native dragging interactions have been enabled on the root element.
|
|
653
|
+
*/
|
|
654
|
+
this._nativeInteractionsEnabled = true;
|
|
655
|
+
/**
|
|
656
|
+
* Elements that can be used to drag the draggable item.
|
|
657
|
+
*/
|
|
658
|
+
this._handles = [];
|
|
659
|
+
/**
|
|
660
|
+
* Registered handles that are currently disabled.
|
|
544
661
|
*/
|
|
545
|
-
this.
|
|
662
|
+
this._disabledHandles = new Set();
|
|
546
663
|
this._disabled = false;
|
|
664
|
+
/**
|
|
665
|
+
* Emits as the drag sequence is being prepared.
|
|
666
|
+
*/
|
|
667
|
+
this.beforeStarted = new Subject();
|
|
547
668
|
/**
|
|
548
669
|
* Emits when the user starts dragging the item.
|
|
549
670
|
*/
|
|
550
|
-
this.started = new
|
|
671
|
+
this.started = new Subject();
|
|
672
|
+
/**
|
|
673
|
+
* Emits when the user has released a drag item, before any animations have started.
|
|
674
|
+
*/
|
|
675
|
+
this.released = new Subject();
|
|
551
676
|
/**
|
|
552
677
|
* Emits when the user stops dragging an item in the container.
|
|
553
678
|
*/
|
|
554
|
-
this.ended = new
|
|
679
|
+
this.ended = new Subject();
|
|
555
680
|
/**
|
|
556
681
|
* Emits when the user has moved the item into a new container.
|
|
557
682
|
*/
|
|
558
|
-
this.entered = new
|
|
683
|
+
this.entered = new Subject();
|
|
559
684
|
/**
|
|
560
685
|
* Emits when the user removes the item its container by dragging it into another container.
|
|
561
686
|
*/
|
|
562
|
-
this.exited = new
|
|
687
|
+
this.exited = new Subject();
|
|
563
688
|
/**
|
|
564
689
|
* Emits when the user drops the item inside a container.
|
|
565
690
|
*/
|
|
566
|
-
this.dropped = new
|
|
691
|
+
this.dropped = new Subject();
|
|
567
692
|
/**
|
|
568
693
|
* Emits as the user is dragging the item. Use with caution,
|
|
569
694
|
* because this event will fire for every pixel that the user has dragged.
|
|
570
695
|
*/
|
|
571
|
-
this.moved = Observable
|
|
696
|
+
this.moved = new Observable((observer) => {
|
|
572
697
|
/** @type {?} */
|
|
573
698
|
const subscription = this._moveEvents.subscribe(observer);
|
|
574
699
|
this._moveEventSubscriptions++;
|
|
@@ -581,20 +706,17 @@ class CdkDrag {
|
|
|
581
706
|
* Handler for the `mousedown`/`touchstart` events.
|
|
582
707
|
*/
|
|
583
708
|
this._pointerDown = (event) => {
|
|
584
|
-
|
|
585
|
-
const handles = this.getChildHandles();
|
|
709
|
+
this.beforeStarted.next();
|
|
586
710
|
// Delegate the event based on whether it started from a handle or the element itself.
|
|
587
|
-
if (
|
|
711
|
+
if (this._handles.length) {
|
|
588
712
|
/** @type {?} */
|
|
589
|
-
const targetHandle =
|
|
590
|
-
/** @type {?} */
|
|
591
|
-
const element = handle.element.nativeElement;
|
|
713
|
+
const targetHandle = this._handles.find(handle => {
|
|
592
714
|
/** @type {?} */
|
|
593
715
|
const target = event.target;
|
|
594
|
-
return !!target && (target ===
|
|
716
|
+
return !!target && (target === handle || handle.contains((/** @type {?} */ (target))));
|
|
595
717
|
});
|
|
596
|
-
if (targetHandle && !targetHandle
|
|
597
|
-
this._initializeDragSequence(targetHandle
|
|
718
|
+
if (targetHandle && !this._disabledHandles.has(targetHandle) && !this.disabled) {
|
|
719
|
+
this._initializeDragSequence(targetHandle, event);
|
|
598
720
|
}
|
|
599
721
|
}
|
|
600
722
|
else if (!this.disabled) {
|
|
@@ -605,9 +727,9 @@ class CdkDrag {
|
|
|
605
727
|
* Handler that is invoked when the user moves their pointer after they've initiated a drag.
|
|
606
728
|
*/
|
|
607
729
|
this._pointerMove = (event) => {
|
|
608
|
-
/** @type {?} */
|
|
609
|
-
const pointerPosition = this._getConstrainedPointerPosition(event);
|
|
610
730
|
if (!this._hasStartedDragging) {
|
|
731
|
+
/** @type {?} */
|
|
732
|
+
const pointerPosition = this._getPointerPositionOnPage(event);
|
|
611
733
|
/** @type {?} */
|
|
612
734
|
const distanceX = Math.abs(pointerPosition.x - this._pickupPositionOnPage.x);
|
|
613
735
|
/** @type {?} */
|
|
@@ -622,24 +744,42 @@ class CdkDrag {
|
|
|
622
744
|
}
|
|
623
745
|
return;
|
|
624
746
|
}
|
|
747
|
+
// We only need the preview dimensions if we have a boundary element.
|
|
748
|
+
if (this._boundaryElement) {
|
|
749
|
+
// Cache the preview element rect if we haven't cached it already or if
|
|
750
|
+
// we cached it too early before the element dimensions were computed.
|
|
751
|
+
if (!this._previewRect || (!this._previewRect.width && !this._previewRect.height)) {
|
|
752
|
+
this._previewRect = (this._preview || this._rootElement).getBoundingClientRect();
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
/** @type {?} */
|
|
756
|
+
const constrainedPointerPosition = this._getConstrainedPointerPosition(event);
|
|
625
757
|
this._hasMoved = true;
|
|
626
758
|
event.preventDefault();
|
|
627
|
-
this._updatePointerDirectionDelta(
|
|
759
|
+
this._updatePointerDirectionDelta(constrainedPointerPosition);
|
|
628
760
|
if (this.dropContainer) {
|
|
629
|
-
this._updateActiveDropContainer(
|
|
761
|
+
this._updateActiveDropContainer(constrainedPointerPosition);
|
|
630
762
|
}
|
|
631
763
|
else {
|
|
632
764
|
/** @type {?} */
|
|
633
765
|
const activeTransform = this._activeTransform;
|
|
634
766
|
activeTransform.x =
|
|
635
|
-
|
|
767
|
+
constrainedPointerPosition.x - this._pickupPositionOnPage.x + this._passiveTransform.x;
|
|
636
768
|
activeTransform.y =
|
|
637
|
-
|
|
769
|
+
constrainedPointerPosition.y - this._pickupPositionOnPage.y + this._passiveTransform.y;
|
|
638
770
|
/** @type {?} */
|
|
639
771
|
const transform = getTransform(activeTransform.x, activeTransform.y);
|
|
640
|
-
// Preserve the previous `transform` value, if there was one.
|
|
772
|
+
// Preserve the previous `transform` value, if there was one. Note that we apply our own
|
|
773
|
+
// transform before the user's, because things like rotation can affect which direction
|
|
774
|
+
// the element will be translated towards.
|
|
641
775
|
this._rootElement.style.transform = this._initialTransform ?
|
|
642
|
-
|
|
776
|
+
transform + ' ' + this._initialTransform : transform;
|
|
777
|
+
// Apply transform as attribute if dragging and svg element to work for IE
|
|
778
|
+
if (typeof SVGElement !== 'undefined' && this._rootElement instanceof SVGElement) {
|
|
779
|
+
/** @type {?} */
|
|
780
|
+
const appliedTransform = `translate(${activeTransform.x} ${activeTransform.y})`;
|
|
781
|
+
this._rootElement.setAttribute('transform', appliedTransform);
|
|
782
|
+
}
|
|
643
783
|
}
|
|
644
784
|
// Since this event gets fired for every pixel while dragging, we only
|
|
645
785
|
// want to fire it if the consumer opted into it. Also we have to
|
|
@@ -648,7 +788,7 @@ class CdkDrag {
|
|
|
648
788
|
this._ngZone.run(() => {
|
|
649
789
|
this._moveEvents.next({
|
|
650
790
|
source: this,
|
|
651
|
-
pointerPosition,
|
|
791
|
+
pointerPosition: constrainedPointerPosition,
|
|
652
792
|
event,
|
|
653
793
|
delta: this._pointerDirectionDelta
|
|
654
794
|
});
|
|
@@ -658,31 +798,39 @@ class CdkDrag {
|
|
|
658
798
|
/**
|
|
659
799
|
* Handler that is invoked when the user lifts their pointer up, after initiating a drag.
|
|
660
800
|
*/
|
|
661
|
-
this._pointerUp = () => {
|
|
662
|
-
|
|
801
|
+
this._pointerUp = (event) => {
|
|
802
|
+
// Note that here we use `isDragging` from the service, rather than from `this`.
|
|
803
|
+
// The difference is that the one from the service reflects whether a dragging sequence
|
|
804
|
+
// has been initiated, whereas the one on `this` includes whether the user has passed
|
|
805
|
+
// the minimum dragging threshold.
|
|
806
|
+
if (!this._dragDropRegistry.isDragging(this)) {
|
|
663
807
|
return;
|
|
664
808
|
}
|
|
665
809
|
this._removeSubscriptions();
|
|
666
810
|
this._dragDropRegistry.stopDragging(this);
|
|
811
|
+
if (this._handles) {
|
|
812
|
+
this._rootElement.style.webkitTapHighlightColor = this._rootElementTapHighlight;
|
|
813
|
+
}
|
|
667
814
|
if (!this._hasStartedDragging) {
|
|
668
815
|
return;
|
|
669
816
|
}
|
|
817
|
+
this.released.next({ source: this });
|
|
670
818
|
if (!this.dropContainer) {
|
|
671
819
|
// Convert the active transform into a passive one. This means that next time
|
|
672
820
|
// the user starts dragging the item, its position will be calculated relatively
|
|
673
821
|
// to the new passive transform.
|
|
674
822
|
this._passiveTransform.x = this._activeTransform.x;
|
|
675
823
|
this._passiveTransform.y = this._activeTransform.y;
|
|
676
|
-
this._ngZone.run(() => this.ended.
|
|
824
|
+
this._ngZone.run(() => this.ended.next({ source: this }));
|
|
677
825
|
this._dragDropRegistry.stopDragging(this);
|
|
678
826
|
return;
|
|
679
827
|
}
|
|
680
828
|
this._animatePreviewToPlaceholder().then(() => {
|
|
681
|
-
this._cleanupDragArtifacts();
|
|
829
|
+
this._cleanupDragArtifacts(event);
|
|
682
830
|
this._dragDropRegistry.stopDragging(this);
|
|
683
831
|
});
|
|
684
832
|
};
|
|
685
|
-
this.
|
|
833
|
+
this.withRootElement(element);
|
|
686
834
|
_dragDropRegistry.registerDragItem(this);
|
|
687
835
|
}
|
|
688
836
|
/**
|
|
@@ -690,14 +838,19 @@ class CdkDrag {
|
|
|
690
838
|
* @return {?}
|
|
691
839
|
*/
|
|
692
840
|
get disabled() {
|
|
693
|
-
return this._disabled || (this.dropContainer && this.dropContainer.disabled);
|
|
841
|
+
return this._disabled || !!(this.dropContainer && this.dropContainer.disabled);
|
|
694
842
|
}
|
|
695
843
|
/**
|
|
696
844
|
* @param {?} value
|
|
697
845
|
* @return {?}
|
|
698
846
|
*/
|
|
699
847
|
set disabled(value) {
|
|
700
|
-
|
|
848
|
+
/** @type {?} */
|
|
849
|
+
const newValue = coerceBooleanProperty(value);
|
|
850
|
+
if (newValue !== this._disabled) {
|
|
851
|
+
this._disabled = newValue;
|
|
852
|
+
this._toggleNativeDragInteractions();
|
|
853
|
+
}
|
|
701
854
|
}
|
|
702
855
|
/**
|
|
703
856
|
* Returns the element that is being used as a placeholder
|
|
@@ -715,90 +868,231 @@ class CdkDrag {
|
|
|
715
868
|
return this._rootElement;
|
|
716
869
|
}
|
|
717
870
|
/**
|
|
718
|
-
*
|
|
719
|
-
* @
|
|
871
|
+
* Registers the handles that can be used to drag the element.
|
|
872
|
+
* @template THIS
|
|
873
|
+
* @this {THIS}
|
|
874
|
+
* @param {?} handles
|
|
875
|
+
* @return {THIS}
|
|
720
876
|
*/
|
|
721
|
-
|
|
722
|
-
this.
|
|
723
|
-
|
|
724
|
-
|
|
877
|
+
withHandles(handles) {
|
|
878
|
+
(/** @type {?} */ (this))._handles = handles.map(handle => coerceElement(handle));
|
|
879
|
+
(/** @type {?} */ (this))._handles.forEach(handle => toggleNativeDragInteractions(handle, false));
|
|
880
|
+
(/** @type {?} */ (this))._toggleNativeDragInteractions();
|
|
881
|
+
return (/** @type {?} */ (this));
|
|
725
882
|
}
|
|
726
883
|
/**
|
|
727
|
-
*
|
|
884
|
+
* Registers the template that should be used for the drag preview.
|
|
885
|
+
* @template THIS
|
|
886
|
+
* @this {THIS}
|
|
887
|
+
* @param {?} template Template that from which to stamp out the preview.
|
|
888
|
+
* @param {?=} context Variables to add to the template's context.
|
|
889
|
+
* @return {THIS}
|
|
728
890
|
*/
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
// for draggable elements inside portals since they get stamped out in
|
|
733
|
-
// their original DOM position and then they get transferred to the portal.
|
|
734
|
-
this._rootElementInitSubscription = this._ngZone.onStable.asObservable()
|
|
735
|
-
.pipe(take(1))
|
|
736
|
-
.subscribe(() => {
|
|
737
|
-
/** @type {?} */
|
|
738
|
-
const rootElement = this._rootElement = this._getRootElement();
|
|
739
|
-
rootElement.addEventListener('mousedown', this._pointerDown, activeEventListenerOptions);
|
|
740
|
-
rootElement.addEventListener('touchstart', this._pointerDown, passiveEventListenerOptions);
|
|
741
|
-
this._handles.changes.pipe(startWith(null)).subscribe(() => toggleNativeDragInteractions(rootElement, this.getChildHandles().length > 0));
|
|
742
|
-
});
|
|
891
|
+
withPreviewTemplate(template, context) {
|
|
892
|
+
(/** @type {?} */ (this))._previewTemplate = { template, context };
|
|
893
|
+
return (/** @type {?} */ (this));
|
|
743
894
|
}
|
|
744
895
|
/**
|
|
745
|
-
*
|
|
896
|
+
* Registers the template that should be used for the drag placeholder.
|
|
897
|
+
* @template THIS
|
|
898
|
+
* @this {THIS}
|
|
899
|
+
* @param {?} template Template that from which to stamp out the placeholder.
|
|
900
|
+
* @param {?=} context Variables to add to the template's context.
|
|
901
|
+
* @return {THIS}
|
|
746
902
|
*/
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
903
|
+
withPlaceholderTemplate(template, context) {
|
|
904
|
+
(/** @type {?} */ (this))._placeholderTemplate = { template, context };
|
|
905
|
+
return (/** @type {?} */ (this));
|
|
906
|
+
}
|
|
907
|
+
/**
|
|
908
|
+
* Sets an alternate drag root element. The root element is the element that will be moved as
|
|
909
|
+
* the user is dragging. Passing an alternate root element is useful when trying to enable
|
|
910
|
+
* dragging on an element that you might not have access to.
|
|
911
|
+
* @template THIS
|
|
912
|
+
* @this {THIS}
|
|
913
|
+
* @param {?} rootElement
|
|
914
|
+
* @return {THIS}
|
|
915
|
+
*/
|
|
916
|
+
withRootElement(rootElement) {
|
|
917
|
+
/** @type {?} */
|
|
918
|
+
const element = coerceElement(rootElement);
|
|
919
|
+
if (element !== (/** @type {?} */ (this))._rootElement) {
|
|
920
|
+
if ((/** @type {?} */ (this))._rootElement) {
|
|
921
|
+
(/** @type {?} */ (this))._removeRootElementListeners((/** @type {?} */ (this))._rootElement);
|
|
758
922
|
}
|
|
923
|
+
element.addEventListener('mousedown', (/** @type {?} */ (this))._pointerDown, activeEventListenerOptions);
|
|
924
|
+
element.addEventListener('touchstart', (/** @type {?} */ (this))._pointerDown, passiveEventListenerOptions);
|
|
925
|
+
(/** @type {?} */ (this))._initialTransform = undefined;
|
|
926
|
+
(/** @type {?} */ (this))._rootElement = element;
|
|
927
|
+
}
|
|
928
|
+
return (/** @type {?} */ (this));
|
|
929
|
+
}
|
|
930
|
+
/**
|
|
931
|
+
* Element to which the draggable's position will be constrained.
|
|
932
|
+
* @template THIS
|
|
933
|
+
* @this {THIS}
|
|
934
|
+
* @param {?} boundaryElement
|
|
935
|
+
* @return {THIS}
|
|
936
|
+
*/
|
|
937
|
+
withBoundaryElement(boundaryElement) {
|
|
938
|
+
(/** @type {?} */ (this))._boundaryElement = boundaryElement ? coerceElement(boundaryElement) : null;
|
|
939
|
+
return (/** @type {?} */ (this));
|
|
940
|
+
}
|
|
941
|
+
/**
|
|
942
|
+
* Removes the dragging functionality from the DOM element.
|
|
943
|
+
* @return {?}
|
|
944
|
+
*/
|
|
945
|
+
dispose() {
|
|
946
|
+
this._removeRootElementListeners(this._rootElement);
|
|
947
|
+
// Do this check before removing from the registry since it'll
|
|
948
|
+
// stop being considered as dragged once it is removed.
|
|
949
|
+
if (this.isDragging()) {
|
|
950
|
+
// Since we move out the element to the end of the body while it's being
|
|
951
|
+
// dragged, we have to make sure that it's removed if it gets destroyed.
|
|
952
|
+
removeElement(this._rootElement);
|
|
759
953
|
}
|
|
760
|
-
this._rootElementInitSubscription.unsubscribe();
|
|
761
954
|
this._destroyPreview();
|
|
762
955
|
this._destroyPlaceholder();
|
|
763
|
-
this._nextSibling = null;
|
|
764
956
|
this._dragDropRegistry.removeDragItem(this);
|
|
765
957
|
this._removeSubscriptions();
|
|
958
|
+
this.beforeStarted.complete();
|
|
959
|
+
this.started.complete();
|
|
960
|
+
this.released.complete();
|
|
961
|
+
this.ended.complete();
|
|
962
|
+
this.entered.complete();
|
|
963
|
+
this.exited.complete();
|
|
964
|
+
this.dropped.complete();
|
|
766
965
|
this._moveEvents.complete();
|
|
966
|
+
this._handles = [];
|
|
967
|
+
this._disabledHandles.clear();
|
|
968
|
+
this._boundaryElement = this._rootElement = this._placeholderTemplate =
|
|
969
|
+
this._previewTemplate = this._nextSibling = (/** @type {?} */ (null));
|
|
767
970
|
}
|
|
768
971
|
/**
|
|
769
972
|
* Checks whether the element is currently being dragged.
|
|
770
973
|
* @return {?}
|
|
771
974
|
*/
|
|
772
|
-
|
|
773
|
-
return this._dragDropRegistry.isDragging(this);
|
|
975
|
+
isDragging() {
|
|
976
|
+
return this._hasStartedDragging && this._dragDropRegistry.isDragging(this);
|
|
774
977
|
}
|
|
775
978
|
/**
|
|
776
|
-
*
|
|
979
|
+
* Resets a standalone drag item to its initial position.
|
|
777
980
|
* @return {?}
|
|
778
981
|
*/
|
|
779
|
-
|
|
780
|
-
|
|
982
|
+
reset() {
|
|
983
|
+
this._rootElement.style.transform = this._initialTransform || '';
|
|
984
|
+
this._activeTransform = { x: 0, y: 0 };
|
|
985
|
+
this._passiveTransform = { x: 0, y: 0 };
|
|
781
986
|
}
|
|
782
987
|
/**
|
|
783
|
-
* Sets
|
|
784
|
-
*
|
|
785
|
-
* @param {?} referenceElement Element that started the drag sequence.
|
|
786
|
-
* @param {?} event Browser event object that started the sequence.
|
|
988
|
+
* Sets a handle as disabled. While a handle is disabled, it'll capture and interrupt dragging.
|
|
989
|
+
* @param {?} handle Handle element that should be disabled.
|
|
787
990
|
* @return {?}
|
|
788
991
|
*/
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
992
|
+
disableHandle(handle) {
|
|
993
|
+
if (this._handles.indexOf(handle) > -1) {
|
|
994
|
+
this._disabledHandles.add(handle);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
/**
|
|
998
|
+
* Enables a handle, if it has been disabled.
|
|
999
|
+
* @param {?} handle Handle element to be enabled.
|
|
1000
|
+
* @return {?}
|
|
1001
|
+
*/
|
|
1002
|
+
enableHandle(handle) {
|
|
1003
|
+
this._disabledHandles.delete(handle);
|
|
1004
|
+
}
|
|
1005
|
+
/**
|
|
1006
|
+
* Unsubscribes from the global subscriptions.
|
|
1007
|
+
* @private
|
|
1008
|
+
* @return {?}
|
|
1009
|
+
*/
|
|
1010
|
+
_removeSubscriptions() {
|
|
1011
|
+
this._pointerMoveSubscription.unsubscribe();
|
|
1012
|
+
this._pointerUpSubscription.unsubscribe();
|
|
1013
|
+
}
|
|
1014
|
+
/**
|
|
1015
|
+
* Destroys the preview element and its ViewRef.
|
|
1016
|
+
* @private
|
|
1017
|
+
* @return {?}
|
|
1018
|
+
*/
|
|
1019
|
+
_destroyPreview() {
|
|
1020
|
+
if (this._preview) {
|
|
1021
|
+
removeElement(this._preview);
|
|
1022
|
+
}
|
|
1023
|
+
if (this._previewRef) {
|
|
1024
|
+
this._previewRef.destroy();
|
|
1025
|
+
}
|
|
1026
|
+
this._preview = this._previewRef = (/** @type {?} */ (null));
|
|
1027
|
+
}
|
|
1028
|
+
/**
|
|
1029
|
+
* Destroys the placeholder element and its ViewRef.
|
|
1030
|
+
* @private
|
|
1031
|
+
* @return {?}
|
|
1032
|
+
*/
|
|
1033
|
+
_destroyPlaceholder() {
|
|
1034
|
+
if (this._placeholder) {
|
|
1035
|
+
removeElement(this._placeholder);
|
|
1036
|
+
}
|
|
1037
|
+
if (this._placeholderRef) {
|
|
1038
|
+
this._placeholderRef.destroy();
|
|
1039
|
+
}
|
|
1040
|
+
this._placeholder = this._placeholderRef = (/** @type {?} */ (null));
|
|
1041
|
+
}
|
|
1042
|
+
/**
|
|
1043
|
+
* Starts the dragging sequence.
|
|
1044
|
+
* @private
|
|
1045
|
+
* @param {?} event
|
|
1046
|
+
* @return {?}
|
|
1047
|
+
*/
|
|
1048
|
+
_startDragSequence(event) {
|
|
1049
|
+
// Emit the event on the item before the one on the container.
|
|
1050
|
+
this.started.next({ source: this });
|
|
1051
|
+
if (isTouchEvent(event)) {
|
|
1052
|
+
this._lastTouchEventTime = Date.now();
|
|
1053
|
+
}
|
|
1054
|
+
if (this.dropContainer) {
|
|
1055
|
+
/** @type {?} */
|
|
1056
|
+
const element = this._rootElement;
|
|
1057
|
+
// Grab the `nextSibling` before the preview and placeholder
|
|
1058
|
+
// have been created so we don't get the preview by accident.
|
|
1059
|
+
this._nextSibling = element.nextSibling;
|
|
1060
|
+
/** @type {?} */
|
|
1061
|
+
const preview = this._preview = this._createPreviewElement();
|
|
1062
|
+
/** @type {?} */
|
|
1063
|
+
const placeholder = this._placeholder = this._createPlaceholderElement();
|
|
1064
|
+
// We move the element out at the end of the body and we make it hidden, because keeping it in
|
|
1065
|
+
// place will throw off the consumer's `:last-child` selectors. We can't remove the element
|
|
1066
|
+
// from the DOM completely, because iOS will stop firing all subsequent events in the chain.
|
|
1067
|
+
element.style.display = 'none';
|
|
1068
|
+
this._document.body.appendChild((/** @type {?} */ (element.parentNode)).replaceChild(placeholder, element));
|
|
1069
|
+
this._document.body.appendChild(preview);
|
|
1070
|
+
this.dropContainer.start();
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
/**
|
|
1074
|
+
* Sets up the different variables and subscriptions
|
|
1075
|
+
* that will be necessary for the dragging sequence.
|
|
1076
|
+
* @private
|
|
1077
|
+
* @param {?} referenceElement Element that started the drag sequence.
|
|
1078
|
+
* @param {?} event Browser event object that started the sequence.
|
|
1079
|
+
* @return {?}
|
|
1080
|
+
*/
|
|
1081
|
+
_initializeDragSequence(referenceElement, event) {
|
|
1082
|
+
// Always stop propagation for the event that initializes
|
|
1083
|
+
// the dragging sequence, in order to prevent it from potentially
|
|
1084
|
+
// starting another sequence for a draggable parent somewhere up the DOM tree.
|
|
1085
|
+
event.stopPropagation();
|
|
1086
|
+
/** @type {?} */
|
|
1087
|
+
const isDragging = this.isDragging();
|
|
796
1088
|
/** @type {?} */
|
|
797
|
-
const
|
|
1089
|
+
const isTouchSequence = isTouchEvent(event);
|
|
798
1090
|
/** @type {?} */
|
|
799
|
-
const isAuxiliaryMouseButton = !
|
|
1091
|
+
const isAuxiliaryMouseButton = !isTouchSequence && ((/** @type {?} */ (event))).button !== 0;
|
|
800
1092
|
/** @type {?} */
|
|
801
|
-
const
|
|
1093
|
+
const rootElement = this._rootElement;
|
|
1094
|
+
/** @type {?} */
|
|
1095
|
+
const isSyntheticEvent = !isTouchSequence && this._lastTouchEventTime &&
|
|
802
1096
|
this._lastTouchEventTime + MOUSE_EVENT_IGNORE_TIME > Date.now();
|
|
803
1097
|
// If the event started from an element with the native HTML drag&drop, it'll interfere
|
|
804
1098
|
// with our own dragging (e.g. `img` tags do it by default). Prevent the default action
|
|
@@ -806,7 +1100,7 @@ class CdkDrag {
|
|
|
806
1100
|
// it's flaky and it fails if the user drags it away quickly. Also note that we only want
|
|
807
1101
|
// to do this for `mousedown` since doing the same for `touchstart` will stop any `click`
|
|
808
1102
|
// events from firing on touch devices.
|
|
809
|
-
if (event.target && (/** @type {?} */ (event.target)).draggable && event.type === 'mousedown') {
|
|
1103
|
+
if (event.target && ((/** @type {?} */ (event.target))).draggable && event.type === 'mousedown') {
|
|
810
1104
|
event.preventDefault();
|
|
811
1105
|
}
|
|
812
1106
|
// Abort if the user is already dragging or is using a mouse button other than the primary one.
|
|
@@ -818,14 +1112,26 @@ class CdkDrag {
|
|
|
818
1112
|
if (this._initialTransform == null) {
|
|
819
1113
|
this._initialTransform = this._rootElement.style.transform || '';
|
|
820
1114
|
}
|
|
1115
|
+
// If we've got handles, we need to disable the tap highlight on the entire root element,
|
|
1116
|
+
// otherwise iOS will still add it, even though all the drag interactions on the handle
|
|
1117
|
+
// are disabled.
|
|
1118
|
+
if (this._handles.length) {
|
|
1119
|
+
this._rootElementTapHighlight = rootElement.style.webkitTapHighlightColor;
|
|
1120
|
+
rootElement.style.webkitTapHighlightColor = 'transparent';
|
|
1121
|
+
}
|
|
1122
|
+
this._toggleNativeDragInteractions();
|
|
821
1123
|
this._hasStartedDragging = this._hasMoved = false;
|
|
822
|
-
this._initialContainer = this.dropContainer;
|
|
1124
|
+
this._initialContainer = (/** @type {?} */ (this.dropContainer));
|
|
823
1125
|
this._pointerMoveSubscription = this._dragDropRegistry.pointerMove.subscribe(this._pointerMove);
|
|
824
1126
|
this._pointerUpSubscription = this._dragDropRegistry.pointerUp.subscribe(this._pointerUp);
|
|
825
1127
|
this._scrollPosition = this._viewportRuler.getViewportScrollPosition();
|
|
1128
|
+
if (this._boundaryElement) {
|
|
1129
|
+
this._boundaryRect = this._boundaryElement.getBoundingClientRect();
|
|
1130
|
+
}
|
|
826
1131
|
// If we have a custom preview template, the element won't be visible anyway so we avoid the
|
|
827
1132
|
// extra `getBoundingClientRect` calls and just move the preview next to the cursor.
|
|
828
|
-
this._pickupPositionInElement = this._previewTemplate
|
|
1133
|
+
this._pickupPositionInElement = this._previewTemplate && this._previewTemplate.template ?
|
|
1134
|
+
{ x: 0, y: 0 } :
|
|
829
1135
|
this._getPointerPositionInElement(referenceElement, event);
|
|
830
1136
|
/** @type {?} */
|
|
831
1137
|
const pointerPosition = this._pickupPositionOnPage = this._getPointerPositionOnPage(event);
|
|
@@ -833,113 +1139,98 @@ class CdkDrag {
|
|
|
833
1139
|
this._pointerPositionAtLastDirectionChange = { x: pointerPosition.x, y: pointerPosition.y };
|
|
834
1140
|
this._dragDropRegistry.startDragging(this, event);
|
|
835
1141
|
}
|
|
836
|
-
/**
|
|
837
|
-
* Starts the dragging sequence.
|
|
838
|
-
* @param {?} event
|
|
839
|
-
* @return {?}
|
|
840
|
-
*/
|
|
841
|
-
_startDragSequence(event) {
|
|
842
|
-
// Emit the event on the item before the one on the container.
|
|
843
|
-
this.started.emit({ source: this });
|
|
844
|
-
if (this._isTouchEvent(event)) {
|
|
845
|
-
this._lastTouchEventTime = Date.now();
|
|
846
|
-
}
|
|
847
|
-
if (this.dropContainer) {
|
|
848
|
-
/** @type {?} */
|
|
849
|
-
const element = this._rootElement;
|
|
850
|
-
// Grab the `nextSibling` before the preview and placeholder
|
|
851
|
-
// have been created so we don't get the preview by accident.
|
|
852
|
-
this._nextSibling = element.nextSibling;
|
|
853
|
-
/** @type {?} */
|
|
854
|
-
const preview = this._preview = this._createPreviewElement();
|
|
855
|
-
/** @type {?} */
|
|
856
|
-
const placeholder = this._placeholder = this._createPlaceholderElement();
|
|
857
|
-
// We move the element out at the end of the body and we make it hidden, because keeping it in
|
|
858
|
-
// place will throw off the consumer's `:last-child` selectors. We can't remove the element
|
|
859
|
-
// from the DOM completely, because iOS will stop firing all subsequent events in the chain.
|
|
860
|
-
element.style.display = 'none';
|
|
861
|
-
this._document.body.appendChild(/** @type {?} */ ((element.parentNode)).replaceChild(placeholder, element));
|
|
862
|
-
this._document.body.appendChild(preview);
|
|
863
|
-
this.dropContainer.start();
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
1142
|
/**
|
|
867
1143
|
* Cleans up the DOM artifacts that were added to facilitate the element being dragged.
|
|
1144
|
+
* @private
|
|
1145
|
+
* @param {?} event
|
|
868
1146
|
* @return {?}
|
|
869
1147
|
*/
|
|
870
|
-
_cleanupDragArtifacts() {
|
|
1148
|
+
_cleanupDragArtifacts(event) {
|
|
871
1149
|
// Restore the element's visibility and insert it at its old position in the DOM.
|
|
872
1150
|
// It's important that we maintain the position, because moving the element around in the DOM
|
|
873
1151
|
// can throw off `NgFor` which does smart diffing and re-creates elements only when necessary,
|
|
874
1152
|
// while moving the existing elements in all other cases.
|
|
875
1153
|
this._rootElement.style.display = '';
|
|
876
1154
|
if (this._nextSibling) {
|
|
877
|
-
/** @type {?} */ (
|
|
1155
|
+
(/** @type {?} */ (this._nextSibling.parentNode)).insertBefore(this._rootElement, this._nextSibling);
|
|
878
1156
|
}
|
|
879
1157
|
else {
|
|
880
1158
|
this._initialContainer.element.nativeElement.appendChild(this._rootElement);
|
|
881
1159
|
}
|
|
882
1160
|
this._destroyPreview();
|
|
883
1161
|
this._destroyPlaceholder();
|
|
1162
|
+
this._boundaryRect = this._previewRect = undefined;
|
|
884
1163
|
// Re-enter the NgZone since we bound `document` events on the outside.
|
|
885
1164
|
this._ngZone.run(() => {
|
|
886
1165
|
/** @type {?} */
|
|
887
|
-
const
|
|
888
|
-
|
|
889
|
-
|
|
1166
|
+
const container = (/** @type {?} */ (this.dropContainer));
|
|
1167
|
+
/** @type {?} */
|
|
1168
|
+
const currentIndex = container.getItemIndex(this);
|
|
1169
|
+
const { x, y } = this._getPointerPositionOnPage(event);
|
|
1170
|
+
/** @type {?} */
|
|
1171
|
+
const isPointerOverContainer = container._isOverContainer(x, y);
|
|
1172
|
+
this.ended.next({ source: this });
|
|
1173
|
+
this.dropped.next({
|
|
890
1174
|
item: this,
|
|
891
1175
|
currentIndex,
|
|
892
1176
|
previousIndex: this._initialContainer.getItemIndex(this),
|
|
893
|
-
container:
|
|
894
|
-
previousContainer: this._initialContainer
|
|
1177
|
+
container: container,
|
|
1178
|
+
previousContainer: this._initialContainer,
|
|
1179
|
+
isPointerOverContainer
|
|
895
1180
|
});
|
|
896
|
-
|
|
1181
|
+
container.drop(this, currentIndex, this._initialContainer, isPointerOverContainer);
|
|
897
1182
|
this.dropContainer = this._initialContainer;
|
|
898
1183
|
});
|
|
899
1184
|
}
|
|
900
1185
|
/**
|
|
901
1186
|
* Updates the item's position in its drop container, or moves it
|
|
902
1187
|
* into a new one, depending on its current drag position.
|
|
1188
|
+
* @private
|
|
903
1189
|
* @param {?} __0
|
|
904
1190
|
* @return {?}
|
|
905
1191
|
*/
|
|
906
1192
|
_updateActiveDropContainer({ x, y }) {
|
|
1193
|
+
// Drop container that draggable has been moved into.
|
|
907
1194
|
/** @type {?} */
|
|
908
|
-
let newContainer = this.dropContainer._getSiblingContainerFromPosition(this, x, y)
|
|
1195
|
+
let newContainer = (/** @type {?} */ (this.dropContainer))._getSiblingContainerFromPosition(this, x, y) ||
|
|
1196
|
+
this._initialContainer._getSiblingContainerFromPosition(this, x, y);
|
|
909
1197
|
// If we couldn't find a new container to move the item into, and the item has left it's
|
|
910
|
-
// initial container, check whether the it's
|
|
911
|
-
//
|
|
912
|
-
//
|
|
1198
|
+
// initial container, check whether the it's over the initial container. This handles the
|
|
1199
|
+
// case where two containers are connected one way and the user tries to undo dragging an
|
|
1200
|
+
// item into a new container.
|
|
913
1201
|
if (!newContainer && this.dropContainer !== this._initialContainer &&
|
|
914
|
-
this._initialContainer.
|
|
1202
|
+
this._initialContainer._isOverContainer(x, y)) {
|
|
915
1203
|
newContainer = this._initialContainer;
|
|
916
1204
|
}
|
|
917
|
-
if (newContainer) {
|
|
1205
|
+
if (newContainer && newContainer !== this.dropContainer) {
|
|
918
1206
|
this._ngZone.run(() => {
|
|
919
1207
|
// Notify the old container that the item has left.
|
|
920
|
-
this.exited.
|
|
921
|
-
this.dropContainer.exit(this);
|
|
1208
|
+
this.exited.next({ item: this, container: (/** @type {?} */ (this.dropContainer)) });
|
|
1209
|
+
(/** @type {?} */ (this.dropContainer)).exit(this);
|
|
922
1210
|
// Notify the new container that the item has entered.
|
|
923
|
-
this.entered.
|
|
924
|
-
this.dropContainer = /** @type {?} */ (
|
|
1211
|
+
this.entered.next({ item: this, container: (/** @type {?} */ (newContainer)) });
|
|
1212
|
+
this.dropContainer = (/** @type {?} */ (newContainer));
|
|
925
1213
|
this.dropContainer.enter(this, x, y);
|
|
926
1214
|
});
|
|
927
1215
|
}
|
|
928
|
-
this.dropContainer._sortItem(this, x, y, this._pointerDirectionDelta);
|
|
1216
|
+
(/** @type {?} */ (this.dropContainer))._sortItem(this, x, y, this._pointerDirectionDelta);
|
|
929
1217
|
this._preview.style.transform =
|
|
930
1218
|
getTransform(x - this._pickupPositionInElement.x, y - this._pickupPositionInElement.y);
|
|
931
1219
|
}
|
|
932
1220
|
/**
|
|
933
1221
|
* Creates the element that will be rendered next to the user's pointer
|
|
934
1222
|
* and will be used as a preview of the element that is being dragged.
|
|
1223
|
+
* @private
|
|
935
1224
|
* @return {?}
|
|
936
1225
|
*/
|
|
937
1226
|
_createPreviewElement() {
|
|
1227
|
+
/** @type {?} */
|
|
1228
|
+
const previewTemplate = this._previewTemplate;
|
|
938
1229
|
/** @type {?} */
|
|
939
1230
|
let preview;
|
|
940
|
-
if (
|
|
1231
|
+
if (previewTemplate && previewTemplate.template) {
|
|
941
1232
|
/** @type {?} */
|
|
942
|
-
const viewRef = this._viewContainerRef.createEmbeddedView(
|
|
1233
|
+
const viewRef = this._viewContainerRef.createEmbeddedView(previewTemplate.template, previewTemplate.context);
|
|
943
1234
|
preview = viewRef.rootNodes[0];
|
|
944
1235
|
this._previewRef = viewRef;
|
|
945
1236
|
preview.style.transform =
|
|
@@ -956,58 +1247,22 @@ class CdkDrag {
|
|
|
956
1247
|
preview.style.transform = getTransform(elementRect.left, elementRect.top);
|
|
957
1248
|
}
|
|
958
1249
|
extendStyles(preview.style, {
|
|
1250
|
+
// It's important that we disable the pointer events on the preview, because
|
|
1251
|
+
// it can throw off the `document.elementFromPoint` calls in the `CdkDropList`.
|
|
1252
|
+
pointerEvents: 'none',
|
|
959
1253
|
position: 'fixed',
|
|
960
1254
|
top: '0',
|
|
961
1255
|
left: '0',
|
|
962
1256
|
zIndex: '1000'
|
|
963
1257
|
});
|
|
1258
|
+
toggleNativeDragInteractions(preview, false);
|
|
964
1259
|
preview.classList.add('cdk-drag-preview');
|
|
965
1260
|
preview.setAttribute('dir', this._dir ? this._dir.value : 'ltr');
|
|
966
1261
|
return preview;
|
|
967
1262
|
}
|
|
968
|
-
/**
|
|
969
|
-
* Creates an element that will be shown instead of the current element while dragging.
|
|
970
|
-
* @return {?}
|
|
971
|
-
*/
|
|
972
|
-
_createPlaceholderElement() {
|
|
973
|
-
/** @type {?} */
|
|
974
|
-
let placeholder;
|
|
975
|
-
if (this._placeholderTemplate) {
|
|
976
|
-
this._placeholderRef = this._viewContainerRef.createEmbeddedView(this._placeholderTemplate.templateRef, this._placeholderTemplate.data);
|
|
977
|
-
placeholder = this._placeholderRef.rootNodes[0];
|
|
978
|
-
}
|
|
979
|
-
else {
|
|
980
|
-
placeholder = deepCloneNode(this._rootElement);
|
|
981
|
-
}
|
|
982
|
-
placeholder.classList.add('cdk-drag-placeholder');
|
|
983
|
-
return placeholder;
|
|
984
|
-
}
|
|
985
|
-
/**
|
|
986
|
-
* Figures out the coordinates at which an element was picked up.
|
|
987
|
-
* @param {?} referenceElement Element that initiated the dragging.
|
|
988
|
-
* @param {?} event Event that initiated the dragging.
|
|
989
|
-
* @return {?}
|
|
990
|
-
*/
|
|
991
|
-
_getPointerPositionInElement(referenceElement, event) {
|
|
992
|
-
/** @type {?} */
|
|
993
|
-
const elementRect = this._rootElement.getBoundingClientRect();
|
|
994
|
-
/** @type {?} */
|
|
995
|
-
const handleElement = referenceElement === this._rootElement ? null : referenceElement;
|
|
996
|
-
/** @type {?} */
|
|
997
|
-
const referenceRect = handleElement ? handleElement.getBoundingClientRect() : elementRect;
|
|
998
|
-
/** @type {?} */
|
|
999
|
-
const point = this._isTouchEvent(event) ? event.targetTouches[0] : event;
|
|
1000
|
-
/** @type {?} */
|
|
1001
|
-
const x = point.pageX - referenceRect.left - this._scrollPosition.left;
|
|
1002
|
-
/** @type {?} */
|
|
1003
|
-
const y = point.pageY - referenceRect.top - this._scrollPosition.top;
|
|
1004
|
-
return {
|
|
1005
|
-
x: referenceRect.left - elementRect.left + x,
|
|
1006
|
-
y: referenceRect.top - elementRect.top + y
|
|
1007
|
-
};
|
|
1008
|
-
}
|
|
1009
1263
|
/**
|
|
1010
1264
|
* Animates the preview element from its current position to the location of the drop placeholder.
|
|
1265
|
+
* @private
|
|
1011
1266
|
* @return {?} Promise that resolves when the animation completes.
|
|
1012
1267
|
*/
|
|
1013
1268
|
_animatePreviewToPlaceholder() {
|
|
@@ -1021,6 +1276,10 @@ class CdkDrag {
|
|
|
1021
1276
|
this._preview.classList.add('cdk-drag-animating');
|
|
1022
1277
|
// Move the preview to the placeholder position.
|
|
1023
1278
|
this._preview.style.transform = getTransform(placeholderRect.left, placeholderRect.top);
|
|
1279
|
+
// If the element doesn't have a `transition`, the `transitionend` event won't fire. Since
|
|
1280
|
+
// we need to trigger a style recalculation in order for the `cdk-drag-animating` class to
|
|
1281
|
+
// apply its style, we take advantage of the available info to figure out whether we need to
|
|
1282
|
+
// bind the event in the first place.
|
|
1024
1283
|
/** @type {?} */
|
|
1025
1284
|
const duration = getTransformTransitionDurationInMs(this._preview);
|
|
1026
1285
|
if (duration === 0) {
|
|
@@ -1029,37 +1288,77 @@ class CdkDrag {
|
|
|
1029
1288
|
return this._ngZone.runOutsideAngular(() => {
|
|
1030
1289
|
return new Promise(resolve => {
|
|
1031
1290
|
/** @type {?} */
|
|
1032
|
-
const handler = /** @type {?} */ (((event) => {
|
|
1291
|
+
const handler = (/** @type {?} */ (((event) => {
|
|
1033
1292
|
if (!event || (event.target === this._preview && event.propertyName === 'transform')) {
|
|
1034
1293
|
this._preview.removeEventListener('transitionend', handler);
|
|
1035
1294
|
resolve();
|
|
1036
1295
|
clearTimeout(timeout);
|
|
1037
1296
|
}
|
|
1038
|
-
}));
|
|
1297
|
+
})));
|
|
1298
|
+
// If a transition is short enough, the browser might not fire the `transitionend` event.
|
|
1299
|
+
// Since we know how long it's supposed to take, add a timeout with a 50% buffer that'll
|
|
1300
|
+
// fire if the transition hasn't completed when it was supposed to.
|
|
1039
1301
|
/** @type {?} */
|
|
1040
|
-
const timeout = setTimeout(/** @type {?} */ (handler), duration * 1.5);
|
|
1302
|
+
const timeout = setTimeout((/** @type {?} */ (handler)), duration * 1.5);
|
|
1041
1303
|
this._preview.addEventListener('transitionend', handler);
|
|
1042
1304
|
});
|
|
1043
1305
|
});
|
|
1044
1306
|
}
|
|
1045
1307
|
/**
|
|
1046
|
-
*
|
|
1047
|
-
* @
|
|
1308
|
+
* Creates an element that will be shown instead of the current element while dragging.
|
|
1309
|
+
* @private
|
|
1048
1310
|
* @return {?}
|
|
1049
1311
|
*/
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1312
|
+
_createPlaceholderElement() {
|
|
1313
|
+
/** @type {?} */
|
|
1314
|
+
const placeholderTemplate = this._placeholderTemplate;
|
|
1315
|
+
/** @type {?} */
|
|
1316
|
+
let placeholder;
|
|
1317
|
+
if (placeholderTemplate && placeholderTemplate.template) {
|
|
1318
|
+
this._placeholderRef = this._viewContainerRef.createEmbeddedView(placeholderTemplate.template, placeholderTemplate.context);
|
|
1319
|
+
placeholder = this._placeholderRef.rootNodes[0];
|
|
1053
1320
|
}
|
|
1321
|
+
else {
|
|
1322
|
+
placeholder = deepCloneNode(this._rootElement);
|
|
1323
|
+
}
|
|
1324
|
+
placeholder.classList.add('cdk-drag-placeholder');
|
|
1325
|
+
return placeholder;
|
|
1326
|
+
}
|
|
1327
|
+
/**
|
|
1328
|
+
* Figures out the coordinates at which an element was picked up.
|
|
1329
|
+
* @private
|
|
1330
|
+
* @param {?} referenceElement Element that initiated the dragging.
|
|
1331
|
+
* @param {?} event Event that initiated the dragging.
|
|
1332
|
+
* @return {?}
|
|
1333
|
+
*/
|
|
1334
|
+
_getPointerPositionInElement(referenceElement, event) {
|
|
1335
|
+
/** @type {?} */
|
|
1336
|
+
const elementRect = this._rootElement.getBoundingClientRect();
|
|
1337
|
+
/** @type {?} */
|
|
1338
|
+
const handleElement = referenceElement === this._rootElement ? null : referenceElement;
|
|
1339
|
+
/** @type {?} */
|
|
1340
|
+
const referenceRect = handleElement ? handleElement.getBoundingClientRect() : elementRect;
|
|
1341
|
+
/** @type {?} */
|
|
1342
|
+
const point = isTouchEvent(event) ? event.targetTouches[0] : event;
|
|
1343
|
+
/** @type {?} */
|
|
1344
|
+
const x = point.pageX - referenceRect.left - this._scrollPosition.left;
|
|
1345
|
+
/** @type {?} */
|
|
1346
|
+
const y = point.pageY - referenceRect.top - this._scrollPosition.top;
|
|
1347
|
+
return {
|
|
1348
|
+
x: referenceRect.left - elementRect.left + x,
|
|
1349
|
+
y: referenceRect.top - elementRect.top + y
|
|
1350
|
+
};
|
|
1054
1351
|
}
|
|
1055
1352
|
/**
|
|
1056
1353
|
* Determines the point of the page that was touched by the user.
|
|
1354
|
+
* @private
|
|
1057
1355
|
* @param {?} event
|
|
1058
1356
|
* @return {?}
|
|
1059
1357
|
*/
|
|
1060
1358
|
_getPointerPositionOnPage(event) {
|
|
1359
|
+
// `touches` will be empty for start/end events so we have to fall back to `changedTouches`.
|
|
1061
1360
|
/** @type {?} */
|
|
1062
|
-
const point =
|
|
1361
|
+
const point = isTouchEvent(event) ? (event.touches[0] || event.changedTouches[0]) : event;
|
|
1063
1362
|
return {
|
|
1064
1363
|
x: point.pageX - this._scrollPosition.left,
|
|
1065
1364
|
y: point.pageY - this._scrollPosition.top
|
|
@@ -1067,6 +1366,7 @@ class CdkDrag {
|
|
|
1067
1366
|
}
|
|
1068
1367
|
/**
|
|
1069
1368
|
* Gets the pointer position on the page, accounting for any position constraints.
|
|
1369
|
+
* @private
|
|
1070
1370
|
* @param {?} event
|
|
1071
1371
|
* @return {?}
|
|
1072
1372
|
*/
|
|
@@ -1081,44 +1381,28 @@ class CdkDrag {
|
|
|
1081
1381
|
else if (this.lockAxis === 'y' || dropContainerLock === 'y') {
|
|
1082
1382
|
point.x = this._pickupPositionOnPage.x;
|
|
1083
1383
|
}
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
this._removeElement(this._preview);
|
|
1101
|
-
}
|
|
1102
|
-
if (this._previewRef) {
|
|
1103
|
-
this._previewRef.destroy();
|
|
1104
|
-
}
|
|
1105
|
-
this._preview = this._previewRef = /** @type {?} */ ((null));
|
|
1106
|
-
}
|
|
1107
|
-
/**
|
|
1108
|
-
* Destroys the placeholder element and its ViewRef.
|
|
1109
|
-
* @return {?}
|
|
1110
|
-
*/
|
|
1111
|
-
_destroyPlaceholder() {
|
|
1112
|
-
if (this._placeholder) {
|
|
1113
|
-
this._removeElement(this._placeholder);
|
|
1114
|
-
}
|
|
1115
|
-
if (this._placeholderRef) {
|
|
1116
|
-
this._placeholderRef.destroy();
|
|
1384
|
+
if (this._boundaryRect) {
|
|
1385
|
+
const { x: pickupX, y: pickupY } = this._pickupPositionInElement;
|
|
1386
|
+
/** @type {?} */
|
|
1387
|
+
const boundaryRect = this._boundaryRect;
|
|
1388
|
+
/** @type {?} */
|
|
1389
|
+
const previewRect = (/** @type {?} */ (this._previewRect));
|
|
1390
|
+
/** @type {?} */
|
|
1391
|
+
const minY = boundaryRect.top + pickupY;
|
|
1392
|
+
/** @type {?} */
|
|
1393
|
+
const maxY = boundaryRect.bottom - (previewRect.height - pickupY);
|
|
1394
|
+
/** @type {?} */
|
|
1395
|
+
const minX = boundaryRect.left + pickupX;
|
|
1396
|
+
/** @type {?} */
|
|
1397
|
+
const maxX = boundaryRect.right - (previewRect.width - pickupX);
|
|
1398
|
+
point.x = clamp$1(point.x, minX, maxX);
|
|
1399
|
+
point.y = clamp$1(point.y, minY, maxY);
|
|
1117
1400
|
}
|
|
1118
|
-
|
|
1401
|
+
return point;
|
|
1119
1402
|
}
|
|
1120
1403
|
/**
|
|
1121
1404
|
* Updates the current drag delta, based on the user's current pointer position on the page.
|
|
1405
|
+
* @private
|
|
1122
1406
|
* @param {?} pointerPositionOnPage
|
|
1123
1407
|
* @return {?}
|
|
1124
1408
|
*/
|
|
@@ -1128,6 +1412,7 @@ class CdkDrag {
|
|
|
1128
1412
|
const delta = this._pointerDirectionDelta;
|
|
1129
1413
|
/** @type {?} */
|
|
1130
1414
|
const positionSinceLastChange = this._pointerPositionAtLastDirectionChange;
|
|
1415
|
+
// Amount of pixels the user has dragged since the last time the direction changed.
|
|
1131
1416
|
/** @type {?} */
|
|
1132
1417
|
const changeX = Math.abs(x - positionSinceLastChange.x);
|
|
1133
1418
|
/** @type {?} */
|
|
@@ -1147,76 +1432,32 @@ class CdkDrag {
|
|
|
1147
1432
|
return delta;
|
|
1148
1433
|
}
|
|
1149
1434
|
/**
|
|
1150
|
-
*
|
|
1435
|
+
* Toggles the native drag interactions, based on how many handles are registered.
|
|
1436
|
+
* @private
|
|
1151
1437
|
* @return {?}
|
|
1152
1438
|
*/
|
|
1153
|
-
|
|
1154
|
-
if (this.
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
(/** @type {?} */ (currentElement)).msMatchesSelector(selector)) {
|
|
1163
|
-
return currentElement;
|
|
1164
|
-
}
|
|
1165
|
-
currentElement = currentElement.parentElement;
|
|
1166
|
-
}
|
|
1439
|
+
_toggleNativeDragInteractions() {
|
|
1440
|
+
if (!this._rootElement || !this._handles) {
|
|
1441
|
+
return;
|
|
1442
|
+
}
|
|
1443
|
+
/** @type {?} */
|
|
1444
|
+
const shouldEnable = this.disabled || this._handles.length > 0;
|
|
1445
|
+
if (shouldEnable !== this._nativeInteractionsEnabled) {
|
|
1446
|
+
this._nativeInteractionsEnabled = shouldEnable;
|
|
1447
|
+
toggleNativeDragInteractions(this._rootElement, shouldEnable);
|
|
1167
1448
|
}
|
|
1168
|
-
return this.element.nativeElement;
|
|
1169
1449
|
}
|
|
1170
1450
|
/**
|
|
1171
|
-
*
|
|
1451
|
+
* Removes the manually-added event listeners from the root element.
|
|
1452
|
+
* @private
|
|
1453
|
+
* @param {?} element
|
|
1172
1454
|
* @return {?}
|
|
1173
1455
|
*/
|
|
1174
|
-
|
|
1175
|
-
this.
|
|
1176
|
-
this.
|
|
1456
|
+
_removeRootElementListeners(element) {
|
|
1457
|
+
element.removeEventListener('mousedown', this._pointerDown, activeEventListenerOptions);
|
|
1458
|
+
element.removeEventListener('touchstart', this._pointerDown, passiveEventListenerOptions);
|
|
1177
1459
|
}
|
|
1178
1460
|
}
|
|
1179
|
-
CdkDrag.decorators = [
|
|
1180
|
-
{ type: Directive, args: [{
|
|
1181
|
-
selector: '[cdkDrag]',
|
|
1182
|
-
exportAs: 'cdkDrag',
|
|
1183
|
-
host: {
|
|
1184
|
-
'class': 'cdk-drag',
|
|
1185
|
-
'[class.cdk-drag-dragging]': '_hasStartedDragging && _isDragging()',
|
|
1186
|
-
},
|
|
1187
|
-
providers: [{
|
|
1188
|
-
provide: CDK_DRAG_PARENT,
|
|
1189
|
-
useExisting: CdkDrag
|
|
1190
|
-
}]
|
|
1191
|
-
},] },
|
|
1192
|
-
];
|
|
1193
|
-
/** @nocollapse */
|
|
1194
|
-
CdkDrag.ctorParameters = () => [
|
|
1195
|
-
{ type: ElementRef },
|
|
1196
|
-
{ type: undefined, decorators: [{ type: Inject, args: [CDK_DROP_LIST_CONTAINER,] }, { type: Optional }, { type: SkipSelf }] },
|
|
1197
|
-
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
|
|
1198
|
-
{ type: NgZone },
|
|
1199
|
-
{ type: ViewContainerRef },
|
|
1200
|
-
{ type: ViewportRuler },
|
|
1201
|
-
{ type: DragDropRegistry },
|
|
1202
|
-
{ type: undefined, decorators: [{ type: Inject, args: [CDK_DRAG_CONFIG,] }] },
|
|
1203
|
-
{ type: Directionality, decorators: [{ type: Optional }] }
|
|
1204
|
-
];
|
|
1205
|
-
CdkDrag.propDecorators = {
|
|
1206
|
-
_handles: [{ type: ContentChildren, args: [CdkDragHandle, { descendants: true },] }],
|
|
1207
|
-
_previewTemplate: [{ type: ContentChild, args: [CdkDragPreview,] }],
|
|
1208
|
-
_placeholderTemplate: [{ type: ContentChild, args: [CdkDragPlaceholder,] }],
|
|
1209
|
-
data: [{ type: Input, args: ['cdkDragData',] }],
|
|
1210
|
-
lockAxis: [{ type: Input, args: ['cdkDragLockAxis',] }],
|
|
1211
|
-
rootElementSelector: [{ type: Input, args: ['cdkDragRootElement',] }],
|
|
1212
|
-
disabled: [{ type: Input, args: ['cdkDragDisabled',] }],
|
|
1213
|
-
started: [{ type: Output, args: ['cdkDragStarted',] }],
|
|
1214
|
-
ended: [{ type: Output, args: ['cdkDragEnded',] }],
|
|
1215
|
-
entered: [{ type: Output, args: ['cdkDragEntered',] }],
|
|
1216
|
-
exited: [{ type: Output, args: ['cdkDragExited',] }],
|
|
1217
|
-
dropped: [{ type: Output, args: ['cdkDragDropped',] }],
|
|
1218
|
-
moved: [{ type: Output, args: ['cdkDragMoved',] }]
|
|
1219
|
-
};
|
|
1220
1461
|
/**
|
|
1221
1462
|
* Gets a 3d `transform` that can be applied to an element.
|
|
1222
1463
|
* @param {?} x Desired position of the element along the X axis.
|
|
@@ -1224,7 +1465,9 @@ CdkDrag.propDecorators = {
|
|
|
1224
1465
|
* @return {?}
|
|
1225
1466
|
*/
|
|
1226
1467
|
function getTransform(x, y) {
|
|
1227
|
-
|
|
1468
|
+
// Round the transforms since some browsers will
|
|
1469
|
+
// blur the elements for sub-pixel transforms.
|
|
1470
|
+
return `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`;
|
|
1228
1471
|
}
|
|
1229
1472
|
/**
|
|
1230
1473
|
* Creates a deep clone of an element.
|
|
@@ -1233,627 +1476,1320 @@ function getTransform(x, y) {
|
|
|
1233
1476
|
*/
|
|
1234
1477
|
function deepCloneNode(node) {
|
|
1235
1478
|
/** @type {?} */
|
|
1236
|
-
const clone = /** @type {?} */ (node.cloneNode(true));
|
|
1479
|
+
const clone = (/** @type {?} */ (node.cloneNode(true)));
|
|
1237
1480
|
// Remove the `id` to avoid having multiple elements with the same id on the page.
|
|
1238
1481
|
clone.removeAttribute('id');
|
|
1239
1482
|
return clone;
|
|
1240
1483
|
}
|
|
1241
|
-
|
|
1242
|
-
/**
|
|
1243
|
-
* @fileoverview added by tsickle
|
|
1244
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
1245
|
-
*/
|
|
1246
|
-
|
|
1247
|
-
/**
|
|
1248
|
-
* Moves an item one index in an array to another.
|
|
1249
|
-
* @template T
|
|
1250
|
-
* @param {?} array Array in which to move the item.
|
|
1251
|
-
* @param {?} fromIndex Starting index of the item.
|
|
1252
|
-
* @param {?} toIndex Index to which the item should be moved.
|
|
1253
|
-
* @return {?}
|
|
1254
|
-
*/
|
|
1255
|
-
function moveItemInArray(array, fromIndex, toIndex) {
|
|
1256
|
-
/** @type {?} */
|
|
1257
|
-
const from = clamp(fromIndex, array.length - 1);
|
|
1258
|
-
/** @type {?} */
|
|
1259
|
-
const to = clamp(toIndex, array.length - 1);
|
|
1260
|
-
if (from === to) {
|
|
1261
|
-
return;
|
|
1262
|
-
}
|
|
1263
|
-
/** @type {?} */
|
|
1264
|
-
const target = array[from];
|
|
1265
|
-
/** @type {?} */
|
|
1266
|
-
const delta = to < from ? -1 : 1;
|
|
1267
|
-
for (let i = from; i !== to; i += delta) {
|
|
1268
|
-
array[i] = array[i + delta];
|
|
1269
|
-
}
|
|
1270
|
-
array[to] = target;
|
|
1271
|
-
}
|
|
1272
1484
|
/**
|
|
1273
|
-
*
|
|
1274
|
-
* @
|
|
1275
|
-
* @param {?}
|
|
1276
|
-
* @param {?}
|
|
1277
|
-
* @param {?} currentIndex Index of the item in its current array.
|
|
1278
|
-
* @param {?} targetIndex Index at which to insert the item.
|
|
1485
|
+
* Clamps a value between a minimum and a maximum.
|
|
1486
|
+
* @param {?} value
|
|
1487
|
+
* @param {?} min
|
|
1488
|
+
* @param {?} max
|
|
1279
1489
|
* @return {?}
|
|
1280
1490
|
*/
|
|
1281
|
-
function
|
|
1282
|
-
|
|
1283
|
-
const from = clamp(currentIndex, currentArray.length - 1);
|
|
1284
|
-
/** @type {?} */
|
|
1285
|
-
const to = clamp(targetIndex, targetArray.length);
|
|
1286
|
-
if (currentArray.length) {
|
|
1287
|
-
targetArray.splice(to, 0, currentArray.splice(from, 1)[0]);
|
|
1288
|
-
}
|
|
1491
|
+
function clamp$1(value, min, max) {
|
|
1492
|
+
return Math.max(min, Math.min(max, value));
|
|
1289
1493
|
}
|
|
1290
1494
|
/**
|
|
1291
|
-
*
|
|
1292
|
-
*
|
|
1293
|
-
* @template T
|
|
1294
|
-
* @param {?} currentArray Array from which to copy the item.
|
|
1295
|
-
* @param {?} targetArray Array into which is copy the item.
|
|
1296
|
-
* @param {?} currentIndex Index of the item in its current array.
|
|
1297
|
-
* @param {?} targetIndex Index at which to insert the item.
|
|
1298
|
-
*
|
|
1495
|
+
* Helper to remove an element from the DOM and to do all the necessary null checks.
|
|
1496
|
+
* @param {?} element Element to be removed.
|
|
1299
1497
|
* @return {?}
|
|
1300
1498
|
*/
|
|
1301
|
-
function
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
if (currentArray.length) {
|
|
1305
|
-
targetArray.splice(to, 0, currentArray[currentIndex]);
|
|
1499
|
+
function removeElement(element) {
|
|
1500
|
+
if (element && element.parentNode) {
|
|
1501
|
+
element.parentNode.removeChild(element);
|
|
1306
1502
|
}
|
|
1307
1503
|
}
|
|
1308
1504
|
/**
|
|
1309
|
-
*
|
|
1310
|
-
* @param {?}
|
|
1311
|
-
* @param {?} max
|
|
1505
|
+
* Determines whether an event is a touch event.
|
|
1506
|
+
* @param {?} event
|
|
1312
1507
|
* @return {?}
|
|
1313
1508
|
*/
|
|
1314
|
-
function
|
|
1315
|
-
return
|
|
1509
|
+
function isTouchEvent(event) {
|
|
1510
|
+
return event.type.startsWith('touch');
|
|
1316
1511
|
}
|
|
1317
1512
|
|
|
1318
1513
|
/**
|
|
1319
1514
|
* @fileoverview added by tsickle
|
|
1320
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
1515
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
1321
1516
|
*/
|
|
1322
1517
|
/**
|
|
1323
|
-
*
|
|
1324
|
-
*
|
|
1325
|
-
* automatically. Can be used as an alternative to the `cdkDropListConnectedTo` input
|
|
1326
|
-
* from `cdkDropList`.
|
|
1327
|
-
* @template T
|
|
1518
|
+
* Injection token that can be used to configure the behavior of `CdkDrag`.
|
|
1519
|
+
* @type {?}
|
|
1328
1520
|
*/
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
*/
|
|
1334
|
-
this._items = new Set();
|
|
1335
|
-
}
|
|
1336
|
-
/**
|
|
1337
|
-
* @return {?}
|
|
1338
|
-
*/
|
|
1339
|
-
ngOnDestroy() {
|
|
1340
|
-
this._items.clear();
|
|
1341
|
-
}
|
|
1342
|
-
}
|
|
1343
|
-
CdkDropListGroup.decorators = [
|
|
1344
|
-
{ type: Directive, args: [{
|
|
1345
|
-
selector: '[cdkDropListGroup]'
|
|
1346
|
-
},] },
|
|
1347
|
-
];
|
|
1348
|
-
|
|
1521
|
+
const CDK_DRAG_CONFIG = new InjectionToken('CDK_DRAG_CONFIG', {
|
|
1522
|
+
providedIn: 'root',
|
|
1523
|
+
factory: CDK_DRAG_CONFIG_FACTORY
|
|
1524
|
+
});
|
|
1349
1525
|
/**
|
|
1350
|
-
*
|
|
1351
|
-
* @
|
|
1526
|
+
* \@docs-private
|
|
1527
|
+
* @return {?}
|
|
1352
1528
|
*/
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
let _uniqueIdCounter = 0;
|
|
1357
|
-
/** *
|
|
1358
|
-
* Proximity, as a ratio to width/height, at which a
|
|
1359
|
-
* dragged item will affect the drop container.
|
|
1360
|
-
@type {?} */
|
|
1361
|
-
const DROP_PROXIMITY_THRESHOLD = 0.05;
|
|
1529
|
+
function CDK_DRAG_CONFIG_FACTORY() {
|
|
1530
|
+
return { dragStartThreshold: 5, pointerDirectionChangeThreshold: 5 };
|
|
1531
|
+
}
|
|
1362
1532
|
/**
|
|
1363
|
-
*
|
|
1533
|
+
* Element that can be moved inside a CdkDropList container.
|
|
1364
1534
|
* @template T
|
|
1365
1535
|
*/
|
|
1366
|
-
class
|
|
1536
|
+
class CdkDrag {
|
|
1367
1537
|
/**
|
|
1368
1538
|
* @param {?} element
|
|
1539
|
+
* @param {?} dropContainer
|
|
1540
|
+
* @param {?} _document
|
|
1541
|
+
* @param {?} _ngZone
|
|
1542
|
+
* @param {?} _viewContainerRef
|
|
1543
|
+
* @param {?} _viewportRuler
|
|
1369
1544
|
* @param {?} _dragDropRegistry
|
|
1370
|
-
* @param {?}
|
|
1371
|
-
* @param {
|
|
1372
|
-
* @param {?=} _group
|
|
1545
|
+
* @param {?} _config
|
|
1546
|
+
* @param {?} _dir
|
|
1373
1547
|
*/
|
|
1374
|
-
constructor(element, _dragDropRegistry,
|
|
1548
|
+
constructor(element, dropContainer, _document, _ngZone, _viewContainerRef, _viewportRuler, _dragDropRegistry, _config, _dir) {
|
|
1375
1549
|
this.element = element;
|
|
1550
|
+
this.dropContainer = dropContainer;
|
|
1551
|
+
this._document = _document;
|
|
1552
|
+
this._ngZone = _ngZone;
|
|
1553
|
+
this._viewContainerRef = _viewContainerRef;
|
|
1554
|
+
this._viewportRuler = _viewportRuler;
|
|
1376
1555
|
this._dragDropRegistry = _dragDropRegistry;
|
|
1377
|
-
this.
|
|
1556
|
+
this._config = _config;
|
|
1378
1557
|
this._dir = _dir;
|
|
1379
|
-
this.
|
|
1380
|
-
|
|
1381
|
-
* Other draggable containers that this container is connected to and into which the
|
|
1382
|
-
* container's items can be transferred. Can either be references to other drop containers,
|
|
1383
|
-
* or their unique IDs.
|
|
1384
|
-
*/
|
|
1385
|
-
this.connectedTo = [];
|
|
1386
|
-
/**
|
|
1387
|
-
* Direction in which the list is oriented.
|
|
1388
|
-
*/
|
|
1389
|
-
this.orientation = 'vertical';
|
|
1558
|
+
this._destroyed = new Subject();
|
|
1559
|
+
this._disabled = false;
|
|
1390
1560
|
/**
|
|
1391
|
-
*
|
|
1392
|
-
* in the `connectedTo` of another `CdkDropList`.
|
|
1561
|
+
* Emits when the user starts dragging the item.
|
|
1393
1562
|
*/
|
|
1394
|
-
this.
|
|
1395
|
-
this._disabled = false;
|
|
1563
|
+
this.started = new EventEmitter();
|
|
1396
1564
|
/**
|
|
1397
|
-
*
|
|
1398
|
-
* is allowed to be moved into a drop container.
|
|
1565
|
+
* Emits when the user has released a drag item, before any animations have started.
|
|
1399
1566
|
*/
|
|
1400
|
-
this.
|
|
1567
|
+
this.released = new EventEmitter();
|
|
1401
1568
|
/**
|
|
1402
|
-
* Emits when the user
|
|
1569
|
+
* Emits when the user stops dragging an item in the container.
|
|
1403
1570
|
*/
|
|
1404
|
-
this.
|
|
1571
|
+
this.ended = new EventEmitter();
|
|
1405
1572
|
/**
|
|
1406
|
-
* Emits when the user has moved
|
|
1573
|
+
* Emits when the user has moved the item into a new container.
|
|
1407
1574
|
*/
|
|
1408
1575
|
this.entered = new EventEmitter();
|
|
1409
1576
|
/**
|
|
1410
|
-
* Emits when the user removes
|
|
1411
|
-
* by dragging it into another container.
|
|
1577
|
+
* Emits when the user removes the item its container by dragging it into another container.
|
|
1412
1578
|
*/
|
|
1413
1579
|
this.exited = new EventEmitter();
|
|
1414
1580
|
/**
|
|
1415
|
-
* Emits
|
|
1416
|
-
*/
|
|
1417
|
-
this.sorted = new EventEmitter();
|
|
1418
|
-
/**
|
|
1419
|
-
* Whether an item in the container is being dragged.
|
|
1420
|
-
*/
|
|
1421
|
-
this._dragging = false;
|
|
1422
|
-
/**
|
|
1423
|
-
* Cache of the dimensions of all the items and the sibling containers.
|
|
1581
|
+
* Emits when the user drops the item inside a container.
|
|
1424
1582
|
*/
|
|
1425
|
-
this.
|
|
1583
|
+
this.dropped = new EventEmitter();
|
|
1426
1584
|
/**
|
|
1427
|
-
*
|
|
1428
|
-
*
|
|
1585
|
+
* Emits as the user is dragging the item. Use with caution,
|
|
1586
|
+
* because this event will fire for every pixel that the user has dragged.
|
|
1429
1587
|
*/
|
|
1430
|
-
this.
|
|
1588
|
+
this.moved = new Observable((observer) => {
|
|
1589
|
+
/** @type {?} */
|
|
1590
|
+
const subscription = this._dragRef.moved.pipe(map(movedEvent => ({
|
|
1591
|
+
source: this,
|
|
1592
|
+
pointerPosition: movedEvent.pointerPosition,
|
|
1593
|
+
event: movedEvent.event,
|
|
1594
|
+
delta: movedEvent.delta
|
|
1595
|
+
}))).subscribe(observer);
|
|
1596
|
+
return () => {
|
|
1597
|
+
subscription.unsubscribe();
|
|
1598
|
+
};
|
|
1599
|
+
});
|
|
1600
|
+
/** @type {?} */
|
|
1601
|
+
const ref = this._dragRef = new DragRef(element, this._document, this._ngZone, this._viewContainerRef, this._viewportRuler, this._dragDropRegistry, this._config, this.dropContainer ? this.dropContainer._dropListRef : undefined, this._dir);
|
|
1602
|
+
ref.data = this;
|
|
1603
|
+
this._syncInputs(ref);
|
|
1604
|
+
this._proxyEvents(ref);
|
|
1431
1605
|
}
|
|
1432
1606
|
/**
|
|
1433
|
-
* Whether starting
|
|
1607
|
+
* Whether starting to drag this element is disabled.
|
|
1434
1608
|
* @return {?}
|
|
1435
1609
|
*/
|
|
1436
|
-
get disabled() {
|
|
1610
|
+
get disabled() {
|
|
1611
|
+
return this._disabled || (this.dropContainer && this.dropContainer.disabled);
|
|
1612
|
+
}
|
|
1437
1613
|
/**
|
|
1438
1614
|
* @param {?} value
|
|
1439
1615
|
* @return {?}
|
|
1440
1616
|
*/
|
|
1441
1617
|
set disabled(value) {
|
|
1442
1618
|
this._disabled = coerceBooleanProperty(value);
|
|
1619
|
+
this._dragRef.disabled = this._disabled;
|
|
1443
1620
|
}
|
|
1444
1621
|
/**
|
|
1622
|
+
* Returns the element that is being used as a placeholder
|
|
1623
|
+
* while the current element is being dragged.
|
|
1445
1624
|
* @return {?}
|
|
1446
1625
|
*/
|
|
1447
|
-
|
|
1448
|
-
this.
|
|
1449
|
-
if (this._group) {
|
|
1450
|
-
this._group._items.add(this);
|
|
1451
|
-
}
|
|
1626
|
+
getPlaceholderElement() {
|
|
1627
|
+
return this._dragRef.getPlaceholderElement();
|
|
1452
1628
|
}
|
|
1453
1629
|
/**
|
|
1630
|
+
* Returns the root draggable element.
|
|
1454
1631
|
* @return {?}
|
|
1455
1632
|
*/
|
|
1456
|
-
|
|
1457
|
-
this.
|
|
1458
|
-
if (this._group) {
|
|
1459
|
-
this._group._items.delete(this);
|
|
1460
|
-
}
|
|
1633
|
+
getRootElement() {
|
|
1634
|
+
return this._dragRef.getRootElement();
|
|
1461
1635
|
}
|
|
1462
1636
|
/**
|
|
1463
|
-
*
|
|
1637
|
+
* Resets a standalone drag item to its initial position.
|
|
1464
1638
|
* @return {?}
|
|
1465
1639
|
*/
|
|
1466
|
-
|
|
1467
|
-
this.
|
|
1468
|
-
this._activeDraggables = this._draggables.toArray();
|
|
1469
|
-
this._cachePositions();
|
|
1470
|
-
this._changeDetectorRef.markForCheck();
|
|
1640
|
+
reset() {
|
|
1641
|
+
this._dragRef.reset();
|
|
1471
1642
|
}
|
|
1472
1643
|
/**
|
|
1473
|
-
* Drops an item into this container.
|
|
1474
|
-
* @param {?} item Item being dropped into the container.
|
|
1475
|
-
* @param {?} currentIndex Index at which the item should be inserted.
|
|
1476
|
-
* @param {?} previousContainer Container from which the item got dragged in.
|
|
1477
1644
|
* @return {?}
|
|
1478
1645
|
*/
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1646
|
+
ngAfterViewInit() {
|
|
1647
|
+
// We need to wait for the zone to stabilize, in order for the reference
|
|
1648
|
+
// element to be in the proper place in the DOM. This is mostly relevant
|
|
1649
|
+
// for draggable elements inside portals since they get stamped out in
|
|
1650
|
+
// their original DOM position and then they get transferred to the portal.
|
|
1651
|
+
this._ngZone.onStable.asObservable()
|
|
1652
|
+
.pipe(take(1), takeUntil(this._destroyed))
|
|
1653
|
+
.subscribe(() => {
|
|
1654
|
+
this._updateRootElement();
|
|
1655
|
+
// Listen for any newly-added handles.
|
|
1656
|
+
this._handles.changes.pipe(startWith(this._handles),
|
|
1657
|
+
// Sync the new handles with the DragRef.
|
|
1658
|
+
tap((handles) => {
|
|
1659
|
+
/** @type {?} */
|
|
1660
|
+
const childHandleElements = handles
|
|
1661
|
+
.filter(handle => handle._parentDrag === this)
|
|
1662
|
+
.map(handle => handle.element);
|
|
1663
|
+
this._dragRef.withHandles(childHandleElements);
|
|
1664
|
+
}),
|
|
1665
|
+
// Listen if the state of any of the handles changes.
|
|
1666
|
+
switchMap((handles) => {
|
|
1667
|
+
return merge(...handles.map(item => item._stateChanges));
|
|
1668
|
+
}), takeUntil(this._destroyed)).subscribe(handleInstance => {
|
|
1669
|
+
// Enabled/disable the handle that changed in the DragRef.
|
|
1670
|
+
/** @type {?} */
|
|
1671
|
+
const dragRef = this._dragRef;
|
|
1672
|
+
/** @type {?} */
|
|
1673
|
+
const handle = handleInstance.element.nativeElement;
|
|
1674
|
+
handleInstance.disabled ? dragRef.disableHandle(handle) : dragRef.enableHandle(handle);
|
|
1675
|
+
});
|
|
1488
1676
|
});
|
|
1489
1677
|
}
|
|
1490
1678
|
/**
|
|
1491
|
-
*
|
|
1492
|
-
* @param {?} item Item that was moved into the container.
|
|
1493
|
-
* @param {?} pointerX Position of the item along the X axis.
|
|
1494
|
-
* @param {?} pointerY Position of the item along the Y axis.
|
|
1679
|
+
* @param {?} changes
|
|
1495
1680
|
* @return {?}
|
|
1496
1681
|
*/
|
|
1497
|
-
|
|
1498
|
-
this.entered.emit({ item, container: this });
|
|
1499
|
-
this.start();
|
|
1500
|
-
/** @type {?} */
|
|
1501
|
-
const newIndex = this._getItemIndexFromPointerPosition(item, pointerX, pointerY);
|
|
1502
|
-
/** @type {?} */
|
|
1503
|
-
const currentIndex = this._activeDraggables.indexOf(item);
|
|
1682
|
+
ngOnChanges(changes) {
|
|
1504
1683
|
/** @type {?} */
|
|
1505
|
-
const
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
if (currentIndex > -1) {
|
|
1511
|
-
this._activeDraggables.splice(currentIndex, 1);
|
|
1512
|
-
}
|
|
1513
|
-
// Don't use items that are being dragged as a reference, because
|
|
1514
|
-
// their element has been moved down to the bottom of the body.
|
|
1515
|
-
if (newPositionReference && !this._dragDropRegistry.isDragging(newPositionReference)) {
|
|
1516
|
-
/** @type {?} */
|
|
1517
|
-
const element = newPositionReference.getRootElement(); /** @type {?} */
|
|
1518
|
-
((element.parentElement)).insertBefore(placeholder, element);
|
|
1519
|
-
this._activeDraggables.splice(newIndex, 0, item);
|
|
1520
|
-
}
|
|
1521
|
-
else {
|
|
1522
|
-
this.element.nativeElement.appendChild(placeholder);
|
|
1523
|
-
this._activeDraggables.push(item);
|
|
1684
|
+
const rootSelectorChange = changes.rootElementSelector;
|
|
1685
|
+
// We don't have to react to the first change since it's being
|
|
1686
|
+
// handled in `ngAfterViewInit` where it needs to be deferred.
|
|
1687
|
+
if (rootSelectorChange && !rootSelectorChange.firstChange) {
|
|
1688
|
+
this._updateRootElement();
|
|
1524
1689
|
}
|
|
1525
|
-
// The transform needs to be cleared so it doesn't throw off the measurements.
|
|
1526
|
-
placeholder.style.transform = '';
|
|
1527
|
-
// Note that the positions were already cached when we called `start` above,
|
|
1528
|
-
// but we need to refresh them since the amount of items has changed.
|
|
1529
|
-
this._cachePositions();
|
|
1530
1690
|
}
|
|
1531
1691
|
/**
|
|
1532
|
-
* Removes an item from the container after it was dragged into another container by the user.
|
|
1533
|
-
* @param {?} item Item that was dragged out.
|
|
1534
1692
|
* @return {?}
|
|
1535
1693
|
*/
|
|
1536
|
-
|
|
1694
|
+
ngOnDestroy() {
|
|
1695
|
+
this._destroyed.next();
|
|
1696
|
+
this._destroyed.complete();
|
|
1697
|
+
this._dragRef.dispose();
|
|
1698
|
+
}
|
|
1699
|
+
/**
|
|
1700
|
+
* Syncs the root element with the `DragRef`.
|
|
1701
|
+
* @private
|
|
1702
|
+
* @return {?}
|
|
1703
|
+
*/
|
|
1704
|
+
_updateRootElement() {
|
|
1705
|
+
/** @type {?} */
|
|
1706
|
+
const element = this.element.nativeElement;
|
|
1707
|
+
/** @type {?} */
|
|
1708
|
+
const rootElement = this.rootElementSelector ?
|
|
1709
|
+
getClosestMatchingAncestor(element, this.rootElementSelector) : element;
|
|
1710
|
+
if (rootElement && rootElement.nodeType !== this._document.ELEMENT_NODE) {
|
|
1711
|
+
throw Error(`cdkDrag must be attached to an element node. ` +
|
|
1712
|
+
`Currently attached to "${rootElement.nodeName}".`);
|
|
1713
|
+
}
|
|
1714
|
+
this._dragRef.withRootElement(rootElement || element);
|
|
1715
|
+
}
|
|
1716
|
+
/**
|
|
1717
|
+
* Gets the boundary element, based on the `boundaryElementSelector`.
|
|
1718
|
+
* @private
|
|
1719
|
+
* @return {?}
|
|
1720
|
+
*/
|
|
1721
|
+
_getBoundaryElement() {
|
|
1722
|
+
/** @type {?} */
|
|
1723
|
+
const selector = this.boundaryElementSelector;
|
|
1724
|
+
return selector ? getClosestMatchingAncestor(this.element.nativeElement, selector) : null;
|
|
1725
|
+
}
|
|
1726
|
+
/**
|
|
1727
|
+
* Syncs the inputs of the CdkDrag with the options of the underlying DragRef.
|
|
1728
|
+
* @private
|
|
1729
|
+
* @param {?} ref
|
|
1730
|
+
* @return {?}
|
|
1731
|
+
*/
|
|
1732
|
+
_syncInputs(ref) {
|
|
1733
|
+
ref.beforeStarted.subscribe(() => {
|
|
1734
|
+
if (!ref.isDragging()) {
|
|
1735
|
+
const { _placeholderTemplate: placeholder, _previewTemplate: preview } = this;
|
|
1736
|
+
ref.disabled = this.disabled;
|
|
1737
|
+
ref.lockAxis = this.lockAxis;
|
|
1738
|
+
ref.withBoundaryElement(this._getBoundaryElement());
|
|
1739
|
+
placeholder ? ref.withPlaceholderTemplate(placeholder.templateRef, placeholder.data) :
|
|
1740
|
+
ref.withPlaceholderTemplate(null);
|
|
1741
|
+
preview ? ref.withPreviewTemplate(preview.templateRef, preview.data) :
|
|
1742
|
+
ref.withPreviewTemplate(null);
|
|
1743
|
+
}
|
|
1744
|
+
});
|
|
1745
|
+
}
|
|
1746
|
+
/**
|
|
1747
|
+
* Proxies the events from a DragRef to events that
|
|
1748
|
+
* match the interfaces of the CdkDrag outputs.
|
|
1749
|
+
* @private
|
|
1750
|
+
* @param {?} ref
|
|
1751
|
+
* @return {?}
|
|
1752
|
+
*/
|
|
1753
|
+
_proxyEvents(ref) {
|
|
1754
|
+
ref.started.subscribe(() => {
|
|
1755
|
+
this.started.emit({ source: this });
|
|
1756
|
+
});
|
|
1757
|
+
ref.released.subscribe(() => {
|
|
1758
|
+
this.released.emit({ source: this });
|
|
1759
|
+
});
|
|
1760
|
+
ref.ended.subscribe(() => {
|
|
1761
|
+
this.ended.emit({ source: this });
|
|
1762
|
+
});
|
|
1763
|
+
ref.entered.subscribe(event => {
|
|
1764
|
+
this.entered.emit({
|
|
1765
|
+
container: event.container.data,
|
|
1766
|
+
item: this
|
|
1767
|
+
});
|
|
1768
|
+
});
|
|
1769
|
+
ref.exited.subscribe(event => {
|
|
1770
|
+
this.exited.emit({
|
|
1771
|
+
container: event.container.data,
|
|
1772
|
+
item: this
|
|
1773
|
+
});
|
|
1774
|
+
});
|
|
1775
|
+
ref.dropped.subscribe(event => {
|
|
1776
|
+
this.dropped.emit({
|
|
1777
|
+
previousIndex: event.previousIndex,
|
|
1778
|
+
currentIndex: event.currentIndex,
|
|
1779
|
+
previousContainer: event.previousContainer.data,
|
|
1780
|
+
container: event.container.data,
|
|
1781
|
+
isPointerOverContainer: event.isPointerOverContainer,
|
|
1782
|
+
item: this
|
|
1783
|
+
});
|
|
1784
|
+
});
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
CdkDrag.decorators = [
|
|
1788
|
+
{ type: Directive, args: [{
|
|
1789
|
+
selector: '[cdkDrag]',
|
|
1790
|
+
exportAs: 'cdkDrag',
|
|
1791
|
+
host: {
|
|
1792
|
+
'class': 'cdk-drag',
|
|
1793
|
+
'[class.cdk-drag-dragging]': '_dragRef.isDragging()',
|
|
1794
|
+
},
|
|
1795
|
+
providers: [{ provide: CDK_DRAG_PARENT, useExisting: CdkDrag }]
|
|
1796
|
+
},] },
|
|
1797
|
+
];
|
|
1798
|
+
/** @nocollapse */
|
|
1799
|
+
CdkDrag.ctorParameters = () => [
|
|
1800
|
+
{ type: ElementRef },
|
|
1801
|
+
{ type: undefined, decorators: [{ type: Inject, args: [CDK_DROP_LIST,] }, { type: Optional }, { type: SkipSelf }] },
|
|
1802
|
+
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
|
|
1803
|
+
{ type: NgZone },
|
|
1804
|
+
{ type: ViewContainerRef },
|
|
1805
|
+
{ type: ViewportRuler },
|
|
1806
|
+
{ type: DragDropRegistry },
|
|
1807
|
+
{ type: undefined, decorators: [{ type: Inject, args: [CDK_DRAG_CONFIG,] }] },
|
|
1808
|
+
{ type: Directionality, decorators: [{ type: Optional }] }
|
|
1809
|
+
];
|
|
1810
|
+
CdkDrag.propDecorators = {
|
|
1811
|
+
_handles: [{ type: ContentChildren, args: [CdkDragHandle, { descendants: true },] }],
|
|
1812
|
+
_previewTemplate: [{ type: ContentChild, args: [CdkDragPreview,] }],
|
|
1813
|
+
_placeholderTemplate: [{ type: ContentChild, args: [CdkDragPlaceholder,] }],
|
|
1814
|
+
data: [{ type: Input, args: ['cdkDragData',] }],
|
|
1815
|
+
lockAxis: [{ type: Input, args: ['cdkDragLockAxis',] }],
|
|
1816
|
+
rootElementSelector: [{ type: Input, args: ['cdkDragRootElement',] }],
|
|
1817
|
+
boundaryElementSelector: [{ type: Input, args: ['cdkDragBoundary',] }],
|
|
1818
|
+
disabled: [{ type: Input, args: ['cdkDragDisabled',] }],
|
|
1819
|
+
started: [{ type: Output, args: ['cdkDragStarted',] }],
|
|
1820
|
+
released: [{ type: Output, args: ['cdkDragReleased',] }],
|
|
1821
|
+
ended: [{ type: Output, args: ['cdkDragEnded',] }],
|
|
1822
|
+
entered: [{ type: Output, args: ['cdkDragEntered',] }],
|
|
1823
|
+
exited: [{ type: Output, args: ['cdkDragExited',] }],
|
|
1824
|
+
dropped: [{ type: Output, args: ['cdkDragDropped',] }],
|
|
1825
|
+
moved: [{ type: Output, args: ['cdkDragMoved',] }]
|
|
1826
|
+
};
|
|
1827
|
+
/**
|
|
1828
|
+
* Gets the closest ancestor of an element that matches a selector.
|
|
1829
|
+
* @param {?} element
|
|
1830
|
+
* @param {?} selector
|
|
1831
|
+
* @return {?}
|
|
1832
|
+
*/
|
|
1833
|
+
function getClosestMatchingAncestor(element, selector) {
|
|
1834
|
+
/** @type {?} */
|
|
1835
|
+
let currentElement = (/** @type {?} */ (element.parentElement));
|
|
1836
|
+
while (currentElement) {
|
|
1837
|
+
// IE doesn't support `matches` so we have to fall back to `msMatchesSelector`.
|
|
1838
|
+
if (currentElement.matches ? currentElement.matches(selector) :
|
|
1839
|
+
((/** @type {?} */ (currentElement))).msMatchesSelector(selector)) {
|
|
1840
|
+
return currentElement;
|
|
1841
|
+
}
|
|
1842
|
+
currentElement = currentElement.parentElement;
|
|
1843
|
+
}
|
|
1844
|
+
return null;
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
/**
|
|
1848
|
+
* @fileoverview added by tsickle
|
|
1849
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
1850
|
+
*/
|
|
1851
|
+
/**
|
|
1852
|
+
* Declaratively connects sibling `cdkDropList` instances together. All of the `cdkDropList`
|
|
1853
|
+
* elements that are placed inside a `cdkDropListGroup` will be connected to each other
|
|
1854
|
+
* automatically. Can be used as an alternative to the `cdkDropListConnectedTo` input
|
|
1855
|
+
* from `cdkDropList`.
|
|
1856
|
+
* @template T
|
|
1857
|
+
*/
|
|
1858
|
+
class CdkDropListGroup {
|
|
1859
|
+
constructor() {
|
|
1860
|
+
/**
|
|
1861
|
+
* Drop lists registered inside the group.
|
|
1862
|
+
*/
|
|
1863
|
+
this._items = new Set();
|
|
1864
|
+
this._disabled = false;
|
|
1865
|
+
}
|
|
1866
|
+
/**
|
|
1867
|
+
* Whether starting a dragging sequence from inside this group is disabled.
|
|
1868
|
+
* @return {?}
|
|
1869
|
+
*/
|
|
1870
|
+
get disabled() { return this._disabled; }
|
|
1871
|
+
/**
|
|
1872
|
+
* @param {?} value
|
|
1873
|
+
* @return {?}
|
|
1874
|
+
*/
|
|
1875
|
+
set disabled(value) {
|
|
1876
|
+
this._disabled = coerceBooleanProperty(value);
|
|
1877
|
+
}
|
|
1878
|
+
/**
|
|
1879
|
+
* @return {?}
|
|
1880
|
+
*/
|
|
1881
|
+
ngOnDestroy() {
|
|
1882
|
+
this._items.clear();
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1885
|
+
CdkDropListGroup.decorators = [
|
|
1886
|
+
{ type: Directive, args: [{
|
|
1887
|
+
selector: '[cdkDropListGroup]',
|
|
1888
|
+
exportAs: 'cdkDropListGroup',
|
|
1889
|
+
},] },
|
|
1890
|
+
];
|
|
1891
|
+
CdkDropListGroup.propDecorators = {
|
|
1892
|
+
disabled: [{ type: Input, args: ['cdkDropListGroupDisabled',] }]
|
|
1893
|
+
};
|
|
1894
|
+
|
|
1895
|
+
/**
|
|
1896
|
+
* @fileoverview added by tsickle
|
|
1897
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
1898
|
+
*/
|
|
1899
|
+
/**
|
|
1900
|
+
* Counter used to generate unique ids for drop refs.
|
|
1901
|
+
* @type {?}
|
|
1902
|
+
*/
|
|
1903
|
+
let _uniqueIdCounter = 0;
|
|
1904
|
+
/**
|
|
1905
|
+
* Proximity, as a ratio to width/height, at which a
|
|
1906
|
+
* dragged item will affect the drop container.
|
|
1907
|
+
* @type {?}
|
|
1908
|
+
*/
|
|
1909
|
+
const DROP_PROXIMITY_THRESHOLD = 0.05;
|
|
1910
|
+
/**
|
|
1911
|
+
* Reference to a drop list. Used to manipulate or dispose of the container.
|
|
1912
|
+
* \@docs-private
|
|
1913
|
+
* @template T
|
|
1914
|
+
*/
|
|
1915
|
+
class DropListRef {
|
|
1916
|
+
/**
|
|
1917
|
+
* @param {?} element
|
|
1918
|
+
* @param {?} _dragDropRegistry
|
|
1919
|
+
* @param {?} _document
|
|
1920
|
+
* @param {?=} _dir
|
|
1921
|
+
*/
|
|
1922
|
+
constructor(element, _dragDropRegistry, _document, _dir) {
|
|
1923
|
+
this.element = element;
|
|
1924
|
+
this._dragDropRegistry = _dragDropRegistry;
|
|
1925
|
+
this._dir = _dir;
|
|
1926
|
+
/**
|
|
1927
|
+
* Unique ID for the drop list.
|
|
1928
|
+
* @deprecated No longer being used. To be removed.
|
|
1929
|
+
* \@breaking-change 8.0.0
|
|
1930
|
+
*/
|
|
1931
|
+
this.id = `cdk-drop-list-ref-${_uniqueIdCounter++}`;
|
|
1932
|
+
/**
|
|
1933
|
+
* Whether starting a dragging sequence from this container is disabled.
|
|
1934
|
+
*/
|
|
1935
|
+
this.disabled = false;
|
|
1936
|
+
/**
|
|
1937
|
+
* Function that is used to determine whether an item
|
|
1938
|
+
* is allowed to be moved into a drop container.
|
|
1939
|
+
*/
|
|
1940
|
+
this.enterPredicate = () => true;
|
|
1941
|
+
/**
|
|
1942
|
+
* Emits right before dragging has started.
|
|
1943
|
+
*/
|
|
1944
|
+
this.beforeStarted = new Subject();
|
|
1945
|
+
/**
|
|
1946
|
+
* Emits when the user has moved a new drag item into this container.
|
|
1947
|
+
*/
|
|
1948
|
+
this.entered = new Subject();
|
|
1949
|
+
/**
|
|
1950
|
+
* Emits when the user removes an item from the container
|
|
1951
|
+
* by dragging it into another container.
|
|
1952
|
+
*/
|
|
1953
|
+
this.exited = new Subject();
|
|
1954
|
+
/**
|
|
1955
|
+
* Emits when the user drops an item inside the container.
|
|
1956
|
+
*/
|
|
1957
|
+
this.dropped = new Subject();
|
|
1958
|
+
/**
|
|
1959
|
+
* Emits as the user is swapping items while actively dragging.
|
|
1960
|
+
*/
|
|
1961
|
+
this.sorted = new Subject();
|
|
1962
|
+
/**
|
|
1963
|
+
* Whether an item in the list is being dragged.
|
|
1964
|
+
*/
|
|
1965
|
+
this._isDragging = false;
|
|
1966
|
+
/**
|
|
1967
|
+
* Cache of the dimensions of all the items inside the container.
|
|
1968
|
+
*/
|
|
1969
|
+
this._itemPositions = [];
|
|
1970
|
+
/**
|
|
1971
|
+
* Keeps track of the item that was last swapped with the dragged item, as
|
|
1972
|
+
* well as what direction the pointer was moving in when the swap occured.
|
|
1973
|
+
*/
|
|
1974
|
+
this._previousSwap = { drag: (/** @type {?} */ (null)), delta: 0 };
|
|
1975
|
+
/**
|
|
1976
|
+
* Drop lists that are connected to the current one.
|
|
1977
|
+
*/
|
|
1978
|
+
this._siblings = [];
|
|
1979
|
+
/**
|
|
1980
|
+
* Direction in which the list is oriented.
|
|
1981
|
+
*/
|
|
1982
|
+
this._orientation = 'vertical';
|
|
1983
|
+
/**
|
|
1984
|
+
* Connected siblings that currently have a dragged item.
|
|
1985
|
+
*/
|
|
1986
|
+
this._activeSiblings = new Set();
|
|
1987
|
+
_dragDropRegistry.registerDropContainer(this);
|
|
1988
|
+
this._document = _document;
|
|
1989
|
+
}
|
|
1990
|
+
/**
|
|
1991
|
+
* Removes the drop list functionality from the DOM element.
|
|
1992
|
+
* @return {?}
|
|
1993
|
+
*/
|
|
1994
|
+
dispose() {
|
|
1995
|
+
this.beforeStarted.complete();
|
|
1996
|
+
this.entered.complete();
|
|
1997
|
+
this.exited.complete();
|
|
1998
|
+
this.dropped.complete();
|
|
1999
|
+
this.sorted.complete();
|
|
2000
|
+
this._activeSiblings.clear();
|
|
2001
|
+
this._dragDropRegistry.removeDropContainer(this);
|
|
2002
|
+
}
|
|
2003
|
+
/**
|
|
2004
|
+
* Whether an item from this list is currently being dragged.
|
|
2005
|
+
* @return {?}
|
|
2006
|
+
*/
|
|
2007
|
+
isDragging() {
|
|
2008
|
+
return this._isDragging;
|
|
2009
|
+
}
|
|
2010
|
+
/**
|
|
2011
|
+
* Starts dragging an item.
|
|
2012
|
+
* @return {?}
|
|
2013
|
+
*/
|
|
2014
|
+
start() {
|
|
2015
|
+
this.beforeStarted.next();
|
|
2016
|
+
this._isDragging = true;
|
|
2017
|
+
this._activeDraggables = this._draggables.slice();
|
|
2018
|
+
this._cacheOwnPosition();
|
|
2019
|
+
this._cacheItemPositions();
|
|
2020
|
+
this._siblings.forEach(sibling => sibling._startReceiving(this));
|
|
2021
|
+
}
|
|
2022
|
+
/**
|
|
2023
|
+
* Emits an event to indicate that the user moved an item into the container.
|
|
2024
|
+
* @param {?} item Item that was moved into the container.
|
|
2025
|
+
* @param {?} pointerX Position of the item along the X axis.
|
|
2026
|
+
* @param {?} pointerY Position of the item along the Y axis.
|
|
2027
|
+
* @return {?}
|
|
2028
|
+
*/
|
|
2029
|
+
enter(item, pointerX, pointerY) {
|
|
2030
|
+
this.entered.next({ item, container: this });
|
|
2031
|
+
this.start();
|
|
2032
|
+
// We use the coordinates of where the item entered the drop
|
|
2033
|
+
// zone to figure out at which index it should be inserted.
|
|
2034
|
+
/** @type {?} */
|
|
2035
|
+
const newIndex = this._getItemIndexFromPointerPosition(item, pointerX, pointerY);
|
|
2036
|
+
/** @type {?} */
|
|
2037
|
+
const currentIndex = this._activeDraggables.indexOf(item);
|
|
2038
|
+
/** @type {?} */
|
|
2039
|
+
const newPositionReference = this._activeDraggables[newIndex];
|
|
2040
|
+
/** @type {?} */
|
|
2041
|
+
const placeholder = item.getPlaceholderElement();
|
|
2042
|
+
// Since the item may be in the `activeDraggables` already (e.g. if the user dragged it
|
|
2043
|
+
// into another container and back again), we have to ensure that it isn't duplicated.
|
|
2044
|
+
if (currentIndex > -1) {
|
|
2045
|
+
this._activeDraggables.splice(currentIndex, 1);
|
|
2046
|
+
}
|
|
2047
|
+
// Don't use items that are being dragged as a reference, because
|
|
2048
|
+
// their element has been moved down to the bottom of the body.
|
|
2049
|
+
if (newPositionReference && !this._dragDropRegistry.isDragging(newPositionReference)) {
|
|
2050
|
+
/** @type {?} */
|
|
2051
|
+
const element = newPositionReference.getRootElement();
|
|
2052
|
+
(/** @type {?} */ (element.parentElement)).insertBefore(placeholder, element);
|
|
2053
|
+
this._activeDraggables.splice(newIndex, 0, item);
|
|
2054
|
+
}
|
|
2055
|
+
else {
|
|
2056
|
+
this.element.nativeElement.appendChild(placeholder);
|
|
2057
|
+
this._activeDraggables.push(item);
|
|
2058
|
+
}
|
|
2059
|
+
// The transform needs to be cleared so it doesn't throw off the measurements.
|
|
2060
|
+
placeholder.style.transform = '';
|
|
2061
|
+
// Note that the positions were already cached when we called `start` above,
|
|
2062
|
+
// but we need to refresh them since the amount of items has changed.
|
|
2063
|
+
this._cacheItemPositions();
|
|
2064
|
+
}
|
|
2065
|
+
/**
|
|
2066
|
+
* Removes an item from the container after it was dragged into another container by the user.
|
|
2067
|
+
* @param {?} item Item that was dragged out.
|
|
2068
|
+
* @return {?}
|
|
2069
|
+
*/
|
|
2070
|
+
exit(item) {
|
|
1537
2071
|
this._reset();
|
|
1538
|
-
this.exited.
|
|
2072
|
+
this.exited.next({ item, container: this });
|
|
2073
|
+
}
|
|
2074
|
+
/**
|
|
2075
|
+
* Drops an item into this container.
|
|
2076
|
+
* @param {?} item Item being dropped into the container.
|
|
2077
|
+
* @param {?} currentIndex Index at which the item should be inserted.
|
|
2078
|
+
* @param {?} previousContainer Container from which the item got dragged in.
|
|
2079
|
+
* @param {?} isPointerOverContainer Whether the user's pointer was over the
|
|
2080
|
+
* container when the item was dropped.
|
|
2081
|
+
* @return {?}
|
|
2082
|
+
*/
|
|
2083
|
+
drop(item, currentIndex, previousContainer, isPointerOverContainer) {
|
|
2084
|
+
this._reset();
|
|
2085
|
+
this.dropped.next({
|
|
2086
|
+
item,
|
|
2087
|
+
currentIndex,
|
|
2088
|
+
previousIndex: previousContainer.getItemIndex(item),
|
|
2089
|
+
container: this,
|
|
2090
|
+
previousContainer,
|
|
2091
|
+
isPointerOverContainer
|
|
2092
|
+
});
|
|
2093
|
+
}
|
|
2094
|
+
/**
|
|
2095
|
+
* Sets the draggable items that are a part of this list.
|
|
2096
|
+
* @template THIS
|
|
2097
|
+
* @this {THIS}
|
|
2098
|
+
* @param {?} items Items that are a part of this list.
|
|
2099
|
+
* @return {THIS}
|
|
2100
|
+
*/
|
|
2101
|
+
withItems(items) {
|
|
2102
|
+
(/** @type {?} */ (this))._draggables = items.slice();
|
|
2103
|
+
return (/** @type {?} */ (this));
|
|
2104
|
+
}
|
|
2105
|
+
/**
|
|
2106
|
+
* Sets the containers that are connected to this one. When two or more containers are
|
|
2107
|
+
* connected, the user will be allowed to transfer items between them.
|
|
2108
|
+
* @template THIS
|
|
2109
|
+
* @this {THIS}
|
|
2110
|
+
* @param {?} connectedTo Other containers that the current containers should be connected to.
|
|
2111
|
+
* @return {THIS}
|
|
2112
|
+
*/
|
|
2113
|
+
connectedTo(connectedTo) {
|
|
2114
|
+
(/** @type {?} */ (this))._siblings = connectedTo.slice();
|
|
2115
|
+
return (/** @type {?} */ (this));
|
|
2116
|
+
}
|
|
2117
|
+
/**
|
|
2118
|
+
* Sets the orientation of the container.
|
|
2119
|
+
* @template THIS
|
|
2120
|
+
* @this {THIS}
|
|
2121
|
+
* @param {?} orientation New orientation for the container.
|
|
2122
|
+
* @return {THIS}
|
|
2123
|
+
*/
|
|
2124
|
+
withOrientation(orientation) {
|
|
2125
|
+
(/** @type {?} */ (this))._orientation = orientation;
|
|
2126
|
+
return (/** @type {?} */ (this));
|
|
2127
|
+
}
|
|
2128
|
+
/**
|
|
2129
|
+
* Figures out the index of an item in the container.
|
|
2130
|
+
* @param {?} item Item whose index should be determined.
|
|
2131
|
+
* @return {?}
|
|
2132
|
+
*/
|
|
2133
|
+
getItemIndex(item) {
|
|
2134
|
+
if (!this._isDragging) {
|
|
2135
|
+
return this._draggables.indexOf(item);
|
|
2136
|
+
}
|
|
2137
|
+
// Items are sorted always by top/left in the cache, however they flow differently in RTL.
|
|
2138
|
+
// The rest of the logic still stands no matter what orientation we're in, however
|
|
2139
|
+
// we need to invert the array when determining the index.
|
|
2140
|
+
/** @type {?} */
|
|
2141
|
+
const items = this._orientation === 'horizontal' && this._dir && this._dir.value === 'rtl' ?
|
|
2142
|
+
this._itemPositions.slice().reverse() : this._itemPositions;
|
|
2143
|
+
return findIndex(items, currentItem => currentItem.drag === item);
|
|
2144
|
+
}
|
|
2145
|
+
/**
|
|
2146
|
+
* Whether the list is able to receive the item that
|
|
2147
|
+
* is currently being dragged inside a connected drop list.
|
|
2148
|
+
* @return {?}
|
|
2149
|
+
*/
|
|
2150
|
+
isReceiving() {
|
|
2151
|
+
return this._activeSiblings.size > 0;
|
|
2152
|
+
}
|
|
2153
|
+
/**
|
|
2154
|
+
* Sorts an item inside the container based on its position.
|
|
2155
|
+
* @param {?} item Item to be sorted.
|
|
2156
|
+
* @param {?} pointerX Position of the item along the X axis.
|
|
2157
|
+
* @param {?} pointerY Position of the item along the Y axis.
|
|
2158
|
+
* @param {?} pointerDelta Direction in which the pointer is moving along each axis.
|
|
2159
|
+
* @return {?}
|
|
2160
|
+
*/
|
|
2161
|
+
_sortItem(item, pointerX, pointerY, pointerDelta) {
|
|
2162
|
+
// Don't sort the item if it's out of range.
|
|
2163
|
+
if (!this._isPointerNearDropContainer(pointerX, pointerY)) {
|
|
2164
|
+
return;
|
|
2165
|
+
}
|
|
2166
|
+
/** @type {?} */
|
|
2167
|
+
const siblings = this._itemPositions;
|
|
2168
|
+
/** @type {?} */
|
|
2169
|
+
const newIndex = this._getItemIndexFromPointerPosition(item, pointerX, pointerY, pointerDelta);
|
|
2170
|
+
if (newIndex === -1 && siblings.length > 0) {
|
|
2171
|
+
return;
|
|
2172
|
+
}
|
|
2173
|
+
/** @type {?} */
|
|
2174
|
+
const isHorizontal = this._orientation === 'horizontal';
|
|
2175
|
+
/** @type {?} */
|
|
2176
|
+
const currentIndex = findIndex(siblings, currentItem => currentItem.drag === item);
|
|
2177
|
+
/** @type {?} */
|
|
2178
|
+
const siblingAtNewPosition = siblings[newIndex];
|
|
2179
|
+
/** @type {?} */
|
|
2180
|
+
const currentPosition = siblings[currentIndex].clientRect;
|
|
2181
|
+
/** @type {?} */
|
|
2182
|
+
const newPosition = siblingAtNewPosition.clientRect;
|
|
2183
|
+
/** @type {?} */
|
|
2184
|
+
const delta = currentIndex > newIndex ? 1 : -1;
|
|
2185
|
+
this._previousSwap.drag = siblingAtNewPosition.drag;
|
|
2186
|
+
this._previousSwap.delta = isHorizontal ? pointerDelta.x : pointerDelta.y;
|
|
2187
|
+
// How many pixels the item's placeholder should be offset.
|
|
2188
|
+
/** @type {?} */
|
|
2189
|
+
const itemOffset = this._getItemOffsetPx(currentPosition, newPosition, delta);
|
|
2190
|
+
// How many pixels all the other items should be offset.
|
|
2191
|
+
/** @type {?} */
|
|
2192
|
+
const siblingOffset = this._getSiblingOffsetPx(currentIndex, siblings, delta);
|
|
2193
|
+
// Save the previous order of the items before moving the item to its new index.
|
|
2194
|
+
// We use this to check whether an item has been moved as a result of the sorting.
|
|
2195
|
+
/** @type {?} */
|
|
2196
|
+
const oldOrder = siblings.slice();
|
|
2197
|
+
// Shuffle the array in place.
|
|
2198
|
+
moveItemInArray(siblings, currentIndex, newIndex);
|
|
2199
|
+
this.sorted.next({
|
|
2200
|
+
previousIndex: currentIndex,
|
|
2201
|
+
currentIndex: newIndex,
|
|
2202
|
+
container: this,
|
|
2203
|
+
item
|
|
2204
|
+
});
|
|
2205
|
+
siblings.forEach((sibling, index) => {
|
|
2206
|
+
// Don't do anything if the position hasn't changed.
|
|
2207
|
+
if (oldOrder[index] === sibling) {
|
|
2208
|
+
return;
|
|
2209
|
+
}
|
|
2210
|
+
/** @type {?} */
|
|
2211
|
+
const isDraggedItem = sibling.drag === item;
|
|
2212
|
+
/** @type {?} */
|
|
2213
|
+
const offset = isDraggedItem ? itemOffset : siblingOffset;
|
|
2214
|
+
/** @type {?} */
|
|
2215
|
+
const elementToOffset = isDraggedItem ? item.getPlaceholderElement() :
|
|
2216
|
+
sibling.drag.getRootElement();
|
|
2217
|
+
// Update the offset to reflect the new position.
|
|
2218
|
+
sibling.offset += offset;
|
|
2219
|
+
// Since we're moving the items with a `transform`, we need to adjust their cached
|
|
2220
|
+
// client rects to reflect their new position, as well as swap their positions in the cache.
|
|
2221
|
+
// Note that we shouldn't use `getBoundingClientRect` here to update the cache, because the
|
|
2222
|
+
// elements may be mid-animation which will give us a wrong result.
|
|
2223
|
+
if (isHorizontal) {
|
|
2224
|
+
// Round the transforms since some browsers will
|
|
2225
|
+
// blur the elements, for sub-pixel transforms.
|
|
2226
|
+
elementToOffset.style.transform = `translate3d(${Math.round(sibling.offset)}px, 0, 0)`;
|
|
2227
|
+
adjustClientRect(sibling.clientRect, 0, offset);
|
|
2228
|
+
}
|
|
2229
|
+
else {
|
|
2230
|
+
elementToOffset.style.transform = `translate3d(0, ${Math.round(sibling.offset)}px, 0)`;
|
|
2231
|
+
adjustClientRect(sibling.clientRect, offset, 0);
|
|
2232
|
+
}
|
|
2233
|
+
});
|
|
2234
|
+
}
|
|
2235
|
+
/**
|
|
2236
|
+
* Caches the position of the drop list.
|
|
2237
|
+
* @private
|
|
2238
|
+
* @return {?}
|
|
2239
|
+
*/
|
|
2240
|
+
_cacheOwnPosition() {
|
|
2241
|
+
this._clientRect = this.element.nativeElement.getBoundingClientRect();
|
|
2242
|
+
}
|
|
2243
|
+
/**
|
|
2244
|
+
* Refreshes the position cache of the items and sibling containers.
|
|
2245
|
+
* @private
|
|
2246
|
+
* @return {?}
|
|
2247
|
+
*/
|
|
2248
|
+
_cacheItemPositions() {
|
|
2249
|
+
/** @type {?} */
|
|
2250
|
+
const isHorizontal = this._orientation === 'horizontal';
|
|
2251
|
+
this._itemPositions = this._activeDraggables.map(drag => {
|
|
2252
|
+
/** @type {?} */
|
|
2253
|
+
const elementToMeasure = this._dragDropRegistry.isDragging(drag) ?
|
|
2254
|
+
// If the element is being dragged, we have to measure the
|
|
2255
|
+
// placeholder, because the element is hidden.
|
|
2256
|
+
drag.getPlaceholderElement() :
|
|
2257
|
+
drag.getRootElement();
|
|
2258
|
+
/** @type {?} */
|
|
2259
|
+
const clientRect = elementToMeasure.getBoundingClientRect();
|
|
2260
|
+
return {
|
|
2261
|
+
drag,
|
|
2262
|
+
offset: 0,
|
|
2263
|
+
// We need to clone the `clientRect` here, because all the values on it are readonly
|
|
2264
|
+
// and we need to be able to update them. Also we can't use a spread here, because
|
|
2265
|
+
// the values on a `ClientRect` aren't own properties. See:
|
|
2266
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect#Notes
|
|
2267
|
+
clientRect: {
|
|
2268
|
+
top: clientRect.top,
|
|
2269
|
+
right: clientRect.right,
|
|
2270
|
+
bottom: clientRect.bottom,
|
|
2271
|
+
left: clientRect.left,
|
|
2272
|
+
width: clientRect.width,
|
|
2273
|
+
height: clientRect.height
|
|
2274
|
+
}
|
|
2275
|
+
};
|
|
2276
|
+
}).sort((a, b) => {
|
|
2277
|
+
return isHorizontal ? a.clientRect.left - b.clientRect.left :
|
|
2278
|
+
a.clientRect.top - b.clientRect.top;
|
|
2279
|
+
});
|
|
1539
2280
|
}
|
|
1540
2281
|
/**
|
|
1541
|
-
*
|
|
1542
|
-
* @
|
|
2282
|
+
* Resets the container to its initial state.
|
|
2283
|
+
* @private
|
|
1543
2284
|
* @return {?}
|
|
1544
2285
|
*/
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
2286
|
+
_reset() {
|
|
2287
|
+
this._isDragging = false;
|
|
2288
|
+
// TODO(crisbeto): may have to wait for the animations to finish.
|
|
2289
|
+
this._activeDraggables.forEach(item => item.getRootElement().style.transform = '');
|
|
2290
|
+
this._siblings.forEach(sibling => sibling._stopReceiving(this));
|
|
2291
|
+
this._activeDraggables = [];
|
|
2292
|
+
this._itemPositions = [];
|
|
2293
|
+
this._previousSwap.drag = null;
|
|
2294
|
+
this._previousSwap.delta = 0;
|
|
1553
2295
|
}
|
|
1554
2296
|
/**
|
|
1555
|
-
*
|
|
1556
|
-
* @
|
|
1557
|
-
* @param {?}
|
|
1558
|
-
* @param {?}
|
|
1559
|
-
* @param {?}
|
|
2297
|
+
* Gets the offset in pixels by which the items that aren't being dragged should be moved.
|
|
2298
|
+
* @private
|
|
2299
|
+
* @param {?} currentIndex Index of the item currently being dragged.
|
|
2300
|
+
* @param {?} siblings All of the items in the list.
|
|
2301
|
+
* @param {?} delta Direction in which the user is moving.
|
|
1560
2302
|
* @return {?}
|
|
1561
2303
|
*/
|
|
1562
|
-
|
|
1563
|
-
// Don't sort the item if it's out of range.
|
|
1564
|
-
if (!this._isPointerNearDropContainer(pointerX, pointerY)) {
|
|
1565
|
-
return;
|
|
1566
|
-
}
|
|
2304
|
+
_getSiblingOffsetPx(currentIndex, siblings, delta) {
|
|
1567
2305
|
/** @type {?} */
|
|
1568
|
-
const
|
|
2306
|
+
const isHorizontal = this._orientation === 'horizontal';
|
|
1569
2307
|
/** @type {?} */
|
|
1570
|
-
const
|
|
1571
|
-
|
|
1572
|
-
|
|
2308
|
+
const currentPosition = siblings[currentIndex].clientRect;
|
|
2309
|
+
/** @type {?} */
|
|
2310
|
+
const immediateSibling = siblings[currentIndex + delta * -1];
|
|
2311
|
+
/** @type {?} */
|
|
2312
|
+
let siblingOffset = currentPosition[isHorizontal ? 'width' : 'height'] * delta;
|
|
2313
|
+
if (immediateSibling) {
|
|
2314
|
+
/** @type {?} */
|
|
2315
|
+
const start = isHorizontal ? 'left' : 'top';
|
|
2316
|
+
/** @type {?} */
|
|
2317
|
+
const end = isHorizontal ? 'right' : 'bottom';
|
|
2318
|
+
// Get the spacing between the start of the current item and the end of the one immediately
|
|
2319
|
+
// after it in the direction in which the user is dragging, or vice versa. We add it to the
|
|
2320
|
+
// offset in order to push the element to where it will be when it's inline and is influenced
|
|
2321
|
+
// by the `margin` of its siblings.
|
|
2322
|
+
if (delta === -1) {
|
|
2323
|
+
siblingOffset -= immediateSibling.clientRect[start] - currentPosition[end];
|
|
2324
|
+
}
|
|
2325
|
+
else {
|
|
2326
|
+
siblingOffset += currentPosition[start] - immediateSibling.clientRect[end];
|
|
2327
|
+
}
|
|
1573
2328
|
}
|
|
2329
|
+
return siblingOffset;
|
|
2330
|
+
}
|
|
2331
|
+
/**
|
|
2332
|
+
* Checks whether the pointer coordinates are close to the drop container.
|
|
2333
|
+
* @private
|
|
2334
|
+
* @param {?} pointerX Coordinates along the X axis.
|
|
2335
|
+
* @param {?} pointerY Coordinates along the Y axis.
|
|
2336
|
+
* @return {?}
|
|
2337
|
+
*/
|
|
2338
|
+
_isPointerNearDropContainer(pointerX, pointerY) {
|
|
2339
|
+
const { top, right, bottom, left, width, height } = this._clientRect;
|
|
1574
2340
|
/** @type {?} */
|
|
1575
|
-
const
|
|
2341
|
+
const xThreshold = width * DROP_PROXIMITY_THRESHOLD;
|
|
1576
2342
|
/** @type {?} */
|
|
1577
|
-
const
|
|
2343
|
+
const yThreshold = height * DROP_PROXIMITY_THRESHOLD;
|
|
2344
|
+
return pointerY > top - yThreshold && pointerY < bottom + yThreshold &&
|
|
2345
|
+
pointerX > left - xThreshold && pointerX < right + xThreshold;
|
|
2346
|
+
}
|
|
2347
|
+
/**
|
|
2348
|
+
* Gets the offset in pixels by which the item that is being dragged should be moved.
|
|
2349
|
+
* @private
|
|
2350
|
+
* @param {?} currentPosition Current position of the item.
|
|
2351
|
+
* @param {?} newPosition Position of the item where the current item should be moved.
|
|
2352
|
+
* @param {?} delta Direction in which the user is moving.
|
|
2353
|
+
* @return {?}
|
|
2354
|
+
*/
|
|
2355
|
+
_getItemOffsetPx(currentPosition, newPosition, delta) {
|
|
1578
2356
|
/** @type {?} */
|
|
1579
|
-
const
|
|
2357
|
+
const isHorizontal = this._orientation === 'horizontal';
|
|
1580
2358
|
/** @type {?} */
|
|
1581
|
-
|
|
2359
|
+
let itemOffset = isHorizontal ? newPosition.left - currentPosition.left :
|
|
2360
|
+
newPosition.top - currentPosition.top;
|
|
2361
|
+
// Account for differences in the item width/height.
|
|
2362
|
+
if (delta === -1) {
|
|
2363
|
+
itemOffset += isHorizontal ? newPosition.width - currentPosition.width :
|
|
2364
|
+
newPosition.height - currentPosition.height;
|
|
2365
|
+
}
|
|
2366
|
+
return itemOffset;
|
|
2367
|
+
}
|
|
2368
|
+
/**
|
|
2369
|
+
* Gets the index of an item in the drop container, based on the position of the user's pointer.
|
|
2370
|
+
* @private
|
|
2371
|
+
* @param {?} item Item that is being sorted.
|
|
2372
|
+
* @param {?} pointerX Position of the user's pointer along the X axis.
|
|
2373
|
+
* @param {?} pointerY Position of the user's pointer along the Y axis.
|
|
2374
|
+
* @param {?=} delta Direction in which the user is moving their pointer.
|
|
2375
|
+
* @return {?}
|
|
2376
|
+
*/
|
|
2377
|
+
_getItemIndexFromPointerPosition(item, pointerX, pointerY, delta) {
|
|
1582
2378
|
/** @type {?} */
|
|
1583
|
-
const
|
|
2379
|
+
const isHorizontal = this._orientation === 'horizontal';
|
|
2380
|
+
return findIndex(this._itemPositions, ({ drag, clientRect }, _, array) => {
|
|
2381
|
+
if (drag === item) {
|
|
2382
|
+
// If there's only one item left in the container, it must be
|
|
2383
|
+
// the dragged item itself so we use it as a reference.
|
|
2384
|
+
return array.length < 2;
|
|
2385
|
+
}
|
|
2386
|
+
if (delta) {
|
|
2387
|
+
/** @type {?} */
|
|
2388
|
+
const direction = isHorizontal ? delta.x : delta.y;
|
|
2389
|
+
// If the user is still hovering over the same item as last time, and they didn't change
|
|
2390
|
+
// the direction in which they're dragging, we don't consider it a direction swap.
|
|
2391
|
+
if (drag === this._previousSwap.drag && direction === this._previousSwap.delta) {
|
|
2392
|
+
return false;
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
return isHorizontal ?
|
|
2396
|
+
// Round these down since most browsers report client rects with
|
|
2397
|
+
// sub-pixel precision, whereas the pointer coordinates are rounded to pixels.
|
|
2398
|
+
pointerX >= Math.floor(clientRect.left) && pointerX <= Math.floor(clientRect.right) :
|
|
2399
|
+
pointerY >= Math.floor(clientRect.top) && pointerY <= Math.floor(clientRect.bottom);
|
|
2400
|
+
});
|
|
2401
|
+
}
|
|
2402
|
+
/**
|
|
2403
|
+
* Checks whether the user's pointer is positioned over the container.
|
|
2404
|
+
* @param {?} x Pointer position along the X axis.
|
|
2405
|
+
* @param {?} y Pointer position along the Y axis.
|
|
2406
|
+
* @return {?}
|
|
2407
|
+
*/
|
|
2408
|
+
_isOverContainer(x, y) {
|
|
2409
|
+
return isInsideClientRect(this._clientRect, x, y);
|
|
2410
|
+
}
|
|
2411
|
+
/**
|
|
2412
|
+
* Figures out whether an item should be moved into a sibling
|
|
2413
|
+
* drop container, based on its current position.
|
|
2414
|
+
* @param {?} item Drag item that is being moved.
|
|
2415
|
+
* @param {?} x Position of the item along the X axis.
|
|
2416
|
+
* @param {?} y Position of the item along the Y axis.
|
|
2417
|
+
* @return {?}
|
|
2418
|
+
*/
|
|
2419
|
+
_getSiblingContainerFromPosition(item, x, y) {
|
|
2420
|
+
return this._siblings.find(sibling => sibling._canReceive(item, x, y));
|
|
2421
|
+
}
|
|
2422
|
+
/**
|
|
2423
|
+
* Checks whether the drop list can receive the passed-in item.
|
|
2424
|
+
* @param {?} item Item that is being dragged into the list.
|
|
2425
|
+
* @param {?} x Position of the item along the X axis.
|
|
2426
|
+
* @param {?} y Position of the item along the Y axis.
|
|
2427
|
+
* @return {?}
|
|
2428
|
+
*/
|
|
2429
|
+
_canReceive(item, x, y) {
|
|
2430
|
+
if (!this.enterPredicate(item, this) || !isInsideClientRect(this._clientRect, x, y)) {
|
|
2431
|
+
return false;
|
|
2432
|
+
}
|
|
1584
2433
|
/** @type {?} */
|
|
1585
|
-
const
|
|
1586
|
-
|
|
1587
|
-
|
|
2434
|
+
const elementFromPoint = this._document.elementFromPoint(x, y);
|
|
2435
|
+
// If there's no element at the pointer position, then
|
|
2436
|
+
// the client rect is probably scrolled out of the view.
|
|
2437
|
+
if (!elementFromPoint) {
|
|
2438
|
+
return false;
|
|
2439
|
+
}
|
|
1588
2440
|
/** @type {?} */
|
|
1589
|
-
const
|
|
2441
|
+
const element = this.element.nativeElement;
|
|
2442
|
+
// The `ClientRect`, that we're using to find the container over which the user is
|
|
2443
|
+
// hovering, doesn't give us any information on whether the element has been scrolled
|
|
2444
|
+
// out of the view or whether it's overlapping with other containers. This means that
|
|
2445
|
+
// we could end up transferring the item into a container that's invisible or is positioned
|
|
2446
|
+
// below another one. We use the result from `elementFromPoint` to get the top-most element
|
|
2447
|
+
// at the pointer position and to find whether it's one of the intersecting drop containers.
|
|
2448
|
+
return elementFromPoint === element || element.contains(elementFromPoint);
|
|
2449
|
+
}
|
|
2450
|
+
/**
|
|
2451
|
+
* Called by one of the connected drop lists when a dragging sequence has started.
|
|
2452
|
+
* @param {?} sibling Sibling in which dragging has started.
|
|
2453
|
+
* @return {?}
|
|
2454
|
+
*/
|
|
2455
|
+
_startReceiving(sibling) {
|
|
1590
2456
|
/** @type {?} */
|
|
1591
|
-
const
|
|
2457
|
+
const activeSiblings = this._activeSiblings;
|
|
2458
|
+
if (!activeSiblings.has(sibling)) {
|
|
2459
|
+
activeSiblings.add(sibling);
|
|
2460
|
+
this._cacheOwnPosition();
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
/**
|
|
2464
|
+
* Called by a connected drop list when dragging has stopped.
|
|
2465
|
+
* @param {?} sibling Sibling whose dragging has stopped.
|
|
2466
|
+
* @return {?}
|
|
2467
|
+
*/
|
|
2468
|
+
_stopReceiving(sibling) {
|
|
2469
|
+
this._activeSiblings.delete(sibling);
|
|
2470
|
+
}
|
|
2471
|
+
}
|
|
2472
|
+
/**
|
|
2473
|
+
* Updates the top/left positions of a `ClientRect`, as well as their bottom/right counterparts.
|
|
2474
|
+
* @param {?} clientRect `ClientRect` that should be updated.
|
|
2475
|
+
* @param {?} top Amount to add to the `top` position.
|
|
2476
|
+
* @param {?} left Amount to add to the `left` position.
|
|
2477
|
+
* @return {?}
|
|
2478
|
+
*/
|
|
2479
|
+
function adjustClientRect(clientRect, top, left) {
|
|
2480
|
+
clientRect.top += top;
|
|
2481
|
+
clientRect.bottom = clientRect.top + clientRect.height;
|
|
2482
|
+
clientRect.left += left;
|
|
2483
|
+
clientRect.right = clientRect.left + clientRect.width;
|
|
2484
|
+
}
|
|
2485
|
+
/**
|
|
2486
|
+
* Finds the index of an item that matches a predicate function. Used as an equivalent
|
|
2487
|
+
* of `Array.prototype.find` which isn't part of the standard Google typings.
|
|
2488
|
+
* @template T
|
|
2489
|
+
* @param {?} array Array in which to look for matches.
|
|
2490
|
+
* @param {?} predicate Function used to determine whether an item is a match.
|
|
2491
|
+
* @return {?}
|
|
2492
|
+
*/
|
|
2493
|
+
function findIndex(array, predicate) {
|
|
2494
|
+
for (let i = 0; i < array.length; i++) {
|
|
2495
|
+
if (predicate(array[i], i, array)) {
|
|
2496
|
+
return i;
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
return -1;
|
|
2500
|
+
}
|
|
2501
|
+
/**
|
|
2502
|
+
* Checks whether some coordinates are within a `ClientRect`.
|
|
2503
|
+
* @param {?} clientRect ClientRect that is being checked.
|
|
2504
|
+
* @param {?} x Coordinates along the X axis.
|
|
2505
|
+
* @param {?} y Coordinates along the Y axis.
|
|
2506
|
+
* @return {?}
|
|
2507
|
+
*/
|
|
2508
|
+
function isInsideClientRect(clientRect, x, y) {
|
|
2509
|
+
const { top, bottom, left, right } = clientRect;
|
|
2510
|
+
return y >= top && y <= bottom && x >= left && x <= right;
|
|
2511
|
+
}
|
|
2512
|
+
|
|
2513
|
+
/**
|
|
2514
|
+
* @fileoverview added by tsickle
|
|
2515
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
2516
|
+
*/
|
|
2517
|
+
/**
|
|
2518
|
+
* Counter used to generate unique ids for drop zones.
|
|
2519
|
+
* @type {?}
|
|
2520
|
+
*/
|
|
2521
|
+
let _uniqueIdCounter$1 = 0;
|
|
2522
|
+
const ɵ0 = undefined;
|
|
2523
|
+
// @breaking-change 8.0.0 `CdkDropList` implements `CdkDropListContainer` for backwards
|
|
2524
|
+
// compatiblity. The implements clause, as well as all the methods that it enforces can
|
|
2525
|
+
// be removed when `CdkDropListContainer` is deleted.
|
|
2526
|
+
/**
|
|
2527
|
+
* Container that wraps a set of draggable items.
|
|
2528
|
+
* @template T
|
|
2529
|
+
*/
|
|
2530
|
+
class CdkDropList {
|
|
2531
|
+
/**
|
|
2532
|
+
* @param {?} element
|
|
2533
|
+
* @param {?} dragDropRegistry
|
|
2534
|
+
* @param {?} _changeDetectorRef
|
|
2535
|
+
* @param {?=} dir
|
|
2536
|
+
* @param {?=} _group
|
|
2537
|
+
* @param {?=} _document
|
|
2538
|
+
*/
|
|
2539
|
+
constructor(element, dragDropRegistry, _changeDetectorRef, dir, _group,
|
|
2540
|
+
// @breaking-change 8.0.0 `_document` parameter to be made required.
|
|
2541
|
+
_document) {
|
|
2542
|
+
this.element = element;
|
|
2543
|
+
this._changeDetectorRef = _changeDetectorRef;
|
|
2544
|
+
this._group = _group;
|
|
2545
|
+
/**
|
|
2546
|
+
* Other draggable containers that this container is connected to and into which the
|
|
2547
|
+
* container's items can be transferred. Can either be references to other drop containers,
|
|
2548
|
+
* or their unique IDs.
|
|
2549
|
+
*/
|
|
2550
|
+
this.connectedTo = [];
|
|
2551
|
+
/**
|
|
2552
|
+
* Direction in which the list is oriented.
|
|
2553
|
+
*/
|
|
2554
|
+
this.orientation = 'vertical';
|
|
2555
|
+
/**
|
|
2556
|
+
* Unique ID for the drop zone. Can be used as a reference
|
|
2557
|
+
* in the `connectedTo` of another `CdkDropList`.
|
|
2558
|
+
*/
|
|
2559
|
+
this.id = `cdk-drop-list-${_uniqueIdCounter$1++}`;
|
|
2560
|
+
this._disabled = false;
|
|
2561
|
+
/**
|
|
2562
|
+
* Function that is used to determine whether an item
|
|
2563
|
+
* is allowed to be moved into a drop container.
|
|
2564
|
+
*/
|
|
2565
|
+
this.enterPredicate = () => true;
|
|
2566
|
+
/**
|
|
2567
|
+
* Emits when the user drops an item inside the container.
|
|
2568
|
+
*/
|
|
2569
|
+
this.dropped = new EventEmitter();
|
|
2570
|
+
/**
|
|
2571
|
+
* Emits when the user has moved a new drag item into this container.
|
|
2572
|
+
*/
|
|
2573
|
+
this.entered = new EventEmitter();
|
|
2574
|
+
/**
|
|
2575
|
+
* Emits when the user removes an item from the container
|
|
2576
|
+
* by dragging it into another container.
|
|
2577
|
+
*/
|
|
2578
|
+
this.exited = new EventEmitter();
|
|
2579
|
+
/**
|
|
2580
|
+
* Emits as the user is swapping items while actively dragging.
|
|
2581
|
+
*/
|
|
2582
|
+
this.sorted = new EventEmitter();
|
|
2583
|
+
// @breaking-change 8.0.0 Remove || once `_document` parameter is required.
|
|
1592
2584
|
/** @type {?} */
|
|
1593
|
-
const
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
if (oldOrder[index] === sibling) {
|
|
1605
|
-
return;
|
|
1606
|
-
}
|
|
1607
|
-
/** @type {?} */
|
|
1608
|
-
const isDraggedItem = sibling.drag === item;
|
|
1609
|
-
/** @type {?} */
|
|
1610
|
-
const offset = isDraggedItem ? itemOffset : siblingOffset;
|
|
1611
|
-
/** @type {?} */
|
|
1612
|
-
const elementToOffset = isDraggedItem ? item.getPlaceholderElement() :
|
|
1613
|
-
sibling.drag.getRootElement();
|
|
1614
|
-
// Update the offset to reflect the new position.
|
|
1615
|
-
sibling.offset += offset;
|
|
1616
|
-
// Since we're moving the items with a `transform`, we need to adjust their cached
|
|
1617
|
-
// client rects to reflect their new position, as well as swap their positions in the cache.
|
|
1618
|
-
// Note that we shouldn't use `getBoundingClientRect` here to update the cache, because the
|
|
1619
|
-
// elements may be mid-animation which will give us a wrong result.
|
|
1620
|
-
if (isHorizontal) {
|
|
1621
|
-
elementToOffset.style.transform = `translate3d(${sibling.offset}px, 0, 0)`;
|
|
1622
|
-
this._adjustClientRect(sibling.clientRect, 0, offset);
|
|
1623
|
-
}
|
|
1624
|
-
else {
|
|
1625
|
-
elementToOffset.style.transform = `translate3d(0, ${sibling.offset}px, 0)`;
|
|
1626
|
-
this._adjustClientRect(sibling.clientRect, offset, 0);
|
|
1627
|
-
}
|
|
1628
|
-
});
|
|
2585
|
+
const ref = this._dropListRef = new DropListRef(element, dragDropRegistry, _document || document, dir);
|
|
2586
|
+
ref.data = this;
|
|
2587
|
+
ref.enterPredicate = (drag, drop) => {
|
|
2588
|
+
return this.enterPredicate(drag.data, drop.data);
|
|
2589
|
+
};
|
|
2590
|
+
this._syncInputs(ref);
|
|
2591
|
+
this._handleEvents(ref);
|
|
2592
|
+
CdkDropList._dropLists.push(this);
|
|
2593
|
+
if (_group) {
|
|
2594
|
+
_group._items.add(this);
|
|
2595
|
+
}
|
|
1629
2596
|
}
|
|
1630
2597
|
/**
|
|
1631
|
-
*
|
|
1632
|
-
* drop container, based on its current position.
|
|
1633
|
-
* @param {?} item Drag item that is being moved.
|
|
1634
|
-
* @param {?} x Position of the item along the X axis.
|
|
1635
|
-
* @param {?} y Position of the item along the Y axis.
|
|
2598
|
+
* Whether starting a dragging sequence from this container is disabled.
|
|
1636
2599
|
* @return {?}
|
|
1637
2600
|
*/
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
const result = this._positionCache.siblings
|
|
1641
|
-
.find(sibling => isInsideClientRect(sibling.clientRect, x, y));
|
|
1642
|
-
return result && result.drop.enterPredicate(item, result.drop) ? result.drop : null;
|
|
2601
|
+
get disabled() {
|
|
2602
|
+
return this._disabled || (!!this._group && this._group.disabled);
|
|
1643
2603
|
}
|
|
1644
2604
|
/**
|
|
1645
|
-
*
|
|
1646
|
-
* after it was moved out into another container.
|
|
1647
|
-
* @param {?} x Position of the item along the X axis.
|
|
1648
|
-
* @param {?} y Position of the item along the Y axis.
|
|
2605
|
+
* @param {?} value
|
|
1649
2606
|
* @return {?}
|
|
1650
2607
|
*/
|
|
1651
|
-
|
|
1652
|
-
|
|
2608
|
+
set disabled(value) {
|
|
2609
|
+
this._disabled = coerceBooleanProperty(value);
|
|
1653
2610
|
}
|
|
1654
2611
|
/**
|
|
1655
|
-
* Refreshes the position cache of the items and sibling containers.
|
|
1656
2612
|
* @return {?}
|
|
1657
2613
|
*/
|
|
1658
|
-
|
|
2614
|
+
ngOnDestroy() {
|
|
1659
2615
|
/** @type {?} */
|
|
1660
|
-
const
|
|
1661
|
-
this.
|
|
1662
|
-
|
|
1663
|
-
.
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
drag.getPlaceholderElement() :
|
|
1669
|
-
drag.getRootElement();
|
|
1670
|
-
/** @type {?} */
|
|
1671
|
-
const clientRect = elementToMeasure.getBoundingClientRect();
|
|
1672
|
-
return {
|
|
1673
|
-
drag,
|
|
1674
|
-
offset: 0,
|
|
1675
|
-
// We need to clone the `clientRect` here, because all the values on it are readonly
|
|
1676
|
-
// and we need to be able to update them. Also we can't use a spread here, because
|
|
1677
|
-
// the values on a `ClientRect` aren't own properties. See:
|
|
1678
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect#Notes
|
|
1679
|
-
clientRect: {
|
|
1680
|
-
top: clientRect.top,
|
|
1681
|
-
right: clientRect.right,
|
|
1682
|
-
bottom: clientRect.bottom,
|
|
1683
|
-
left: clientRect.left,
|
|
1684
|
-
width: clientRect.width,
|
|
1685
|
-
height: clientRect.height
|
|
1686
|
-
}
|
|
1687
|
-
};
|
|
1688
|
-
})
|
|
1689
|
-
.sort((a, b) => {
|
|
1690
|
-
return isHorizontal ? a.clientRect.left - b.clientRect.left :
|
|
1691
|
-
a.clientRect.top - b.clientRect.top;
|
|
1692
|
-
});
|
|
1693
|
-
this._positionCache.siblings = this._getConnectedLists().map(drop => ({
|
|
1694
|
-
drop,
|
|
1695
|
-
clientRect: drop.element.nativeElement.getBoundingClientRect()
|
|
1696
|
-
}));
|
|
2616
|
+
const index = CdkDropList._dropLists.indexOf(this);
|
|
2617
|
+
this._dropListRef.dispose();
|
|
2618
|
+
if (index > -1) {
|
|
2619
|
+
CdkDropList._dropLists.splice(index, 1);
|
|
2620
|
+
}
|
|
2621
|
+
if (this._group) {
|
|
2622
|
+
this._group._items.delete(this);
|
|
2623
|
+
}
|
|
1697
2624
|
}
|
|
1698
2625
|
/**
|
|
1699
|
-
*
|
|
2626
|
+
* Starts dragging an item.
|
|
1700
2627
|
* @return {?}
|
|
1701
2628
|
*/
|
|
1702
|
-
|
|
1703
|
-
this.
|
|
1704
|
-
// TODO(crisbeto): may have to wait for the animations to finish.
|
|
1705
|
-
this._activeDraggables.forEach(item => item.getRootElement().style.transform = '');
|
|
1706
|
-
this._activeDraggables = [];
|
|
1707
|
-
this._positionCache.items = [];
|
|
1708
|
-
this._positionCache.siblings = [];
|
|
1709
|
-
this._previousSwap.drag = null;
|
|
1710
|
-
this._previousSwap.delta = 0;
|
|
2629
|
+
start() {
|
|
2630
|
+
this._dropListRef.start();
|
|
1711
2631
|
}
|
|
1712
2632
|
/**
|
|
1713
|
-
*
|
|
1714
|
-
* @param {?}
|
|
1715
|
-
* @param {?}
|
|
1716
|
-
* @param {?}
|
|
2633
|
+
* Drops an item into this container.
|
|
2634
|
+
* @param {?} item Item being dropped into the container.
|
|
2635
|
+
* @param {?} currentIndex Index at which the item should be inserted.
|
|
2636
|
+
* @param {?} previousContainer Container from which the item got dragged in.
|
|
2637
|
+
* @param {?} isPointerOverContainer Whether the user's pointer was over the
|
|
2638
|
+
* container when the item was dropped.
|
|
1717
2639
|
* @return {?}
|
|
1718
2640
|
*/
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
clientRect.bottom = clientRect.top + clientRect.height;
|
|
1722
|
-
clientRect.left += left;
|
|
1723
|
-
clientRect.right = clientRect.left + clientRect.width;
|
|
2641
|
+
drop(item, currentIndex, previousContainer, isPointerOverContainer) {
|
|
2642
|
+
this._dropListRef.drop(item._dragRef, currentIndex, ((/** @type {?} */ (previousContainer)))._dropListRef, isPointerOverContainer);
|
|
1724
2643
|
}
|
|
1725
2644
|
/**
|
|
1726
|
-
*
|
|
1727
|
-
* @param {?} item Item that
|
|
1728
|
-
* @param {?} pointerX Position of the
|
|
1729
|
-
* @param {?} pointerY Position of the
|
|
1730
|
-
* @param {?=} delta Direction in which the user is moving their pointer.
|
|
2645
|
+
* Emits an event to indicate that the user moved an item into the container.
|
|
2646
|
+
* @param {?} item Item that was moved into the container.
|
|
2647
|
+
* @param {?} pointerX Position of the item along the X axis.
|
|
2648
|
+
* @param {?} pointerY Position of the item along the Y axis.
|
|
1731
2649
|
* @return {?}
|
|
1732
2650
|
*/
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
const isHorizontal = this.orientation === 'horizontal';
|
|
1736
|
-
return findIndex(this._positionCache.items, ({ drag, clientRect }, _, array) => {
|
|
1737
|
-
if (drag === item) {
|
|
1738
|
-
// If there's only one item left in the container, it must be
|
|
1739
|
-
// the dragged item itself so we use it as a reference.
|
|
1740
|
-
return array.length < 2;
|
|
1741
|
-
}
|
|
1742
|
-
if (delta) {
|
|
1743
|
-
/** @type {?} */
|
|
1744
|
-
const direction = isHorizontal ? delta.x : delta.y;
|
|
1745
|
-
// If the user is still hovering over the same item as last time, and they didn't change
|
|
1746
|
-
// the direction in which they're dragging, we don't consider it a direction swap.
|
|
1747
|
-
if (drag === this._previousSwap.drag && direction === this._previousSwap.delta) {
|
|
1748
|
-
return false;
|
|
1749
|
-
}
|
|
1750
|
-
}
|
|
1751
|
-
return isHorizontal ?
|
|
1752
|
-
// Round these down since most browsers report client rects with
|
|
1753
|
-
// sub-pixel precision, whereas the pointer coordinates are rounded to pixels.
|
|
1754
|
-
pointerX >= Math.floor(clientRect.left) && pointerX <= Math.floor(clientRect.right) :
|
|
1755
|
-
pointerY >= Math.floor(clientRect.top) && pointerY <= Math.floor(clientRect.bottom);
|
|
1756
|
-
});
|
|
2651
|
+
enter(item, pointerX, pointerY) {
|
|
2652
|
+
this._dropListRef.enter(item._dragRef, pointerX, pointerY);
|
|
1757
2653
|
}
|
|
1758
2654
|
/**
|
|
1759
|
-
*
|
|
1760
|
-
* @param {?}
|
|
1761
|
-
* @param {?} pointerY Coordinates along the Y axis.
|
|
2655
|
+
* Removes an item from the container after it was dragged into another container by the user.
|
|
2656
|
+
* @param {?} item Item that was dragged out.
|
|
1762
2657
|
* @return {?}
|
|
1763
2658
|
*/
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
/** @type {?} */
|
|
1767
|
-
const xThreshold = width * DROP_PROXIMITY_THRESHOLD;
|
|
1768
|
-
/** @type {?} */
|
|
1769
|
-
const yThreshold = height * DROP_PROXIMITY_THRESHOLD;
|
|
1770
|
-
return pointerY > top - yThreshold && pointerY < bottom + yThreshold &&
|
|
1771
|
-
pointerX > left - xThreshold && pointerX < right + xThreshold;
|
|
2659
|
+
exit(item) {
|
|
2660
|
+
this._dropListRef.exit(item._dragRef);
|
|
1772
2661
|
}
|
|
1773
2662
|
/**
|
|
1774
|
-
*
|
|
1775
|
-
* @param {?}
|
|
1776
|
-
* @param {?} newPosition Position of the item where the current item should be moved.
|
|
1777
|
-
* @param {?} delta Direction in which the user is moving.
|
|
2663
|
+
* Figures out the index of an item in the container.
|
|
2664
|
+
* @param {?} item Item whose index should be determined.
|
|
1778
2665
|
* @return {?}
|
|
1779
2666
|
*/
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
const isHorizontal = this.orientation === 'horizontal';
|
|
1783
|
-
/** @type {?} */
|
|
1784
|
-
let itemOffset = isHorizontal ? newPosition.left - currentPosition.left :
|
|
1785
|
-
newPosition.top - currentPosition.top;
|
|
1786
|
-
// Account for differences in the item width/height.
|
|
1787
|
-
if (delta === -1) {
|
|
1788
|
-
itemOffset += isHorizontal ? newPosition.width - currentPosition.width :
|
|
1789
|
-
newPosition.height - currentPosition.height;
|
|
1790
|
-
}
|
|
1791
|
-
return itemOffset;
|
|
2667
|
+
getItemIndex(item) {
|
|
2668
|
+
return this._dropListRef.getItemIndex(item._dragRef);
|
|
1792
2669
|
}
|
|
1793
2670
|
/**
|
|
1794
|
-
*
|
|
1795
|
-
* @param {?}
|
|
1796
|
-
* @param {?}
|
|
1797
|
-
* @param {?}
|
|
2671
|
+
* Sorts an item inside the container based on its position.
|
|
2672
|
+
* @param {?} item Item to be sorted.
|
|
2673
|
+
* @param {?} pointerX Position of the item along the X axis.
|
|
2674
|
+
* @param {?} pointerY Position of the item along the Y axis.
|
|
2675
|
+
* @param {?} pointerDelta Direction in which the pointer is moving along each axis.
|
|
1798
2676
|
* @return {?}
|
|
1799
2677
|
*/
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
2678
|
+
_sortItem(item, pointerX, pointerY, pointerDelta) {
|
|
2679
|
+
return this._dropListRef._sortItem(item._dragRef, pointerX, pointerY, pointerDelta);
|
|
2680
|
+
}
|
|
2681
|
+
/**
|
|
2682
|
+
* Figures out whether an item should be moved into a sibling
|
|
2683
|
+
* drop container, based on its current position.
|
|
2684
|
+
* @param {?} item Drag item that is being moved.
|
|
2685
|
+
* @param {?} x Position of the item along the X axis.
|
|
2686
|
+
* @param {?} y Position of the item along the Y axis.
|
|
2687
|
+
* @return {?}
|
|
2688
|
+
*/
|
|
2689
|
+
_getSiblingContainerFromPosition(item, x, y) {
|
|
1807
2690
|
/** @type {?} */
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
2691
|
+
const result = this._dropListRef._getSiblingContainerFromPosition(item._dragRef, x, y);
|
|
2692
|
+
return result ? result.data : null;
|
|
2693
|
+
}
|
|
2694
|
+
/**
|
|
2695
|
+
* Checks whether the user's pointer is positioned over the container.
|
|
2696
|
+
* @param {?} x Pointer position along the X axis.
|
|
2697
|
+
* @param {?} y Pointer position along the Y axis.
|
|
2698
|
+
* @return {?}
|
|
2699
|
+
*/
|
|
2700
|
+
_isOverContainer(x, y) {
|
|
2701
|
+
return this._dropListRef._isOverContainer(x, y);
|
|
2702
|
+
}
|
|
2703
|
+
/**
|
|
2704
|
+
* Syncs the inputs of the CdkDropList with the options of the underlying DropListRef.
|
|
2705
|
+
* @private
|
|
2706
|
+
* @param {?} ref
|
|
2707
|
+
* @return {?}
|
|
2708
|
+
*/
|
|
2709
|
+
_syncInputs(ref) {
|
|
2710
|
+
ref.beforeStarted.subscribe(() => {
|
|
1812
2711
|
/** @type {?} */
|
|
1813
|
-
const
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
2712
|
+
const siblings = coerceArray(this.connectedTo).map(drop => {
|
|
2713
|
+
return typeof drop === 'string' ?
|
|
2714
|
+
(/** @type {?} */ (CdkDropList._dropLists.find(list => list.id === drop))) : drop;
|
|
2715
|
+
});
|
|
2716
|
+
if (this._group) {
|
|
2717
|
+
this._group._items.forEach(drop => {
|
|
2718
|
+
if (siblings.indexOf(drop) === -1) {
|
|
2719
|
+
siblings.push(drop);
|
|
2720
|
+
}
|
|
2721
|
+
});
|
|
1823
2722
|
}
|
|
1824
|
-
|
|
1825
|
-
|
|
2723
|
+
ref.lockAxis = this.lockAxis;
|
|
2724
|
+
ref
|
|
2725
|
+
.connectedTo(siblings.filter(drop => drop && drop !== this).map(list => list._dropListRef))
|
|
2726
|
+
.withOrientation(this.orientation)
|
|
2727
|
+
.withItems(this._draggables.map(drag => drag._dragRef));
|
|
2728
|
+
});
|
|
1826
2729
|
}
|
|
1827
2730
|
/**
|
|
1828
|
-
*
|
|
2731
|
+
* Handles events from the underlying DropListRef.
|
|
2732
|
+
* @private
|
|
2733
|
+
* @param {?} ref
|
|
1829
2734
|
* @return {?}
|
|
1830
2735
|
*/
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
return typeof drop === 'string' ? /** @type {?} */ ((this._dragDropRegistry.getDropContainer(drop))) : drop;
|
|
2736
|
+
_handleEvents(ref) {
|
|
2737
|
+
ref.beforeStarted.subscribe(() => {
|
|
2738
|
+
this._changeDetectorRef.markForCheck();
|
|
1835
2739
|
});
|
|
1836
|
-
|
|
1837
|
-
this.
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
}
|
|
2740
|
+
ref.entered.subscribe(event => {
|
|
2741
|
+
this.entered.emit({
|
|
2742
|
+
container: this,
|
|
2743
|
+
item: event.item.data
|
|
1841
2744
|
});
|
|
1842
|
-
}
|
|
1843
|
-
|
|
2745
|
+
});
|
|
2746
|
+
ref.exited.subscribe(event => {
|
|
2747
|
+
this.exited.emit({
|
|
2748
|
+
container: this,
|
|
2749
|
+
item: event.item.data
|
|
2750
|
+
});
|
|
2751
|
+
});
|
|
2752
|
+
ref.sorted.subscribe(event => {
|
|
2753
|
+
this.sorted.emit({
|
|
2754
|
+
previousIndex: event.previousIndex,
|
|
2755
|
+
currentIndex: event.currentIndex,
|
|
2756
|
+
container: this,
|
|
2757
|
+
item: event.item.data
|
|
2758
|
+
});
|
|
2759
|
+
});
|
|
2760
|
+
ref.dropped.subscribe(event => {
|
|
2761
|
+
this.dropped.emit({
|
|
2762
|
+
previousIndex: event.previousIndex,
|
|
2763
|
+
currentIndex: event.currentIndex,
|
|
2764
|
+
previousContainer: event.previousContainer.data,
|
|
2765
|
+
container: event.container.data,
|
|
2766
|
+
item: event.item.data,
|
|
2767
|
+
isPointerOverContainer: event.isPointerOverContainer
|
|
2768
|
+
});
|
|
2769
|
+
// Mark for check since all of these events run outside of change
|
|
2770
|
+
// detection and we're not guaranteed for something else to have triggered it.
|
|
2771
|
+
this._changeDetectorRef.markForCheck();
|
|
2772
|
+
});
|
|
1844
2773
|
}
|
|
1845
2774
|
}
|
|
2775
|
+
/**
|
|
2776
|
+
* Keeps track of the drop lists that are currently on the page.
|
|
2777
|
+
*/
|
|
2778
|
+
CdkDropList._dropLists = [];
|
|
1846
2779
|
CdkDropList.decorators = [
|
|
1847
2780
|
{ type: Directive, args: [{
|
|
1848
2781
|
selector: '[cdkDropList], cdk-drop-list',
|
|
1849
2782
|
exportAs: 'cdkDropList',
|
|
1850
2783
|
providers: [
|
|
2784
|
+
// Prevent child drop lists from picking up the same group as their parent.
|
|
2785
|
+
{ provide: CdkDropListGroup, useValue: ɵ0 },
|
|
1851
2786
|
{ provide: CDK_DROP_LIST_CONTAINER, useExisting: CdkDropList },
|
|
1852
2787
|
],
|
|
1853
2788
|
host: {
|
|
1854
2789
|
'class': 'cdk-drop-list',
|
|
1855
2790
|
'[id]': 'id',
|
|
1856
|
-
'[class.cdk-drop-list-dragging]': '
|
|
2791
|
+
'[class.cdk-drop-list-dragging]': '_dropListRef.isDragging()',
|
|
2792
|
+
'[class.cdk-drop-list-receiving]': '_dropListRef.isReceiving()',
|
|
1857
2793
|
}
|
|
1858
2794
|
},] },
|
|
1859
2795
|
];
|
|
@@ -1863,7 +2799,8 @@ CdkDropList.ctorParameters = () => [
|
|
|
1863
2799
|
{ type: DragDropRegistry },
|
|
1864
2800
|
{ type: ChangeDetectorRef },
|
|
1865
2801
|
{ type: Directionality, decorators: [{ type: Optional }] },
|
|
1866
|
-
{ type: CdkDropListGroup, decorators: [{ type: Optional }] }
|
|
2802
|
+
{ type: CdkDropListGroup, decorators: [{ type: Optional }, { type: SkipSelf }] },
|
|
2803
|
+
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DOCUMENT,] }] }
|
|
1867
2804
|
];
|
|
1868
2805
|
CdkDropList.propDecorators = {
|
|
1869
2806
|
_draggables: [{ type: ContentChildren, args: [forwardRef(() => CdkDrag),] }],
|
|
@@ -1879,37 +2816,10 @@ CdkDropList.propDecorators = {
|
|
|
1879
2816
|
exited: [{ type: Output, args: ['cdkDropListExited',] }],
|
|
1880
2817
|
sorted: [{ type: Output, args: ['cdkDropListSorted',] }]
|
|
1881
2818
|
};
|
|
1882
|
-
/**
|
|
1883
|
-
* Finds the index of an item that matches a predicate function. Used as an equivalent
|
|
1884
|
-
* of `Array.prototype.find` which isn't part of the standard Google typings.
|
|
1885
|
-
* @template T
|
|
1886
|
-
* @param {?} array Array in which to look for matches.
|
|
1887
|
-
* @param {?} predicate Function used to determine whether an item is a match.
|
|
1888
|
-
* @return {?}
|
|
1889
|
-
*/
|
|
1890
|
-
function findIndex(array, predicate) {
|
|
1891
|
-
for (let i = 0; i < array.length; i++) {
|
|
1892
|
-
if (predicate(array[i], i, array)) {
|
|
1893
|
-
return i;
|
|
1894
|
-
}
|
|
1895
|
-
}
|
|
1896
|
-
return -1;
|
|
1897
|
-
}
|
|
1898
|
-
/**
|
|
1899
|
-
* Checks whether some coordinates are within a `ClientRect`.
|
|
1900
|
-
* @param {?} clientRect ClientRect that is being checked.
|
|
1901
|
-
* @param {?} x Coordinates along the X axis.
|
|
1902
|
-
* @param {?} y Coordinates along the Y axis.
|
|
1903
|
-
* @return {?}
|
|
1904
|
-
*/
|
|
1905
|
-
function isInsideClientRect(clientRect, x, y) {
|
|
1906
|
-
const { top, bottom, left, right } = clientRect;
|
|
1907
|
-
return y >= top && y <= bottom && x >= left && x <= right;
|
|
1908
|
-
}
|
|
1909
2819
|
|
|
1910
2820
|
/**
|
|
1911
2821
|
* @fileoverview added by tsickle
|
|
1912
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
2822
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
1913
2823
|
*/
|
|
1914
2824
|
class DragDropModule {
|
|
1915
2825
|
}
|
|
@@ -1936,13 +2846,13 @@ DragDropModule.decorators = [
|
|
|
1936
2846
|
|
|
1937
2847
|
/**
|
|
1938
2848
|
* @fileoverview added by tsickle
|
|
1939
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
2849
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
1940
2850
|
*/
|
|
1941
2851
|
|
|
1942
2852
|
/**
|
|
1943
2853
|
* @fileoverview added by tsickle
|
|
1944
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
2854
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
1945
2855
|
*/
|
|
1946
2856
|
|
|
1947
|
-
export {
|
|
2857
|
+
export { CDK_DROP_LIST, CDK_DROP_LIST_CONTAINER, moveItemInArray, transferArrayItem, copyArrayItem, DragDropModule, DragDropRegistry, CdkDropList, CdkDropListGroup, CDK_DRAG_CONFIG_FACTORY, CDK_DRAG_CONFIG, CdkDrag, CdkDragHandle, CdkDragPreview, CdkDragPlaceholder, CDK_DRAG_PARENT as ɵa };
|
|
1948
2858
|
//# sourceMappingURL=drag-drop.js.map
|