source: trip-planner-front/node_modules/@angular/cdk/bundles/cdk-overlay.umd.js@ e29cc2e

Last change on this file since e29cc2e was e29cc2e, checked in by Ema <ema_spirova@…>, 3 years ago

primeNG components

  • Property mode set to 100644
File size: 177.1 KB
RevLine 
[6a3a178]1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/cdk/scrolling'), require('@angular/common'), require('@angular/core'), require('@angular/cdk/coercion'), require('@angular/cdk/platform'), require('@angular/cdk/bidi'), require('@angular/cdk/portal'), require('rxjs'), require('rxjs/operators'), require('@angular/cdk/keycodes')) :
3 typeof define === 'function' && define.amd ? define('@angular/cdk/overlay', ['exports', '@angular/cdk/scrolling', '@angular/common', '@angular/core', '@angular/cdk/coercion', '@angular/cdk/platform', '@angular/cdk/bidi', '@angular/cdk/portal', 'rxjs', 'rxjs/operators', '@angular/cdk/keycodes'], factory) :
4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.ng = global.ng || {}, global.ng.cdk = global.ng.cdk || {}, global.ng.cdk.overlay = {}), global.ng.cdk.scrolling, global.ng.common, global.ng.core, global.ng.cdk.coercion, global.ng.cdk.platform, global.ng.cdk.bidi, global.ng.cdk.portal, global.rxjs, global.rxjs.operators, global.ng.cdk.keycodes));
5}(this, (function (exports, i1, i1$1, i0, coercion, i2, bidi, portal, rxjs, operators, keycodes) { 'use strict';
6
7 function _interopNamespace(e) {
8 if (e && e.__esModule) return e;
9 var n = Object.create(null);
10 if (e) {
11 Object.keys(e).forEach(function (k) {
12 if (k !== 'default') {
13 var d = Object.getOwnPropertyDescriptor(e, k);
14 Object.defineProperty(n, k, d.get ? d : {
15 enumerable: true,
16 get: function () {
17 return e[k];
18 }
19 });
20 }
21 });
22 }
23 n['default'] = e;
24 return Object.freeze(n);
25 }
26
27 var i1__namespace = /*#__PURE__*/_interopNamespace(i1);
28 var i1__namespace$1 = /*#__PURE__*/_interopNamespace(i1$1);
29 var i0__namespace = /*#__PURE__*/_interopNamespace(i0);
30 var i2__namespace = /*#__PURE__*/_interopNamespace(i2);
31
32 /*! *****************************************************************************
33 Copyright (c) Microsoft Corporation.
34
35 Permission to use, copy, modify, and/or distribute this software for any
36 purpose with or without fee is hereby granted.
37
38 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
39 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
40 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
41 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
42 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
43 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
44 PERFORMANCE OF THIS SOFTWARE.
45 ***************************************************************************** */
46 /* global Reflect, Promise */
47 var extendStatics = function (d, b) {
48 extendStatics = Object.setPrototypeOf ||
49 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
50 function (d, b) { for (var p in b)
51 if (Object.prototype.hasOwnProperty.call(b, p))
52 d[p] = b[p]; };
53 return extendStatics(d, b);
54 };
55 function __extends(d, b) {
56 if (typeof b !== "function" && b !== null)
57 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
58 extendStatics(d, b);
59 function __() { this.constructor = d; }
60 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
61 }
62 var __assign = function () {
63 __assign = Object.assign || function __assign(t) {
64 for (var s, i = 1, n = arguments.length; i < n; i++) {
65 s = arguments[i];
66 for (var p in s)
67 if (Object.prototype.hasOwnProperty.call(s, p))
68 t[p] = s[p];
69 }
70 return t;
71 };
72 return __assign.apply(this, arguments);
73 };
74 function __rest(s, e) {
75 var t = {};
76 for (var p in s)
77 if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
78 t[p] = s[p];
79 if (s != null && typeof Object.getOwnPropertySymbols === "function")
80 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
81 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
82 t[p[i]] = s[p[i]];
83 }
84 return t;
85 }
86 function __decorate(decorators, target, key, desc) {
87 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
88 if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
89 r = Reflect.decorate(decorators, target, key, desc);
90 else
91 for (var i = decorators.length - 1; i >= 0; i--)
92 if (d = decorators[i])
93 r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
94 return c > 3 && r && Object.defineProperty(target, key, r), r;
95 }
96 function __param(paramIndex, decorator) {
97 return function (target, key) { decorator(target, key, paramIndex); };
98 }
99 function __metadata(metadataKey, metadataValue) {
100 if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
101 return Reflect.metadata(metadataKey, metadataValue);
102 }
103 function __awaiter(thisArg, _arguments, P, generator) {
104 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
105 return new (P || (P = Promise))(function (resolve, reject) {
106 function fulfilled(value) { try {
107 step(generator.next(value));
108 }
109 catch (e) {
110 reject(e);
111 } }
112 function rejected(value) { try {
113 step(generator["throw"](value));
114 }
115 catch (e) {
116 reject(e);
117 } }
118 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
119 step((generator = generator.apply(thisArg, _arguments || [])).next());
120 });
121 }
122 function __generator(thisArg, body) {
123 var _ = { label: 0, sent: function () { if (t[0] & 1)
124 throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
125 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g;
126 function verb(n) { return function (v) { return step([n, v]); }; }
127 function step(op) {
128 if (f)
129 throw new TypeError("Generator is already executing.");
130 while (_)
131 try {
132 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done)
133 return t;
134 if (y = 0, t)
135 op = [op[0] & 2, t.value];
136 switch (op[0]) {
137 case 0:
138 case 1:
139 t = op;
140 break;
141 case 4:
142 _.label++;
143 return { value: op[1], done: false };
144 case 5:
145 _.label++;
146 y = op[1];
147 op = [0];
148 continue;
149 case 7:
150 op = _.ops.pop();
151 _.trys.pop();
152 continue;
153 default:
154 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
155 _ = 0;
156 continue;
157 }
158 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) {
159 _.label = op[1];
160 break;
161 }
162 if (op[0] === 6 && _.label < t[1]) {
163 _.label = t[1];
164 t = op;
165 break;
166 }
167 if (t && _.label < t[2]) {
168 _.label = t[2];
169 _.ops.push(op);
170 break;
171 }
172 if (t[2])
173 _.ops.pop();
174 _.trys.pop();
175 continue;
176 }
177 op = body.call(thisArg, _);
178 }
179 catch (e) {
180 op = [6, e];
181 y = 0;
182 }
183 finally {
184 f = t = 0;
185 }
186 if (op[0] & 5)
187 throw op[1];
188 return { value: op[0] ? op[1] : void 0, done: true };
189 }
190 }
191 var __createBinding = Object.create ? (function (o, m, k, k2) {
192 if (k2 === undefined)
193 k2 = k;
194 Object.defineProperty(o, k2, { enumerable: true, get: function () { return m[k]; } });
195 }) : (function (o, m, k, k2) {
196 if (k2 === undefined)
197 k2 = k;
198 o[k2] = m[k];
199 });
200 function __exportStar(m, o) {
201 for (var p in m)
202 if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p))
203 __createBinding(o, m, p);
204 }
205 function __values(o) {
206 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
207 if (m)
208 return m.call(o);
209 if (o && typeof o.length === "number")
210 return {
211 next: function () {
212 if (o && i >= o.length)
213 o = void 0;
214 return { value: o && o[i++], done: !o };
215 }
216 };
217 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
218 }
219 function __read(o, n) {
220 var m = typeof Symbol === "function" && o[Symbol.iterator];
221 if (!m)
222 return o;
223 var i = m.call(o), r, ar = [], e;
224 try {
225 while ((n === void 0 || n-- > 0) && !(r = i.next()).done)
226 ar.push(r.value);
227 }
228 catch (error) {
229 e = { error: error };
230 }
231 finally {
232 try {
233 if (r && !r.done && (m = i["return"]))
234 m.call(i);
235 }
236 finally {
237 if (e)
238 throw e.error;
239 }
240 }
241 return ar;
242 }
243 /** @deprecated */
244 function __spread() {
245 for (var ar = [], i = 0; i < arguments.length; i++)
246 ar = ar.concat(__read(arguments[i]));
247 return ar;
248 }
249 /** @deprecated */
250 function __spreadArrays() {
251 for (var s = 0, i = 0, il = arguments.length; i < il; i++)
252 s += arguments[i].length;
253 for (var r = Array(s), k = 0, i = 0; i < il; i++)
254 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
255 r[k] = a[j];
256 return r;
257 }
258 function __spreadArray(to, from, pack) {
259 if (pack || arguments.length === 2)
260 for (var i = 0, l = from.length, ar; i < l; i++) {
261 if (ar || !(i in from)) {
262 if (!ar)
263 ar = Array.prototype.slice.call(from, 0, i);
264 ar[i] = from[i];
265 }
266 }
267 return to.concat(ar || from);
268 }
269 function __await(v) {
270 return this instanceof __await ? (this.v = v, this) : new __await(v);
271 }
272 function __asyncGenerator(thisArg, _arguments, generator) {
273 if (!Symbol.asyncIterator)
274 throw new TypeError("Symbol.asyncIterator is not defined.");
275 var g = generator.apply(thisArg, _arguments || []), i, q = [];
276 return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
277 function verb(n) { if (g[n])
278 i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
279 function resume(n, v) { try {
280 step(g[n](v));
281 }
282 catch (e) {
283 settle(q[0][3], e);
284 } }
285 function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
286 function fulfill(value) { resume("next", value); }
287 function reject(value) { resume("throw", value); }
288 function settle(f, v) { if (f(v), q.shift(), q.length)
289 resume(q[0][0], q[0][1]); }
290 }
291 function __asyncDelegator(o) {
292 var i, p;
293 return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
294 function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
295 }
296 function __asyncValues(o) {
297 if (!Symbol.asyncIterator)
298 throw new TypeError("Symbol.asyncIterator is not defined.");
299 var m = o[Symbol.asyncIterator], i;
300 return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
301 function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
302 function settle(resolve, reject, d, v) { Promise.resolve(v).then(function (v) { resolve({ value: v, done: d }); }, reject); }
303 }
304 function __makeTemplateObject(cooked, raw) {
305 if (Object.defineProperty) {
306 Object.defineProperty(cooked, "raw", { value: raw });
307 }
308 else {
309 cooked.raw = raw;
310 }
311 return cooked;
312 }
313 ;
314 var __setModuleDefault = Object.create ? (function (o, v) {
315 Object.defineProperty(o, "default", { enumerable: true, value: v });
316 }) : function (o, v) {
317 o["default"] = v;
318 };
319 function __importStar(mod) {
320 if (mod && mod.__esModule)
321 return mod;
322 var result = {};
323 if (mod != null)
324 for (var k in mod)
325 if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k))
326 __createBinding(result, mod, k);
327 __setModuleDefault(result, mod);
328 return result;
329 }
330 function __importDefault(mod) {
331 return (mod && mod.__esModule) ? mod : { default: mod };
332 }
333 function __classPrivateFieldGet(receiver, state, kind, f) {
334 if (kind === "a" && !f)
335 throw new TypeError("Private accessor was defined without a getter");
336 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
337 throw new TypeError("Cannot read private member from an object whose class did not declare it");
338 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
339 }
340 function __classPrivateFieldSet(receiver, state, value, kind, f) {
341 if (kind === "m")
342 throw new TypeError("Private method is not writable");
343 if (kind === "a" && !f)
344 throw new TypeError("Private accessor was defined without a setter");
345 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
346 throw new TypeError("Cannot write private member to an object whose class did not declare it");
347 return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
348 }
349
350 /**
351 * @license
352 * Copyright Google LLC All Rights Reserved.
353 *
354 * Use of this source code is governed by an MIT-style license that can be
355 * found in the LICENSE file at https://angular.io/license
356 */
357 var scrollBehaviorSupported = i2.supportsScrollBehavior();
358 /**
359 * Strategy that will prevent the user from scrolling while the overlay is visible.
360 */
361 var BlockScrollStrategy = /** @class */ (function () {
362 function BlockScrollStrategy(_viewportRuler, document) {
363 this._viewportRuler = _viewportRuler;
364 this._previousHTMLStyles = { top: '', left: '' };
365 this._isEnabled = false;
366 this._document = document;
367 }
368 /** Attaches this scroll strategy to an overlay. */
369 BlockScrollStrategy.prototype.attach = function () { };
370 /** Blocks page-level scroll while the attached overlay is open. */
371 BlockScrollStrategy.prototype.enable = function () {
372 if (this._canBeEnabled()) {
373 var root = this._document.documentElement;
374 this._previousScrollPosition = this._viewportRuler.getViewportScrollPosition();
375 // Cache the previous inline styles in case the user had set them.
376 this._previousHTMLStyles.left = root.style.left || '';
377 this._previousHTMLStyles.top = root.style.top || '';
378 // Note: we're using the `html` node, instead of the `body`, because the `body` may
379 // have the user agent margin, whereas the `html` is guaranteed not to have one.
380 root.style.left = coercion.coerceCssPixelValue(-this._previousScrollPosition.left);
381 root.style.top = coercion.coerceCssPixelValue(-this._previousScrollPosition.top);
382 root.classList.add('cdk-global-scrollblock');
383 this._isEnabled = true;
384 }
385 };
386 /** Unblocks page-level scroll while the attached overlay is open. */
387 BlockScrollStrategy.prototype.disable = function () {
388 if (this._isEnabled) {
389 var html = this._document.documentElement;
390 var body = this._document.body;
391 var htmlStyle = html.style;
392 var bodyStyle = body.style;
393 var previousHtmlScrollBehavior = htmlStyle.scrollBehavior || '';
394 var previousBodyScrollBehavior = bodyStyle.scrollBehavior || '';
395 this._isEnabled = false;
396 htmlStyle.left = this._previousHTMLStyles.left;
397 htmlStyle.top = this._previousHTMLStyles.top;
398 html.classList.remove('cdk-global-scrollblock');
399 // Disable user-defined smooth scrolling temporarily while we restore the scroll position.
400 // See https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior
401 // Note that we don't mutate the property if the browser doesn't support `scroll-behavior`,
402 // because it can throw off feature detections in `supportsScrollBehavior` which
403 // checks for `'scrollBehavior' in documentElement.style`.
404 if (scrollBehaviorSupported) {
405 htmlStyle.scrollBehavior = bodyStyle.scrollBehavior = 'auto';
406 }
407 window.scroll(this._previousScrollPosition.left, this._previousScrollPosition.top);
408 if (scrollBehaviorSupported) {
409 htmlStyle.scrollBehavior = previousHtmlScrollBehavior;
410 bodyStyle.scrollBehavior = previousBodyScrollBehavior;
411 }
412 }
413 };
414 BlockScrollStrategy.prototype._canBeEnabled = function () {
415 // Since the scroll strategies can't be singletons, we have to use a global CSS class
416 // (`cdk-global-scrollblock`) to make sure that we don't try to disable global
417 // scrolling multiple times.
418 var html = this._document.documentElement;
419 if (html.classList.contains('cdk-global-scrollblock') || this._isEnabled) {
420 return false;
421 }
422 var body = this._document.body;
423 var viewport = this._viewportRuler.getViewportSize();
424 return body.scrollHeight > viewport.height || body.scrollWidth > viewport.width;
425 };
426 return BlockScrollStrategy;
427 }());
428
429 /**
430 * @license
431 * Copyright Google LLC All Rights Reserved.
432 *
433 * Use of this source code is governed by an MIT-style license that can be
434 * found in the LICENSE file at https://angular.io/license
435 */
436 /**
437 * Returns an error to be thrown when attempting to attach an already-attached scroll strategy.
438 */
439 function getMatScrollStrategyAlreadyAttachedError() {
440 return Error("Scroll strategy has already been attached.");
441 }
442
443 /**
444 * Strategy that will close the overlay as soon as the user starts scrolling.
445 */
446 var CloseScrollStrategy = /** @class */ (function () {
447 function CloseScrollStrategy(_scrollDispatcher, _ngZone, _viewportRuler, _config) {
448 var _this = this;
449 this._scrollDispatcher = _scrollDispatcher;
450 this._ngZone = _ngZone;
451 this._viewportRuler = _viewportRuler;
452 this._config = _config;
453 this._scrollSubscription = null;
454 /** Detaches the overlay ref and disables the scroll strategy. */
455 this._detach = function () {
456 _this.disable();
457 if (_this._overlayRef.hasAttached()) {
458 _this._ngZone.run(function () { return _this._overlayRef.detach(); });
459 }
460 };
461 }
462 /** Attaches this scroll strategy to an overlay. */
463 CloseScrollStrategy.prototype.attach = function (overlayRef) {
464 if (this._overlayRef && (typeof ngDevMode === 'undefined' || ngDevMode)) {
465 throw getMatScrollStrategyAlreadyAttachedError();
466 }
467 this._overlayRef = overlayRef;
468 };
469 /** Enables the closing of the attached overlay on scroll. */
470 CloseScrollStrategy.prototype.enable = function () {
471 var _this = this;
472 if (this._scrollSubscription) {
473 return;
474 }
475 var stream = this._scrollDispatcher.scrolled(0);
476 if (this._config && this._config.threshold && this._config.threshold > 1) {
477 this._initialScrollPosition = this._viewportRuler.getViewportScrollPosition().top;
478 this._scrollSubscription = stream.subscribe(function () {
479 var scrollPosition = _this._viewportRuler.getViewportScrollPosition().top;
480 if (Math.abs(scrollPosition - _this._initialScrollPosition) > _this._config.threshold) {
481 _this._detach();
482 }
483 else {
484 _this._overlayRef.updatePosition();
485 }
486 });
487 }
488 else {
489 this._scrollSubscription = stream.subscribe(this._detach);
490 }
491 };
492 /** Disables the closing the attached overlay on scroll. */
493 CloseScrollStrategy.prototype.disable = function () {
494 if (this._scrollSubscription) {
495 this._scrollSubscription.unsubscribe();
496 this._scrollSubscription = null;
497 }
498 };
499 CloseScrollStrategy.prototype.detach = function () {
500 this.disable();
501 this._overlayRef = null;
502 };
503 return CloseScrollStrategy;
504 }());
505
506 /**
507 * @license
508 * Copyright Google LLC All Rights Reserved.
509 *
510 * Use of this source code is governed by an MIT-style license that can be
511 * found in the LICENSE file at https://angular.io/license
512 */
513 /** Scroll strategy that doesn't do anything. */
514 var NoopScrollStrategy = /** @class */ (function () {
515 function NoopScrollStrategy() {
516 }
517 /** Does nothing, as this scroll strategy is a no-op. */
518 NoopScrollStrategy.prototype.enable = function () { };
519 /** Does nothing, as this scroll strategy is a no-op. */
520 NoopScrollStrategy.prototype.disable = function () { };
521 /** Does nothing, as this scroll strategy is a no-op. */
522 NoopScrollStrategy.prototype.attach = function () { };
523 return NoopScrollStrategy;
524 }());
525
526 /**
527 * @license
528 * Copyright Google LLC All Rights Reserved.
529 *
530 * Use of this source code is governed by an MIT-style license that can be
531 * found in the LICENSE file at https://angular.io/license
532 */
533 // TODO(jelbourn): move this to live with the rest of the scrolling code
534 // TODO(jelbourn): someday replace this with IntersectionObservers
535 /**
536 * Gets whether an element is scrolled outside of view by any of its parent scrolling containers.
537 * @param element Dimensions of the element (from getBoundingClientRect)
538 * @param scrollContainers Dimensions of element's scrolling containers (from getBoundingClientRect)
539 * @returns Whether the element is scrolled out of view
540 * @docs-private
541 */
542 function isElementScrolledOutsideView(element, scrollContainers) {
543 return scrollContainers.some(function (containerBounds) {
544 var outsideAbove = element.bottom < containerBounds.top;
545 var outsideBelow = element.top > containerBounds.bottom;
546 var outsideLeft = element.right < containerBounds.left;
547 var outsideRight = element.left > containerBounds.right;
548 return outsideAbove || outsideBelow || outsideLeft || outsideRight;
549 });
550 }
551 /**
552 * Gets whether an element is clipped by any of its scrolling containers.
553 * @param element Dimensions of the element (from getBoundingClientRect)
554 * @param scrollContainers Dimensions of element's scrolling containers (from getBoundingClientRect)
555 * @returns Whether the element is clipped
556 * @docs-private
557 */
558 function isElementClippedByScrolling(element, scrollContainers) {
559 return scrollContainers.some(function (scrollContainerRect) {
560 var clippedAbove = element.top < scrollContainerRect.top;
561 var clippedBelow = element.bottom > scrollContainerRect.bottom;
562 var clippedLeft = element.left < scrollContainerRect.left;
563 var clippedRight = element.right > scrollContainerRect.right;
564 return clippedAbove || clippedBelow || clippedLeft || clippedRight;
565 });
566 }
567
568 /**
569 * @license
570 * Copyright Google LLC All Rights Reserved.
571 *
572 * Use of this source code is governed by an MIT-style license that can be
573 * found in the LICENSE file at https://angular.io/license
574 */
575 /**
576 * Strategy that will update the element position as the user is scrolling.
577 */
578 var RepositionScrollStrategy = /** @class */ (function () {
579 function RepositionScrollStrategy(_scrollDispatcher, _viewportRuler, _ngZone, _config) {
580 this._scrollDispatcher = _scrollDispatcher;
581 this._viewportRuler = _viewportRuler;
582 this._ngZone = _ngZone;
583 this._config = _config;
584 this._scrollSubscription = null;
585 }
586 /** Attaches this scroll strategy to an overlay. */
587 RepositionScrollStrategy.prototype.attach = function (overlayRef) {
588 if (this._overlayRef && (typeof ngDevMode === 'undefined' || ngDevMode)) {
589 throw getMatScrollStrategyAlreadyAttachedError();
590 }
591 this._overlayRef = overlayRef;
592 };
593 /** Enables repositioning of the attached overlay on scroll. */
594 RepositionScrollStrategy.prototype.enable = function () {
595 var _this = this;
596 if (!this._scrollSubscription) {
597 var throttle = this._config ? this._config.scrollThrottle : 0;
598 this._scrollSubscription = this._scrollDispatcher.scrolled(throttle).subscribe(function () {
599 _this._overlayRef.updatePosition();
600 // TODO(crisbeto): make `close` on by default once all components can handle it.
601 if (_this._config && _this._config.autoClose) {
602 var overlayRect = _this._overlayRef.overlayElement.getBoundingClientRect();
603 var _a = _this._viewportRuler.getViewportSize(), width = _a.width, height = _a.height;
604 // TODO(crisbeto): include all ancestor scroll containers here once
605 // we have a way of exposing the trigger element to the scroll strategy.
606 var parentRects = [{ width: width, height: height, bottom: height, right: width, top: 0, left: 0 }];
607 if (isElementScrolledOutsideView(overlayRect, parentRects)) {
608 _this.disable();
609 _this._ngZone.run(function () { return _this._overlayRef.detach(); });
610 }
611 }
612 });
613 }
614 };
615 /** Disables repositioning of the attached overlay on scroll. */
616 RepositionScrollStrategy.prototype.disable = function () {
617 if (this._scrollSubscription) {
618 this._scrollSubscription.unsubscribe();
619 this._scrollSubscription = null;
620 }
621 };
622 RepositionScrollStrategy.prototype.detach = function () {
623 this.disable();
624 this._overlayRef = null;
625 };
626 return RepositionScrollStrategy;
627 }());
628
629 /**
630 * @license
631 * Copyright Google LLC All Rights Reserved.
632 *
633 * Use of this source code is governed by an MIT-style license that can be
634 * found in the LICENSE file at https://angular.io/license
635 */
636 /**
637 * Options for how an overlay will handle scrolling.
638 *
639 * Users can provide a custom value for `ScrollStrategyOptions` to replace the default
640 * behaviors. This class primarily acts as a factory for ScrollStrategy instances.
641 */
642 var ScrollStrategyOptions = /** @class */ (function () {
643 function ScrollStrategyOptions(_scrollDispatcher, _viewportRuler, _ngZone, document) {
644 var _this = this;
645 this._scrollDispatcher = _scrollDispatcher;
646 this._viewportRuler = _viewportRuler;
647 this._ngZone = _ngZone;
648 /** Do nothing on scroll. */
649 this.noop = function () { return new NoopScrollStrategy(); };
650 /**
651 * Close the overlay as soon as the user scrolls.
652 * @param config Configuration to be used inside the scroll strategy.
653 */
654 this.close = function (config) { return new CloseScrollStrategy(_this._scrollDispatcher, _this._ngZone, _this._viewportRuler, config); };
655 /** Block scrolling. */
656 this.block = function () { return new BlockScrollStrategy(_this._viewportRuler, _this._document); };
657 /**
658 * Update the overlay's position on scroll.
659 * @param config Configuration to be used inside the scroll strategy.
660 * Allows debouncing the reposition calls.
661 */
662 this.reposition = function (config) { return new RepositionScrollStrategy(_this._scrollDispatcher, _this._viewportRuler, _this._ngZone, config); };
663 this._document = document;
664 }
665 return ScrollStrategyOptions;
666 }());
667 ScrollStrategyOptions.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function ScrollStrategyOptions_Factory() { return new ScrollStrategyOptions(i0__namespace.ɵɵinject(i1__namespace.ScrollDispatcher), i0__namespace.ɵɵinject(i1__namespace.ViewportRuler), i0__namespace.ɵɵinject(i0__namespace.NgZone), i0__namespace.ɵɵinject(i1__namespace$1.DOCUMENT)); }, token: ScrollStrategyOptions, providedIn: "root" });
668 ScrollStrategyOptions.decorators = [
669 { type: i0.Injectable, args: [{ providedIn: 'root' },] }
670 ];
671 ScrollStrategyOptions.ctorParameters = function () { return [
672 { type: i1.ScrollDispatcher },
673 { type: i1.ViewportRuler },
674 { type: i0.NgZone },
675 { type: undefined, decorators: [{ type: i0.Inject, args: [i1$1.DOCUMENT,] }] }
676 ]; };
677
678 /**
679 * @license
680 * Copyright Google LLC All Rights Reserved.
681 *
682 * Use of this source code is governed by an MIT-style license that can be
683 * found in the LICENSE file at https://angular.io/license
684 */
685
686 /** Initial configuration used when creating an overlay. */
687 var OverlayConfig = /** @class */ (function () {
688 function OverlayConfig(config) {
689 var e_1, _a;
690 /** Strategy to be used when handling scroll events while the overlay is open. */
691 this.scrollStrategy = new NoopScrollStrategy();
692 /** Custom class to add to the overlay pane. */
693 this.panelClass = '';
694 /** Whether the overlay has a backdrop. */
695 this.hasBackdrop = false;
696 /** Custom class to add to the backdrop */
697 this.backdropClass = 'cdk-overlay-dark-backdrop';
698 /**
699 * Whether the overlay should be disposed of when the user goes backwards/forwards in history.
700 * Note that this usually doesn't include clicking on links (unless the user is using
701 * the `HashLocationStrategy`).
702 */
703 this.disposeOnNavigation = false;
704 if (config) {
705 // Use `Iterable` instead of `Array` because TypeScript, as of 3.6.3,
706 // loses the array generic type in the `for of`. But we *also* have to use `Array` because
707 // typescript won't iterate over an `Iterable` unless you compile with `--downlevelIteration`
708 var configKeys = Object.keys(config);
709 try {
710 for (var configKeys_1 = __values(configKeys), configKeys_1_1 = configKeys_1.next(); !configKeys_1_1.done; configKeys_1_1 = configKeys_1.next()) {
711 var key = configKeys_1_1.value;
712 if (config[key] !== undefined) {
713 // TypeScript, as of version 3.5, sees the left-hand-side of this expression
714 // as "I don't know *which* key this is, so the only valid value is the intersection
715 // of all the posible values." In this case, that happens to be `undefined`. TypeScript
716 // is not smart enough to see that the right-hand-side is actually an access of the same
717 // exact type with the same exact key, meaning that the value type must be identical.
718 // So we use `any` to work around this.
719 this[key] = config[key];
720 }
721 }
722 }
723 catch (e_1_1) { e_1 = { error: e_1_1 }; }
724 finally {
725 try {
726 if (configKeys_1_1 && !configKeys_1_1.done && (_a = configKeys_1.return)) _a.call(configKeys_1);
727 }
728 finally { if (e_1) throw e_1.error; }
729 }
730 }
731 }
732 return OverlayConfig;
733 }());
734
735 /**
736 * @license
737 * Copyright Google LLC All Rights Reserved.
738 *
739 * Use of this source code is governed by an MIT-style license that can be
740 * found in the LICENSE file at https://angular.io/license
741 */
742 /** The points of the origin element and the overlay element to connect. */
743 var ConnectionPositionPair = /** @class */ (function () {
744 function ConnectionPositionPair(origin, overlay,
745 /** Offset along the X axis. */
746 offsetX,
747 /** Offset along the Y axis. */
748 offsetY,
749 /** Class(es) to be applied to the panel while this position is active. */
750 panelClass) {
751 this.offsetX = offsetX;
752 this.offsetY = offsetY;
753 this.panelClass = panelClass;
754 this.originX = origin.originX;
755 this.originY = origin.originY;
756 this.overlayX = overlay.overlayX;
757 this.overlayY = overlay.overlayY;
758 }
759 return ConnectionPositionPair;
760 }());
761 /**
762 * Set of properties regarding the position of the origin and overlay relative to the viewport
763 * with respect to the containing Scrollable elements.
764 *
765 * The overlay and origin are clipped if any part of their bounding client rectangle exceeds the
766 * bounds of any one of the strategy's Scrollable's bounding client rectangle.
767 *
768 * The overlay and origin are outside view if there is no overlap between their bounding client
769 * rectangle and any one of the strategy's Scrollable's bounding client rectangle.
770 *
771 * ----------- -----------
772 * | outside | | clipped |
773 * | view | --------------------------
774 * | | | | | |
775 * ---------- | ----------- |
776 * -------------------------- | |
777 * | | | Scrollable |
778 * | | | |
779 * | | --------------------------
780 * | Scrollable |
781 * | |
782 * --------------------------
783 *
784 * @docs-private
785 */
786 var ScrollingVisibility = /** @class */ (function () {
787 function ScrollingVisibility() {
788 }
789 return ScrollingVisibility;
790 }());
791 /** The change event emitted by the strategy when a fallback position is used. */
792 var ConnectedOverlayPositionChange = /** @class */ (function () {
793 function ConnectedOverlayPositionChange(
794 /** The position used as a result of this change. */
795 connectionPair,
796 /** @docs-private */
797 scrollableViewProperties) {
798 this.connectionPair = connectionPair;
799 this.scrollableViewProperties = scrollableViewProperties;
800 }
801 return ConnectedOverlayPositionChange;
802 }());
803 ConnectedOverlayPositionChange.ctorParameters = function () { return [
804 { type: ConnectionPositionPair },
805 { type: ScrollingVisibility, decorators: [{ type: i0.Optional }] }
806 ]; };
807 /**
808 * Validates whether a vertical position property matches the expected values.
809 * @param property Name of the property being validated.
810 * @param value Value of the property being validated.
811 * @docs-private
812 */
813 function validateVerticalPosition(property, value) {
814 if (value !== 'top' && value !== 'bottom' && value !== 'center') {
815 throw Error("ConnectedPosition: Invalid " + property + " \"" + value + "\". " +
816 "Expected \"top\", \"bottom\" or \"center\".");
817 }
818 }
819 /**
820 * Validates whether a horizontal position property matches the expected values.
821 * @param property Name of the property being validated.
822 * @param value Value of the property being validated.
823 * @docs-private
824 */
825 function validateHorizontalPosition(property, value) {
826 if (value !== 'start' && value !== 'end' && value !== 'center') {
827 throw Error("ConnectedPosition: Invalid " + property + " \"" + value + "\". " +
828 "Expected \"start\", \"end\" or \"center\".");
829 }
830 }
831
832 /**
833 * @license
834 * Copyright Google LLC All Rights Reserved.
835 *
836 * Use of this source code is governed by an MIT-style license that can be
837 * found in the LICENSE file at https://angular.io/license
838 */
839 /**
840 * Service for dispatching events that land on the body to appropriate overlay ref,
841 * if any. It maintains a list of attached overlays to determine best suited overlay based
842 * on event target and order of overlay opens.
843 */
844 var BaseOverlayDispatcher = /** @class */ (function () {
845 function BaseOverlayDispatcher(document) {
846 /** Currently attached overlays in the order they were attached. */
847 this._attachedOverlays = [];
848 this._document = document;
849 }
850 BaseOverlayDispatcher.prototype.ngOnDestroy = function () {
851 this.detach();
852 };
853 /** Add a new overlay to the list of attached overlay refs. */
854 BaseOverlayDispatcher.prototype.add = function (overlayRef) {
855 // Ensure that we don't get the same overlay multiple times.
856 this.remove(overlayRef);
857 this._attachedOverlays.push(overlayRef);
858 };
859 /** Remove an overlay from the list of attached overlay refs. */
860 BaseOverlayDispatcher.prototype.remove = function (overlayRef) {
861 var index = this._attachedOverlays.indexOf(overlayRef);
862 if (index > -1) {
863 this._attachedOverlays.splice(index, 1);
864 }
865 // Remove the global listener once there are no more overlays.
866 if (this._attachedOverlays.length === 0) {
867 this.detach();
868 }
869 };
870 return BaseOverlayDispatcher;
871 }());
872 BaseOverlayDispatcher.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function BaseOverlayDispatcher_Factory() { return new BaseOverlayDispatcher(i0__namespace.ɵɵinject(i1__namespace$1.DOCUMENT)); }, token: BaseOverlayDispatcher, providedIn: "root" });
873 BaseOverlayDispatcher.decorators = [
874 { type: i0.Injectable, args: [{ providedIn: 'root' },] }
875 ];
876 BaseOverlayDispatcher.ctorParameters = function () { return [
877 { type: undefined, decorators: [{ type: i0.Inject, args: [i1$1.DOCUMENT,] }] }
878 ]; };
879
880 /**
881 * Service for dispatching keyboard events that land on the body to appropriate overlay ref,
882 * if any. It maintains a list of attached overlays to determine best suited overlay based
883 * on event target and order of overlay opens.
884 */
885 var OverlayKeyboardDispatcher = /** @class */ (function (_super) {
886 __extends(OverlayKeyboardDispatcher, _super);
887 function OverlayKeyboardDispatcher(document) {
888 var _this = _super.call(this, document) || this;
889 /** Keyboard event listener that will be attached to the body. */
890 _this._keydownListener = function (event) {
891 var overlays = _this._attachedOverlays;
892 for (var i = overlays.length - 1; i > -1; i--) {
893 // Dispatch the keydown event to the top overlay which has subscribers to its keydown events.
894 // We want to target the most recent overlay, rather than trying to match where the event came
895 // from, because some components might open an overlay, but keep focus on a trigger element
896 // (e.g. for select and autocomplete). We skip overlays without keydown event subscriptions,
897 // because we don't want overlays that don't handle keyboard events to block the ones below
898 // them that do.
899 if (overlays[i]._keydownEvents.observers.length > 0) {
900 overlays[i]._keydownEvents.next(event);
901 break;
902 }
903 }
904 };
905 return _this;
906 }
907 /** Add a new overlay to the list of attached overlay refs. */
908 OverlayKeyboardDispatcher.prototype.add = function (overlayRef) {
909 _super.prototype.add.call(this, overlayRef);
910 // Lazily start dispatcher once first overlay is added
911 if (!this._isAttached) {
912 this._document.body.addEventListener('keydown', this._keydownListener);
913 this._isAttached = true;
914 }
915 };
916 /** Detaches the global keyboard event listener. */
917 OverlayKeyboardDispatcher.prototype.detach = function () {
918 if (this._isAttached) {
919 this._document.body.removeEventListener('keydown', this._keydownListener);
920 this._isAttached = false;
921 }
922 };
923 return OverlayKeyboardDispatcher;
924 }(BaseOverlayDispatcher));
925 OverlayKeyboardDispatcher.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function OverlayKeyboardDispatcher_Factory() { return new OverlayKeyboardDispatcher(i0__namespace.ɵɵinject(i1__namespace$1.DOCUMENT)); }, token: OverlayKeyboardDispatcher, providedIn: "root" });
926 OverlayKeyboardDispatcher.decorators = [
927 { type: i0.Injectable, args: [{ providedIn: 'root' },] }
928 ];
929 OverlayKeyboardDispatcher.ctorParameters = function () { return [
930 { type: undefined, decorators: [{ type: i0.Inject, args: [i1$1.DOCUMENT,] }] }
931 ]; };
932
933 /**
934 * Service for dispatching mouse click events that land on the body to appropriate overlay ref,
935 * if any. It maintains a list of attached overlays to determine best suited overlay based
936 * on event target and order of overlay opens.
937 */
938 var OverlayOutsideClickDispatcher = /** @class */ (function (_super) {
939 __extends(OverlayOutsideClickDispatcher, _super);
940 function OverlayOutsideClickDispatcher(document, _platform) {
941 var _this = _super.call(this, document) || this;
942 _this._platform = _platform;
943 _this._cursorStyleIsSet = false;
[e29cc2e]944 /** Store pointerdown event target to track origin of click. */
945 _this._pointerDownListener = function (event) {
946 _this._pointerDownEventTarget = i2._getEventTarget(event);
947 };
[6a3a178]948 /** Click event listener that will be attached to the body propagate phase. */
949 _this._clickListener = function (event) {
950 var target = i2._getEventTarget(event);
[e29cc2e]951 // In case of a click event, we want to check the origin of the click
952 // (e.g. in case where a user starts a click inside the overlay and
953 // releases the click outside of it).
954 // This is done by using the event target of the preceding pointerdown event.
955 // Every click event caused by a pointer device has a preceding pointerdown
956 // event, unless the click was programmatically triggered (e.g. in a unit test).
957 var origin = event.type === 'click' && _this._pointerDownEventTarget
958 ? _this._pointerDownEventTarget : target;
959 // Reset the stored pointerdown event target, to avoid having it interfere
960 // in subsequent events.
961 _this._pointerDownEventTarget = null;
[6a3a178]962 // We copy the array because the original may be modified asynchronously if the
963 // outsidePointerEvents listener decides to detach overlays resulting in index errors inside
964 // the for loop.
965 var overlays = _this._attachedOverlays.slice();
966 // Dispatch the mouse event to the top overlay which has subscribers to its mouse events.
967 // We want to target all overlays for which the click could be considered as outside click.
968 // As soon as we reach an overlay for which the click is not outside click we break off
969 // the loop.
970 for (var i = overlays.length - 1; i > -1; i--) {
971 var overlayRef = overlays[i];
972 if (overlayRef._outsidePointerEvents.observers.length < 1 || !overlayRef.hasAttached()) {
973 continue;
974 }
975 // If it's a click inside the overlay, just break - we should do nothing
[e29cc2e]976 // If it's an outside click (both origin and target of the click) dispatch the mouse event,
977 // and proceed with the next overlay
978 if (overlayRef.overlayElement.contains(target) ||
979 overlayRef.overlayElement.contains(origin)) {
[6a3a178]980 break;
981 }
982 overlayRef._outsidePointerEvents.next(event);
983 }
984 };
985 return _this;
986 }
987 /** Add a new overlay to the list of attached overlay refs. */
988 OverlayOutsideClickDispatcher.prototype.add = function (overlayRef) {
989 _super.prototype.add.call(this, overlayRef);
990 // Safari on iOS does not generate click events for non-interactive
991 // elements. However, we want to receive a click for any element outside
992 // the overlay. We can force a "clickable" state by setting
993 // `cursor: pointer` on the document body. See:
994 // https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event#Safari_Mobile
995 // https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html
996 if (!this._isAttached) {
997 var body = this._document.body;
[e29cc2e]998 body.addEventListener('pointerdown', this._pointerDownListener, true);
[6a3a178]999 body.addEventListener('click', this._clickListener, true);
1000 body.addEventListener('auxclick', this._clickListener, true);
1001 body.addEventListener('contextmenu', this._clickListener, true);
1002 // click event is not fired on iOS. To make element "clickable" we are
1003 // setting the cursor to pointer
1004 if (this._platform.IOS && !this._cursorStyleIsSet) {
1005 this._cursorOriginalValue = body.style.cursor;
1006 body.style.cursor = 'pointer';
1007 this._cursorStyleIsSet = true;
1008 }
1009 this._isAttached = true;
1010 }
1011 };
1012 /** Detaches the global keyboard event listener. */
1013 OverlayOutsideClickDispatcher.prototype.detach = function () {
1014 if (this._isAttached) {
1015 var body = this._document.body;
[e29cc2e]1016 body.removeEventListener('pointerdown', this._pointerDownListener, true);
[6a3a178]1017 body.removeEventListener('click', this._clickListener, true);
1018 body.removeEventListener('auxclick', this._clickListener, true);
1019 body.removeEventListener('contextmenu', this._clickListener, true);
1020 if (this._platform.IOS && this._cursorStyleIsSet) {
1021 body.style.cursor = this._cursorOriginalValue;
1022 this._cursorStyleIsSet = false;
1023 }
1024 this._isAttached = false;
1025 }
1026 };
1027 return OverlayOutsideClickDispatcher;
1028 }(BaseOverlayDispatcher));
1029 OverlayOutsideClickDispatcher.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function OverlayOutsideClickDispatcher_Factory() { return new OverlayOutsideClickDispatcher(i0__namespace.ɵɵinject(i1__namespace$1.DOCUMENT), i0__namespace.ɵɵinject(i2__namespace.Platform)); }, token: OverlayOutsideClickDispatcher, providedIn: "root" });
1030 OverlayOutsideClickDispatcher.decorators = [
1031 { type: i0.Injectable, args: [{ providedIn: 'root' },] }
1032 ];
1033 OverlayOutsideClickDispatcher.ctorParameters = function () { return [
1034 { type: undefined, decorators: [{ type: i0.Inject, args: [i1$1.DOCUMENT,] }] },
1035 { type: i2.Platform }
1036 ]; };
1037
1038 /**
1039 * @license
1040 * Copyright Google LLC All Rights Reserved.
1041 *
1042 * Use of this source code is governed by an MIT-style license that can be
1043 * found in the LICENSE file at https://angular.io/license
1044 */
1045 /** Container inside which all overlays will render. */
1046 var OverlayContainer = /** @class */ (function () {
1047 function OverlayContainer(document, _platform) {
1048 this._platform = _platform;
1049 this._document = document;
1050 }
1051 OverlayContainer.prototype.ngOnDestroy = function () {
1052 var container = this._containerElement;
1053 if (container && container.parentNode) {
1054 container.parentNode.removeChild(container);
1055 }
1056 };
1057 /**
1058 * This method returns the overlay container element. It will lazily
1059 * create the element the first time it is called to facilitate using
1060 * the container in non-browser environments.
1061 * @returns the container element
1062 */
1063 OverlayContainer.prototype.getContainerElement = function () {
1064 if (!this._containerElement) {
1065 this._createContainer();
1066 }
1067 return this._containerElement;
1068 };
1069 /**
1070 * Create the overlay container element, which is simply a div
1071 * with the 'cdk-overlay-container' class on the document body.
1072 */
1073 OverlayContainer.prototype._createContainer = function () {
1074 var containerClass = 'cdk-overlay-container';
1075 // TODO(crisbeto): remove the testing check once we have an overlay testing
1076 // module or Angular starts tearing down the testing `NgModule`. See:
1077 // https://github.com/angular/angular/issues/18831
1078 if (this._platform.isBrowser || i2._isTestEnvironment()) {
1079 var oppositePlatformContainers = this._document.querySelectorAll("." + containerClass + "[platform=\"server\"], " +
1080 ("." + containerClass + "[platform=\"test\"]"));
1081 // Remove any old containers from the opposite platform.
1082 // This can happen when transitioning from the server to the client.
1083 for (var i = 0; i < oppositePlatformContainers.length; i++) {
1084 oppositePlatformContainers[i].parentNode.removeChild(oppositePlatformContainers[i]);
1085 }
1086 }
1087 var container = this._document.createElement('div');
1088 container.classList.add(containerClass);
1089 // A long time ago we kept adding new overlay containers whenever a new app was instantiated,
1090 // but at some point we added logic which clears the duplicate ones in order to avoid leaks.
1091 // The new logic was a little too aggressive since it was breaking some legitimate use cases.
1092 // To mitigate the problem we made it so that only containers from a different platform are
1093 // cleared, but the side-effect was that people started depending on the overly-aggressive
1094 // logic to clean up their tests for them. Until we can introduce an overlay-specific testing
1095 // module which does the cleanup, we try to detect that we're in a test environment and we
1096 // always clear the container. See #17006.
1097 // TODO(crisbeto): remove the test environment check once we have an overlay testing module.
1098 if (i2._isTestEnvironment()) {
1099 container.setAttribute('platform', 'test');
1100 }
1101 else if (!this._platform.isBrowser) {
1102 container.setAttribute('platform', 'server');
1103 }
1104 this._document.body.appendChild(container);
1105 this._containerElement = container;
1106 };
1107 return OverlayContainer;
1108 }());
1109 OverlayContainer.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function OverlayContainer_Factory() { return new OverlayContainer(i0__namespace.ɵɵinject(i1__namespace$1.DOCUMENT), i0__namespace.ɵɵinject(i2__namespace.Platform)); }, token: OverlayContainer, providedIn: "root" });
1110 OverlayContainer.decorators = [
1111 { type: i0.Injectable, args: [{ providedIn: 'root' },] }
1112 ];
1113 OverlayContainer.ctorParameters = function () { return [
1114 { type: undefined, decorators: [{ type: i0.Inject, args: [i1$1.DOCUMENT,] }] },
1115 { type: i2.Platform }
1116 ]; };
1117
1118 /**
1119 * @license
1120 * Copyright Google LLC All Rights Reserved.
1121 *
1122 * Use of this source code is governed by an MIT-style license that can be
1123 * found in the LICENSE file at https://angular.io/license
1124 */
1125 /**
1126 * Reference to an overlay that has been created with the Overlay service.
1127 * Used to manipulate or dispose of said overlay.
1128 */
1129 var OverlayRef = /** @class */ (function () {
1130 function OverlayRef(_portalOutlet, _host, _pane, _config, _ngZone, _keyboardDispatcher, _document, _location, _outsideClickDispatcher) {
1131 var _this = this;
1132 this._portalOutlet = _portalOutlet;
1133 this._host = _host;
1134 this._pane = _pane;
1135 this._config = _config;
1136 this._ngZone = _ngZone;
1137 this._keyboardDispatcher = _keyboardDispatcher;
1138 this._document = _document;
1139 this._location = _location;
1140 this._outsideClickDispatcher = _outsideClickDispatcher;
1141 this._backdropElement = null;
1142 this._backdropClick = new rxjs.Subject();
1143 this._attachments = new rxjs.Subject();
1144 this._detachments = new rxjs.Subject();
1145 this._locationChanges = rxjs.Subscription.EMPTY;
1146 this._backdropClickHandler = function (event) { return _this._backdropClick.next(event); };
1147 /** Stream of keydown events dispatched to this overlay. */
1148 this._keydownEvents = new rxjs.Subject();
1149 /** Stream of mouse outside events dispatched to this overlay. */
1150 this._outsidePointerEvents = new rxjs.Subject();
1151 if (_config.scrollStrategy) {
1152 this._scrollStrategy = _config.scrollStrategy;
1153 this._scrollStrategy.attach(this);
1154 }
1155 this._positionStrategy = _config.positionStrategy;
1156 }
1157 Object.defineProperty(OverlayRef.prototype, "overlayElement", {
1158 /** The overlay's HTML element */
1159 get: function () {
1160 return this._pane;
1161 },
1162 enumerable: false,
1163 configurable: true
1164 });
1165 Object.defineProperty(OverlayRef.prototype, "backdropElement", {
1166 /** The overlay's backdrop HTML element. */
1167 get: function () {
1168 return this._backdropElement;
1169 },
1170 enumerable: false,
1171 configurable: true
1172 });
1173 Object.defineProperty(OverlayRef.prototype, "hostElement", {
1174 /**
1175 * Wrapper around the panel element. Can be used for advanced
1176 * positioning where a wrapper with specific styling is
1177 * required around the overlay pane.
1178 */
1179 get: function () {
1180 return this._host;
1181 },
1182 enumerable: false,
1183 configurable: true
1184 });
1185 /**
1186 * Attaches content, given via a Portal, to the overlay.
1187 * If the overlay is configured to have a backdrop, it will be created.
1188 *
1189 * @param portal Portal instance to which to attach the overlay.
1190 * @returns The portal attachment result.
1191 */
1192 OverlayRef.prototype.attach = function (portal) {
1193 var _this = this;
1194 var attachResult = this._portalOutlet.attach(portal);
1195 // Update the pane element with the given configuration.
1196 if (!this._host.parentElement && this._previousHostParent) {
1197 this._previousHostParent.appendChild(this._host);
1198 }
1199 if (this._positionStrategy) {
1200 this._positionStrategy.attach(this);
1201 }
1202 this._updateStackingOrder();
1203 this._updateElementSize();
1204 this._updateElementDirection();
1205 if (this._scrollStrategy) {
1206 this._scrollStrategy.enable();
1207 }
1208 // Update the position once the zone is stable so that the overlay will be fully rendered
1209 // before attempting to position it, as the position may depend on the size of the rendered
1210 // content.
1211 this._ngZone.onStable
1212 .pipe(operators.take(1))
1213 .subscribe(function () {
1214 // The overlay could've been detached before the zone has stabilized.
1215 if (_this.hasAttached()) {
1216 _this.updatePosition();
1217 }
1218 });
1219 // Enable pointer events for the overlay pane element.
1220 this._togglePointerEvents(true);
1221 if (this._config.hasBackdrop) {
1222 this._attachBackdrop();
1223 }
1224 if (this._config.panelClass) {
1225 this._toggleClasses(this._pane, this._config.panelClass, true);
1226 }
1227 // Only emit the `attachments` event once all other setup is done.
1228 this._attachments.next();
1229 // Track this overlay by the keyboard dispatcher
1230 this._keyboardDispatcher.add(this);
1231 if (this._config.disposeOnNavigation) {
1232 this._locationChanges = this._location.subscribe(function () { return _this.dispose(); });
1233 }
1234 this._outsideClickDispatcher.add(this);
1235 return attachResult;
1236 };
1237 /**
1238 * Detaches an overlay from a portal.
1239 * @returns The portal detachment result.
1240 */
1241 OverlayRef.prototype.detach = function () {
1242 if (!this.hasAttached()) {
1243 return;
1244 }
1245 this.detachBackdrop();
1246 // When the overlay is detached, the pane element should disable pointer events.
1247 // This is necessary because otherwise the pane element will cover the page and disable
1248 // pointer events therefore. Depends on the position strategy and the applied pane boundaries.
1249 this._togglePointerEvents(false);
1250 if (this._positionStrategy && this._positionStrategy.detach) {
1251 this._positionStrategy.detach();
1252 }
1253 if (this._scrollStrategy) {
1254 this._scrollStrategy.disable();
1255 }
1256 var detachmentResult = this._portalOutlet.detach();
1257 // Only emit after everything is detached.
1258 this._detachments.next();
1259 // Remove this overlay from keyboard dispatcher tracking.
1260 this._keyboardDispatcher.remove(this);
1261 // Keeping the host element in the DOM can cause scroll jank, because it still gets
1262 // rendered, even though it's transparent and unclickable which is why we remove it.
1263 this._detachContentWhenStable();
1264 this._locationChanges.unsubscribe();
1265 this._outsideClickDispatcher.remove(this);
1266 return detachmentResult;
1267 };
1268 /** Cleans up the overlay from the DOM. */
1269 OverlayRef.prototype.dispose = function () {
1270 var isAttached = this.hasAttached();
1271 if (this._positionStrategy) {
1272 this._positionStrategy.dispose();
1273 }
1274 this._disposeScrollStrategy();
1275 this._disposeBackdrop(this._backdropElement);
1276 this._locationChanges.unsubscribe();
1277 this._keyboardDispatcher.remove(this);
1278 this._portalOutlet.dispose();
1279 this._attachments.complete();
1280 this._backdropClick.complete();
1281 this._keydownEvents.complete();
1282 this._outsidePointerEvents.complete();
1283 this._outsideClickDispatcher.remove(this);
1284 if (this._host && this._host.parentNode) {
1285 this._host.parentNode.removeChild(this._host);
1286 this._host = null;
1287 }
1288 this._previousHostParent = this._pane = null;
1289 if (isAttached) {
1290 this._detachments.next();
1291 }
1292 this._detachments.complete();
1293 };
1294 /** Whether the overlay has attached content. */
1295 OverlayRef.prototype.hasAttached = function () {
1296 return this._portalOutlet.hasAttached();
1297 };
1298 /** Gets an observable that emits when the backdrop has been clicked. */
1299 OverlayRef.prototype.backdropClick = function () {
1300 return this._backdropClick;
1301 };
1302 /** Gets an observable that emits when the overlay has been attached. */
1303 OverlayRef.prototype.attachments = function () {
1304 return this._attachments;
1305 };
1306 /** Gets an observable that emits when the overlay has been detached. */
1307 OverlayRef.prototype.detachments = function () {
1308 return this._detachments;
1309 };
1310 /** Gets an observable of keydown events targeted to this overlay. */
1311 OverlayRef.prototype.keydownEvents = function () {
1312 return this._keydownEvents;
1313 };
1314 /** Gets an observable of pointer events targeted outside this overlay. */
1315 OverlayRef.prototype.outsidePointerEvents = function () {
1316 return this._outsidePointerEvents;
1317 };
1318 /** Gets the current overlay configuration, which is immutable. */
1319 OverlayRef.prototype.getConfig = function () {
1320 return this._config;
1321 };
1322 /** Updates the position of the overlay based on the position strategy. */
1323 OverlayRef.prototype.updatePosition = function () {
1324 if (this._positionStrategy) {
1325 this._positionStrategy.apply();
1326 }
1327 };
1328 /** Switches to a new position strategy and updates the overlay position. */
1329 OverlayRef.prototype.updatePositionStrategy = function (strategy) {
1330 if (strategy === this._positionStrategy) {
1331 return;
1332 }
1333 if (this._positionStrategy) {
1334 this._positionStrategy.dispose();
1335 }
1336 this._positionStrategy = strategy;
1337 if (this.hasAttached()) {
1338 strategy.attach(this);
1339 this.updatePosition();
1340 }
1341 };
1342 /** Update the size properties of the overlay. */
1343 OverlayRef.prototype.updateSize = function (sizeConfig) {
1344 this._config = Object.assign(Object.assign({}, this._config), sizeConfig);
1345 this._updateElementSize();
1346 };
1347 /** Sets the LTR/RTL direction for the overlay. */
1348 OverlayRef.prototype.setDirection = function (dir) {
1349 this._config = Object.assign(Object.assign({}, this._config), { direction: dir });
1350 this._updateElementDirection();
1351 };
1352 /** Add a CSS class or an array of classes to the overlay pane. */
1353 OverlayRef.prototype.addPanelClass = function (classes) {
1354 if (this._pane) {
1355 this._toggleClasses(this._pane, classes, true);
1356 }
1357 };
1358 /** Remove a CSS class or an array of classes from the overlay pane. */
1359 OverlayRef.prototype.removePanelClass = function (classes) {
1360 if (this._pane) {
1361 this._toggleClasses(this._pane, classes, false);
1362 }
1363 };
1364 /**
1365 * Returns the layout direction of the overlay panel.
1366 */
1367 OverlayRef.prototype.getDirection = function () {
1368 var direction = this._config.direction;
1369 if (!direction) {
1370 return 'ltr';
1371 }
1372 return typeof direction === 'string' ? direction : direction.value;
1373 };
1374 /** Switches to a new scroll strategy. */
1375 OverlayRef.prototype.updateScrollStrategy = function (strategy) {
1376 if (strategy === this._scrollStrategy) {
1377 return;
1378 }
1379 this._disposeScrollStrategy();
1380 this._scrollStrategy = strategy;
1381 if (this.hasAttached()) {
1382 strategy.attach(this);
1383 strategy.enable();
1384 }
1385 };
1386 /** Updates the text direction of the overlay panel. */
1387 OverlayRef.prototype._updateElementDirection = function () {
1388 this._host.setAttribute('dir', this.getDirection());
1389 };
1390 /** Updates the size of the overlay element based on the overlay config. */
1391 OverlayRef.prototype._updateElementSize = function () {
1392 if (!this._pane) {
1393 return;
1394 }
1395 var style = this._pane.style;
1396 style.width = coercion.coerceCssPixelValue(this._config.width);
1397 style.height = coercion.coerceCssPixelValue(this._config.height);
1398 style.minWidth = coercion.coerceCssPixelValue(this._config.minWidth);
1399 style.minHeight = coercion.coerceCssPixelValue(this._config.minHeight);
1400 style.maxWidth = coercion.coerceCssPixelValue(this._config.maxWidth);
1401 style.maxHeight = coercion.coerceCssPixelValue(this._config.maxHeight);
1402 };
1403 /** Toggles the pointer events for the overlay pane element. */
1404 OverlayRef.prototype._togglePointerEvents = function (enablePointer) {
1405 this._pane.style.pointerEvents = enablePointer ? '' : 'none';
1406 };
1407 /** Attaches a backdrop for this overlay. */
1408 OverlayRef.prototype._attachBackdrop = function () {
1409 var _this = this;
1410 var showingClass = 'cdk-overlay-backdrop-showing';
1411 this._backdropElement = this._document.createElement('div');
1412 this._backdropElement.classList.add('cdk-overlay-backdrop');
1413 if (this._config.backdropClass) {
1414 this._toggleClasses(this._backdropElement, this._config.backdropClass, true);
1415 }
1416 // Insert the backdrop before the pane in the DOM order,
1417 // in order to handle stacked overlays properly.
1418 this._host.parentElement.insertBefore(this._backdropElement, this._host);
1419 // Forward backdrop clicks such that the consumer of the overlay can perform whatever
1420 // action desired when such a click occurs (usually closing the overlay).
1421 this._backdropElement.addEventListener('click', this._backdropClickHandler);
1422 // Add class to fade-in the backdrop after one frame.
1423 if (typeof requestAnimationFrame !== 'undefined') {
1424 this._ngZone.runOutsideAngular(function () {
1425 requestAnimationFrame(function () {
1426 if (_this._backdropElement) {
1427 _this._backdropElement.classList.add(showingClass);
1428 }
1429 });
1430 });
1431 }
1432 else {
1433 this._backdropElement.classList.add(showingClass);
1434 }
1435 };
1436 /**
1437 * Updates the stacking order of the element, moving it to the top if necessary.
1438 * This is required in cases where one overlay was detached, while another one,
1439 * that should be behind it, was destroyed. The next time both of them are opened,
1440 * the stacking will be wrong, because the detached element's pane will still be
1441 * in its original DOM position.
1442 */
1443 OverlayRef.prototype._updateStackingOrder = function () {
1444 if (this._host.nextSibling) {
1445 this._host.parentNode.appendChild(this._host);
1446 }
1447 };
1448 /** Detaches the backdrop (if any) associated with the overlay. */
1449 OverlayRef.prototype.detachBackdrop = function () {
1450 var _this = this;
1451 var backdropToDetach = this._backdropElement;
1452 if (!backdropToDetach) {
1453 return;
1454 }
1455 var timeoutId;
1456 var finishDetach = function () {
1457 // It may not be attached to anything in certain cases (e.g. unit tests).
1458 if (backdropToDetach) {
1459 backdropToDetach.removeEventListener('click', _this._backdropClickHandler);
1460 backdropToDetach.removeEventListener('transitionend', finishDetach);
1461 _this._disposeBackdrop(backdropToDetach);
1462 }
1463 if (_this._config.backdropClass) {
1464 _this._toggleClasses(backdropToDetach, _this._config.backdropClass, false);
1465 }
1466 clearTimeout(timeoutId);
1467 };
1468 backdropToDetach.classList.remove('cdk-overlay-backdrop-showing');
1469 this._ngZone.runOutsideAngular(function () {
1470 backdropToDetach.addEventListener('transitionend', finishDetach);
1471 });
1472 // If the backdrop doesn't have a transition, the `transitionend` event won't fire.
1473 // In this case we make it unclickable and we try to remove it after a delay.
1474 backdropToDetach.style.pointerEvents = 'none';
1475 // Run this outside the Angular zone because there's nothing that Angular cares about.
1476 // If it were to run inside the Angular zone, every test that used Overlay would have to be
1477 // either async or fakeAsync.
1478 timeoutId = this._ngZone.runOutsideAngular(function () { return setTimeout(finishDetach, 500); });
1479 };
1480 /** Toggles a single CSS class or an array of classes on an element. */
1481 OverlayRef.prototype._toggleClasses = function (element, cssClasses, isAdd) {
1482 var classList = element.classList;
1483 coercion.coerceArray(cssClasses).forEach(function (cssClass) {
1484 // We can't do a spread here, because IE doesn't support setting multiple classes.
1485 // Also trying to add an empty string to a DOMTokenList will throw.
1486 if (cssClass) {
1487 isAdd ? classList.add(cssClass) : classList.remove(cssClass);
1488 }
1489 });
1490 };
1491 /** Detaches the overlay content next time the zone stabilizes. */
1492 OverlayRef.prototype._detachContentWhenStable = function () {
1493 var _this = this;
1494 // Normally we wouldn't have to explicitly run this outside the `NgZone`, however
1495 // if the consumer is using `zone-patch-rxjs`, the `Subscription.unsubscribe` call will
1496 // be patched to run inside the zone, which will throw us into an infinite loop.
1497 this._ngZone.runOutsideAngular(function () {
1498 // We can't remove the host here immediately, because the overlay pane's content
1499 // might still be animating. This stream helps us avoid interrupting the animation
1500 // by waiting for the pane to become empty.
1501 var subscription = _this._ngZone.onStable
1502 .pipe(operators.takeUntil(rxjs.merge(_this._attachments, _this._detachments)))
1503 .subscribe(function () {
1504 // Needs a couple of checks for the pane and host, because
1505 // they may have been removed by the time the zone stabilizes.
1506 if (!_this._pane || !_this._host || _this._pane.children.length === 0) {
1507 if (_this._pane && _this._config.panelClass) {
1508 _this._toggleClasses(_this._pane, _this._config.panelClass, false);
1509 }
1510 if (_this._host && _this._host.parentElement) {
1511 _this._previousHostParent = _this._host.parentElement;
1512 _this._previousHostParent.removeChild(_this._host);
1513 }
1514 subscription.unsubscribe();
1515 }
1516 });
1517 });
1518 };
1519 /** Disposes of a scroll strategy. */
1520 OverlayRef.prototype._disposeScrollStrategy = function () {
1521 var scrollStrategy = this._scrollStrategy;
1522 if (scrollStrategy) {
1523 scrollStrategy.disable();
1524 if (scrollStrategy.detach) {
1525 scrollStrategy.detach();
1526 }
1527 }
1528 };
1529 /** Removes a backdrop element from the DOM. */
1530 OverlayRef.prototype._disposeBackdrop = function (backdrop) {
1531 if (backdrop) {
1532 if (backdrop.parentNode) {
1533 backdrop.parentNode.removeChild(backdrop);
1534 }
1535 // It is possible that a new portal has been attached to this overlay since we started
1536 // removing the backdrop. If that is the case, only clear the backdrop reference if it
1537 // is still the same instance that we started to remove.
1538 if (this._backdropElement === backdrop) {
1539 this._backdropElement = null;
1540 }
1541 }
1542 };
1543 return OverlayRef;
1544 }());
1545
1546 // TODO: refactor clipping detection into a separate thing (part of scrolling module)
1547 // TODO: doesn't handle both flexible width and height when it has to scroll along both axis.
1548 /** Class to be added to the overlay bounding box. */
1549 var boundingBoxClass = 'cdk-overlay-connected-position-bounding-box';
1550 /** Regex used to split a string on its CSS units. */
1551 var cssUnitPattern = /([A-Za-z%]+)$/;
1552 /**
1553 * A strategy for positioning overlays. Using this strategy, an overlay is given an
1554 * implicit position relative some origin element. The relative position is defined in terms of
1555 * a point on the origin element that is connected to a point on the overlay element. For example,
1556 * a basic dropdown is connecting the bottom-left corner of the origin to the top-left corner
1557 * of the overlay.
1558 */
1559 var FlexibleConnectedPositionStrategy = /** @class */ (function () {
1560 function FlexibleConnectedPositionStrategy(connectedTo, _viewportRuler, _document, _platform, _overlayContainer) {
1561 this._viewportRuler = _viewportRuler;
1562 this._document = _document;
1563 this._platform = _platform;
1564 this._overlayContainer = _overlayContainer;
1565 /** Last size used for the bounding box. Used to avoid resizing the overlay after open. */
1566 this._lastBoundingBoxSize = { width: 0, height: 0 };
1567 /** Whether the overlay was pushed in a previous positioning. */
1568 this._isPushed = false;
1569 /** Whether the overlay can be pushed on-screen on the initial open. */
1570 this._canPush = true;
1571 /** Whether the overlay can grow via flexible width/height after the initial open. */
1572 this._growAfterOpen = false;
1573 /** Whether the overlay's width and height can be constrained to fit within the viewport. */
1574 this._hasFlexibleDimensions = true;
1575 /** Whether the overlay position is locked. */
1576 this._positionLocked = false;
1577 /** Amount of space that must be maintained between the overlay and the edge of the viewport. */
1578 this._viewportMargin = 0;
1579 /** The Scrollable containers used to check scrollable view properties on position change. */
1580 this._scrollables = [];
1581 /** Ordered list of preferred positions, from most to least desirable. */
1582 this._preferredPositions = [];
1583 /** Subject that emits whenever the position changes. */
1584 this._positionChanges = new rxjs.Subject();
1585 /** Subscription to viewport size changes. */
1586 this._resizeSubscription = rxjs.Subscription.EMPTY;
1587 /** Default offset for the overlay along the x axis. */
1588 this._offsetX = 0;
1589 /** Default offset for the overlay along the y axis. */
1590 this._offsetY = 0;
1591 /** Keeps track of the CSS classes that the position strategy has applied on the overlay panel. */
1592 this._appliedPanelClasses = [];
1593 /** Observable sequence of position changes. */
1594 this.positionChanges = this._positionChanges;
1595 this.setOrigin(connectedTo);
1596 }
1597 Object.defineProperty(FlexibleConnectedPositionStrategy.prototype, "positions", {
1598 /** Ordered list of preferred positions, from most to least desirable. */
1599 get: function () {
1600 return this._preferredPositions;
1601 },
1602 enumerable: false,
1603 configurable: true
1604 });
1605 /** Attaches this position strategy to an overlay. */
1606 FlexibleConnectedPositionStrategy.prototype.attach = function (overlayRef) {
1607 var _this = this;
1608 if (this._overlayRef && overlayRef !== this._overlayRef &&
1609 (typeof ngDevMode === 'undefined' || ngDevMode)) {
1610 throw Error('This position strategy is already attached to an overlay');
1611 }
1612 this._validatePositions();
1613 overlayRef.hostElement.classList.add(boundingBoxClass);
1614 this._overlayRef = overlayRef;
1615 this._boundingBox = overlayRef.hostElement;
1616 this._pane = overlayRef.overlayElement;
1617 this._isDisposed = false;
1618 this._isInitialRender = true;
1619 this._lastPosition = null;
1620 this._resizeSubscription.unsubscribe();
1621 this._resizeSubscription = this._viewportRuler.change().subscribe(function () {
1622 // When the window is resized, we want to trigger the next reposition as if it
1623 // was an initial render, in order for the strategy to pick a new optimal position,
1624 // otherwise position locking will cause it to stay at the old one.
1625 _this._isInitialRender = true;
1626 _this.apply();
1627 });
1628 };
1629 /**
1630 * Updates the position of the overlay element, using whichever preferred position relative
1631 * to the origin best fits on-screen.
1632 *
1633 * The selection of a position goes as follows:
1634 * - If any positions fit completely within the viewport as-is,
1635 * choose the first position that does so.
1636 * - If flexible dimensions are enabled and at least one satifies the given minimum width/height,
1637 * choose the position with the greatest available size modified by the positions' weight.
1638 * - If pushing is enabled, take the position that went off-screen the least and push it
1639 * on-screen.
1640 * - If none of the previous criteria were met, use the position that goes off-screen the least.
1641 * @docs-private
1642 */
1643 FlexibleConnectedPositionStrategy.prototype.apply = function () {
1644 var e_1, _a, e_2, _b;
1645 // We shouldn't do anything if the strategy was disposed or we're on the server.
1646 if (this._isDisposed || !this._platform.isBrowser) {
1647 return;
1648 }
1649 // If the position has been applied already (e.g. when the overlay was opened) and the
1650 // consumer opted into locking in the position, re-use the old position, in order to
1651 // prevent the overlay from jumping around.
1652 if (!this._isInitialRender && this._positionLocked && this._lastPosition) {
1653 this.reapplyLastPosition();
1654 return;
1655 }
1656 this._clearPanelClasses();
1657 this._resetOverlayElementStyles();
1658 this._resetBoundingBoxStyles();
1659 // We need the bounding rects for the origin and the overlay to determine how to position
1660 // the overlay relative to the origin.
1661 // We use the viewport rect to determine whether a position would go off-screen.
1662 this._viewportRect = this._getNarrowedViewportRect();
1663 this._originRect = this._getOriginRect();
1664 this._overlayRect = this._pane.getBoundingClientRect();
1665 var originRect = this._originRect;
1666 var overlayRect = this._overlayRect;
1667 var viewportRect = this._viewportRect;
1668 // Positions where the overlay will fit with flexible dimensions.
1669 var flexibleFits = [];
1670 // Fallback if none of the preferred positions fit within the viewport.
1671 var fallback;
1672 try {
1673 // Go through each of the preferred positions looking for a good fit.
1674 // If a good fit is found, it will be applied immediately.
1675 for (var _c = __values(this._preferredPositions), _d = _c.next(); !_d.done; _d = _c.next()) {
1676 var pos = _d.value;
1677 // Get the exact (x, y) coordinate for the point-of-origin on the origin element.
1678 var originPoint = this._getOriginPoint(originRect, pos);
1679 // From that point-of-origin, get the exact (x, y) coordinate for the top-left corner of the
1680 // overlay in this position. We use the top-left corner for calculations and later translate
1681 // this into an appropriate (top, left, bottom, right) style.
1682 var overlayPoint = this._getOverlayPoint(originPoint, overlayRect, pos);
1683 // Calculate how well the overlay would fit into the viewport with this point.
1684 var overlayFit = this._getOverlayFit(overlayPoint, overlayRect, viewportRect, pos);
1685 // If the overlay, without any further work, fits into the viewport, use this position.
1686 if (overlayFit.isCompletelyWithinViewport) {
1687 this._isPushed = false;
1688 this._applyPosition(pos, originPoint);
1689 return;
1690 }
1691 // If the overlay has flexible dimensions, we can use this position
1692 // so long as there's enough space for the minimum dimensions.
1693 if (this._canFitWithFlexibleDimensions(overlayFit, overlayPoint, viewportRect)) {
1694 // Save positions where the overlay will fit with flexible dimensions. We will use these
1695 // if none of the positions fit *without* flexible dimensions.
1696 flexibleFits.push({
1697 position: pos,
1698 origin: originPoint,
1699 overlayRect: overlayRect,
1700 boundingBoxRect: this._calculateBoundingBoxRect(originPoint, pos)
1701 });
1702 continue;
1703 }
1704 // If the current preferred position does not fit on the screen, remember the position
1705 // if it has more visible area on-screen than we've seen and move onto the next preferred
1706 // position.
1707 if (!fallback || fallback.overlayFit.visibleArea < overlayFit.visibleArea) {
1708 fallback = { overlayFit: overlayFit, overlayPoint: overlayPoint, originPoint: originPoint, position: pos, overlayRect: overlayRect };
1709 }
1710 }
1711 }
1712 catch (e_1_1) { e_1 = { error: e_1_1 }; }
1713 finally {
1714 try {
1715 if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
1716 }
1717 finally { if (e_1) throw e_1.error; }
1718 }
1719 // If there are any positions where the overlay would fit with flexible dimensions, choose the
1720 // one that has the greatest area available modified by the position's weight
1721 if (flexibleFits.length) {
1722 var bestFit = null;
1723 var bestScore = -1;
1724 try {
1725 for (var flexibleFits_1 = __values(flexibleFits), flexibleFits_1_1 = flexibleFits_1.next(); !flexibleFits_1_1.done; flexibleFits_1_1 = flexibleFits_1.next()) {
1726 var fit = flexibleFits_1_1.value;
1727 var score = fit.boundingBoxRect.width * fit.boundingBoxRect.height * (fit.position.weight || 1);
1728 if (score > bestScore) {
1729 bestScore = score;
1730 bestFit = fit;
1731 }
1732 }
1733 }
1734 catch (e_2_1) { e_2 = { error: e_2_1 }; }
1735 finally {
1736 try {
1737 if (flexibleFits_1_1 && !flexibleFits_1_1.done && (_b = flexibleFits_1.return)) _b.call(flexibleFits_1);
1738 }
1739 finally { if (e_2) throw e_2.error; }
1740 }
1741 this._isPushed = false;
1742 this._applyPosition(bestFit.position, bestFit.origin);
1743 return;
1744 }
1745 // When none of the preferred positions fit within the viewport, take the position
1746 // that went off-screen the least and attempt to push it on-screen.
1747 if (this._canPush) {
1748 // TODO(jelbourn): after pushing, the opening "direction" of the overlay might not make sense.
1749 this._isPushed = true;
1750 this._applyPosition(fallback.position, fallback.originPoint);
1751 return;
1752 }
1753 // All options for getting the overlay within the viewport have been exhausted, so go with the
1754 // position that went off-screen the least.
1755 this._applyPosition(fallback.position, fallback.originPoint);
1756 };
1757 FlexibleConnectedPositionStrategy.prototype.detach = function () {
1758 this._clearPanelClasses();
1759 this._lastPosition = null;
1760 this._previousPushAmount = null;
1761 this._resizeSubscription.unsubscribe();
1762 };
1763 /** Cleanup after the element gets destroyed. */
1764 FlexibleConnectedPositionStrategy.prototype.dispose = function () {
1765 if (this._isDisposed) {
1766 return;
1767 }
1768 // We can't use `_resetBoundingBoxStyles` here, because it resets
1769 // some properties to zero, rather than removing them.
1770 if (this._boundingBox) {
1771 extendStyles(this._boundingBox.style, {
1772 top: '',
1773 left: '',
1774 right: '',
1775 bottom: '',
1776 height: '',
1777 width: '',
1778 alignItems: '',
1779 justifyContent: '',
1780 });
1781 }
1782 if (this._pane) {
1783 this._resetOverlayElementStyles();
1784 }
1785 if (this._overlayRef) {
1786 this._overlayRef.hostElement.classList.remove(boundingBoxClass);
1787 }
1788 this.detach();
1789 this._positionChanges.complete();
1790 this._overlayRef = this._boundingBox = null;
1791 this._isDisposed = true;
1792 };
1793 /**
1794 * This re-aligns the overlay element with the trigger in its last calculated position,
1795 * even if a position higher in the "preferred positions" list would now fit. This
1796 * allows one to re-align the panel without changing the orientation of the panel.
1797 */
1798 FlexibleConnectedPositionStrategy.prototype.reapplyLastPosition = function () {
1799 if (!this._isDisposed && (!this._platform || this._platform.isBrowser)) {
1800 this._originRect = this._getOriginRect();
1801 this._overlayRect = this._pane.getBoundingClientRect();
1802 this._viewportRect = this._getNarrowedViewportRect();
1803 var lastPosition = this._lastPosition || this._preferredPositions[0];
1804 var originPoint = this._getOriginPoint(this._originRect, lastPosition);
1805 this._applyPosition(lastPosition, originPoint);
1806 }
1807 };
1808 /**
1809 * Sets the list of Scrollable containers that host the origin element so that
1810 * on reposition we can evaluate if it or the overlay has been clipped or outside view. Every
1811 * Scrollable must be an ancestor element of the strategy's origin element.
1812 */
1813 FlexibleConnectedPositionStrategy.prototype.withScrollableContainers = function (scrollables) {
1814 this._scrollables = scrollables;
1815 return this;
1816 };
1817 /**
1818 * Adds new preferred positions.
1819 * @param positions List of positions options for this overlay.
1820 */
1821 FlexibleConnectedPositionStrategy.prototype.withPositions = function (positions) {
1822 this._preferredPositions = positions;
1823 // If the last calculated position object isn't part of the positions anymore, clear
1824 // it in order to avoid it being picked up if the consumer tries to re-apply.
1825 if (positions.indexOf(this._lastPosition) === -1) {
1826 this._lastPosition = null;
1827 }
1828 this._validatePositions();
1829 return this;
1830 };
1831 /**
1832 * Sets a minimum distance the overlay may be positioned to the edge of the viewport.
1833 * @param margin Required margin between the overlay and the viewport edge in pixels.
1834 */
1835 FlexibleConnectedPositionStrategy.prototype.withViewportMargin = function (margin) {
1836 this._viewportMargin = margin;
1837 return this;
1838 };
1839 /** Sets whether the overlay's width and height can be constrained to fit within the viewport. */
1840 FlexibleConnectedPositionStrategy.prototype.withFlexibleDimensions = function (flexibleDimensions) {
1841 if (flexibleDimensions === void 0) { flexibleDimensions = true; }
1842 this._hasFlexibleDimensions = flexibleDimensions;
1843 return this;
1844 };
1845 /** Sets whether the overlay can grow after the initial open via flexible width/height. */
1846 FlexibleConnectedPositionStrategy.prototype.withGrowAfterOpen = function (growAfterOpen) {
1847 if (growAfterOpen === void 0) { growAfterOpen = true; }
1848 this._growAfterOpen = growAfterOpen;
1849 return this;
1850 };
1851 /** Sets whether the overlay can be pushed on-screen if none of the provided positions fit. */
1852 FlexibleConnectedPositionStrategy.prototype.withPush = function (canPush) {
1853 if (canPush === void 0) { canPush = true; }
1854 this._canPush = canPush;
1855 return this;
1856 };
1857 /**
1858 * Sets whether the overlay's position should be locked in after it is positioned
1859 * initially. When an overlay is locked in, it won't attempt to reposition itself
1860 * when the position is re-applied (e.g. when the user scrolls away).
1861 * @param isLocked Whether the overlay should locked in.
1862 */
1863 FlexibleConnectedPositionStrategy.prototype.withLockedPosition = function (isLocked) {
1864 if (isLocked === void 0) { isLocked = true; }
1865 this._positionLocked = isLocked;
1866 return this;
1867 };
1868 /**
1869 * Sets the origin, relative to which to position the overlay.
1870 * Using an element origin is useful for building components that need to be positioned
1871 * relatively to a trigger (e.g. dropdown menus or tooltips), whereas using a point can be
1872 * used for cases like contextual menus which open relative to the user's pointer.
1873 * @param origin Reference to the new origin.
1874 */
1875 FlexibleConnectedPositionStrategy.prototype.setOrigin = function (origin) {
1876 this._origin = origin;
1877 return this;
1878 };
1879 /**
1880 * Sets the default offset for the overlay's connection point on the x-axis.
1881 * @param offset New offset in the X axis.
1882 */
1883 FlexibleConnectedPositionStrategy.prototype.withDefaultOffsetX = function (offset) {
1884 this._offsetX = offset;
1885 return this;
1886 };
1887 /**
1888 * Sets the default offset for the overlay's connection point on the y-axis.
1889 * @param offset New offset in the Y axis.
1890 */
1891 FlexibleConnectedPositionStrategy.prototype.withDefaultOffsetY = function (offset) {
1892 this._offsetY = offset;
1893 return this;
1894 };
1895 /**
1896 * Configures that the position strategy should set a `transform-origin` on some elements
1897 * inside the overlay, depending on the current position that is being applied. This is
1898 * useful for the cases where the origin of an animation can change depending on the
1899 * alignment of the overlay.
1900 * @param selector CSS selector that will be used to find the target
1901 * elements onto which to set the transform origin.
1902 */
1903 FlexibleConnectedPositionStrategy.prototype.withTransformOriginOn = function (selector) {
1904 this._transformOriginSelector = selector;
1905 return this;
1906 };
1907 /**
1908 * Gets the (x, y) coordinate of a connection point on the origin based on a relative position.
1909 */
1910 FlexibleConnectedPositionStrategy.prototype._getOriginPoint = function (originRect, pos) {
1911 var x;
1912 if (pos.originX == 'center') {
1913 // Note: when centering we should always use the `left`
1914 // offset, otherwise the position will be wrong in RTL.
1915 x = originRect.left + (originRect.width / 2);
1916 }
1917 else {
1918 var startX = this._isRtl() ? originRect.right : originRect.left;
1919 var endX = this._isRtl() ? originRect.left : originRect.right;
1920 x = pos.originX == 'start' ? startX : endX;
1921 }
1922 var y;
1923 if (pos.originY == 'center') {
1924 y = originRect.top + (originRect.height / 2);
1925 }
1926 else {
1927 y = pos.originY == 'top' ? originRect.top : originRect.bottom;
1928 }
1929 return { x: x, y: y };
1930 };
1931 /**
1932 * Gets the (x, y) coordinate of the top-left corner of the overlay given a given position and
1933 * origin point to which the overlay should be connected.
1934 */
1935 FlexibleConnectedPositionStrategy.prototype._getOverlayPoint = function (originPoint, overlayRect, pos) {
1936 // Calculate the (overlayStartX, overlayStartY), the start of the
1937 // potential overlay position relative to the origin point.
1938 var overlayStartX;
1939 if (pos.overlayX == 'center') {
1940 overlayStartX = -overlayRect.width / 2;
1941 }
1942 else if (pos.overlayX === 'start') {
1943 overlayStartX = this._isRtl() ? -overlayRect.width : 0;
1944 }
1945 else {
1946 overlayStartX = this._isRtl() ? 0 : -overlayRect.width;
1947 }
1948 var overlayStartY;
1949 if (pos.overlayY == 'center') {
1950 overlayStartY = -overlayRect.height / 2;
1951 }
1952 else {
1953 overlayStartY = pos.overlayY == 'top' ? 0 : -overlayRect.height;
1954 }
1955 // The (x, y) coordinates of the overlay.
1956 return {
1957 x: originPoint.x + overlayStartX,
1958 y: originPoint.y + overlayStartY,
1959 };
1960 };
1961 /** Gets how well an overlay at the given point will fit within the viewport. */
1962 FlexibleConnectedPositionStrategy.prototype._getOverlayFit = function (point, rawOverlayRect, viewport, position) {
1963 // Round the overlay rect when comparing against the
1964 // viewport, because the viewport is always rounded.
1965 var overlay = getRoundedBoundingClientRect(rawOverlayRect);
1966 var x = point.x, y = point.y;
1967 var offsetX = this._getOffset(position, 'x');
1968 var offsetY = this._getOffset(position, 'y');
1969 // Account for the offsets since they could push the overlay out of the viewport.
1970 if (offsetX) {
1971 x += offsetX;
1972 }
1973 if (offsetY) {
1974 y += offsetY;
1975 }
1976 // How much the overlay would overflow at this position, on each side.
1977 var leftOverflow = 0 - x;
1978 var rightOverflow = (x + overlay.width) - viewport.width;
1979 var topOverflow = 0 - y;
1980 var bottomOverflow = (y + overlay.height) - viewport.height;
1981 // Visible parts of the element on each axis.
1982 var visibleWidth = this._subtractOverflows(overlay.width, leftOverflow, rightOverflow);
1983 var visibleHeight = this._subtractOverflows(overlay.height, topOverflow, bottomOverflow);
1984 var visibleArea = visibleWidth * visibleHeight;
1985 return {
1986 visibleArea: visibleArea,
1987 isCompletelyWithinViewport: (overlay.width * overlay.height) === visibleArea,
1988 fitsInViewportVertically: visibleHeight === overlay.height,
1989 fitsInViewportHorizontally: visibleWidth == overlay.width,
1990 };
1991 };
1992 /**
1993 * Whether the overlay can fit within the viewport when it may resize either its width or height.
1994 * @param fit How well the overlay fits in the viewport at some position.
1995 * @param point The (x, y) coordinates of the overlat at some position.
1996 * @param viewport The geometry of the viewport.
1997 */
1998 FlexibleConnectedPositionStrategy.prototype._canFitWithFlexibleDimensions = function (fit, point, viewport) {
1999 if (this._hasFlexibleDimensions) {
2000 var availableHeight = viewport.bottom - point.y;
2001 var availableWidth = viewport.right - point.x;
2002 var minHeight = getPixelValue(this._overlayRef.getConfig().minHeight);
2003 var minWidth = getPixelValue(this._overlayRef.getConfig().minWidth);
2004 var verticalFit = fit.fitsInViewportVertically ||
2005 (minHeight != null && minHeight <= availableHeight);
2006 var horizontalFit = fit.fitsInViewportHorizontally ||
2007 (minWidth != null && minWidth <= availableWidth);
2008 return verticalFit && horizontalFit;
2009 }
2010 return false;
2011 };
2012 /**
2013 * Gets the point at which the overlay can be "pushed" on-screen. If the overlay is larger than
2014 * the viewport, the top-left corner will be pushed on-screen (with overflow occuring on the
2015 * right and bottom).
2016 *
2017 * @param start Starting point from which the overlay is pushed.
2018 * @param overlay Dimensions of the overlay.
2019 * @param scrollPosition Current viewport scroll position.
2020 * @returns The point at which to position the overlay after pushing. This is effectively a new
2021 * originPoint.
2022 */
2023 FlexibleConnectedPositionStrategy.prototype._pushOverlayOnScreen = function (start, rawOverlayRect, scrollPosition) {
2024 // If the position is locked and we've pushed the overlay already, reuse the previous push
2025 // amount, rather than pushing it again. If we were to continue pushing, the element would
2026 // remain in the viewport, which goes against the expectations when position locking is enabled.
2027 if (this._previousPushAmount && this._positionLocked) {
2028 return {
2029 x: start.x + this._previousPushAmount.x,
2030 y: start.y + this._previousPushAmount.y
2031 };
2032 }
2033 // Round the overlay rect when comparing against the
2034 // viewport, because the viewport is always rounded.
2035 var overlay = getRoundedBoundingClientRect(rawOverlayRect);
2036 var viewport = this._viewportRect;
2037 // Determine how much the overlay goes outside the viewport on each
2038 // side, which we'll use to decide which direction to push it.
2039 var overflowRight = Math.max(start.x + overlay.width - viewport.width, 0);
2040 var overflowBottom = Math.max(start.y + overlay.height - viewport.height, 0);
2041 var overflowTop = Math.max(viewport.top - scrollPosition.top - start.y, 0);
2042 var overflowLeft = Math.max(viewport.left - scrollPosition.left - start.x, 0);
2043 // Amount by which to push the overlay in each axis such that it remains on-screen.
2044 var pushX = 0;
2045 var pushY = 0;
2046 // If the overlay fits completely within the bounds of the viewport, push it from whichever
2047 // direction is goes off-screen. Otherwise, push the top-left corner such that its in the
2048 // viewport and allow for the trailing end of the overlay to go out of bounds.
2049 if (overlay.width <= viewport.width) {
2050 pushX = overflowLeft || -overflowRight;
2051 }
2052 else {
2053 pushX = start.x < this._viewportMargin ? (viewport.left - scrollPosition.left) - start.x : 0;
2054 }
2055 if (overlay.height <= viewport.height) {
2056 pushY = overflowTop || -overflowBottom;
2057 }
2058 else {
2059 pushY = start.y < this._viewportMargin ? (viewport.top - scrollPosition.top) - start.y : 0;
2060 }
2061 this._previousPushAmount = { x: pushX, y: pushY };
2062 return {
2063 x: start.x + pushX,
2064 y: start.y + pushY,
2065 };
2066 };
2067 /**
2068 * Applies a computed position to the overlay and emits a position change.
2069 * @param position The position preference
2070 * @param originPoint The point on the origin element where the overlay is connected.
2071 */
2072 FlexibleConnectedPositionStrategy.prototype._applyPosition = function (position, originPoint) {
2073 this._setTransformOrigin(position);
2074 this._setOverlayElementStyles(originPoint, position);
2075 this._setBoundingBoxStyles(originPoint, position);
2076 if (position.panelClass) {
2077 this._addPanelClasses(position.panelClass);
2078 }
2079 // Save the last connected position in case the position needs to be re-calculated.
2080 this._lastPosition = position;
2081 // Notify that the position has been changed along with its change properties.
2082 // We only emit if we've got any subscriptions, because the scroll visibility
2083 // calculcations can be somewhat expensive.
2084 if (this._positionChanges.observers.length) {
2085 var scrollableViewProperties = this._getScrollVisibility();
2086 var changeEvent = new ConnectedOverlayPositionChange(position, scrollableViewProperties);
2087 this._positionChanges.next(changeEvent);
2088 }
2089 this._isInitialRender = false;
2090 };
2091 /** Sets the transform origin based on the configured selector and the passed-in position. */
2092 FlexibleConnectedPositionStrategy.prototype._setTransformOrigin = function (position) {
2093 if (!this._transformOriginSelector) {
2094 return;
2095 }
2096 var elements = this._boundingBox.querySelectorAll(this._transformOriginSelector);
2097 var xOrigin;
2098 var yOrigin = position.overlayY;
2099 if (position.overlayX === 'center') {
2100 xOrigin = 'center';
2101 }
2102 else if (this._isRtl()) {
2103 xOrigin = position.overlayX === 'start' ? 'right' : 'left';
2104 }
2105 else {
2106 xOrigin = position.overlayX === 'start' ? 'left' : 'right';
2107 }
2108 for (var i = 0; i < elements.length; i++) {
2109 elements[i].style.transformOrigin = xOrigin + " " + yOrigin;
2110 }
2111 };
2112 /**
2113 * Gets the position and size of the overlay's sizing container.
2114 *
2115 * This method does no measuring and applies no styles so that we can cheaply compute the
2116 * bounds for all positions and choose the best fit based on these results.
2117 */
2118 FlexibleConnectedPositionStrategy.prototype._calculateBoundingBoxRect = function (origin, position) {
2119 var viewport = this._viewportRect;
2120 var isRtl = this._isRtl();
2121 var height, top, bottom;
2122 if (position.overlayY === 'top') {
2123 // Overlay is opening "downward" and thus is bound by the bottom viewport edge.
2124 top = origin.y;
2125 height = viewport.height - top + this._viewportMargin;
2126 }
2127 else if (position.overlayY === 'bottom') {
2128 // Overlay is opening "upward" and thus is bound by the top viewport edge. We need to add
2129 // the viewport margin back in, because the viewport rect is narrowed down to remove the
2130 // margin, whereas the `origin` position is calculated based on its `ClientRect`.
2131 bottom = viewport.height - origin.y + this._viewportMargin * 2;
2132 height = viewport.height - bottom + this._viewportMargin;
2133 }
2134 else {
2135 // If neither top nor bottom, it means that the overlay is vertically centered on the
2136 // origin point. Note that we want the position relative to the viewport, rather than
2137 // the page, which is why we don't use something like `viewport.bottom - origin.y` and
2138 // `origin.y - viewport.top`.
2139 var smallestDistanceToViewportEdge = Math.min(viewport.bottom - origin.y + viewport.top, origin.y);
2140 var previousHeight = this._lastBoundingBoxSize.height;
2141 height = smallestDistanceToViewportEdge * 2;
2142 top = origin.y - smallestDistanceToViewportEdge;
2143 if (height > previousHeight && !this._isInitialRender && !this._growAfterOpen) {
2144 top = origin.y - (previousHeight / 2);
2145 }
2146 }
2147 // The overlay is opening 'right-ward' (the content flows to the right).
2148 var isBoundedByRightViewportEdge = (position.overlayX === 'start' && !isRtl) ||
2149 (position.overlayX === 'end' && isRtl);
2150 // The overlay is opening 'left-ward' (the content flows to the left).
2151 var isBoundedByLeftViewportEdge = (position.overlayX === 'end' && !isRtl) ||
2152 (position.overlayX === 'start' && isRtl);
2153 var width, left, right;
2154 if (isBoundedByLeftViewportEdge) {
2155 right = viewport.width - origin.x + this._viewportMargin;
2156 width = origin.x - this._viewportMargin;
2157 }
2158 else if (isBoundedByRightViewportEdge) {
2159 left = origin.x;
2160 width = viewport.right - origin.x;
2161 }
2162 else {
2163 // If neither start nor end, it means that the overlay is horizontally centered on the
2164 // origin point. Note that we want the position relative to the viewport, rather than
2165 // the page, which is why we don't use something like `viewport.right - origin.x` and
2166 // `origin.x - viewport.left`.
2167 var smallestDistanceToViewportEdge = Math.min(viewport.right - origin.x + viewport.left, origin.x);
2168 var previousWidth = this._lastBoundingBoxSize.width;
2169 width = smallestDistanceToViewportEdge * 2;
2170 left = origin.x - smallestDistanceToViewportEdge;
2171 if (width > previousWidth && !this._isInitialRender && !this._growAfterOpen) {
2172 left = origin.x - (previousWidth / 2);
2173 }
2174 }
2175 return { top: top, left: left, bottom: bottom, right: right, width: width, height: height };
2176 };
2177 /**
2178 * Sets the position and size of the overlay's sizing wrapper. The wrapper is positioned on the
2179 * origin's connection point and stetches to the bounds of the viewport.
2180 *
2181 * @param origin The point on the origin element where the overlay is connected.
2182 * @param position The position preference
2183 */
2184 FlexibleConnectedPositionStrategy.prototype._setBoundingBoxStyles = function (origin, position) {
2185 var boundingBoxRect = this._calculateBoundingBoxRect(origin, position);
2186 // It's weird if the overlay *grows* while scrolling, so we take the last size into account
2187 // when applying a new size.
2188 if (!this._isInitialRender && !this._growAfterOpen) {
2189 boundingBoxRect.height = Math.min(boundingBoxRect.height, this._lastBoundingBoxSize.height);
2190 boundingBoxRect.width = Math.min(boundingBoxRect.width, this._lastBoundingBoxSize.width);
2191 }
2192 var styles = {};
2193 if (this._hasExactPosition()) {
2194 styles.top = styles.left = '0';
2195 styles.bottom = styles.right = styles.maxHeight = styles.maxWidth = '';
2196 styles.width = styles.height = '100%';
2197 }
2198 else {
2199 var maxHeight = this._overlayRef.getConfig().maxHeight;
2200 var maxWidth = this._overlayRef.getConfig().maxWidth;
2201 styles.height = coercion.coerceCssPixelValue(boundingBoxRect.height);
2202 styles.top = coercion.coerceCssPixelValue(boundingBoxRect.top);
2203 styles.bottom = coercion.coerceCssPixelValue(boundingBoxRect.bottom);
2204 styles.width = coercion.coerceCssPixelValue(boundingBoxRect.width);
2205 styles.left = coercion.coerceCssPixelValue(boundingBoxRect.left);
2206 styles.right = coercion.coerceCssPixelValue(boundingBoxRect.right);
2207 // Push the pane content towards the proper direction.
2208 if (position.overlayX === 'center') {
2209 styles.alignItems = 'center';
2210 }
2211 else {
2212 styles.alignItems = position.overlayX === 'end' ? 'flex-end' : 'flex-start';
2213 }
2214 if (position.overlayY === 'center') {
2215 styles.justifyContent = 'center';
2216 }
2217 else {
2218 styles.justifyContent = position.overlayY === 'bottom' ? 'flex-end' : 'flex-start';
2219 }
2220 if (maxHeight) {
2221 styles.maxHeight = coercion.coerceCssPixelValue(maxHeight);
2222 }
2223 if (maxWidth) {
2224 styles.maxWidth = coercion.coerceCssPixelValue(maxWidth);
2225 }
2226 }
2227 this._lastBoundingBoxSize = boundingBoxRect;
2228 extendStyles(this._boundingBox.style, styles);
2229 };
2230 /** Resets the styles for the bounding box so that a new positioning can be computed. */
2231 FlexibleConnectedPositionStrategy.prototype._resetBoundingBoxStyles = function () {
2232 extendStyles(this._boundingBox.style, {
2233 top: '0',
2234 left: '0',
2235 right: '0',
2236 bottom: '0',
2237 height: '',
2238 width: '',
2239 alignItems: '',
2240 justifyContent: '',
2241 });
2242 };
2243 /** Resets the styles for the overlay pane so that a new positioning can be computed. */
2244 FlexibleConnectedPositionStrategy.prototype._resetOverlayElementStyles = function () {
2245 extendStyles(this._pane.style, {
2246 top: '',
2247 left: '',
2248 bottom: '',
2249 right: '',
2250 position: '',
2251 transform: '',
2252 });
2253 };
2254 /** Sets positioning styles to the overlay element. */
2255 FlexibleConnectedPositionStrategy.prototype._setOverlayElementStyles = function (originPoint, position) {
2256 var styles = {};
2257 var hasExactPosition = this._hasExactPosition();
2258 var hasFlexibleDimensions = this._hasFlexibleDimensions;
2259 var config = this._overlayRef.getConfig();
2260 if (hasExactPosition) {
2261 var scrollPosition = this._viewportRuler.getViewportScrollPosition();
2262 extendStyles(styles, this._getExactOverlayY(position, originPoint, scrollPosition));
2263 extendStyles(styles, this._getExactOverlayX(position, originPoint, scrollPosition));
2264 }
2265 else {
2266 styles.position = 'static';
2267 }
2268 // Use a transform to apply the offsets. We do this because the `center` positions rely on
2269 // being in the normal flex flow and setting a `top` / `left` at all will completely throw
2270 // off the position. We also can't use margins, because they won't have an effect in some
2271 // cases where the element doesn't have anything to "push off of". Finally, this works
2272 // better both with flexible and non-flexible positioning.
2273 var transformString = '';
2274 var offsetX = this._getOffset(position, 'x');
2275 var offsetY = this._getOffset(position, 'y');
2276 if (offsetX) {
2277 transformString += "translateX(" + offsetX + "px) ";
2278 }
2279 if (offsetY) {
2280 transformString += "translateY(" + offsetY + "px)";
2281 }
2282 styles.transform = transformString.trim();
2283 // If a maxWidth or maxHeight is specified on the overlay, we remove them. We do this because
2284 // we need these values to both be set to "100%" for the automatic flexible sizing to work.
2285 // The maxHeight and maxWidth are set on the boundingBox in order to enforce the constraint.
2286 // Note that this doesn't apply when we have an exact position, in which case we do want to
2287 // apply them because they'll be cleared from the bounding box.
2288 if (config.maxHeight) {
2289 if (hasExactPosition) {
2290 styles.maxHeight = coercion.coerceCssPixelValue(config.maxHeight);
2291 }
2292 else if (hasFlexibleDimensions) {
2293 styles.maxHeight = '';
2294 }
2295 }
2296 if (config.maxWidth) {
2297 if (hasExactPosition) {
2298 styles.maxWidth = coercion.coerceCssPixelValue(config.maxWidth);
2299 }
2300 else if (hasFlexibleDimensions) {
2301 styles.maxWidth = '';
2302 }
2303 }
2304 extendStyles(this._pane.style, styles);
2305 };
2306 /** Gets the exact top/bottom for the overlay when not using flexible sizing or when pushing. */
2307 FlexibleConnectedPositionStrategy.prototype._getExactOverlayY = function (position, originPoint, scrollPosition) {
2308 // Reset any existing styles. This is necessary in case the
2309 // preferred position has changed since the last `apply`.
2310 var styles = { top: '', bottom: '' };
2311 var overlayPoint = this._getOverlayPoint(originPoint, this._overlayRect, position);
2312 if (this._isPushed) {
2313 overlayPoint = this._pushOverlayOnScreen(overlayPoint, this._overlayRect, scrollPosition);
2314 }
2315 var virtualKeyboardOffset = this._overlayContainer.getContainerElement().getBoundingClientRect().top;
2316 // Normally this would be zero, however when the overlay is attached to an input (e.g. in an
2317 // autocomplete), mobile browsers will shift everything in order to put the input in the middle
2318 // of the screen and to make space for the virtual keyboard. We need to account for this offset,
2319 // otherwise our positioning will be thrown off.
2320 overlayPoint.y -= virtualKeyboardOffset;
2321 // We want to set either `top` or `bottom` based on whether the overlay wants to appear
2322 // above or below the origin and the direction in which the element will expand.
2323 if (position.overlayY === 'bottom') {
2324 // When using `bottom`, we adjust the y position such that it is the distance
2325 // from the bottom of the viewport rather than the top.
2326 var documentHeight = this._document.documentElement.clientHeight;
2327 styles.bottom = documentHeight - (overlayPoint.y + this._overlayRect.height) + "px";
2328 }
2329 else {
2330 styles.top = coercion.coerceCssPixelValue(overlayPoint.y);
2331 }
2332 return styles;
2333 };
2334 /** Gets the exact left/right for the overlay when not using flexible sizing or when pushing. */
2335 FlexibleConnectedPositionStrategy.prototype._getExactOverlayX = function (position, originPoint, scrollPosition) {
2336 // Reset any existing styles. This is necessary in case the preferred position has
2337 // changed since the last `apply`.
2338 var styles = { left: '', right: '' };
2339 var overlayPoint = this._getOverlayPoint(originPoint, this._overlayRect, position);
2340 if (this._isPushed) {
2341 overlayPoint = this._pushOverlayOnScreen(overlayPoint, this._overlayRect, scrollPosition);
2342 }
2343 // We want to set either `left` or `right` based on whether the overlay wants to appear "before"
2344 // or "after" the origin, which determines the direction in which the element will expand.
2345 // For the horizontal axis, the meaning of "before" and "after" change based on whether the
2346 // page is in RTL or LTR.
2347 var horizontalStyleProperty;
2348 if (this._isRtl()) {
2349 horizontalStyleProperty = position.overlayX === 'end' ? 'left' : 'right';
2350 }
2351 else {
2352 horizontalStyleProperty = position.overlayX === 'end' ? 'right' : 'left';
2353 }
2354 // When we're setting `right`, we adjust the x position such that it is the distance
2355 // from the right edge of the viewport rather than the left edge.
2356 if (horizontalStyleProperty === 'right') {
2357 var documentWidth = this._document.documentElement.clientWidth;
2358 styles.right = documentWidth - (overlayPoint.x + this._overlayRect.width) + "px";
2359 }
2360 else {
2361 styles.left = coercion.coerceCssPixelValue(overlayPoint.x);
2362 }
2363 return styles;
2364 };
2365 /**
2366 * Gets the view properties of the trigger and overlay, including whether they are clipped
2367 * or completely outside the view of any of the strategy's scrollables.
2368 */
2369 FlexibleConnectedPositionStrategy.prototype._getScrollVisibility = function () {
2370 // Note: needs fresh rects since the position could've changed.
2371 var originBounds = this._getOriginRect();
2372 var overlayBounds = this._pane.getBoundingClientRect();
2373 // TODO(jelbourn): instead of needing all of the client rects for these scrolling containers
2374 // every time, we should be able to use the scrollTop of the containers if the size of those
2375 // containers hasn't changed.
2376 var scrollContainerBounds = this._scrollables.map(function (scrollable) {
2377 return scrollable.getElementRef().nativeElement.getBoundingClientRect();
2378 });
2379 return {
2380 isOriginClipped: isElementClippedByScrolling(originBounds, scrollContainerBounds),
2381 isOriginOutsideView: isElementScrolledOutsideView(originBounds, scrollContainerBounds),
2382 isOverlayClipped: isElementClippedByScrolling(overlayBounds, scrollContainerBounds),
2383 isOverlayOutsideView: isElementScrolledOutsideView(overlayBounds, scrollContainerBounds),
2384 };
2385 };
2386 /** Subtracts the amount that an element is overflowing on an axis from its length. */
2387 FlexibleConnectedPositionStrategy.prototype._subtractOverflows = function (length) {
2388 var overflows = [];
2389 for (var _i = 1; _i < arguments.length; _i++) {
2390 overflows[_i - 1] = arguments[_i];
2391 }
2392 return overflows.reduce(function (currentValue, currentOverflow) {
2393 return currentValue - Math.max(currentOverflow, 0);
2394 }, length);
2395 };
2396 /** Narrows the given viewport rect by the current _viewportMargin. */
2397 FlexibleConnectedPositionStrategy.prototype._getNarrowedViewportRect = function () {
2398 // We recalculate the viewport rect here ourselves, rather than using the ViewportRuler,
2399 // because we want to use the `clientWidth` and `clientHeight` as the base. The difference
2400 // being that the client properties don't include the scrollbar, as opposed to `innerWidth`
2401 // and `innerHeight` that do. This is necessary, because the overlay container uses
2402 // 100% `width` and `height` which don't include the scrollbar either.
2403 var width = this._document.documentElement.clientWidth;
2404 var height = this._document.documentElement.clientHeight;
2405 var scrollPosition = this._viewportRuler.getViewportScrollPosition();
2406 return {
2407 top: scrollPosition.top + this._viewportMargin,
2408 left: scrollPosition.left + this._viewportMargin,
2409 right: scrollPosition.left + width - this._viewportMargin,
2410 bottom: scrollPosition.top + height - this._viewportMargin,
2411 width: width - (2 * this._viewportMargin),
2412 height: height - (2 * this._viewportMargin),
2413 };
2414 };
2415 /** Whether the we're dealing with an RTL context */
2416 FlexibleConnectedPositionStrategy.prototype._isRtl = function () {
2417 return this._overlayRef.getDirection() === 'rtl';
2418 };
2419 /** Determines whether the overlay uses exact or flexible positioning. */
2420 FlexibleConnectedPositionStrategy.prototype._hasExactPosition = function () {
2421 return !this._hasFlexibleDimensions || this._isPushed;
2422 };
2423 /** Retrieves the offset of a position along the x or y axis. */
2424 FlexibleConnectedPositionStrategy.prototype._getOffset = function (position, axis) {
2425 if (axis === 'x') {
2426 // We don't do something like `position['offset' + axis]` in
2427 // order to avoid breking minifiers that rename properties.
2428 return position.offsetX == null ? this._offsetX : position.offsetX;
2429 }
2430 return position.offsetY == null ? this._offsetY : position.offsetY;
2431 };
2432 /** Validates that the current position match the expected values. */
2433 FlexibleConnectedPositionStrategy.prototype._validatePositions = function () {
2434 if (typeof ngDevMode === 'undefined' || ngDevMode) {
2435 if (!this._preferredPositions.length) {
2436 throw Error('FlexibleConnectedPositionStrategy: At least one position is required.');
2437 }
2438 // TODO(crisbeto): remove these once Angular's template type
2439 // checking is advanced enough to catch these cases.
2440 this._preferredPositions.forEach(function (pair) {
2441 validateHorizontalPosition('originX', pair.originX);
2442 validateVerticalPosition('originY', pair.originY);
2443 validateHorizontalPosition('overlayX', pair.overlayX);
2444 validateVerticalPosition('overlayY', pair.overlayY);
2445 });
2446 }
2447 };
2448 /** Adds a single CSS class or an array of classes on the overlay panel. */
2449 FlexibleConnectedPositionStrategy.prototype._addPanelClasses = function (cssClasses) {
2450 var _this = this;
2451 if (this._pane) {
2452 coercion.coerceArray(cssClasses).forEach(function (cssClass) {
2453 if (cssClass !== '' && _this._appliedPanelClasses.indexOf(cssClass) === -1) {
2454 _this._appliedPanelClasses.push(cssClass);
2455 _this._pane.classList.add(cssClass);
2456 }
2457 });
2458 }
2459 };
2460 /** Clears the classes that the position strategy has applied from the overlay panel. */
2461 FlexibleConnectedPositionStrategy.prototype._clearPanelClasses = function () {
2462 var _this = this;
2463 if (this._pane) {
2464 this._appliedPanelClasses.forEach(function (cssClass) {
2465 _this._pane.classList.remove(cssClass);
2466 });
2467 this._appliedPanelClasses = [];
2468 }
2469 };
2470 /** Returns the ClientRect of the current origin. */
2471 FlexibleConnectedPositionStrategy.prototype._getOriginRect = function () {
2472 var origin = this._origin;
2473 if (origin instanceof i0.ElementRef) {
2474 return origin.nativeElement.getBoundingClientRect();
2475 }
2476 // Check for Element so SVG elements are also supported.
2477 if (origin instanceof Element) {
2478 return origin.getBoundingClientRect();
2479 }
2480 var width = origin.width || 0;
2481 var height = origin.height || 0;
2482 // If the origin is a point, return a client rect as if it was a 0x0 element at the point.
2483 return {
2484 top: origin.y,
2485 bottom: origin.y + height,
2486 left: origin.x,
2487 right: origin.x + width,
2488 height: height,
2489 width: width
2490 };
2491 };
2492 return FlexibleConnectedPositionStrategy;
2493 }());
2494 /** Shallow-extends a stylesheet object with another stylesheet object. */
2495 function extendStyles(destination, source) {
2496 for (var key in source) {
2497 if (source.hasOwnProperty(key)) {
2498 destination[key] = source[key];
2499 }
2500 }
2501 return destination;
2502 }
2503 /**
2504 * Extracts the pixel value as a number from a value, if it's a number
2505 * or a CSS pixel string (e.g. `1337px`). Otherwise returns null.
2506 */
2507 function getPixelValue(input) {
2508 if (typeof input !== 'number' && input != null) {
2509 var _a = __read(input.split(cssUnitPattern), 2), value = _a[0], units = _a[1];
2510 return (!units || units === 'px') ? parseFloat(value) : null;
2511 }
2512 return input || null;
2513 }
2514 /**
2515 * Gets a version of an element's bounding `ClientRect` where all the values are rounded down to
2516 * the nearest pixel. This allows us to account for the cases where there may be sub-pixel
2517 * deviations in the `ClientRect` returned by the browser (e.g. when zoomed in with a percentage
2518 * size, see #21350).
2519 */
2520 function getRoundedBoundingClientRect(clientRect) {
2521 return {
2522 top: Math.floor(clientRect.top),
2523 right: Math.floor(clientRect.right),
2524 bottom: Math.floor(clientRect.bottom),
2525 left: Math.floor(clientRect.left),
2526 width: Math.floor(clientRect.width),
2527 height: Math.floor(clientRect.height)
2528 };
2529 }
2530
2531 /**
2532 * @license
2533 * Copyright Google LLC All Rights Reserved.
2534 *
2535 * Use of this source code is governed by an MIT-style license that can be
2536 * found in the LICENSE file at https://angular.io/license
2537 */
2538 /**
2539 * A strategy for positioning overlays. Using this strategy, an overlay is given an
2540 * implicit position relative to some origin element. The relative position is defined in terms of
2541 * a point on the origin element that is connected to a point on the overlay element. For example,
2542 * a basic dropdown is connecting the bottom-left corner of the origin to the top-left corner
2543 * of the overlay.
2544 * @deprecated Use `FlexibleConnectedPositionStrategy` instead.
2545 * @breaking-change 8.0.0
2546 */
2547 var ConnectedPositionStrategy = /** @class */ (function () {
2548 function ConnectedPositionStrategy(originPos, overlayPos, connectedTo, viewportRuler, document, platform, overlayContainer) {
2549 /** Ordered list of preferred positions, from most to least desirable. */
2550 this._preferredPositions = [];
2551 // Since the `ConnectedPositionStrategy` is deprecated and we don't want to maintain
2552 // the extra logic, we create an instance of the positioning strategy that has some
2553 // defaults that make it behave as the old position strategy and to which we'll
2554 // proxy all of the API calls.
2555 this._positionStrategy = new FlexibleConnectedPositionStrategy(connectedTo, viewportRuler, document, platform, overlayContainer)
2556 .withFlexibleDimensions(false)
2557 .withPush(false)
2558 .withViewportMargin(0);
2559 this.withFallbackPosition(originPos, overlayPos);
2560 this.onPositionChange = this._positionStrategy.positionChanges;
2561 }
2562 Object.defineProperty(ConnectedPositionStrategy.prototype, "positions", {
2563 /** Ordered list of preferred positions, from most to least desirable. */
2564 get: function () {
2565 return this._preferredPositions;
2566 },
2567 enumerable: false,
2568 configurable: true
2569 });
2570 /** Attach this position strategy to an overlay. */
2571 ConnectedPositionStrategy.prototype.attach = function (overlayRef) {
2572 this._overlayRef = overlayRef;
2573 this._positionStrategy.attach(overlayRef);
2574 if (this._direction) {
2575 overlayRef.setDirection(this._direction);
2576 this._direction = null;
2577 }
2578 };
2579 /** Disposes all resources used by the position strategy. */
2580 ConnectedPositionStrategy.prototype.dispose = function () {
2581 this._positionStrategy.dispose();
2582 };
2583 /** @docs-private */
2584 ConnectedPositionStrategy.prototype.detach = function () {
2585 this._positionStrategy.detach();
2586 };
2587 /**
2588 * Updates the position of the overlay element, using whichever preferred position relative
2589 * to the origin fits on-screen.
2590 * @docs-private
2591 */
2592 ConnectedPositionStrategy.prototype.apply = function () {
2593 this._positionStrategy.apply();
2594 };
2595 /**
2596 * Re-positions the overlay element with the trigger in its last calculated position,
2597 * even if a position higher in the "preferred positions" list would now fit. This
2598 * allows one to re-align the panel without changing the orientation of the panel.
2599 */
2600 ConnectedPositionStrategy.prototype.recalculateLastPosition = function () {
2601 this._positionStrategy.reapplyLastPosition();
2602 };
2603 /**
2604 * Sets the list of Scrollable containers that host the origin element so that
2605 * on reposition we can evaluate if it or the overlay has been clipped or outside view. Every
2606 * Scrollable must be an ancestor element of the strategy's origin element.
2607 */
2608 ConnectedPositionStrategy.prototype.withScrollableContainers = function (scrollables) {
2609 this._positionStrategy.withScrollableContainers(scrollables);
2610 };
2611 /**
2612 * Adds a new preferred fallback position.
2613 * @param originPos
2614 * @param overlayPos
2615 */
2616 ConnectedPositionStrategy.prototype.withFallbackPosition = function (originPos, overlayPos, offsetX, offsetY) {
2617 var position = new ConnectionPositionPair(originPos, overlayPos, offsetX, offsetY);
2618 this._preferredPositions.push(position);
2619 this._positionStrategy.withPositions(this._preferredPositions);
2620 return this;
2621 };
2622 /**
2623 * Sets the layout direction so the overlay's position can be adjusted to match.
2624 * @param dir New layout direction.
2625 */
2626 ConnectedPositionStrategy.prototype.withDirection = function (dir) {
2627 // Since the direction might be declared before the strategy is attached,
2628 // we save the value in a temporary property and we'll transfer it to the
2629 // overlay ref on attachment.
2630 if (this._overlayRef) {
2631 this._overlayRef.setDirection(dir);
2632 }
2633 else {
2634 this._direction = dir;
2635 }
2636 return this;
2637 };
2638 /**
2639 * Sets an offset for the overlay's connection point on the x-axis
2640 * @param offset New offset in the X axis.
2641 */
2642 ConnectedPositionStrategy.prototype.withOffsetX = function (offset) {
2643 this._positionStrategy.withDefaultOffsetX(offset);
2644 return this;
2645 };
2646 /**
2647 * Sets an offset for the overlay's connection point on the y-axis
2648 * @param offset New offset in the Y axis.
2649 */
2650 ConnectedPositionStrategy.prototype.withOffsetY = function (offset) {
2651 this._positionStrategy.withDefaultOffsetY(offset);
2652 return this;
2653 };
2654 /**
2655 * Sets whether the overlay's position should be locked in after it is positioned
2656 * initially. When an overlay is locked in, it won't attempt to reposition itself
2657 * when the position is re-applied (e.g. when the user scrolls away).
2658 * @param isLocked Whether the overlay should locked in.
2659 */
2660 ConnectedPositionStrategy.prototype.withLockedPosition = function (isLocked) {
2661 this._positionStrategy.withLockedPosition(isLocked);
2662 return this;
2663 };
2664 /**
2665 * Overwrites the current set of positions with an array of new ones.
2666 * @param positions Position pairs to be set on the strategy.
2667 */
2668 ConnectedPositionStrategy.prototype.withPositions = function (positions) {
2669 this._preferredPositions = positions.slice();
2670 this._positionStrategy.withPositions(this._preferredPositions);
2671 return this;
2672 };
2673 /**
2674 * Sets the origin element, relative to which to position the overlay.
2675 * @param origin Reference to the new origin element.
2676 */
2677 ConnectedPositionStrategy.prototype.setOrigin = function (origin) {
2678 this._positionStrategy.setOrigin(origin);
2679 return this;
2680 };
2681 return ConnectedPositionStrategy;
2682 }());
2683
2684 /**
2685 * @license
2686 * Copyright Google LLC All Rights Reserved.
2687 *
2688 * Use of this source code is governed by an MIT-style license that can be
2689 * found in the LICENSE file at https://angular.io/license
2690 */
2691 /** Class to be added to the overlay pane wrapper. */
2692 var wrapperClass = 'cdk-global-overlay-wrapper';
2693 /**
2694 * A strategy for positioning overlays. Using this strategy, an overlay is given an
2695 * explicit position relative to the browser's viewport. We use flexbox, instead of
2696 * transforms, in order to avoid issues with subpixel rendering which can cause the
2697 * element to become blurry.
2698 */
2699 var GlobalPositionStrategy = /** @class */ (function () {
2700 function GlobalPositionStrategy() {
2701 this._cssPosition = 'static';
2702 this._topOffset = '';
2703 this._bottomOffset = '';
2704 this._leftOffset = '';
2705 this._rightOffset = '';
2706 this._alignItems = '';
2707 this._justifyContent = '';
2708 this._width = '';
2709 this._height = '';
2710 }
2711 GlobalPositionStrategy.prototype.attach = function (overlayRef) {
2712 var config = overlayRef.getConfig();
2713 this._overlayRef = overlayRef;
2714 if (this._width && !config.width) {
2715 overlayRef.updateSize({ width: this._width });
2716 }
2717 if (this._height && !config.height) {
2718 overlayRef.updateSize({ height: this._height });
2719 }
2720 overlayRef.hostElement.classList.add(wrapperClass);
2721 this._isDisposed = false;
2722 };
2723 /**
2724 * Sets the top position of the overlay. Clears any previously set vertical position.
2725 * @param value New top offset.
2726 */
2727 GlobalPositionStrategy.prototype.top = function (value) {
2728 if (value === void 0) { value = ''; }
2729 this._bottomOffset = '';
2730 this._topOffset = value;
2731 this._alignItems = 'flex-start';
2732 return this;
2733 };
2734 /**
2735 * Sets the left position of the overlay. Clears any previously set horizontal position.
2736 * @param value New left offset.
2737 */
2738 GlobalPositionStrategy.prototype.left = function (value) {
2739 if (value === void 0) { value = ''; }
2740 this._rightOffset = '';
2741 this._leftOffset = value;
2742 this._justifyContent = 'flex-start';
2743 return this;
2744 };
2745 /**
2746 * Sets the bottom position of the overlay. Clears any previously set vertical position.
2747 * @param value New bottom offset.
2748 */
2749 GlobalPositionStrategy.prototype.bottom = function (value) {
2750 if (value === void 0) { value = ''; }
2751 this._topOffset = '';
2752 this._bottomOffset = value;
2753 this._alignItems = 'flex-end';
2754 return this;
2755 };
2756 /**
2757 * Sets the right position of the overlay. Clears any previously set horizontal position.
2758 * @param value New right offset.
2759 */
2760 GlobalPositionStrategy.prototype.right = function (value) {
2761 if (value === void 0) { value = ''; }
2762 this._leftOffset = '';
2763 this._rightOffset = value;
2764 this._justifyContent = 'flex-end';
2765 return this;
2766 };
2767 /**
2768 * Sets the overlay width and clears any previously set width.
2769 * @param value New width for the overlay
2770 * @deprecated Pass the `width` through the `OverlayConfig`.
2771 * @breaking-change 8.0.0
2772 */
2773 GlobalPositionStrategy.prototype.width = function (value) {
2774 if (value === void 0) { value = ''; }
2775 if (this._overlayRef) {
2776 this._overlayRef.updateSize({ width: value });
2777 }
2778 else {
2779 this._width = value;
2780 }
2781 return this;
2782 };
2783 /**
2784 * Sets the overlay height and clears any previously set height.
2785 * @param value New height for the overlay
2786 * @deprecated Pass the `height` through the `OverlayConfig`.
2787 * @breaking-change 8.0.0
2788 */
2789 GlobalPositionStrategy.prototype.height = function (value) {
2790 if (value === void 0) { value = ''; }
2791 if (this._overlayRef) {
2792 this._overlayRef.updateSize({ height: value });
2793 }
2794 else {
2795 this._height = value;
2796 }
2797 return this;
2798 };
2799 /**
2800 * Centers the overlay horizontally with an optional offset.
2801 * Clears any previously set horizontal position.
2802 *
2803 * @param offset Overlay offset from the horizontal center.
2804 */
2805 GlobalPositionStrategy.prototype.centerHorizontally = function (offset) {
2806 if (offset === void 0) { offset = ''; }
2807 this.left(offset);
2808 this._justifyContent = 'center';
2809 return this;
2810 };
2811 /**
2812 * Centers the overlay vertically with an optional offset.
2813 * Clears any previously set vertical position.
2814 *
2815 * @param offset Overlay offset from the vertical center.
2816 */
2817 GlobalPositionStrategy.prototype.centerVertically = function (offset) {
2818 if (offset === void 0) { offset = ''; }
2819 this.top(offset);
2820 this._alignItems = 'center';
2821 return this;
2822 };
2823 /**
2824 * Apply the position to the element.
2825 * @docs-private
2826 */
2827 GlobalPositionStrategy.prototype.apply = function () {
2828 // Since the overlay ref applies the strategy asynchronously, it could
2829 // have been disposed before it ends up being applied. If that is the
2830 // case, we shouldn't do anything.
2831 if (!this._overlayRef || !this._overlayRef.hasAttached()) {
2832 return;
2833 }
2834 var styles = this._overlayRef.overlayElement.style;
2835 var parentStyles = this._overlayRef.hostElement.style;
2836 var config = this._overlayRef.getConfig();
2837 var width = config.width, height = config.height, maxWidth = config.maxWidth, maxHeight = config.maxHeight;
2838 var shouldBeFlushHorizontally = (width === '100%' || width === '100vw') &&
2839 (!maxWidth || maxWidth === '100%' || maxWidth === '100vw');
2840 var shouldBeFlushVertically = (height === '100%' || height === '100vh') &&
2841 (!maxHeight || maxHeight === '100%' || maxHeight === '100vh');
2842 styles.position = this._cssPosition;
2843 styles.marginLeft = shouldBeFlushHorizontally ? '0' : this._leftOffset;
2844 styles.marginTop = shouldBeFlushVertically ? '0' : this._topOffset;
2845 styles.marginBottom = this._bottomOffset;
2846 styles.marginRight = this._rightOffset;
2847 if (shouldBeFlushHorizontally) {
2848 parentStyles.justifyContent = 'flex-start';
2849 }
2850 else if (this._justifyContent === 'center') {
2851 parentStyles.justifyContent = 'center';
2852 }
2853 else if (this._overlayRef.getConfig().direction === 'rtl') {
2854 // In RTL the browser will invert `flex-start` and `flex-end` automatically, but we
2855 // don't want that because our positioning is explicitly `left` and `right`, hence
2856 // why we do another inversion to ensure that the overlay stays in the same position.
2857 // TODO: reconsider this if we add `start` and `end` methods.
2858 if (this._justifyContent === 'flex-start') {
2859 parentStyles.justifyContent = 'flex-end';
2860 }
2861 else if (this._justifyContent === 'flex-end') {
2862 parentStyles.justifyContent = 'flex-start';
2863 }
2864 }
2865 else {
2866 parentStyles.justifyContent = this._justifyContent;
2867 }
2868 parentStyles.alignItems = shouldBeFlushVertically ? 'flex-start' : this._alignItems;
2869 };
2870 /**
2871 * Cleans up the DOM changes from the position strategy.
2872 * @docs-private
2873 */
2874 GlobalPositionStrategy.prototype.dispose = function () {
2875 if (this._isDisposed || !this._overlayRef) {
2876 return;
2877 }
2878 var styles = this._overlayRef.overlayElement.style;
2879 var parent = this._overlayRef.hostElement;
2880 var parentStyles = parent.style;
2881 parent.classList.remove(wrapperClass);
2882 parentStyles.justifyContent = parentStyles.alignItems = styles.marginTop =
2883 styles.marginBottom = styles.marginLeft = styles.marginRight = styles.position = '';
2884 this._overlayRef = null;
2885 this._isDisposed = true;
2886 };
2887 return GlobalPositionStrategy;
2888 }());
2889
2890 /**
2891 * @license
2892 * Copyright Google LLC All Rights Reserved.
2893 *
2894 * Use of this source code is governed by an MIT-style license that can be
2895 * found in the LICENSE file at https://angular.io/license
2896 */
2897 /** Builder for overlay position strategy. */
2898 var OverlayPositionBuilder = /** @class */ (function () {
2899 function OverlayPositionBuilder(_viewportRuler, _document, _platform, _overlayContainer) {
2900 this._viewportRuler = _viewportRuler;
2901 this._document = _document;
2902 this._platform = _platform;
2903 this._overlayContainer = _overlayContainer;
2904 }
2905 /**
2906 * Creates a global position strategy.
2907 */
2908 OverlayPositionBuilder.prototype.global = function () {
2909 return new GlobalPositionStrategy();
2910 };
2911 /**
2912 * Creates a relative position strategy.
2913 * @param elementRef
2914 * @param originPos
2915 * @param overlayPos
2916 * @deprecated Use `flexibleConnectedTo` instead.
2917 * @breaking-change 8.0.0
2918 */
2919 OverlayPositionBuilder.prototype.connectedTo = function (elementRef, originPos, overlayPos) {
2920 return new ConnectedPositionStrategy(originPos, overlayPos, elementRef, this._viewportRuler, this._document, this._platform, this._overlayContainer);
2921 };
2922 /**
2923 * Creates a flexible position strategy.
2924 * @param origin Origin relative to which to position the overlay.
2925 */
2926 OverlayPositionBuilder.prototype.flexibleConnectedTo = function (origin) {
2927 return new FlexibleConnectedPositionStrategy(origin, this._viewportRuler, this._document, this._platform, this._overlayContainer);
2928 };
2929 return OverlayPositionBuilder;
2930 }());
2931 OverlayPositionBuilder.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function OverlayPositionBuilder_Factory() { return new OverlayPositionBuilder(i0__namespace.ɵɵinject(i1__namespace.ViewportRuler), i0__namespace.ɵɵinject(i1__namespace$1.DOCUMENT), i0__namespace.ɵɵinject(i2__namespace.Platform), i0__namespace.ɵɵinject(OverlayContainer)); }, token: OverlayPositionBuilder, providedIn: "root" });
2932 OverlayPositionBuilder.decorators = [
2933 { type: i0.Injectable, args: [{ providedIn: 'root' },] }
2934 ];
2935 OverlayPositionBuilder.ctorParameters = function () { return [
2936 { type: i1.ViewportRuler },
2937 { type: undefined, decorators: [{ type: i0.Inject, args: [i1$1.DOCUMENT,] }] },
2938 { type: i2.Platform },
2939 { type: OverlayContainer }
2940 ]; };
2941
2942 /**
2943 * @license
2944 * Copyright Google LLC All Rights Reserved.
2945 *
2946 * Use of this source code is governed by an MIT-style license that can be
2947 * found in the LICENSE file at https://angular.io/license
2948 */
2949 /** Next overlay unique ID. */
2950 var nextUniqueId = 0;
2951 // Note that Overlay is *not* scoped to the app root because of the ComponentFactoryResolver
2952 // which needs to be different depending on where OverlayModule is imported.
2953 /**
2954 * Service to create Overlays. Overlays are dynamically added pieces of floating UI, meant to be
2955 * used as a low-level building block for other components. Dialogs, tooltips, menus,
2956 * selects, etc. can all be built using overlays. The service should primarily be used by authors
2957 * of re-usable components rather than developers building end-user applications.
2958 *
2959 * An overlay *is* a PortalOutlet, so any kind of Portal can be loaded into one.
2960 */
2961 var Overlay = /** @class */ (function () {
2962 function Overlay(
2963 /** Scrolling strategies that can be used when creating an overlay. */
2964 scrollStrategies, _overlayContainer, _componentFactoryResolver, _positionBuilder, _keyboardDispatcher, _injector, _ngZone, _document, _directionality, _location, _outsideClickDispatcher) {
2965 this.scrollStrategies = scrollStrategies;
2966 this._overlayContainer = _overlayContainer;
2967 this._componentFactoryResolver = _componentFactoryResolver;
2968 this._positionBuilder = _positionBuilder;
2969 this._keyboardDispatcher = _keyboardDispatcher;
2970 this._injector = _injector;
2971 this._ngZone = _ngZone;
2972 this._document = _document;
2973 this._directionality = _directionality;
2974 this._location = _location;
2975 this._outsideClickDispatcher = _outsideClickDispatcher;
2976 }
2977 /**
2978 * Creates an overlay.
2979 * @param config Configuration applied to the overlay.
2980 * @returns Reference to the created overlay.
2981 */
2982 Overlay.prototype.create = function (config) {
2983 var host = this._createHostElement();
2984 var pane = this._createPaneElement(host);
2985 var portalOutlet = this._createPortalOutlet(pane);
2986 var overlayConfig = new OverlayConfig(config);
2987 overlayConfig.direction = overlayConfig.direction || this._directionality.value;
2988 return new OverlayRef(portalOutlet, host, pane, overlayConfig, this._ngZone, this._keyboardDispatcher, this._document, this._location, this._outsideClickDispatcher);
2989 };
2990 /**
2991 * Gets a position builder that can be used, via fluent API,
2992 * to construct and configure a position strategy.
2993 * @returns An overlay position builder.
2994 */
2995 Overlay.prototype.position = function () {
2996 return this._positionBuilder;
2997 };
2998 /**
2999 * Creates the DOM element for an overlay and appends it to the overlay container.
3000 * @returns Newly-created pane element
3001 */
3002 Overlay.prototype._createPaneElement = function (host) {
3003 var pane = this._document.createElement('div');
3004 pane.id = "cdk-overlay-" + nextUniqueId++;
3005 pane.classList.add('cdk-overlay-pane');
3006 host.appendChild(pane);
3007 return pane;
3008 };
3009 /**
3010 * Creates the host element that wraps around an overlay
3011 * and can be used for advanced positioning.
3012 * @returns Newly-create host element.
3013 */
3014 Overlay.prototype._createHostElement = function () {
3015 var host = this._document.createElement('div');
3016 this._overlayContainer.getContainerElement().appendChild(host);
3017 return host;
3018 };
3019 /**
3020 * Create a DomPortalOutlet into which the overlay content can be loaded.
3021 * @param pane The DOM element to turn into a portal outlet.
3022 * @returns A portal outlet for the given DOM element.
3023 */
3024 Overlay.prototype._createPortalOutlet = function (pane) {
3025 // We have to resolve the ApplicationRef later in order to allow people
3026 // to use overlay-based providers during app initialization.
3027 if (!this._appRef) {
3028 this._appRef = this._injector.get(i0.ApplicationRef);
3029 }
3030 return new portal.DomPortalOutlet(pane, this._componentFactoryResolver, this._appRef, this._injector, this._document);
3031 };
3032 return Overlay;
3033 }());
3034 Overlay.decorators = [
3035 { type: i0.Injectable }
3036 ];
3037 Overlay.ctorParameters = function () { return [
3038 { type: ScrollStrategyOptions },
3039 { type: OverlayContainer },
3040 { type: i0.ComponentFactoryResolver },
3041 { type: OverlayPositionBuilder },
3042 { type: OverlayKeyboardDispatcher },
3043 { type: i0.Injector },
3044 { type: i0.NgZone },
3045 { type: undefined, decorators: [{ type: i0.Inject, args: [i1$1.DOCUMENT,] }] },
3046 { type: bidi.Directionality },
3047 { type: i1$1.Location },
3048 { type: OverlayOutsideClickDispatcher }
3049 ]; };
3050
3051 /**
3052 * @license
3053 * Copyright Google LLC All Rights Reserved.
3054 *
3055 * Use of this source code is governed by an MIT-style license that can be
3056 * found in the LICENSE file at https://angular.io/license
3057 */
3058 /** Default set of positions for the overlay. Follows the behavior of a dropdown. */
3059 var defaultPositionList = [
3060 {
3061 originX: 'start',
3062 originY: 'bottom',
3063 overlayX: 'start',
3064 overlayY: 'top'
3065 },
3066 {
3067 originX: 'start',
3068 originY: 'top',
3069 overlayX: 'start',
3070 overlayY: 'bottom'
3071 },
3072 {
3073 originX: 'end',
3074 originY: 'top',
3075 overlayX: 'end',
3076 overlayY: 'bottom'
3077 },
3078 {
3079 originX: 'end',
3080 originY: 'bottom',
3081 overlayX: 'end',
3082 overlayY: 'top'
3083 }
3084 ];
3085 /** Injection token that determines the scroll handling while the connected overlay is open. */
3086 var CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY = new i0.InjectionToken('cdk-connected-overlay-scroll-strategy');
3087 /**
3088 * Directive applied to an element to make it usable as an origin for an Overlay using a
3089 * ConnectedPositionStrategy.
3090 */
3091 var CdkOverlayOrigin = /** @class */ (function () {
3092 function CdkOverlayOrigin(
3093 /** Reference to the element on which the directive is applied. */
3094 elementRef) {
3095 this.elementRef = elementRef;
3096 }
3097 return CdkOverlayOrigin;
3098 }());
3099 CdkOverlayOrigin.decorators = [
3100 { type: i0.Directive, args: [{
3101 selector: '[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]',
3102 exportAs: 'cdkOverlayOrigin',
3103 },] }
3104 ];
3105 CdkOverlayOrigin.ctorParameters = function () { return [
3106 { type: i0.ElementRef }
3107 ]; };
3108 /**
3109 * Directive to facilitate declarative creation of an
3110 * Overlay using a FlexibleConnectedPositionStrategy.
3111 */
3112 var CdkConnectedOverlay = /** @class */ (function () {
3113 // TODO(jelbourn): inputs for size, scroll behavior, animation, etc.
3114 function CdkConnectedOverlay(_overlay, templateRef, viewContainerRef, scrollStrategyFactory, _dir) {
3115 this._overlay = _overlay;
3116 this._dir = _dir;
3117 this._hasBackdrop = false;
3118 this._lockPosition = false;
3119 this._growAfterOpen = false;
3120 this._flexibleDimensions = false;
3121 this._push = false;
3122 this._backdropSubscription = rxjs.Subscription.EMPTY;
3123 this._attachSubscription = rxjs.Subscription.EMPTY;
3124 this._detachSubscription = rxjs.Subscription.EMPTY;
3125 this._positionSubscription = rxjs.Subscription.EMPTY;
3126 /** Margin between the overlay and the viewport edges. */
3127 this.viewportMargin = 0;
3128 /** Whether the overlay is open. */
3129 this.open = false;
3130 /** Whether the overlay can be closed by user interaction. */
3131 this.disableClose = false;
3132 /** Event emitted when the backdrop is clicked. */
3133 this.backdropClick = new i0.EventEmitter();
3134 /** Event emitted when the position has changed. */
3135 this.positionChange = new i0.EventEmitter();
3136 /** Event emitted when the overlay has been attached. */
3137 this.attach = new i0.EventEmitter();
3138 /** Event emitted when the overlay has been detached. */
3139 this.detach = new i0.EventEmitter();
3140 /** Emits when there are keyboard events that are targeted at the overlay. */
3141 this.overlayKeydown = new i0.EventEmitter();
3142 /** Emits when there are mouse outside click events that are targeted at the overlay. */
3143 this.overlayOutsideClick = new i0.EventEmitter();
3144 this._templatePortal = new portal.TemplatePortal(templateRef, viewContainerRef);
3145 this._scrollStrategyFactory = scrollStrategyFactory;
3146 this.scrollStrategy = this._scrollStrategyFactory();
3147 }
3148 Object.defineProperty(CdkConnectedOverlay.prototype, "offsetX", {
3149 /** The offset in pixels for the overlay connection point on the x-axis */
3150 get: function () { return this._offsetX; },
3151 set: function (offsetX) {
3152 this._offsetX = offsetX;
3153 if (this._position) {
3154 this._updatePositionStrategy(this._position);
3155 }
3156 },
3157 enumerable: false,
3158 configurable: true
3159 });
3160 Object.defineProperty(CdkConnectedOverlay.prototype, "offsetY", {
3161 /** The offset in pixels for the overlay connection point on the y-axis */
3162 get: function () { return this._offsetY; },
3163 set: function (offsetY) {
3164 this._offsetY = offsetY;
3165 if (this._position) {
3166 this._updatePositionStrategy(this._position);
3167 }
3168 },
3169 enumerable: false,
3170 configurable: true
3171 });
3172 Object.defineProperty(CdkConnectedOverlay.prototype, "hasBackdrop", {
3173 /** Whether or not the overlay should attach a backdrop. */
3174 get: function () { return this._hasBackdrop; },
3175 set: function (value) { this._hasBackdrop = coercion.coerceBooleanProperty(value); },
3176 enumerable: false,
3177 configurable: true
3178 });
3179 Object.defineProperty(CdkConnectedOverlay.prototype, "lockPosition", {
3180 /** Whether or not the overlay should be locked when scrolling. */
3181 get: function () { return this._lockPosition; },
3182 set: function (value) { this._lockPosition = coercion.coerceBooleanProperty(value); },
3183 enumerable: false,
3184 configurable: true
3185 });
3186 Object.defineProperty(CdkConnectedOverlay.prototype, "flexibleDimensions", {
3187 /** Whether the overlay's width and height can be constrained to fit within the viewport. */
3188 get: function () { return this._flexibleDimensions; },
3189 set: function (value) {
3190 this._flexibleDimensions = coercion.coerceBooleanProperty(value);
3191 },
3192 enumerable: false,
3193 configurable: true
3194 });
3195 Object.defineProperty(CdkConnectedOverlay.prototype, "growAfterOpen", {
3196 /** Whether the overlay can grow after the initial open when flexible positioning is turned on. */
3197 get: function () { return this._growAfterOpen; },
3198 set: function (value) { this._growAfterOpen = coercion.coerceBooleanProperty(value); },
3199 enumerable: false,
3200 configurable: true
3201 });
3202 Object.defineProperty(CdkConnectedOverlay.prototype, "push", {
3203 /** Whether the overlay can be pushed on-screen if none of the provided positions fit. */
3204 get: function () { return this._push; },
3205 set: function (value) { this._push = coercion.coerceBooleanProperty(value); },
3206 enumerable: false,
3207 configurable: true
3208 });
3209 Object.defineProperty(CdkConnectedOverlay.prototype, "overlayRef", {
3210 /** The associated overlay reference. */
3211 get: function () {
3212 return this._overlayRef;
3213 },
3214 enumerable: false,
3215 configurable: true
3216 });
3217 Object.defineProperty(CdkConnectedOverlay.prototype, "dir", {
3218 /** The element's layout direction. */
3219 get: function () {
3220 return this._dir ? this._dir.value : 'ltr';
3221 },
3222 enumerable: false,
3223 configurable: true
3224 });
3225 CdkConnectedOverlay.prototype.ngOnDestroy = function () {
3226 this._attachSubscription.unsubscribe();
3227 this._detachSubscription.unsubscribe();
3228 this._backdropSubscription.unsubscribe();
3229 this._positionSubscription.unsubscribe();
3230 if (this._overlayRef) {
3231 this._overlayRef.dispose();
3232 }
3233 };
3234 CdkConnectedOverlay.prototype.ngOnChanges = function (changes) {
3235 if (this._position) {
3236 this._updatePositionStrategy(this._position);
3237 this._overlayRef.updateSize({
3238 width: this.width,
3239 minWidth: this.minWidth,
3240 height: this.height,
3241 minHeight: this.minHeight,
3242 });
3243 if (changes['origin'] && this.open) {
3244 this._position.apply();
3245 }
3246 }
3247 if (changes['open']) {
3248 this.open ? this._attachOverlay() : this._detachOverlay();
3249 }
3250 };
3251 /** Creates an overlay */
3252 CdkConnectedOverlay.prototype._createOverlay = function () {
3253 var _this = this;
3254 if (!this.positions || !this.positions.length) {
3255 this.positions = defaultPositionList;
3256 }
3257 var overlayRef = this._overlayRef = this._overlay.create(this._buildConfig());
3258 this._attachSubscription = overlayRef.attachments().subscribe(function () { return _this.attach.emit(); });
3259 this._detachSubscription = overlayRef.detachments().subscribe(function () { return _this.detach.emit(); });
3260 overlayRef.keydownEvents().subscribe(function (event) {
3261 _this.overlayKeydown.next(event);
3262 if (event.keyCode === keycodes.ESCAPE && !_this.disableClose && !keycodes.hasModifierKey(event)) {
3263 event.preventDefault();
3264 _this._detachOverlay();
3265 }
3266 });
3267 this._overlayRef.outsidePointerEvents().subscribe(function (event) {
3268 _this.overlayOutsideClick.next(event);
3269 });
3270 };
3271 /** Builds the overlay config based on the directive's inputs */
3272 CdkConnectedOverlay.prototype._buildConfig = function () {
3273 var positionStrategy = this._position =
3274 this.positionStrategy || this._createPositionStrategy();
3275 var overlayConfig = new OverlayConfig({
3276 direction: this._dir,
3277 positionStrategy: positionStrategy,
3278 scrollStrategy: this.scrollStrategy,
3279 hasBackdrop: this.hasBackdrop
3280 });
3281 if (this.width || this.width === 0) {
3282 overlayConfig.width = this.width;
3283 }
3284 if (this.height || this.height === 0) {
3285 overlayConfig.height = this.height;
3286 }
3287 if (this.minWidth || this.minWidth === 0) {
3288 overlayConfig.minWidth = this.minWidth;
3289 }
3290 if (this.minHeight || this.minHeight === 0) {
3291 overlayConfig.minHeight = this.minHeight;
3292 }
3293 if (this.backdropClass) {
3294 overlayConfig.backdropClass = this.backdropClass;
3295 }
3296 if (this.panelClass) {
3297 overlayConfig.panelClass = this.panelClass;
3298 }
3299 return overlayConfig;
3300 };
3301 /** Updates the state of a position strategy, based on the values of the directive inputs. */
3302 CdkConnectedOverlay.prototype._updatePositionStrategy = function (positionStrategy) {
3303 var _this = this;
3304 var positions = this.positions.map(function (currentPosition) { return ({
3305 originX: currentPosition.originX,
3306 originY: currentPosition.originY,
3307 overlayX: currentPosition.overlayX,
3308 overlayY: currentPosition.overlayY,
3309 offsetX: currentPosition.offsetX || _this.offsetX,
3310 offsetY: currentPosition.offsetY || _this.offsetY,
3311 panelClass: currentPosition.panelClass || undefined,
3312 }); });
3313 return positionStrategy
3314 .setOrigin(this.origin.elementRef)
3315 .withPositions(positions)
3316 .withFlexibleDimensions(this.flexibleDimensions)
3317 .withPush(this.push)
3318 .withGrowAfterOpen(this.growAfterOpen)
3319 .withViewportMargin(this.viewportMargin)
3320 .withLockedPosition(this.lockPosition)
3321 .withTransformOriginOn(this.transformOriginSelector);
3322 };
3323 /** Returns the position strategy of the overlay to be set on the overlay config */
3324 CdkConnectedOverlay.prototype._createPositionStrategy = function () {
3325 var strategy = this._overlay.position().flexibleConnectedTo(this.origin.elementRef);
3326 this._updatePositionStrategy(strategy);
3327 return strategy;
3328 };
3329 /** Attaches the overlay and subscribes to backdrop clicks if backdrop exists */
3330 CdkConnectedOverlay.prototype._attachOverlay = function () {
3331 var _this = this;
3332 if (!this._overlayRef) {
3333 this._createOverlay();
3334 }
3335 else {
3336 // Update the overlay size, in case the directive's inputs have changed
3337 this._overlayRef.getConfig().hasBackdrop = this.hasBackdrop;
3338 }
3339 if (!this._overlayRef.hasAttached()) {
3340 this._overlayRef.attach(this._templatePortal);
3341 }
3342 if (this.hasBackdrop) {
3343 this._backdropSubscription = this._overlayRef.backdropClick().subscribe(function (event) {
3344 _this.backdropClick.emit(event);
3345 });
3346 }
3347 else {
3348 this._backdropSubscription.unsubscribe();
3349 }
3350 this._positionSubscription.unsubscribe();
3351 // Only subscribe to `positionChanges` if requested, because putting
3352 // together all the information for it can be expensive.
3353 if (this.positionChange.observers.length > 0) {
3354 this._positionSubscription = this._position.positionChanges
3355 .pipe(operators.takeWhile(function () { return _this.positionChange.observers.length > 0; }))
3356 .subscribe(function (position) {
3357 _this.positionChange.emit(position);
3358 if (_this.positionChange.observers.length === 0) {
3359 _this._positionSubscription.unsubscribe();
3360 }
3361 });
3362 }
3363 };
3364 /** Detaches the overlay and unsubscribes to backdrop clicks if backdrop exists */
3365 CdkConnectedOverlay.prototype._detachOverlay = function () {
3366 if (this._overlayRef) {
3367 this._overlayRef.detach();
3368 }
3369 this._backdropSubscription.unsubscribe();
3370 this._positionSubscription.unsubscribe();
3371 };
3372 return CdkConnectedOverlay;
3373 }());
3374 CdkConnectedOverlay.decorators = [
3375 { type: i0.Directive, args: [{
3376 selector: '[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]',
3377 exportAs: 'cdkConnectedOverlay'
3378 },] }
3379 ];
3380 CdkConnectedOverlay.ctorParameters = function () { return [
3381 { type: Overlay },
3382 { type: i0.TemplateRef },
3383 { type: i0.ViewContainerRef },
3384 { type: undefined, decorators: [{ type: i0.Inject, args: [CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY,] }] },
3385 { type: bidi.Directionality, decorators: [{ type: i0.Optional }] }
3386 ]; };
3387 CdkConnectedOverlay.propDecorators = {
3388 origin: [{ type: i0.Input, args: ['cdkConnectedOverlayOrigin',] }],
3389 positions: [{ type: i0.Input, args: ['cdkConnectedOverlayPositions',] }],
3390 positionStrategy: [{ type: i0.Input, args: ['cdkConnectedOverlayPositionStrategy',] }],
3391 offsetX: [{ type: i0.Input, args: ['cdkConnectedOverlayOffsetX',] }],
3392 offsetY: [{ type: i0.Input, args: ['cdkConnectedOverlayOffsetY',] }],
3393 width: [{ type: i0.Input, args: ['cdkConnectedOverlayWidth',] }],
3394 height: [{ type: i0.Input, args: ['cdkConnectedOverlayHeight',] }],
3395 minWidth: [{ type: i0.Input, args: ['cdkConnectedOverlayMinWidth',] }],
3396 minHeight: [{ type: i0.Input, args: ['cdkConnectedOverlayMinHeight',] }],
3397 backdropClass: [{ type: i0.Input, args: ['cdkConnectedOverlayBackdropClass',] }],
3398 panelClass: [{ type: i0.Input, args: ['cdkConnectedOverlayPanelClass',] }],
3399 viewportMargin: [{ type: i0.Input, args: ['cdkConnectedOverlayViewportMargin',] }],
3400 scrollStrategy: [{ type: i0.Input, args: ['cdkConnectedOverlayScrollStrategy',] }],
3401 open: [{ type: i0.Input, args: ['cdkConnectedOverlayOpen',] }],
3402 disableClose: [{ type: i0.Input, args: ['cdkConnectedOverlayDisableClose',] }],
3403 transformOriginSelector: [{ type: i0.Input, args: ['cdkConnectedOverlayTransformOriginOn',] }],
3404 hasBackdrop: [{ type: i0.Input, args: ['cdkConnectedOverlayHasBackdrop',] }],
3405 lockPosition: [{ type: i0.Input, args: ['cdkConnectedOverlayLockPosition',] }],
3406 flexibleDimensions: [{ type: i0.Input, args: ['cdkConnectedOverlayFlexibleDimensions',] }],
3407 growAfterOpen: [{ type: i0.Input, args: ['cdkConnectedOverlayGrowAfterOpen',] }],
3408 push: [{ type: i0.Input, args: ['cdkConnectedOverlayPush',] }],
3409 backdropClick: [{ type: i0.Output }],
3410 positionChange: [{ type: i0.Output }],
3411 attach: [{ type: i0.Output }],
3412 detach: [{ type: i0.Output }],
3413 overlayKeydown: [{ type: i0.Output }],
3414 overlayOutsideClick: [{ type: i0.Output }]
3415 };
3416 /** @docs-private */
3417 function CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER_FACTORY(overlay) {
3418 return function () { return overlay.scrollStrategies.reposition(); };
3419 }
3420 /** @docs-private */
3421 var CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER = {
3422 provide: CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY,
3423 deps: [Overlay],
3424 useFactory: CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER_FACTORY,
3425 };
3426
3427 /**
3428 * @license
3429 * Copyright Google LLC All Rights Reserved.
3430 *
3431 * Use of this source code is governed by an MIT-style license that can be
3432 * found in the LICENSE file at https://angular.io/license
3433 */
3434 var OverlayModule = /** @class */ (function () {
3435 function OverlayModule() {
3436 }
3437 return OverlayModule;
3438 }());
3439 OverlayModule.decorators = [
3440 { type: i0.NgModule, args: [{
3441 imports: [bidi.BidiModule, portal.PortalModule, i1.ScrollingModule],
3442 exports: [CdkConnectedOverlay, CdkOverlayOrigin, i1.ScrollingModule],
3443 declarations: [CdkConnectedOverlay, CdkOverlayOrigin],
3444 providers: [
3445 Overlay,
3446 CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER,
3447 ],
3448 },] }
3449 ];
3450
3451 /**
3452 * @license
3453 * Copyright Google LLC All Rights Reserved.
3454 *
3455 * Use of this source code is governed by an MIT-style license that can be
3456 * found in the LICENSE file at https://angular.io/license
3457 */
3458
3459 /**
3460 * Alternative to OverlayContainer that supports correct displaying of overlay elements in
3461 * Fullscreen mode
3462 * https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullScreen
3463 *
3464 * Should be provided in the root component.
3465 */
3466 var FullscreenOverlayContainer = /** @class */ (function (_super) {
3467 __extends(FullscreenOverlayContainer, _super);
3468 function FullscreenOverlayContainer(_document, platform) {
3469 return _super.call(this, _document, platform) || this;
3470 }
3471 FullscreenOverlayContainer.prototype.ngOnDestroy = function () {
3472 _super.prototype.ngOnDestroy.call(this);
3473 if (this._fullScreenEventName && this._fullScreenListener) {
3474 this._document.removeEventListener(this._fullScreenEventName, this._fullScreenListener);
3475 }
3476 };
3477 FullscreenOverlayContainer.prototype._createContainer = function () {
3478 var _this = this;
3479 _super.prototype._createContainer.call(this);
3480 this._adjustParentForFullscreenChange();
3481 this._addFullscreenChangeListener(function () { return _this._adjustParentForFullscreenChange(); });
3482 };
3483 FullscreenOverlayContainer.prototype._adjustParentForFullscreenChange = function () {
3484 if (!this._containerElement) {
3485 return;
3486 }
3487 var fullscreenElement = this.getFullscreenElement();
3488 var parent = fullscreenElement || this._document.body;
3489 parent.appendChild(this._containerElement);
3490 };
3491 FullscreenOverlayContainer.prototype._addFullscreenChangeListener = function (fn) {
3492 var eventName = this._getEventName();
3493 if (eventName) {
3494 if (this._fullScreenListener) {
3495 this._document.removeEventListener(eventName, this._fullScreenListener);
3496 }
3497 this._document.addEventListener(eventName, fn);
3498 this._fullScreenListener = fn;
3499 }
3500 };
3501 FullscreenOverlayContainer.prototype._getEventName = function () {
3502 if (!this._fullScreenEventName) {
3503 var _document = this._document;
3504 if (_document.fullscreenEnabled) {
3505 this._fullScreenEventName = 'fullscreenchange';
3506 }
3507 else if (_document.webkitFullscreenEnabled) {
3508 this._fullScreenEventName = 'webkitfullscreenchange';
3509 }
3510 else if (_document.mozFullScreenEnabled) {
3511 this._fullScreenEventName = 'mozfullscreenchange';
3512 }
3513 else if (_document.msFullscreenEnabled) {
3514 this._fullScreenEventName = 'MSFullscreenChange';
3515 }
3516 }
3517 return this._fullScreenEventName;
3518 };
3519 /**
3520 * When the page is put into fullscreen mode, a specific element is specified.
3521 * Only that element and its children are visible when in fullscreen mode.
3522 */
3523 FullscreenOverlayContainer.prototype.getFullscreenElement = function () {
3524 var _document = this._document;
3525 return _document.fullscreenElement ||
3526 _document.webkitFullscreenElement ||
3527 _document.mozFullScreenElement ||
3528 _document.msFullscreenElement ||
3529 null;
3530 };
3531 return FullscreenOverlayContainer;
3532 }(OverlayContainer));
3533 FullscreenOverlayContainer.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function FullscreenOverlayContainer_Factory() { return new FullscreenOverlayContainer(i0__namespace.ɵɵinject(i1__namespace$1.DOCUMENT), i0__namespace.ɵɵinject(i2__namespace.Platform)); }, token: FullscreenOverlayContainer, providedIn: "root" });
3534 FullscreenOverlayContainer.decorators = [
3535 { type: i0.Injectable, args: [{ providedIn: 'root' },] }
3536 ];
3537 FullscreenOverlayContainer.ctorParameters = function () { return [
3538 { type: undefined, decorators: [{ type: i0.Inject, args: [i1$1.DOCUMENT,] }] },
3539 { type: i2.Platform }
3540 ]; };
3541
3542 /**
3543 * @license
3544 * Copyright Google LLC All Rights Reserved.
3545 *
3546 * Use of this source code is governed by an MIT-style license that can be
3547 * found in the LICENSE file at https://angular.io/license
3548 */
3549
3550 /**
3551 * Generated bundle index. Do not edit.
3552 */
3553
3554 Object.defineProperty(exports, 'CdkScrollable', {
3555 enumerable: true,
3556 get: function () {
3557 return i1.CdkScrollable;
3558 }
3559 });
3560 Object.defineProperty(exports, 'ScrollDispatcher', {
3561 enumerable: true,
3562 get: function () {
3563 return i1.ScrollDispatcher;
3564 }
3565 });
3566 Object.defineProperty(exports, 'ViewportRuler', {
3567 enumerable: true,
3568 get: function () {
3569 return i1.ViewportRuler;
3570 }
3571 });
3572 exports.BlockScrollStrategy = BlockScrollStrategy;
3573 exports.CdkConnectedOverlay = CdkConnectedOverlay;
3574 exports.CdkOverlayOrigin = CdkOverlayOrigin;
3575 exports.CloseScrollStrategy = CloseScrollStrategy;
3576 exports.ConnectedOverlayPositionChange = ConnectedOverlayPositionChange;
3577 exports.ConnectedPositionStrategy = ConnectedPositionStrategy;
3578 exports.ConnectionPositionPair = ConnectionPositionPair;
3579 exports.FlexibleConnectedPositionStrategy = FlexibleConnectedPositionStrategy;
3580 exports.FullscreenOverlayContainer = FullscreenOverlayContainer;
3581 exports.GlobalPositionStrategy = GlobalPositionStrategy;
3582 exports.NoopScrollStrategy = NoopScrollStrategy;
3583 exports.Overlay = Overlay;
3584 exports.OverlayConfig = OverlayConfig;
3585 exports.OverlayContainer = OverlayContainer;
3586 exports.OverlayKeyboardDispatcher = OverlayKeyboardDispatcher;
3587 exports.OverlayModule = OverlayModule;
3588 exports.OverlayOutsideClickDispatcher = OverlayOutsideClickDispatcher;
3589 exports.OverlayPositionBuilder = OverlayPositionBuilder;
3590 exports.OverlayRef = OverlayRef;
3591 exports.RepositionScrollStrategy = RepositionScrollStrategy;
3592 exports.ScrollStrategyOptions = ScrollStrategyOptions;
3593 exports.ScrollingVisibility = ScrollingVisibility;
3594 exports.validateHorizontalPosition = validateHorizontalPosition;
3595 exports.validateVerticalPosition = validateVerticalPosition;
3596 exports.ɵangular_material_src_cdk_overlay_overlay_a = CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY;
3597 exports.ɵangular_material_src_cdk_overlay_overlay_b = CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER_FACTORY;
3598 exports.ɵangular_material_src_cdk_overlay_overlay_c = CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER;
3599 exports.ɵangular_material_src_cdk_overlay_overlay_d = BaseOverlayDispatcher;
3600
3601 Object.defineProperty(exports, '__esModule', { value: true });
3602
3603})));
3604//# sourceMappingURL=cdk-overlay.umd.js.map
Note: See TracBrowser for help on using the repository browser.