@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
@@ -138,6 +138,78 @@
138
138
  pointerX > left - xThreshold && pointerX < right + xThreshold;
139
139
  }
140
140
 
141
+ /**
142
+ * @license
143
+ * Copyright Google LLC All Rights Reserved.
144
+ *
145
+ * Use of this source code is governed by an MIT-style license that can be
146
+ * found in the LICENSE file at https://angular.io/license
147
+ */
148
+ /** Keeps track of the scroll position and dimensions of the parents of an element. */
149
+ var ParentPositionTracker = /** @class */ (function () {
150
+ function ParentPositionTracker(_document, _viewportRuler) {
151
+ this._document = _document;
152
+ this._viewportRuler = _viewportRuler;
153
+ /** Cached positions of the scrollable parent elements. */
154
+ this.positions = new Map();
155
+ }
156
+ /** Clears the cached positions. */
157
+ ParentPositionTracker.prototype.clear = function () {
158
+ this.positions.clear();
159
+ };
160
+ /** Caches the positions. Should be called at the beginning of a drag sequence. */
161
+ ParentPositionTracker.prototype.cache = function (elements) {
162
+ var _this = this;
163
+ this.clear();
164
+ this.positions.set(this._document, {
165
+ scrollPosition: this._viewportRuler.getViewportScrollPosition(),
166
+ });
167
+ elements.forEach(function (element) {
168
+ _this.positions.set(element, {
169
+ scrollPosition: { top: element.scrollTop, left: element.scrollLeft },
170
+ clientRect: getMutableClientRect(element)
171
+ });
172
+ });
173
+ };
174
+ /** Handles scrolling while a drag is taking place. */
175
+ ParentPositionTracker.prototype.handleScroll = function (event) {
176
+ var target = event.target;
177
+ var cachedPosition = this.positions.get(target);
178
+ if (!cachedPosition) {
179
+ return null;
180
+ }
181
+ // Used when figuring out whether an element is inside the scroll parent. If the scrolled
182
+ // parent is the `document`, we use the `documentElement`, because IE doesn't support
183
+ // `contains` on the `document`.
184
+ var scrolledParentNode = target === this._document ? target.documentElement : target;
185
+ var scrollPosition = cachedPosition.scrollPosition;
186
+ var newTop;
187
+ var newLeft;
188
+ if (target === this._document) {
189
+ var viewportScrollPosition = this._viewportRuler.getViewportScrollPosition();
190
+ newTop = viewportScrollPosition.top;
191
+ newLeft = viewportScrollPosition.left;
192
+ }
193
+ else {
194
+ newTop = target.scrollTop;
195
+ newLeft = target.scrollLeft;
196
+ }
197
+ var topDifference = scrollPosition.top - newTop;
198
+ var leftDifference = scrollPosition.left - newLeft;
199
+ // Go through and update the cached positions of the scroll
200
+ // parents that are inside the element that was scrolled.
201
+ this.positions.forEach(function (position, node) {
202
+ if (position.clientRect && target !== node && scrolledParentNode.contains(node)) {
203
+ adjustClientRect(position.clientRect, topDifference, leftDifference);
204
+ }
205
+ });
206
+ scrollPosition.top = newTop;
207
+ scrollPosition.left = newLeft;
208
+ return { top: topDifference, left: leftDifference };
209
+ };
210
+ return ParentPositionTracker;
211
+ }());
212
+
141
213
  /**
142
214
  * @license
143
215
  * Copyright Google LLC All Rights Reserved.
@@ -315,6 +387,7 @@
315
387
  _this._endDragSequence(event);
316
388
  };
317
389
  this.withRootElement(element);
390
+ this._parentPositions = new ParentPositionTracker(_document, _viewportRuler);
318
391
  _dragDropRegistry.registerDragItem(this);
319
392
  }
320
393
  Object.defineProperty(DragRef.prototype, "disabled", {
@@ -435,6 +508,7 @@
435
508
  this._disabledHandles.clear();
436
509
  this._dropContainer = undefined;
437
510
  this._resizeSubscription.unsubscribe();
511
+ this._parentPositions.clear();
438
512
  this._boundaryElement = this._rootElement = this._placeholderTemplate =
439
513
  this._previewTemplate = this._anchor = null;
440
514
  };
@@ -582,7 +656,8 @@
582
656
  this._lastTouchEventTime = Date.now();
583
657
  }
584
658
  this._toggleNativeDragInteractions();
585
- if (this._dropContainer) {
659
+ var dropContainer = this._dropContainer;
660
+ if (dropContainer) {
586
661
  var element = this._rootElement;
587
662
  var parent_1 = element.parentNode;
588
663
  var preview = this._preview = this._createPreviewElement();
@@ -596,13 +671,16 @@
596
671
  element.style.display = 'none';
597
672
  this._document.body.appendChild(parent_1.replaceChild(placeholder, element));
598
673
  getPreviewInsertionPoint(this._document).appendChild(preview);
599
- this._dropContainer.start();
600
- this._initialContainer = this._dropContainer;
601
- this._initialIndex = this._dropContainer.getItemIndex(this);
674
+ dropContainer.start();
675
+ this._initialContainer = dropContainer;
676
+ this._initialIndex = dropContainer.getItemIndex(this);
602
677
  }
603
678
  else {
604
679
  this._initialContainer = this._initialIndex = undefined;
605
680
  }
681
+ // Important to run after we've called `start` on the parent container
682
+ // so that it has had time to resolve its scrollable parents.
683
+ this._parentPositions.cache(dropContainer ? dropContainer.getScrollableParents() : []);
606
684
  };
607
685
  /**
608
686
  * Sets up the different variables and subscriptions
@@ -648,8 +726,8 @@
648
726
  this._removeSubscriptions();
649
727
  this._pointerMoveSubscription = this._dragDropRegistry.pointerMove.subscribe(this._pointerMove);
650
728
  this._pointerUpSubscription = this._dragDropRegistry.pointerUp.subscribe(this._pointerUp);
651
- this._scrollSubscription = this._dragDropRegistry.scroll.pipe(operators.startWith(null)).subscribe(function () {
652
- _this._updateOnScroll();
729
+ this._scrollSubscription = this._dragDropRegistry.scroll.subscribe(function (scrollEvent) {
730
+ _this._updateOnScroll(scrollEvent);
653
731
  });
654
732
  if (this._boundaryElement) {
655
733
  this._boundaryRect = getMutableClientRect(this._boundaryElement);
@@ -749,13 +827,16 @@
749
827
  var previewClass = this.previewClass;
750
828
  var previewTemplate = previewConfig ? previewConfig.template : null;
751
829
  var preview;
752
- if (previewTemplate) {
830
+ if (previewTemplate && previewConfig) {
831
+ // Measure the element before we've inserted the preview
832
+ // since the insertion could throw off the measurement.
833
+ var rootRect = previewConfig.matchSize ? this._rootElement.getBoundingClientRect() : null;
753
834
  var viewRef = previewConfig.viewContainer.createEmbeddedView(previewTemplate, previewConfig.context);
754
835
  viewRef.detectChanges();
755
836
  preview = getRootNode(viewRef, this._document);
756
837
  this._previewRef = viewRef;
757
838
  if (previewConfig.matchSize) {
758
- matchElementSize(preview, this._rootElement);
839
+ matchElementSize(preview, rootRect);
759
840
  }
760
841
  else {
761
842
  preview.style.transform =
@@ -765,7 +846,7 @@
765
846
  else {
766
847
  var element = this._rootElement;
767
848
  preview = deepCloneNode(element);
768
- matchElementSize(preview, element);
849
+ matchElementSize(preview, element.getBoundingClientRect());
769
850
  }
770
851
  extendStyles(preview.style, {
771
852
  // It's important that we disable the pointer events on the preview, because
@@ -857,8 +938,9 @@
857
938
  var handleElement = referenceElement === this._rootElement ? null : referenceElement;
858
939
  var referenceRect = handleElement ? handleElement.getBoundingClientRect() : elementRect;
859
940
  var point = isTouchEvent(event) ? event.targetTouches[0] : event;
860
- var x = point.pageX - referenceRect.left - this._scrollPosition.left;
861
- var y = point.pageY - referenceRect.top - this._scrollPosition.top;
941
+ var scrollPosition = this._getViewportScrollPosition();
942
+ var x = point.pageX - referenceRect.left - scrollPosition.left;
943
+ var y = point.pageY - referenceRect.top - scrollPosition.top;
862
944
  return {
863
945
  x: referenceRect.left - elementRect.left + x,
864
946
  y: referenceRect.top - elementRect.top + y
@@ -868,9 +950,10 @@
868
950
  DragRef.prototype._getPointerPositionOnPage = function (event) {
869
951
  // `touches` will be empty for start/end events so we have to fall back to `changedTouches`.
870
952
  var point = isTouchEvent(event) ? (event.touches[0] || event.changedTouches[0]) : event;
953
+ var scrollPosition = this._getViewportScrollPosition();
871
954
  return {
872
- x: point.pageX - this._scrollPosition.left,
873
- y: point.pageY - this._scrollPosition.top
955
+ x: point.pageX - scrollPosition.left,
956
+ y: point.pageY - scrollPosition.top
874
957
  };
875
958
  };
876
959
  /** Gets the pointer position on the page, accounting for any position constraints. */
