@angular/cdk 9.2.1 → 9.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/a11y/focus-monitor/focus-monitor.d.ts +10 -3
  2. package/a11y/high-contrast-mode/high-contrast-mode-detector.d.ts +2 -2
  3. package/a11y/index.metadata.json +1 -1
  4. package/bundles/cdk-a11y.umd.js +62 -27
  5. package/bundles/cdk-a11y.umd.js.map +1 -1
  6. package/bundles/cdk-a11y.umd.min.js +12 -5
  7. package/bundles/cdk-a11y.umd.min.js.map +1 -1
  8. package/bundles/cdk-drag-drop.umd.js +193 -109
  9. package/bundles/cdk-drag-drop.umd.js.map +1 -1
  10. package/bundles/cdk-drag-drop.umd.min.js +17 -10
  11. package/bundles/cdk-drag-drop.umd.min.js.map +1 -1
  12. package/bundles/cdk-overlay.umd.js.map +1 -1
  13. package/bundles/cdk-platform.umd.js +3 -1
  14. package/bundles/cdk-platform.umd.js.map +1 -1
  15. package/bundles/cdk-platform.umd.min.js +4 -4
  16. package/bundles/cdk-platform.umd.min.js.map +1 -1
  17. package/bundles/cdk-scrolling.umd.js +18 -3
  18. package/bundles/cdk-scrolling.umd.js.map +1 -1
  19. package/bundles/cdk-scrolling.umd.min.js +2 -2
  20. package/bundles/cdk-scrolling.umd.min.js.map +1 -1
  21. package/bundles/cdk-testing-testbed.umd.js +62 -10
  22. package/bundles/cdk-testing-testbed.umd.js.map +1 -1
  23. package/bundles/cdk-testing-testbed.umd.min.js +5 -5
  24. package/bundles/cdk-testing-testbed.umd.min.js.map +1 -1
  25. package/bundles/cdk-tree.umd.js +1 -0
  26. package/bundles/cdk-tree.umd.js.map +1 -1
  27. package/bundles/cdk-tree.umd.min.js +1 -1
  28. package/bundles/cdk-tree.umd.min.js.map +1 -1
  29. package/bundles/cdk.umd.js +1 -1
  30. package/bundles/cdk.umd.js.map +1 -1
  31. package/bundles/cdk.umd.min.js +1 -1
  32. package/bundles/cdk.umd.min.js.map +1 -1
  33. package/drag-drop/drag-ref.d.ts +4 -2
  34. package/drag-drop/drop-list-ref.d.ts +9 -8
  35. package/drag-drop/index.metadata.json +1 -1
  36. package/drag-drop/parent-position-tracker.d.ts +31 -0
  37. package/drag-drop/public-api.d.ts +1 -1
  38. package/esm2015/a11y/aria-describer/aria-reference.js +6 -6
  39. package/esm2015/a11y/focus-monitor/focus-monitor.js +84 -26
  40. package/esm2015/a11y/high-contrast-mode/high-contrast-mode-detector.js +3 -3
  41. package/esm2015/drag-drop/drag-drop-module.js +3 -1
  42. package/esm2015/drag-drop/drag-ref.js +55 -35
  43. package/esm2015/drag-drop/drop-list-ref.js +115 -124
  44. package/esm2015/drag-drop/parent-position-tracker.js +141 -0
  45. package/esm2015/drag-drop/public-api.js +1 -1
  46. package/esm2015/overlay/position/flexible-connected-position-strategy.js +1 -1
  47. package/esm2015/platform/features/shadow-dom.js +4 -2
  48. package/esm2015/scrolling/public-api.js +2 -2
  49. package/esm2015/scrolling/scrolling-module.js +15 -4
  50. package/esm2015/testing/testbed/fake-events/dispatch-events.js +11 -4
  51. package/esm2015/testing/testbed/fake-events/event-objects.js +37 -3
  52. package/esm2015/testing/testbed/unit-test-element.js +13 -2
  53. package/esm2015/tree/tree.js +2 -1
  54. package/esm2015/version.js +1 -1
  55. package/esm5/a11y/aria-describer/aria-reference.js +6 -6
  56. package/esm5/a11y/focus-monitor/focus-monitor.js +57 -22
  57. package/esm5/a11y/high-contrast-mode/high-contrast-mode-detector.js +3 -3
  58. package/esm5/drag-drop/drag-drop-module.js +3 -1
  59. package/esm5/drag-drop/drag-ref.js +39 -26
  60. package/esm5/drag-drop/drop-list-ref.js +85 -86
  61. package/esm5/drag-drop/parent-position-tracker.js +74 -0
  62. package/esm5/drag-drop/public-api.js +1 -1
  63. package/esm5/overlay/position/flexible-connected-position-strategy.js +1 -1
  64. package/esm5/platform/features/shadow-dom.js +4 -2
  65. package/esm5/scrolling/scrolling-module.js +19 -4
  66. package/esm5/testing/testbed/fake-events/dispatch-events.js +15 -7
  67. package/esm5/testing/testbed/fake-events/event-objects.js +43 -5
  68. package/esm5/testing/testbed/unit-test-element.js +10 -3
  69. package/esm5/tree/tree.js +2 -1
  70. package/esm5/version.js +1 -1
  71. package/fesm2015/a11y.js +90 -32
  72. package/fesm2015/a11y.js.map +1 -1
  73. package/fesm2015/cdk.js +1 -1
  74. package/fesm2015/cdk.js.map +1 -1
  75. package/fesm2015/drag-drop.js +302 -158
  76. package/fesm2015/drag-drop.js.map +1 -1
  77. package/fesm2015/overlay.js.map +1 -1
  78. package/fesm2015/platform.js +3 -1
  79. package/fesm2015/platform.js.map +1 -1
  80. package/fesm2015/scrolling.js +15 -4
  81. package/fesm2015/scrolling.js.map +1 -1
  82. package/fesm2015/testing/testbed.js +56 -4
  83. package/fesm2015/testing/testbed.js.map +1 -1
  84. package/fesm2015/tree.js +1 -0
  85. package/fesm2015/tree.js.map +1 -1
  86. package/fesm5/a11y.js +63 -28
  87. package/fesm5/a11y.js.map +1 -1
  88. package/fesm5/cdk.js +1 -1
  89. package/fesm5/cdk.js.map +1 -1
  90. package/fesm5/drag-drop.js +195 -111
  91. package/fesm5/drag-drop.js.map +1 -1
  92. package/fesm5/overlay.js.map +1 -1
  93. package/fesm5/platform.js +3 -1
  94. package/fesm5/platform.js.map +1 -1
  95. package/fesm5/scrolling.js +18 -4
  96. package/fesm5/scrolling.js.map +1 -1
  97. package/fesm5/testing/testbed.js +63 -11
  98. package/fesm5/testing/testbed.js.map +1 -1
  99. package/fesm5/tree.js +1 -0
  100. package/fesm5/tree.js.map +1 -1
  101. package/overlay/position/flexible-connected-position-strategy.d.ts +1 -1
  102. package/package.json +1 -1
  103. package/schematics/ng-add/index.js +1 -1
  104. package/schematics/ng-update/devkit-file-system.d.ts +29 -0
  105. package/schematics/ng-update/devkit-file-system.js +67 -0
  106. package/schematics/ng-update/devkit-migration-rule.d.ts +25 -0
  107. package/schematics/ng-update/devkit-migration-rule.js +152 -0
  108. package/schematics/ng-update/devkit-migration.d.ts +37 -0
  109. package/schematics/ng-update/devkit-migration.js +29 -0
  110. package/schematics/ng-update/index.js +7 -7
  111. package/schematics/ng-update/{upgrade-rules/attribute-selectors-rule.d.ts → migrations/attribute-selectors.d.ts} +6 -6
  112. package/schematics/ng-update/migrations/attribute-selectors.js +76 -0
  113. package/schematics/ng-update/{upgrade-rules/class-inheritance-rule.d.ts → migrations/class-inheritance.d.ts} +6 -6
  114. package/schematics/ng-update/migrations/class-inheritance.js +67 -0
  115. package/schematics/ng-update/{upgrade-rules/class-names-rule.d.ts → migrations/class-names.d.ts} +6 -6
  116. package/schematics/ng-update/migrations/class-names.js +98 -0
  117. package/schematics/ng-update/{upgrade-rules/constructor-signature-rule.d.ts → migrations/constructor-signature.d.ts} +6 -6
  118. package/schematics/ng-update/migrations/constructor-signature.js +144 -0
  119. package/schematics/ng-update/{upgrade-rules/css-selectors-rule.d.ts → migrations/css-selectors.d.ts} +6 -6
  120. package/schematics/ng-update/migrations/css-selectors.js +83 -0
  121. package/schematics/ng-update/{upgrade-rules/element-selectors-rule.d.ts → migrations/element-selectors.d.ts} +6 -6
  122. package/schematics/ng-update/migrations/element-selectors.js +74 -0
  123. package/schematics/ng-update/{upgrade-rules/input-names-rule.d.ts → migrations/input-names.d.ts} +6 -6
  124. package/schematics/ng-update/migrations/input-names.js +69 -0
  125. package/schematics/ng-update/{upgrade-rules/method-call-arguments-rule.d.ts → migrations/method-call-arguments.d.ts} +6 -6
  126. package/schematics/ng-update/migrations/method-call-arguments.js +70 -0
  127. package/schematics/ng-update/{upgrade-rules/misc-template-rule.d.ts → migrations/misc-template.d.ts} +6 -6
  128. package/schematics/ng-update/migrations/misc-template.js +47 -0
  129. package/schematics/ng-update/{upgrade-rules/output-names-rule.d.ts → migrations/output-names.d.ts} +6 -6
  130. package/schematics/ng-update/migrations/output-names.js +56 -0
  131. package/schematics/ng-update/{upgrade-rules/property-names-rule.d.ts → migrations/property-names.d.ts} +6 -6
  132. package/schematics/ng-update/migrations/property-names.js +56 -0
  133. package/schematics/ng-update/public-api.d.ts +3 -2
  134. package/schematics/ng-update/public-api.js +5 -4
  135. package/schematics/ng-update/upgrade-data.d.ts +7 -8
  136. package/schematics/ng-update/upgrade-data.js +6 -7
  137. package/schematics/update-tool/component-resource-collector.d.ts +3 -1
  138. package/schematics/update-tool/component-resource-collector.js +8 -8
  139. package/schematics/update-tool/file-system.d.ts +38 -0
  140. package/schematics/update-tool/file-system.js +20 -0
  141. package/schematics/update-tool/index.d.ts +41 -11
  142. package/schematics/update-tool/index.js +135 -106
  143. package/schematics/update-tool/logger.d.ts +16 -0
  144. package/schematics/update-tool/logger.js +27 -0
  145. package/schematics/update-tool/{migration-rule.d.ts → migration.d.ts} +23 -45
  146. package/schematics/update-tool/migration.js +76 -0
  147. package/schematics/update-tool/public-api.d.ts +5 -4
  148. package/schematics/update-tool/public-api.js +6 -6
  149. package/schematics/update-tool/update-recorder.d.ts +14 -0
  150. package/schematics/update-tool/update-recorder.js +20 -0
  151. package/schematics/update-tool/utils/parse-tsconfig.js +1 -1
  152. package/schematics/update-tool/version-changes.js +3 -4
  153. package/scrolling/index.metadata.json +1 -1
  154. package/scrolling/scrolling-module.d.ts +2 -0
  155. package/testing/testbed/fake-events/dispatch-events.d.ts +8 -3
  156. package/testing/testbed/fake-events/event-objects.d.ts +12 -1
  157. package/tree/index.metadata.json +1 -1
  158. package/schematics/ng-update/upgrade-rules/attribute-selectors-rule.js +0 -76
  159. package/schematics/ng-update/upgrade-rules/class-inheritance-rule.js +0 -67
  160. package/schematics/ng-update/upgrade-rules/class-names-rule.js +0 -98
  161. package/schematics/ng-update/upgrade-rules/constructor-signature-rule.js +0 -144
  162. package/schematics/ng-update/upgrade-rules/css-selectors-rule.js +0 -83
  163. package/schematics/ng-update/upgrade-rules/element-selectors-rule.js +0 -74
  164. package/schematics/ng-update/upgrade-rules/index.d.ts +0 -22
  165. package/schematics/ng-update/upgrade-rules/index.js +0 -116
  166. package/schematics/ng-update/upgrade-rules/input-names-rule.js +0 -69
  167. package/schematics/ng-update/upgrade-rules/method-call-arguments-rule.js +0 -70
  168. package/schematics/ng-update/upgrade-rules/misc-template-rule.js +0 -47
  169. package/schematics/ng-update/upgrade-rules/output-names-rule.js +0 -56
  170. package/schematics/ng-update/upgrade-rules/property-names-rule.js +0 -56
  171. package/schematics/update-tool/migration-rule.js +0 -101
