@angular/cdk 11.0.2 → 11.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/LICENSE +1 -1
  2. package/a11y/aria-describer/aria-describer.d.ts +9 -14
  3. package/a11y/focus-monitor/focus-monitor.d.ts +6 -0
  4. package/a11y/index.metadata.json +1 -1
  5. package/bundles/cdk-a11y.umd.js +83 -66
  6. package/bundles/cdk-a11y.umd.js.map +1 -1
  7. package/bundles/cdk-a11y.umd.min.js +13 -21
  8. package/bundles/cdk-a11y.umd.min.js.map +1 -1
  9. package/bundles/cdk-accordion.umd.js.map +1 -1
  10. package/bundles/cdk-bidi.umd.js.map +1 -1
  11. package/bundles/cdk-coercion.umd.js +9 -1
  12. package/bundles/cdk-coercion.umd.js.map +1 -1
  13. package/bundles/cdk-coercion.umd.min.js.map +1 -1
  14. package/bundles/cdk-collections.umd.js +9 -1
  15. package/bundles/cdk-collections.umd.js.map +1 -1
  16. package/bundles/cdk-collections.umd.min.js +1 -1
  17. package/bundles/cdk-collections.umd.min.js.map +1 -1
  18. package/bundles/cdk-drag-drop.umd.js +96 -50
  19. package/bundles/cdk-drag-drop.umd.js.map +1 -1
  20. package/bundles/cdk-drag-drop.umd.min.js +8 -8
  21. package/bundles/cdk-drag-drop.umd.min.js.map +1 -1
  22. package/bundles/cdk-overlay.umd.js +48 -10
  23. package/bundles/cdk-overlay.umd.js.map +1 -1
  24. package/bundles/cdk-overlay.umd.min.js +18 -25
  25. package/bundles/cdk-overlay.umd.min.js.map +1 -1
  26. package/bundles/cdk-platform.umd.js +1 -0
  27. package/bundles/cdk-platform.umd.js.map +1 -1
  28. package/bundles/cdk-platform.umd.min.js +1 -1
  29. package/bundles/cdk-platform.umd.min.js.map +1 -1
  30. package/bundles/cdk-portal.umd.js +9 -1
  31. package/bundles/cdk-portal.umd.js.map +1 -1
  32. package/bundles/cdk-portal.umd.min.js +2 -2
  33. package/bundles/cdk-portal.umd.min.js.map +1 -1
  34. package/bundles/cdk-scrolling.umd.js +25 -11
  35. package/bundles/cdk-scrolling.umd.js.map +1 -1
  36. package/bundles/cdk-scrolling.umd.min.js +4 -4
  37. package/bundles/cdk-scrolling.umd.min.js.map +1 -1
  38. package/bundles/cdk-table.umd.js +99 -30
  39. package/bundles/cdk-table.umd.js.map +1 -1
  40. package/bundles/cdk-table.umd.min.js +7 -7
  41. package/bundles/cdk-table.umd.min.js.map +1 -1
  42. package/bundles/cdk-testing-protractor.umd.js +59 -13
  43. package/bundles/cdk-testing-protractor.umd.js.map +1 -1
  44. package/bundles/cdk-testing-protractor.umd.min.js +2 -2
  45. package/bundles/cdk-testing-protractor.umd.min.js.map +1 -1
  46. package/bundles/cdk-testing-testbed.umd.js +40 -15
  47. package/bundles/cdk-testing-testbed.umd.js.map +1 -1
  48. package/bundles/cdk-testing-testbed.umd.min.js +7 -7
  49. package/bundles/cdk-testing-testbed.umd.min.js.map +1 -1
  50. package/bundles/cdk-testing.umd.js +11 -10
  51. package/bundles/cdk-testing.umd.js.map +1 -1
  52. package/bundles/cdk-testing.umd.min.js +2 -2
  53. package/bundles/cdk-testing.umd.min.js.map +1 -1
  54. package/bundles/cdk-tree.umd.js +9 -1
  55. package/bundles/cdk-tree.umd.js.map +1 -1
  56. package/bundles/cdk-tree.umd.min.js +5 -5
  57. package/bundles/cdk-tree.umd.min.js.map +1 -1
  58. package/bundles/cdk.umd.js +1 -1
  59. package/bundles/cdk.umd.js.map +1 -1
  60. package/bundles/cdk.umd.min.js +1 -1
  61. package/bundles/cdk.umd.min.js.map +1 -1
  62. package/drag-drop/directives/drag.d.ts +1 -1
  63. package/drag-drop/directives/drop-list.d.ts +4 -1
  64. package/drag-drop/drag-drop-registry.d.ts +8 -1
  65. package/drag-drop/drag-ref.d.ts +2 -0
  66. package/drag-drop/drop-list-ref.d.ts +7 -1
  67. package/drag-drop/index.metadata.json +1 -1
  68. package/esm2015/a11y/aria-describer/aria-describer.js +50 -55
  69. package/esm2015/a11y/focus-monitor/focus-monitor.js +18 -3
  70. package/esm2015/drag-drop/directives/drag.js +6 -4
  71. package/esm2015/drag-drop/directives/drop-list.js +4 -2
  72. package/esm2015/drag-drop/drag-drop-registry.js +25 -12
  73. package/esm2015/drag-drop/drag-ref.js +10 -8
  74. package/esm2015/drag-drop/drop-list-ref.js +46 -28
  75. package/esm2015/overlay/position/flexible-connected-position-strategy.js +25 -3
  76. package/esm2015/overlay/scroll/block-scroll-strategy.js +13 -4
  77. package/esm2015/platform/features/scrolling.js +2 -1
  78. package/esm2015/scrolling/fixed-size-virtual-scroll.js +3 -2
  79. package/esm2015/scrolling/scroll-dispatcher.js +9 -8
  80. package/esm2015/scrolling/virtual-for-of.js +8 -4
  81. package/esm2015/scrolling/virtual-scroll-viewport.js +1 -1
  82. package/esm2015/table/public-api.js +2 -1
  83. package/esm2015/table/sticky-position-listener.js +11 -0
  84. package/esm2015/table/sticky-styler.js +60 -14
  85. package/esm2015/table/table.js +9 -4
  86. package/esm2015/testing/change-detection.js +1 -8
  87. package/esm2015/testing/harness-environment.js +3 -3
  88. package/esm2015/testing/protractor/protractor-element.js +29 -13
  89. package/esm2015/testing/test-element.js +1 -1
  90. package/esm2015/testing/testbed/fake-events/dispatch-events.js +3 -3
  91. package/esm2015/testing/testbed/fake-events/event-objects.js +6 -6
  92. package/esm2015/testing/testbed/unit-test-element.js +21 -9
  93. package/esm2015/tree/nested-node.js +1 -1
  94. package/esm2015/tree/padding.js +1 -1
  95. package/esm2015/tree/toggle.js +1 -1
  96. package/esm2015/tree/tree.js +1 -1
  97. package/esm2015/version.js +1 -1
  98. package/fesm2015/a11y.js +67 -55
  99. package/fesm2015/a11y.js.map +1 -1
  100. package/fesm2015/accordion.js.map +1 -1
  101. package/fesm2015/bidi.js.map +1 -1
  102. package/fesm2015/cdk.js +1 -1
  103. package/fesm2015/cdk.js.map +1 -1
  104. package/fesm2015/drag-drop.js +85 -48
  105. package/fesm2015/drag-drop.js.map +1 -1
  106. package/fesm2015/overlay.js +36 -6
  107. package/fesm2015/overlay.js.map +1 -1
  108. package/fesm2015/platform.js +1 -0
  109. package/fesm2015/platform.js.map +1 -1
  110. package/fesm2015/scrolling.js +17 -12
  111. package/fesm2015/scrolling.js.map +1 -1
  112. package/fesm2015/table.js +77 -17
  113. package/fesm2015/table.js.map +1 -1
  114. package/fesm2015/testing/protractor.js +27 -11
  115. package/fesm2015/testing/protractor.js.map +1 -1
  116. package/fesm2015/testing/testbed.js +25 -13
  117. package/fesm2015/testing/testbed.js.map +1 -1
  118. package/fesm2015/testing.js +2 -9
  119. package/fesm2015/testing.js.map +1 -1
  120. package/fesm2015/tree.js.map +1 -1
  121. package/overlay/index.metadata.json +1 -1
  122. package/package.json +1 -1
  123. package/schematics/ng-add/index.js +1 -1
  124. package/scrolling/index.metadata.json +1 -1
  125. package/scrolling/scroll-dispatcher.d.ts +3 -3
  126. package/table/index.metadata.json +1 -1
  127. package/table/public-api.d.ts +1 -0
  128. package/table/sticky-position-listener.d.ts +28 -0
  129. package/table/sticky-styler.d.ts +7 -2
  130. package/table/table.d.ts +4 -2
  131. package/testing/change-detection.d.ts +44 -1
  132. package/testing/protractor/protractor-element.d.ts +12 -4
  133. package/testing/test-element.d.ts +11 -5
  134. package/testing/testbed/fake-events/dispatch-events.d.ts +1 -1
  135. package/testing/testbed/fake-events/event-objects.d.ts +1 -1
  136. package/testing/testbed/unit-test-element.d.ts +12 -4
  137. package/tree/index.metadata.json +1 -1
  138. package/tree/nested-node.d.ts +3 -3
  139. package/tree/padding.d.ts +2 -2
  140. package/tree/toggle.d.ts +4 -4
  141. package/tree/tree.d.ts +5 -5