@@ -966,6 +1049,7 @@
966
1049
  /** Cleans up any cached element dimensions that we don't need after dragging has stopped. */
967
1050
  DragRef.prototype._cleanupCachedDimensions = function () {
968
1051
  this._boundaryRect = this._previewRect = undefined;
1052
+ this._parentPositions.clear();
969
1053
  };
970
1054
  /**
971
1055
  * Checks whether the element is still inside its boundary after the viewport has been resized.
@@ -1030,17 +1114,19 @@
1030
1114
  return value ? value.mouse : 0;
1031
1115
  };
1032
1116
  /** Updates the internal state of the draggable element when scrolling has occurred. */
1033
- DragRef.prototype._updateOnScroll = function () {
1034
- var oldScrollPosition = this._scrollPosition;
1035
- var currentScrollPosition = this._viewportRuler.getViewportScrollPosition();
1117
+ DragRef.prototype._updateOnScroll = function (event) {
1118
+ var scrollDifference = this._parentPositions.handleScroll(event);
1036
1119
  // ClientRect dimensions are based on the page's scroll position so
1037
1120
  // we have to update the cached boundary ClientRect if the user has scrolled.
1038
- if (oldScrollPosition && this._boundaryRect) {
1039
- var topDifference = oldScrollPosition.top - currentScrollPosition.top;
1040
- var leftDifference = oldScrollPosition.left - currentScrollPosition.left;
1041
- adjustClientRect(this._boundaryRect, topDifference, leftDifference);
1121
+ if (this._boundaryRect && scrollDifference) {
1122
+ adjustClientRect(this._boundaryRect, scrollDifference.top, scrollDifference.left);
1042
1123
  }
1043
- this._scrollPosition = currentScrollPosition;
1124
+ };
1125
+ /** Gets the scroll position of the viewport. */
1126
+ DragRef.prototype._getViewportScrollPosition = function () {
1127
+ var cachedPosition = this._parentPositions.positions.get(this._document);
1128
+ return cachedPosition ? cachedPosition.scrollPosition :
1129
+ this._viewportRuler.getViewportScrollPosition();
1044
1130
  };
1045
1131
  return DragRef;
1046
1132
  }());