@@ -1,10 +1,10 @@
1
1
  import { Injectable, NgZone, Inject, ɵɵdefineInjectable, ɵɵinject, InjectionToken, Directive, ElementRef, Optional, Input, TemplateRef, EventEmitter, isDevMode, SkipSelf, ViewContainerRef, ChangeDetectorRef, ContentChildren, ContentChild, Output, NgModule } from '@angular/core';
2
2
  import { DOCUMENT } from '@angular/common';
3
- import { ViewportRuler, ScrollDispatcher } from '@angular/cdk/scrolling';
3
+ import { ViewportRuler, ScrollDispatcher, CdkScrollableModule } from '@angular/cdk/scrolling';
4
4
  import { normalizePassiveListenerOptions, _getShadowRoot } from '@angular/cdk/platform';
5
5
  import { coerceBooleanProperty, coerceElement, coerceNumberProperty, coerceArray } from '@angular/cdk/coercion';
6
6
  import { Subject, Subscription, interval, animationFrameScheduler, Observable, merge } from 'rxjs';
7
- import { startWith, takeUntil, map, take, tap, switchMap } from 'rxjs/operators';
7
+ import { takeUntil, map, take, startWith, tap, switchMap } from 'rxjs/operators';
8
8
  import { Directionality } from '@angular/cdk/bidi';