package/fesm2015/a11y.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { DOCUMENT } from '@angular/common';
2
2
  import { ɵɵdefineInjectable, ɵɵinject, Injectable, Inject, QueryList, NgZone, Directive, ElementRef, Input, InjectionToken, Optional, EventEmitter, Output, NgModule } from '@angular/core';
3
- import { Platform, normalizePassiveListenerOptions, _getShadowRoot, PlatformModule } from '@angular/cdk/platform';
4
3
  import { Subject, Subscription, of } from 'rxjs';
5
4
  import { hasModifierKey, A, Z, ZERO, NINE, END, HOME, LEFT_ARROW, RIGHT_ARROW, UP_ARROW, DOWN_ARROW, TAB } from '@angular/cdk/keycodes';
6
5
  import { tap, debounceTime, filter, map, take } from 'rxjs/operators';
7
6
  import { coerceBooleanProperty, coerceElement } from '@angular/cdk/coercion';
7
+ import { Platform, normalizePassiveListenerOptions, _getShadowRoot, PlatformModule } from '@angular/cdk/platform';
8
8
  import { ContentObserver, ObserversModule } from '@angular/cdk/observers';
9
9
 
10
10
  /**
@@ -76,49 +76,40 @@ let messagesContainer = null;
76
76
  * content.
77
77
  */