@@ -1124,10 +1210,9 @@
1124
1210
  /**
1125
1211
  * Matches the target element's size to the source's size.
1126
1212
  * @param target Element that needs to be resized.
1127
- * @param source Element whose size needs to be matched.
1213
+ * @param sourceRect Dimensions of the source element.
1128
1214
  */
1129
- function matchElementSize(target, source) {
1130
- var sourceRect = source.getBoundingClientRect();
1215
+ function matchElementSize(target, sourceRect) {
1131
1216
  target.style.width = sourceRect.width + "px";
1132
1217
  target.style.height = sourceRect.height + "px";
1133
1218
  target.style.transform = getTransform(sourceRect.left, sourceRect.top);
@@ -1454,8 +1539,6 @@
1454
1539
  this._isDragging = false;
1455
1540
  /** Cache of the dimensions of all the items inside the container. */
1456
1541
  this._itemPositions = [];
1457
- /** Cached positions of the scrollable parent elements. */
1458
- this._parentPositions = new Map();
1459
1542
  /**
1460
1543
  * Keeps track of the item that was last swapped with the dragged item, as
1461
1544
  * well as what direction the pointer was moving in when the swap occured.
@@ -1504,6 +1587,7 @@
1504
1587
  this._document = _document;
1505
1588
  this.withScrollableParents([this.element]);
1506
1589
  _dragDropRegistry.registerDropContainer(this);
1590
+ this._parentPositions = new ParentPositionTracker(_document, _viewportRuler);
1507
1591
  }
1508
1592
  /** Removes the drop list functionality from the DOM element. */
1509
1593
  DropListRef.prototype.dispose = function () {
@@ -1587,14 +1671,22 @@
1587
1671
  activeDraggables.splice(newIndex, 0, item);
1588
1672
  }
1589
1673
  else {
1590
- coercion.coerceElement(this.element).appendChild(placeholder);
1591
- activeDraggables.push(item);
1674
+ var element = coercion.coerceElement(this.element);
1675
+ if (this._shouldEnterAsFirstChild(pointerX, pointerY)) {
1676
+ element.insertBefore(placeholder, activeDraggables[0].getRootElement());
1677
+ activeDraggables.unshift(item);
1678
+ }
1679
+ else {
1680
+ element.appendChild(placeholder);
1681
+ activeDraggables.push(item);
1682
+ }
1592
1683
  }
1593
1684
  // The transform needs to be cleared so it doesn't throw off the measurements.
1594
1685
  placeholder.style.transform = '';
1595
1686
  // Note that the positions were already cached when we called `start` above,
1596
- // but we need to refresh them since the amount of items has changed.
1687
+ // but we need to refresh them since the amount of items has changed and also parent rects.
1597
1688
  this._cacheItemPositions();
1689
+ this._cacheParentPositions();
1598
1690
  this.entered.next({ item: item, container: this, currentIndex: this.getItemIndex(item) });
1599
1691
  };
1600
1692
  /**
@@ -1638,10 +1730,19 @@
1638
1730
  */
1639
1731
  DropListRef.prototype.withItems = function (items) {
1640
1732
  var _this = this;
1733
+ var previousItems = this._draggables;
1641
1734
  this._draggables = items;
1642
1735
  items.forEach(function (item) { return item._withDropContainer(_this); });
1643
1736
  if (this.isDragging()) {
1644
- this._cacheItems();
1737
+ var draggedItems = previousItems.filter(function (item) { return item.isDragging(); });
1738
+ // If all of the items being dragged were removed
1739
+ // from the list, abort the current drag sequence.
1740
+ if (draggedItems.every(function (item) { return items.indexOf(item) === -1; })) {
1741
+ this._reset();
1742
+ }
1743
+ else {
1744
+ this._cacheItems();
1745
+ }
1645
1746
  }
1646
1747
  return this;
1647
1748
  };
@@ -1679,6 +1780,10 @@
1679
1780
  elements.indexOf(element) === -1 ? __spread([element], elements) : elements.slice();
1680
1781
  return this;
1681
1782
  };