9
9
 
10
10
  /**
@@ -212,6 +212,139 @@ function isPointerNearClientRect(rect, threshold, pointerX, pointerY) {
212
212
  pointerX > left - xThreshold && pointerX < right + xThreshold;
213
213
  }
214
214
 
215
+ /**
216
+ * @fileoverview added by tsickle
217
+ * Generated from: src/cdk/drag-drop/parent-position-tracker.ts
218
+ * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
219
+ */
220
+ /**
221
+ * Object holding the scroll position of something.
222
+ * @record
223
+ */
224
+ function ScrollPosition() { }
225
+ if (false) {
226
+ /** @type {?} */
227
+ ScrollPosition.prototype.top;
228
+ /** @type {?} */
229
+ ScrollPosition.prototype.left;
230
+ }
231
+ /**
232
+ * Keeps track of the scroll position and dimensions of the parents of an element.
233
+ */
234
+ class ParentPositionTracker {
235
+ /**
236
+ * @param {?} _document
237
+ * @param {?} _viewportRuler
238
+ */
239
+ constructor(_document, _viewportRuler) {
240
+ this._document = _document;
241
+ this._viewportRuler = _viewportRuler;
242
+ /**
243
+ * Cached positions of the scrollable parent elements.
244
+ */
245
+ this.positions = new Map();
246
+ }
247
+ /**
248
+ * Clears the cached positions.
249
+ * @return {?}
250
+ */
251
+ clear() {
252
+ this.positions.clear();
253
+ }
254
+ /**
255
+ * Caches the positions. Should be called at the beginning of a drag sequence.
256
+ * @param {?} elements
257
+ * @return {?}
258
+ */
259
+ cache(elements) {
260
+ this.clear();
261
+ this.positions.set(this._document, {
262
+ scrollPosition: this._viewportRuler.getViewportScrollPosition(),
263
+ });
264
+ elements.forEach((/**
265
+ * @param {?} element
266
+ * @return {?}
267
+ */
268
+ element => {
269
+ this.positions.set(element, {
270
+ scrollPosition: { top: element.scrollTop, left: element.scrollLeft },
271
+ clientRect: getMutableClientRect(element)
272
+ });
273
+ }));
274
+ }
275
+ /**
276
+ * Handles scrolling while a drag is taking place.
277
+ * @param {?} event
278
+ * @return {?}
279
+ */
280
+ handleScroll(event) {
281
+ /** @type {?} */
282
+ const target = (/** @type {?} */ (event.target));
283
+ /** @type {?} */
284
+ const cachedPosition = this.positions.get(target);
285
+ if (!cachedPosition) {
286
+ return null;
287
+ }
288
+ // Used when figuring out whether an element is inside the scroll parent. If the scrolled
289
+ // parent is the `document`, we use the `documentElement`, because IE doesn't support
290
+ // `contains` on the `document`.
291
+ /** @type {?} */
292
+ const scrolledParentNode = target === this._document ? target.documentElement : target;
293
+ /** @type {?} */
294
+ const scrollPosition = cachedPosition.scrollPosition;
295
+ /** @type {?} */
296
+ let newTop;
297
+ /** @type {?} */
298
+ let newLeft;
299
+ if (target === this._document) {
300
+ /** @type {?} */
301
+ const viewportScrollPosition = (/** @type {?} */ (this._viewportRuler)).getViewportScrollPosition();
302
+ newTop = viewportScrollPosition.top;
303
+ newLeft = viewportScrollPosition.left;
304
+ }
305
+ else {
306
+ newTop = ((/** @type {?} */ (target))).scrollTop;
307
+ newLeft = ((/** @type {?} */ (target))).scrollLeft;
308
+ }
309
+ /** @type {?} */
310
+ const topDifference = scrollPosition.top - newTop;
311
+ /** @type {?} */
312
+ const leftDifference = scrollPosition.left - newLeft;
313
+ // Go through and update the cached positions of the scroll
314
+ // parents that are inside the element that was scrolled.
315
+ this.positions.forEach((/**
316
+ * @param {?} position
317
+ * @param {?} node
318
+ * @return {?}
319
+ */
320
+ (position, node) => {
321
+ if (position.clientRect && target !== node && scrolledParentNode.contains(node)) {
322
+ adjustClientRect(position.clientRect, topDifference, leftDifference);
323
+ }
324
+ }));
325
+ scrollPosition.top = newTop;
326
+ scrollPosition.left = newLeft;
327
+ return { top: topDifference, left: leftDifference };
328
+ }
329
+ }
330
+ if (false) {
331
+ /**
332
+ * Cached positions of the scrollable parent elements.
333
+ * @type {?}
334
+ */
335
+ ParentPositionTracker.prototype.positions;
336
+ /**
337
+ * @type {?}
338
+ * @private
339
+ */
340
+ ParentPositionTracker.prototype._document;
341
+ /**
342
+ * @type {?}
343
+ * @private
344
+ */
345
+ ParentPositionTracker.prototype._viewportRuler;
346
+ }
347
+
215
348
  /**
216
349
  * @fileoverview added by tsickle
217
350
  * Generated from: src/cdk/drag-drop/drag-ref.ts
@@ -542,6 +675,7 @@ class DragRef {
542
675
  this._endDragSequence(event);
543
676
  });
544
677
  this.withRootElement(element);
678
+ this._parentPositions = new ParentPositionTracker(_document, _viewportRuler);
545
679
  _dragDropRegistry.registerDragItem(this);
546
680
  }
547
681
  /**
@@ -707,6 +841,7 @@ class DragRef {
707
841
  this._disabledHandles.clear();
708
842
  this._dropContainer = undefined;
709
843
  this._resizeSubscription.unsubscribe();
844
+ this._parentPositions.clear();
710
845
  this._boundaryElement = this._rootElement = this._placeholderTemplate =
711
846
  this._previewTemplate = this._anchor = (/** @type {?} */ (null));
