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