1783
+ /** Gets the scrollable parents that are registered with this drop container. */
1784
+ DropListRef.prototype.getScrollableParents = function () {
1785
+ return this._scrollableElements;
1786
+ };
1682
1787
  /**
1683
1788
  * Figures out the index of an item in the container.
1684
1789
  * @param item Item whose index should be determined.
@@ -1784,7 +1889,7 @@
1784
1889
  var verticalScrollDirection = 0 /* NONE */;
1785
1890
  var horizontalScrollDirection = 0 /* NONE */;
1786
1891
  // Check whether we should start scrolling any of the parent containers.
1787
- this._parentPositions.forEach(function (position, element) {
1892
+ this._parentPositions.positions.forEach(function (position, element) {
1788
1893
  var _a;
1789
1894
  // We have special handling for the `document` below. Also this would be
1790
1895
  // nicer with a for...of loop, but it requires changing a compiler flag.
@@ -1826,24 +1931,11 @@
1826
1931
  };
1827
1932
  /** Caches the positions of the configured scrollable parents. */
1828
1933
  DropListRef.prototype._cacheParentPositions = function () {
1829
- var _this = this;
1830
- this._parentPositions.clear();
1831
- this._parentPositions.set(this._document, {
1832
- scrollPosition: this._viewportRuler.getViewportScrollPosition(),
1833
- });
1834
- this._scrollableElements.forEach(function (element) {
1835
- var clientRect = getMutableClientRect(element);
1836
- // We keep the ClientRect cached in two properties, because it's referenced in a lot of
1837
- // performance-sensitive places and we want to avoid the extra lookups. The `element` is
1838
- // guaranteed to always be in the `_scrollableElements` so this should always match.
1839
- if (element === _this.element) {
1840
- _this._clientRect = clientRect;
1841
- }
1842
- _this._parentPositions.set(element, {
1843
- scrollPosition: { top: element.scrollTop, left: element.scrollLeft },
1844
- clientRect: clientRect
1845
- });
1846
- });
1934
+ var element = coercion.coerceElement(this.element);
1935
+ this._parentPositions.cache(this._scrollableElements);
1936
+ // The list element is always in the `scrollableElements`
1937
+ // so we can take advantage of the cached `ClientRect`.
1938
+ this._clientRect = this._parentPositions.positions.get(element).clientRect;
1847
1939
  };
1848
1940
  /** Refreshes the position cache of the items and sibling containers. */
1849
1941
  DropListRef.prototype._cacheItemPositions = function () {
@@ -1863,7 +1955,12 @@
1863
1955
  var styles = coercion.coerceElement(this.element).style;
1864
1956
  styles.scrollSnapType = styles.msScrollSnapType = this._initialScrollSnap;
1865
1957
  // TODO(crisbeto): may have to wait for the animations to finish.
1866
- this._activeDraggables.forEach(function (item) { return item.getRootElement().style.transform = ''; });
1958
+ this._activeDraggables.forEach(function (item) {
1959
+ var rootElement = item.getRootElement();
1960
+ if (rootElement) {
1961
+ rootElement.style.transform = '';
1962
+ }
1963
+ });
1867
1964
  this._siblings.forEach(function (sibling) { return sibling._stopReceiving(_this); });
1868
1965
  this._activeDraggables = [];
1869
1966
  this._itemPositions = [];
@@ -1917,6 +2014,29 @@
1917
2014
  }
1918
2015
  return itemOffset;
1919
2016
  };
2017
+ /**
2018
+ * Checks if pointer is entering in the first position
2019
+ * @param pointerX Position of the user's pointer along the X axis.
2020
+ * @param pointerY Position of the user's pointer along the Y axis.
2021
+ */
2022
+ DropListRef.prototype._shouldEnterAsFirstChild = function (pointerX, pointerY) {
2023
+ if (!this._activeDraggables.length) {
2024
+ return false;
2025
+ }
2026
+ var itemPositions = this._itemPositions;
2027
+ var isHorizontal = this._orientation === 'horizontal';
2028
+ // `itemPositions` are sorted by position while `activeDraggables` are sorted by child index
2029
+ // check if container is using some sort of "reverse" ordering (eg: flex-direction: row-reverse)
2030
+ var reversed = itemPositions[0].drag !== this._activeDraggables[0];
2031
+ if (reversed) {
2032
+ var lastItemRect = itemPositions[itemPositions.length - 1].clientRect;
2033
+ return isHorizontal ? pointerX >= lastItemRect.right : pointerY >= lastItemRect.bottom;
2034
+ }
2035
+ else {
2036
+ var firstItemRect = itemPositions[0].clientRect;
2037
+ return isHorizontal ? pointerX <= firstItemRect.left : pointerY <= firstItemRect.top;
2038
+ }
2039
+ };
1920
2040
  /**
1921
2041
  * Gets the index of an item in the drop container, based on the position of the user's pointer.
1922
2042
  * @param item Item that is being sorted.
@@ -1945,8 +2065,8 @@
1945
2065
  return isHorizontal ?
1946
2066
  // Round these down since most browsers report client rects with
1947
2067
  // sub-pixel precision, whereas the pointer coordinates are rounded to pixels.
1948
- pointerX >= Math.floor(clientRect.left) && pointerX <= Math.floor(clientRect.right) :
1949
- pointerY >= Math.floor(clientRect.top) && pointerY <= Math.floor(clientRect.bottom);
2068
+ pointerX >= Math.floor(clientRect.left) && pointerX < Math.floor(clientRect.right) :
2069
+ pointerY >= Math.floor(clientRect.top) && pointerY < Math.floor(clientRect.bottom);
1950
2070
  });
1951
2071
  };
1952
2072
  /** Caches the current items in the list and their positions. */
@@ -1955,48 +2075,6 @@
1955
2075
  this._cacheItemPositions();
1956
2076
  this._cacheParentPositions();
1957
2077
  };
1958
- /**
1959
- * Updates the internal state of the container after a scroll event has happened.
1960
- * @param scrolledParent Element that was scrolled.
1961
- * @param newTop New top scroll position.
1962
- * @param newLeft New left scroll position.
1963
- */
1964
- DropListRef.prototype._updateAfterScroll = function (scrolledParent, newTop, newLeft) {
1965
- var _this = this;
1966
- // Used when figuring out whether an element is inside the scroll parent. If the scrolled
1967
- // parent is the `document`, we use the `documentElement`, because IE doesn't support `contains`
1968
- // on the `document`.
1969
- var scrolledParentNode = scrolledParent === this._document ? scrolledParent.documentElement : scrolledParent;
1970
- var scrollPosition = this._parentPositions.get(scrolledParent).scrollPosition;
1971
- var topDifference = scrollPosition.top - newTop;
1972
- var leftDifference = scrollPosition.left - newLeft;
1973
- // Go through and update the cached positions of the scroll
1974
- // parents that are inside the element that was scrolled.
1975
- this._parentPositions.forEach(function (position, node) {
1976
- if (position.clientRect && scrolledParent !== node && scrolledParentNode.contains(node)) {
1977
- adjustClientRect(position.clientRect, topDifference, leftDifference);
1978
- }
1979
- });
1980
- // Since we know the amount that the user has scrolled we can shift all of the client rectangles
1981
- // ourselves. This is cheaper than re-measuring everything and we can avoid inconsistent
1982
- // behavior where we might be measuring the element before its position has changed.
1983
- this._itemPositions.forEach(function (_a) {
1984
- var clientRect = _a.clientRect;
1985
- adjustClientRect(clientRect, topDifference, leftDifference);
1986
- });
1987
- // We need two loops for this, because we want all of the cached
1988
- // positions to be up-to-date before we re-sort the item.
1989
- this._itemPositions.forEach(function (_a) {
1990
- var drag = _a.drag;
1991
- if (_this._dragDropRegistry.isDragging(drag)) {
1992
- // We need to re-sort the item manually, because the pointer move
1993
- // events won't be dispatched while the user is scrolling.
1994
- drag._sortFromLastPointerPosition();
1995
- }
1996
- });
1997
- scrollPosition.top = newTop;
1998
- scrollPosition.left = newLeft;
1999
- };
2000
2078
  /**
2001
2079
  * Checks whether the user's pointer is positioned over the container.
2002
2080
  * @param x Pointer position along the X axis.
@@ -2068,21 +2146,26 @@
2068
2146
  var _this = this;
2069
2147
  this._viewportScrollSubscription = this._dragDropRegistry.scroll.subscribe(function (event) {
2070
2148
  if (_this.isDragging()) {
2071
- var target = event.target;
2072
- var position = _this._parentPositions.get(target);
2073
- if (position) {
2074
- var newTop = void 0;
2075
- var newLeft = void 0;
2076
- if (target === _this._document) {
2077
- var scrollPosition = _this._viewportRuler.getViewportScrollPosition();
2078
- newTop = scrollPosition.top;
2079
- newLeft = scrollPosition.left;
2080
- }
2081
- else {
2082
- newTop = target.scrollTop;
2083
- newLeft = target.scrollLeft;
2084
- }
2085
- _this._updateAfterScroll(target, newTop, newLeft);
2149
+ var scrollDifference_1 = _this._parentPositions.handleScroll(event);
2150
+ if (scrollDifference_1) {
2151
+ // Since we know the amount that the user has scrolled we can shift all of the
2152
+ // client rectangles ourselves. This is cheaper than re-measuring everything and
2153
+ // we can avoid inconsistent behavior where we might be measuring the element before
2154
+ // its position has changed.
2155
+ _this._itemPositions.forEach(function (_a) {
2156
+ var clientRect = _a.clientRect;
2157
+ adjustClientRect(clientRect, scrollDifference_1.top, scrollDifference_1.left);
2158
+ });
2159
+ // We need two loops for this, because we want all of the cached
2160
+ // positions to be up-to-date before we re-sort the item.
2161
+ _this._itemPositions.forEach(function (_a) {
2162
+ var drag = _a.drag;
2163
+ if (_this._dragDropRegistry.isDragging(drag)) {
2164
+ // We need to re-sort the item manually, because the pointer move
2165
+ // events won't be dispatched while the user is scrolling.
2166
+ drag._sortFromLastPointerPosition();
2167
+ }
2168
+ });
2086
2169
  }
2087
2170
  }
2088
2171
  else if (_this.isReceiving()) {
@@ -3353,6 +3436,7 @@
3353
3436
  CdkDragPlaceholder,
3354
3437
  ],
3355
3438
  exports: [
3439
+ i2.CdkScrollableModule,
3356
3440
  CdkDropList,
3357
3441
  CdkDropListGroup,
3358
3442
  CdkDrag,