712
847
  }
@@ -905,7 +1040,9 @@ class DragRef {
905
1040
  this._lastTouchEventTime = Date.now();
906
1041
  }
907
1042
  this._toggleNativeDragInteractions();
908
- if (this._dropContainer) {
1043
+ /** @type {?} */
1044
+ const dropContainer = this._dropContainer;
1045
+ if (dropContainer) {
909
1046
  /** @type {?} */
910
1047
  const element = this._rootElement;
911
1048
  /** @type {?} */
@@ -924,13 +1061,16 @@ class DragRef {
924
1061
  element.style.display = 'none';
925
1062
  this._document.body.appendChild(parent.replaceChild(placeholder, element));
926
1063
  getPreviewInsertionPoint(this._document).appendChild(preview);
927
- this._dropContainer.start();
928
- this._initialContainer = this._dropContainer;
929
- this._initialIndex = this._dropContainer.getItemIndex(this);
1064
+ dropContainer.start();
1065
+ this._initialContainer = dropContainer;
1066
+ this._initialIndex = dropContainer.getItemIndex(this);
930
1067
  }
931
1068
  else {
932
1069
  this._initialContainer = this._initialIndex = (/** @type {?} */ (undefined));
933
1070
  }
1071
+ // Important to run after we've called `start` on the parent container
1072
+ // so that it has had time to resolve its scrollable parents.
1073
+ this._parentPositions.cache(dropContainer ? dropContainer.getScrollableParents() : []);
934
1074
  }
935
1075
  /**
936
1076
  * Sets up the different variables and subscriptions
@@ -982,11 +1122,12 @@ class DragRef {
982
1122
  this._removeSubscriptions();
983
1123
  this._pointerMoveSubscription = this._dragDropRegistry.pointerMove.subscribe(this._pointerMove);
984
1124
  this._pointerUpSubscription = this._dragDropRegistry.pointerUp.subscribe(this._pointerUp);
985
- this._scrollSubscription = this._dragDropRegistry.scroll.pipe(startWith(null)).subscribe((/**
1125
+ this._scrollSubscription = this._dragDropRegistry.scroll.subscribe((/**
1126
+ * @param {?} scrollEvent
986
1127
  * @return {?}
987
1128
  */
988
- () => {
989
- this._updateOnScroll();
1129
+ scrollEvent => {
1130
+ this._updateOnScroll(scrollEvent);
990
1131
  }));