78
78
  class AriaDescriber {
79
- constructor(_document,
80
- /**
81
- * @breaking-change 8.0.0 `_platform` parameter to be made required.
82
- */
83
- _platform) {
84
- this._platform = _platform;
79
+ constructor(_document) {
85
80
  this._document = _document;
86
81
  }
87
- /**
88
- * Adds to the host element an aria-describedby reference to a hidden element that contains
89
- * the message. If the same message has already been registered, then it will reuse the created
90
- * message element.
91
- */
92
- describe(hostElement, message) {
82
+ describe(hostElement, message, role) {
93
83
  if (!this._canBeDescribed(hostElement, message)) {
94
84
  return;
95
85
  }
86
+ const key = getKey(message, role);
96
87
  if (typeof message !== 'string') {
97
88
  // We need to ensure that the element has an ID.
98
- this._setMessageId(message);
99
- messageRegistry.set(message, { messageElement: message, referenceCount: 0 });
89
+ setMessageId(message);
90
+ messageRegistry.set(key, { messageElement: message, referenceCount: 0 });
100
91
  }
101
- else if (!messageRegistry.has(message)) {
102
- this._createMessageElement(message);
92
+ else if (!messageRegistry.has(key)) {
93
+ this._createMessageElement(message, role);
103
94
  }
104
- if (!this._isElementDescribedByMessage(hostElement, message)) {
105
- this._addMessageReference(hostElement, message);
95
+ if (!this._isElementDescribedByMessage(hostElement, key)) {
96
+ this._addMessageReference(hostElement, key);
106
97
  }
107
98
  }
108
- /** Removes the host element's aria-describedby reference to the message element. */
109
- removeDescription(hostElement, message) {
99
+ removeDescription(hostElement, message, role) {
110
100
  if (!message || !this._isElementNode(hostElement)) {
111
101
  return;
112
102
  }
113
- if (this._isElementDescribedByMessage(hostElement, message)) {
114
- this._removeMessageReference(hostElement, message);
103
+ const key = getKey(message, role);
104
+ if (this._isElementDescribedByMessage(hostElement, key)) {
105
+ this._removeMessageReference(hostElement, key);
115
106
  }
116
107
  // If the message is a string, it means that it's one that we created for the
117
108
  // consumer so we can remove it safely, otherwise we should leave it in place.
118
109
  if (typeof message === 'string') {
119
- const registeredMessage = messageRegistry.get(message);
110
+ const registeredMessage = messageRegistry.get(key);
120
111
  if (registeredMessage && registeredMessage.referenceCount === 0) {
121
- this._deleteMessageElement(message);
112
+ this._deleteMessageElement(key);
122
113
  }
123
114
  }
124
115
  if (messagesContainer && messagesContainer.childNodes.length === 0) {
@@ -141,34 +132,29 @@ class AriaDescriber {
141
132
  * Creates a new element in the visually hidden message container element with the message
142
133
  * as its content and adds it to the message registry.
143
134
  */
144
- _createMessageElement(message) {
135
+ _createMessageElement(message, role) {
145
136
  const messageElement = this._document.createElement('div');
146
- this._setMessageId(messageElement);
137
+ setMessageId(messageElement);
147
138
  messageElement.textContent = message;
139
+ if (role) {
140
+ messageElement.setAttribute('role', role);
141
+ }
148
142
  this._createMessagesContainer();
149
143
  messagesContainer.appendChild(messageElement);
150
- messageRegistry.set(message, { messageElement, referenceCount: 0 });
151
- }
152
- /** Assigns a unique ID to an element, if it doesn't have one already. */
153
- _setMessageId(element) {
154
- if (!element.id) {
155
- element.id = `${CDK_DESCRIBEDBY_ID_PREFIX}-${nextId++}`;
156
- }
144
+ messageRegistry.set(getKey(message, role), { messageElement, referenceCount: 0 });
157
145
  }
158
146
  /** Deletes the message element from the global messages container. */
159
- _deleteMessageElement(message) {
160
- const registeredMessage = messageRegistry.get(message);
147
+ _deleteMessageElement(key) {
148
+ const registeredMessage = messageRegistry.get(key);
161
149
  const messageElement = registeredMessage && registeredMessage.messageElement;
162
150
  if (messagesContainer && messageElement) {
163
151
  messagesContainer.removeChild(messageElement);
164
152
  }
165
- messageRegistry.delete(message);
153
+ messageRegistry.delete(key);
166
154
  }
167
155
  /** Creates the global container for all aria-describedby messages. */
168
156
  _createMessagesContainer() {
169
157
  if (!messagesContainer) {
170
- // @breaking-change 8.0.0 `_platform` null check can be removed once the parameter is required
171
- const canBeAriaHidden = !this._platform || (!this._platform.EDGE && !this._platform.TRIDENT);
172
158
  const preExistingContainer = this._document.getElementById(MESSAGES_CONTAINER_ID);
173
159
  // When going from the server to the client, we may end up in a situation where there's
174
160
  // already a container on the page, but we don't have a reference to it. Clear the
@@ -179,12 +165,14 @@ class AriaDescriber {
179
165
  }
180
166
  messagesContainer = this._document.createElement('div');
181
167
  messagesContainer.id = MESSAGES_CONTAINER_ID;
168
+ // We add `visibility: hidden` in order to prevent text in this container from
169
+ // being searchable by the browser's Ctrl + F functionality.
170
+ // Screen-readers will still read the description for elements with aria-describedby even
171
+ // when the description element is not visible.
172
+ messagesContainer.style.visibility = 'hidden';
173
+ // Even though we use `visibility: hidden`, we still apply `cdk-visually-hidden` so that
174
+ // the description element doesn't impact page layout.
182
175
  messagesContainer.classList.add('cdk-visually-hidden');
183
- // IE and Edge won't read out the messages if they're in an `aria-hidden` container.
184
- // We only disable `aria-hidden` for these platforms, because it comes with the
185
- // disadvantage that people might hit the messages when they've navigated past
186
- // the end of the document using the arrow keys.
187
- messagesContainer.setAttribute('aria-hidden', canBeAriaHidden + '');
188
176
  this._document.body.appendChild(messagesContainer);
189
177
  }
190
178
  }
@@ -206,8 +194,8 @@ class AriaDescriber {
206
194
  * Adds a message reference to the element using aria-describedby and increments the registered
207
195
  * message's reference count.
208
196
  */
209
- _addMessageReference(element, message) {
210
- const registeredMessage = messageRegistry.get(message);
197
+ _addMessageReference(element, key) {
198
+ const registeredMessage = messageRegistry.get(key);
211
199
  // Add the aria-describedby reference and set the
212
200
  // describedby_host attribute to mark the element.
213
201
  addAriaReferencedId(element, 'aria-describedby', registeredMessage.messageElement.id);
@@ -218,16 +206,16 @@ class AriaDescriber {
218
206
  * Removes a message reference from the element using aria-describedby
219
207
  * and decrements the registered message's reference count.
220
208
  */
221
- _removeMessageReference(element, message) {
222
- const registeredMessage = messageRegistry.get(message);
209
+ _removeMessageReference(element, key) {
210
+ const registeredMessage = messageRegistry.get(key);
223
211
  registeredMessage.referenceCount--;
224
212
  removeAriaReferencedId(element, 'aria-describedby', registeredMessage.messageElement.id);
225
213
  element.removeAttribute(CDK_DESCRIBEDBY_HOST_ATTRIBUTE);
226
214
  }
227
215
  /** Returns true if the element has been described by the provided message ID. */
228
- _isElementDescribedByMessage(element, message) {
216
+ _isElementDescribedByMessage(element, key) {
229
217
  const referenceIds = getAriaReferenceIds(element, 'aria-describedby');
230
- const registeredMessage = messageRegistry.get(message);
218
+ const registeredMessage = messageRegistry.get(key);
231
219
  const messageId = registeredMessage && registeredMessage.messageElement.id;
232
220
  return !!messageId && referenceIds.indexOf(messageId) != -1;
233
221
  }
@@ -253,14 +241,23 @@ class AriaDescriber {
253
241
  return element.nodeType === this._document.ELEMENT_NODE;
254
242
  }
255
243
  }
256
- AriaDescriber.ɵprov = ɵɵdefineInjectable({ factory: function AriaDescriber_Factory() { return new AriaDescriber(ɵɵinject(DOCUMENT), ɵɵinject(Platform)); }, token: AriaDescriber, providedIn: "root" });
244
+ AriaDescriber.ɵprov = ɵɵdefineInjectable({ factory: function AriaDescriber_Factory() { return new AriaDescriber(ɵɵinject(DOCUMENT)); }, token: AriaDescriber, providedIn: "root" });
257
245
  AriaDescriber.decorators = [
258
246
  { type: Injectable, args: [{ providedIn: 'root' },] }
259
247
  ];
260
248
  AriaDescriber.ctorParameters = () => [
261
- { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
262
- { type: Platform }
249
+ { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
263
250
  ];
251
+ /** Gets a key that can be used to look messages up in the registry. */
252
+ function getKey(message, role) {
253
+ return typeof message === 'string' ? `${role || ''}/${message}` : message;
254
+ }
255
+ /** Assigns a unique ID to an element, if it doesn't have one already. */
256
+ function setMessageId(element) {
257
+ if (!element.id) {
258
+ element.id = `${CDK_DESCRIBEDBY_ID_PREFIX}-${nextId++}`;
259
+ }
260
+ }
264
261
 
265
262
  /**
266
263
  * @license
@@ -1852,8 +1849,9 @@ class FocusMonitor {
1852
1849
  // If the element is focused already, calling `focus` again won't trigger the event listener
1853
1850
  // which means that the focus classes won't be updated. If that's the case, update the classes
1854
1851
  // directly without waiting for an event.
1855
- if (nativeElement === focusedElement && this._elementInfo.has(nativeElement)) {
1856
- this._originChanged(nativeElement, origin, this._elementInfo.get(nativeElement));
1852
+ if (nativeElement === focusedElement) {
1853
+ this._getClosestElementsInfo(nativeElement)
1854
+ .forEach(([currentElement, info]) => this._originChanged(currentElement, origin, info));
1857
1855
  }
1858
1856
  else {
1859
1857
  this._setOriginForCurrentEventQueue(origin);
@@ -2055,6 +2053,20 @@ class FocusMonitor {
2055
2053
  this._emitOrigin(elementInfo.subject, origin);
2056
2054
  this._lastFocusOrigin = origin;
2057
2055
  }
2056
+ /**
2057
+ * Collects the `MonitoredElementInfo` of a particular element and
2058
+ * all of its ancestors that have enabled `checkChildren`.
2059
+ * @param element Element from which to start the search.
2060
+ */
2061
+ _getClosestElementsInfo(element) {
2062
+ const results = [];
2063
+ this._elementInfo.forEach((info, currentElement) => {
2064
+ if (currentElement === element || (info.checkChildren && currentElement.contains(element))) {
2065
+ results.push([currentElement, info]);
2066
+ }
2067
+ });
2068
+ return results;
2069
+ }
2058
2070
  }
2059
2071
  FocusMonitor.ɵprov = ɵɵdefineInjectable({ factory: function FocusMonitor_Factory() { return new FocusMonitor(ɵɵinject(NgZone), ɵɵinject(Platform), ɵɵinject(DOCUMENT, 8), ɵɵinject(FOCUS_MONITOR_DEFAULT_OPTIONS, 8)); }, token: FocusMonitor, providedIn: "root" });
2060
2072
  FocusMonitor.decorators = [