991
1132
  if (this._boundaryElement) {
992
1133
  this._boundaryRect = getMutableClientRect(this._boundaryElement);
@@ -1111,14 +1252,18 @@ class DragRef {
1111
1252
  const previewTemplate = previewConfig ? previewConfig.template : null;
1112
1253
  /** @type {?} */
1113
1254
  let preview;
1114
- if (previewTemplate) {
1255
+ if (previewTemplate && previewConfig) {
1256
+ // Measure the element before we've inserted the preview
1257
+ // since the insertion could throw off the measurement.
1115
1258
  /** @type {?} */
1116
- const viewRef = (/** @type {?} */ (previewConfig)).viewContainer.createEmbeddedView(previewTemplate, (/** @type {?} */ (previewConfig)).context);
1259
+ const rootRect = previewConfig.matchSize ? this._rootElement.getBoundingClientRect() : null;
1260
+ /** @type {?} */
1261
+ const viewRef = previewConfig.viewContainer.createEmbeddedView(previewTemplate, previewConfig.context);
1117
1262
  viewRef.detectChanges();
1118
1263
  preview = getRootNode(viewRef, this._document);
1119
1264
  this._previewRef = viewRef;
1120
- if ((/** @type {?} */ (previewConfig)).matchSize) {
1121
- matchElementSize(preview, this._rootElement);
1265
+ if (previewConfig.matchSize) {
1266
+ matchElementSize(preview, (/** @type {?} */ (rootRect)));
1122
1267
  }
1123
1268
  else {
1124
1269
  preview.style.transform =
@@ -1129,7 +1274,7 @@ class DragRef {
1129
1274
  /** @type {?} */
1130
1275
  const element = this._rootElement;
1131
1276
  preview = deepCloneNode(element);
1132
- matchElementSize(preview, element);
1277
+ matchElementSize(preview, element.getBoundingClientRect());
1133
1278
  }
1134
1279
  extendStyles(preview.style, {
1135
1280
  // It's important that we disable the pointer events on the preview, because
@@ -1254,9 +1399,11 @@ class DragRef {
1254
1399
  /** @type {?} */
1255
1400
  const point = isTouchEvent(event) ? event.targetTouches[0] : event;
1256
1401
  /** @type {?} */
1257
- const x = point.pageX - referenceRect.left - this._scrollPosition.left;
1402
+ const scrollPosition = this._getViewportScrollPosition();
1403
+ /** @type {?} */
1404
+ const x = point.pageX - referenceRect.left - scrollPosition.left;
1258
1405
  /** @type {?} */
1259
- const y = point.pageY - referenceRect.top - this._scrollPosition.top;
1406
+ const y = point.pageY - referenceRect.top - scrollPosition.top;
1260
1407
  return {
1261
1408
  x: referenceRect.left - elementRect.left + x,
1262
1409
  y: referenceRect.top - elementRect.top + y
@@ -1272,9 +1419,11 @@ class DragRef {
1272
1419
  // `touches` will be empty for start/end events so we have to fall back to `changedTouches`.
1273
1420
  /** @type {?} */
1274
1421
  const point = isTouchEvent(event) ? (event.touches[0] || event.changedTouches[0]) : event;
1422
+ /** @type {?} */
1423
+ const scrollPosition = this._getViewportScrollPosition();
1275
1424
  return {
1276
- x: point.pageX - this._scrollPosition.left,
1277
- y: point.pageY - this._scrollPosition.top
1425
+ x: point.pageX - scrollPosition.left,
1426
+ y: point.pageY - scrollPosition.top
1278
1427
  };
1279
1428
  }
1280
1429
  /**
@@ -1412,6 +1561,7 @@ class DragRef {
1412
1561
  */
1413
1562
  _cleanupCachedDimensions() {
1414
1563
  this._boundaryRect = this._previewRect = undefined;
1564
+ this._parentPositions.clear();
1415
1565
  }
1416
1566
  /**
1417
1567
  * Checks whether the element is still inside its boundary after the viewport has been resized.
@@ -1492,23 +1642,28 @@ class DragRef {
1492
1642
  /**
1493
1643
  * Updates the internal state of the draggable element when scrolling has occurred.
1494
1644
  * @private
1645
+ * @param {?} event
1495
1646
  * @return {?}
1496
1647
  */
1497
- _updateOnScroll() {
1498
- /** @type {?} */
1499
- const oldScrollPosition = this._scrollPosition;
1648
+ _updateOnScroll(event) {
1500
1649
  /** @type {?} */
1501
- const currentScrollPosition = this._viewportRuler.getViewportScrollPosition();
1650
+ const scrollDifference = this._parentPositions.handleScroll(event);
1502
1651
  // ClientRect dimensions are based on the page's scroll position so
1503
1652
  // we have to update the cached boundary ClientRect if the user has scrolled.
1504
- if (oldScrollPosition && this._boundaryRect) {
1505
- /** @type {?} */
1506
- const topDifference = oldScrollPosition.top - currentScrollPosition.top;
1507
- /** @type {?} */
1508
- const leftDifference = oldScrollPosition.left - currentScrollPosition.left;
1509
- adjustClientRect(this._boundaryRect, topDifference, leftDifference);
1653
+ if (this._boundaryRect && scrollDifference) {
1654
+ adjustClientRect(this._boundaryRect, scrollDifference.top, scrollDifference.left);
1510
1655
  }
1511
- this._scrollPosition = currentScrollPosition;
1656
+ }
1657
+ /**
1658
+ * Gets the scroll position of the viewport.
1659
+ * @private
1660
+ * @return {?}
1661
+ */
1662
+ _getViewportScrollPosition() {
1663
+ /** @type {?} */
1664
+ const cachedPosition = this._parentPositions.positions.get(this._document);
1665
+ return cachedPosition ? cachedPosition.scrollPosition :
1666
+ this._viewportRuler.getViewportScrollPosition();
1512
1667
  }
1513
1668
  }
1514
1669
  if (false) {
@@ -1602,11 +1757,11 @@ if (false) {
1602
1757
  */
1603
1758
  DragRef.prototype._initialIndex;
1604
1759
  /**
1605
- * Cached scroll position on the page when the element was picked up.
1760
+ * Cached positions of scrollable parent elements.
1606
1761
  * @type {?}
1607
1762
  * @private
1608
1763
  */
1609
- DragRef.prototype._scrollPosition;
1764
+ DragRef.prototype._parentPositions;
1610
1765
  /**
1611
1766
  * Emits when the item is being moved.
1612
1767
  * @type {?}
@@ -1970,12 +2125,10 @@ function getRootNode(viewRef, _document) {
1970
2125
  /**
1971
2126
  * Matches the target element's size to the source's size.
1972
2127
  * @param {?} target Element that needs to be resized.
1973
- * @param {?} source Element whose size needs to be matched.
2128
+ * @param {?} sourceRect Dimensions of the source element.
1974
2129
  * @return {?}
1975
2130
  */
1976
- function matchElementSize(target, source) {
1977
- /** @type {?} */
1978
- const sourceRect = source.getBoundingClientRect();
2131
+ function matchElementSize(target, sourceRect) {
1979
2132
  target.style.width = `${sourceRect.width}px`;
1980
2133
  target.style.height = `${sourceRect.height}px`;
1981
2134
  target.style.transform = getTransform(sourceRect.left, sourceRect.top);
@@ -2110,17 +2263,6 @@ if (false) {
2110
2263
  */
2111
2264
  CachedItemPosition.prototype.offset;
2112
2265
  }
2113
- /**
2114
- * Object holding the scroll position of something.
2115
- * @record
2116
- */
2117
- function ScrollPosition() { }
2118
- if (false) {
2119
- /** @type {?} */
2120
- ScrollPosition.prototype.top;
2121
- /** @type {?} */
2122
- ScrollPosition.prototype.left;
2123
- }
2124
2266
  /** @enum {number} */
2125
2267
  const AutoScrollVerticalDirection = {
2126
2268
  NONE: 0, UP: 1, DOWN: 2,
@@ -2202,10 +2344,6 @@ class DropListRef {
2202
2344
  * Cache of the dimensions of all the items inside the container.
2203
2345
  */
2204
2346
  this._itemPositions = [];
2205
- /**
2206
- * Cached positions of the scrollable parent elements.
2207
- */
2208
- this._parentPositions = new Map();
2209
2347
  /**
2210
2348
  * Keeps track of the item that was last swapped with the dragged item, as
2211
2349
  * well as what direction the pointer was moving in when the swap occured.
@@ -2281,6 +2419,7 @@ class DropListRef {
2281
2419
  this._document = _document;
2282
2420
  this.withScrollableParents([this.element]);
2283
2421
  _dragDropRegistry.registerDropContainer(this);
2422
+ this._parentPositions = new ParentPositionTracker(_document, _viewportRuler);
2284
2423
  }
2285
2424
  /**
2286
2425
  * Removes the drop list functionality from the DOM element.
@@ -2384,14 +2523,23 @@ class DropListRef {
2384
2523
  activeDraggables.splice(newIndex, 0, item);
2385
2524
  }
2386
2525
  else {
2387
- coerceElement(this.element).appendChild(placeholder);
2388
- activeDraggables.push(item);
2526
+ /** @type {?} */
2527
+ const element = coerceElement(this.element);
2528
+ if (this._shouldEnterAsFirstChild(pointerX, pointerY)) {
2529
+ element.insertBefore(placeholder, activeDraggables[0].getRootElement());
2530
+ activeDraggables.unshift(item);
2531
+ }
2532
+ else {
2533
+ element.appendChild(placeholder);
2534
+ activeDraggables.push(item);
2535
+ }
2389
2536
  }
2390
2537
  // The transform needs to be cleared so it doesn't throw off the measurements.
2391
2538
  placeholder.style.transform = '';
2392
2539
  // Note that the positions were already cached when we called `start` above,
2393
- // but we need to refresh them since the amount of items has changed.
2540
+ // but we need to refresh them since the amount of items has changed and also parent rects.
2394
2541
  this._cacheItemPositions();
2542
+ this._cacheParentPositions();
2395
2543
  this.entered.next({ item, container: this, currentIndex: this.getItemIndex(item) });
2396
2544
  }
2397
2545
  /**
@@ -2439,6 +2587,8 @@ class DropListRef {
2439
2587
  * @return {THIS}
2440
2588
  */
2441
2589
  withItems(items) {
2590
+ /** @type {?} */
2591
+ const previousItems = (/** @type {?} */ (this))._draggables;
2442
2592
  (/** @type {?} */ (this))._draggables = items;
2443
2593
  items.forEach((/**
2444
2594
  * @param {?} item
@@ -2446,7 +2596,24 @@ class DropListRef {
2446
2596
  */
2447
2597
  item => item._withDropContainer((/** @type {?} */ (this)))));
2448
2598
  if ((/** @type {?} */ (this)).isDragging()) {
2449
- (/** @type {?} */ (this))._cacheItems();
2599
+ /** @type {?} */
2600
+ const draggedItems = previousItems.filter((/**
2601
+ * @param {?} item
2602
+ * @return {?}
2603
+ */
2604
+ item => item.isDragging()));
2605
+ // If all of the items being dragged were removed
2606
+ // from the list, abort the current drag sequence.
2607
+ if (draggedItems.every((/**
2608
+ * @param {?} item
2609
+ * @return {?}
2610
+ */
2611
+ item => items.indexOf(item) === -1))) {
2612
+ (/** @type {?} */ (this))._reset();
2613
+ }
2614
+ else {
2615
+ (/** @type {?} */ (this))._cacheItems();
2616
+ }
2450
2617
  }
2451
2618
  return (/** @type {?} */ (this));
2452
2619
  }
@@ -2500,6 +2667,13 @@ class DropListRef {
2500
2667
  elements.indexOf(element) === -1 ? [element, ...elements] : elements.slice();
2501
2668
  return (/** @type {?} */ (this));
2502
2669
  }
2670
+ /**
2671
+ * Gets the scrollable parents that are registered with this drop container.
2672
+ * @return {?}
2673
+ */
2674
+ getScrollableParents() {
2675
+ return this._scrollableElements;
2676
+ }
2503
2677
  /**
2504
2678
  * Figures out the index of an item in the container.
2505
2679
  * @param {?} item Item whose index should be determined.
@@ -2639,7 +2813,7 @@ class DropListRef {
2639
2813
  /** @type {?} */
2640
2814
  let horizontalScrollDirection = 0 /* NONE */;
2641
2815
  // Check whether we should start scrolling any of the parent containers.
2642
- this._parentPositions.forEach((/**
2816
+ this._parentPositions.positions.forEach((/**
2643
2817
  * @param {?} position
2644
2818
  * @param {?} element
2645
2819
  * @return {?}
@@ -2693,28 +2867,12 @@ class DropListRef {
2693
2867
  * @return {?}
2694
2868
  */
2695
2869
  _cacheParentPositions() {
2696
- this._parentPositions.clear();
2697
- this._parentPositions.set(this._document, {
2698
- scrollPosition: (/** @type {?} */ (this._viewportRuler)).getViewportScrollPosition(),
2699
- });
2700
- this._scrollableElements.forEach((/**
2701
- * @param {?} element
2702
- * @return {?}
2703
- */
2704
- element => {
2705
- /** @type {?} */
2706
- const clientRect = getMutableClientRect(element);
2707
- // We keep the ClientRect cached in two properties, because it's referenced in a lot of
2708
- // performance-sensitive places and we want to avoid the extra lookups. The `element` is
2709
- // guaranteed to always be in the `_scrollableElements` so this should always match.
2710
- if (element === this.element) {
2711
- this._clientRect = clientRect;
2712
- }
2713
- this._parentPositions.set(element, {
2714
- scrollPosition: { top: element.scrollTop, left: element.scrollLeft },
2715
- clientRect
2716
- });
2717
- }));
2870
+ /** @type {?} */
2871
+ const element = coerceElement(this.element);
2872
+ this._parentPositions.cache(this._scrollableElements);
2873
+ // The list element is always in the `scrollableElements`
2874
+ // so we can take advantage of the cached `ClientRect`.
2875
+ this._clientRect = (/** @type {?} */ ((/** @type {?} */ (this._parentPositions.positions.get(element))).clientRect));
2718
2876
  }
2719
2877
  /**
2720
2878
  * Refreshes the position cache of the items and sibling containers.
@@ -2757,7 +2915,13 @@ class DropListRef {
2757
2915
  * @param {?} item
2758
2916
  * @return {?}
2759
2917
  */
2760
- item => item.getRootElement().style.transform = ''));
2918
+ item => {
2919
+ /** @type {?} */
2920
+ const rootElement = item.getRootElement();
2921
+ if (rootElement) {
2922
+ rootElement.style.transform = '';
2923
+ }
2924
+ }));
2761
2925
  this._siblings.forEach((/**
2762
2926
  * @param {?} sibling
2763
2927
  * @return {?}
@@ -2827,6 +2991,36 @@ class DropListRef {
2827
2991
  }
2828
2992
  return itemOffset;
2829
2993
  }
2994
+ /**
2995
+ * Checks if pointer is entering in the first position
2996
+ * @private
2997
+ * @param {?} pointerX Position of the user's pointer along the X axis.
2998
+ * @param {?} pointerY Position of the user's pointer along the Y axis.
2999
+ * @return {?}
3000
+ */
3001
+ _shouldEnterAsFirstChild(pointerX, pointerY) {
3002
+ if (!this._activeDraggables.length) {
3003
+ return false;
3004
+ }
3005
+ /** @type {?} */
3006
+ const itemPositions = this._itemPositions;
3007
+ /** @type {?} */
3008
+ const isHorizontal = this._orientation === 'horizontal';
3009
+ // `itemPositions` are sorted by position while `activeDraggables` are sorted by child index
3010
+ // check if container is using some sort of "reverse" ordering (eg: flex-direction: row-reverse)
3011
+ /** @type {?} */
3012
+ const reversed = itemPositions[0].drag !== this._activeDraggables[0];
3013
+ if (reversed) {
3014
+ /** @type {?} */
3015
+ const lastItemRect = itemPositions[itemPositions.length - 1].clientRect;
3016
+ return isHorizontal ? pointerX >= lastItemRect.right : pointerY >= lastItemRect.bottom;
3017
+ }
3018
+ else {
3019
+ /** @type {?} */
3020
+ const firstItemRect = itemPositions[0].clientRect;
3021
+ return isHorizontal ? pointerX <= firstItemRect.left : pointerY <= firstItemRect.top;
3022
+ }
3023
+ }
2830
3024
  /**
2831
3025
  * Gets the index of an item in the drop container, based on the position of the user's pointer.
2832
3026
  * @private
@@ -2863,8 +3057,8 @@ class DropListRef {
2863
3057
  return isHorizontal ?
2864
3058
  // Round these down since most browsers report client rects with
2865
3059
  // sub-pixel precision, whereas the pointer coordinates are rounded to pixels.
2866
- pointerX >= Math.floor(clientRect.left) && pointerX <= Math.floor(clientRect.right) :
2867
- pointerY >= Math.floor(clientRect.top) && pointerY <= Math.floor(clientRect.bottom);
3060
+ pointerX >= Math.floor(clientRect.left) && pointerX < Math.floor(clientRect.right) :
3061
+ pointerY >= Math.floor(clientRect.top) && pointerY < Math.floor(clientRect.bottom);
2868
3062
  }));
2869
3063
  }
2870
3064
  /**
@@ -2877,64 +3071,6 @@ class DropListRef {
2877
3071
  this._cacheItemPositions();
2878
3072
  this._cacheParentPositions();
2879
3073
  }
2880
- /**
2881
- * Updates the internal state of the container after a scroll event has happened.
2882
- * @private
2883
- * @param {?} scrolledParent Element that was scrolled.
2884
- * @param {?} newTop New top scroll position.
2885
- * @param {?} newLeft New left scroll position.
2886
- * @return {?}
2887
- */
2888
- _updateAfterScroll(scrolledParent, newTop, newLeft) {
2889
- // Used when figuring out whether an element is inside the scroll parent. If the scrolled
2890
- // parent is the `document`, we use the `documentElement`, because IE doesn't support `contains`
2891
- // on the `document`.
2892
- /** @type {?} */
2893
- const scrolledParentNode = scrolledParent === this._document ? scrolledParent.documentElement : scrolledParent;
2894
- /** @type {?} */
2895
- const scrollPosition = (/** @type {?} */ (this._parentPositions.get(scrolledParent))).scrollPosition;
2896
- /** @type {?} */
2897
- const topDifference = scrollPosition.top - newTop;
2898
- /** @type {?} */
2899
- const leftDifference = scrollPosition.left - newLeft;
2900
- // Go through and update the cached positions of the scroll
2901
- // parents that are inside the element that was scrolled.
2902
- this._parentPositions.forEach((/**
2903
- * @param {?} position
2904
- * @param {?} node
2905
- * @return {?}
2906
- */
2907
- (position, node) => {
2908
- if (position.clientRect && scrolledParent !== node && scrolledParentNode.contains(node)) {
2909
- adjustClientRect(position.clientRect, topDifference, leftDifference);
2910
- }
2911
- }));
2912
- // Since we know the amount that the user has scrolled we can shift all of the client rectangles
2913
- // ourselves. This is cheaper than re-measuring everything and we can avoid inconsistent
2914
- // behavior where we might be measuring the element before its position has changed.
2915
- this._itemPositions.forEach((/**
2916
- * @param {?} __0
2917
- * @return {?}
2918
- */
2919
- ({ clientRect }) => {
2920
- adjustClientRect(clientRect, topDifference, leftDifference);
2921
- }));
2922
- // We need two loops for this, because we want all of the cached
2923
- // positions to be up-to-date before we re-sort the item.
2924
- this._itemPositions.forEach((/**
2925
- * @param {?} __0
2926
- * @return {?}
2927
- */
2928
- ({ drag }) => {
2929
- if (this._dragDropRegistry.isDragging(drag)) {
2930
- // We need to re-sort the item manually, because the pointer move
2931
- // events won't be dispatched while the user is scrolling.
2932
- drag._sortFromLastPointerPosition();
2933
- }
2934
- }));
2935
- scrollPosition.top = newTop;
2936
- scrollPosition.left = newLeft;
2937
- }
2938
3074
  /**
2939
3075
  * Checks whether the user's pointer is positioned over the container.
2940
3076
  * @param {?} x Pointer position along the X axis.
@@ -3024,25 +3160,32 @@ class DropListRef {
3024
3160
  event => {
3025
3161
  if (this.isDragging()) {
3026
3162
  /** @type {?} */
3027
- const target = (/** @type {?} */ (event.target));
3028
- /** @type {?} */
3029
- const position = this._parentPositions.get(target);
3030
- if (position) {
3031
- /** @type {?} */
3032
- let newTop;
3033
- /** @type {?} */
3034
- let newLeft;
3035
- if (target === this._document) {
3036
- /** @type {?} */
3037
- const scrollPosition = (/** @type {?} */ (this._viewportRuler)).getViewportScrollPosition();
3038
- newTop = scrollPosition.top;
3039
- newLeft = scrollPosition.left;
3040
- }
3041
- else {
3042
- newTop = ((/** @type {?} */ (target))).scrollTop;
3043
- newLeft = ((/** @type {?} */ (target))).scrollLeft;
3044
- }
3045
- this._updateAfterScroll(target, newTop, newLeft);
3163
+ const scrollDifference = this._parentPositions.handleScroll(event);
3164
+ if (scrollDifference) {
3165
+ // Since we know the amount that the user has scrolled we can shift all of the
3166
+ // client rectangles ourselves. This is cheaper than re-measuring everything and
3167
+ // we can avoid inconsistent behavior where we might be measuring the element before
3168
+ // its position has changed.
3169
+ this._itemPositions.forEach((/**
3170
+ * @param {?} __0
3171
+ * @return {?}
3172
+ */
3173
+ ({ clientRect }) => {
3174
+ adjustClientRect(clientRect, scrollDifference.top, scrollDifference.left);
3175
+ }));
3176
+ // We need two loops for this, because we want all of the cached
3177
+ // positions to be up-to-date before we re-sort the item.
3178
+ this._itemPositions.forEach((/**
3179
+ * @param {?} __0
3180
+ * @return {?}
3181
+ */
3182
+ ({ drag }) => {
3183
+ if (this._dragDropRegistry.isDragging(drag)) {
3184
+ // We need to re-sort the item manually, because the pointer move
3185
+ // events won't be dispatched while the user is scrolling.
3186
+ drag._sortFromLastPointerPosition();
3187
+ }
3188
+ }));
3046
3189
  }
3047
3190
  }
3048
3191
  else if (this.isReceiving()) {
@@ -3144,7 +3287,7 @@ if (false) {
3144
3287
  */
3145
3288
  DropListRef.prototype._itemPositions;
3146
3289
  /**
3147
- * Cached positions of the scrollable parent elements.
3290
+ * Keeps track of the positions of any parent scrollable elements.
3148
3291
  * @type {?}
3149
3292
  * @private
3150
3293
  */
@@ -5594,6 +5737,7 @@ DragDropModule.decorators = [
5594
5737
  CdkDragPlaceholder,
5595
5738
  ],
5596
5739
  exports: [
5740
+ CdkScrollableModule,
5597
5741
  CdkDropList,
5598
5742
  CdkDropListGroup,
5599
5743
  CdkDrag,