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

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

initial commit

  • Property mode set to 100644
File size: 175.8 KB
Line 
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;
944 /** Click event listener that will be attached to the body propagate phase. */
945 _this._clickListener = function (event) {
946 var target = i2._getEventTarget(event);
947 // We copy the array because the original may be modified asynchronously if the
948 // outsidePointerEvents listener decides to detach overlays resulting in index errors inside
949 // the for loop.
950 var overlays = _this._attachedOverlays.slice();
951 // Dispatch the mouse event to the top overlay which has subscribers to its mouse events.
952 // We want to target all overlays for which the click could be considered as outside click.
953 // As soon as we reach an overlay for which the click is not outside click we break off
954 // the loop.
955 for (var i = overlays.length - 1; i > -1; i--) {
956 var overlayRef = overlays[i];
957 if (overlayRef._outsidePointerEvents.observers.length < 1 || !overlayRef.hasAttached()) {
958 continue;
959 }
960 // If it's a click inside the overlay, just break - we should do nothing
961 // If it's an outside click dispatch the mouse event, and proceed with the next overlay
962 if (overlayRef.overlayElement.contains(target)) {
963 break;
964 }
965 overlayRef._outsidePointerEvents.next(event);
966 }
967 };
968 return _this;
969 }
970 /** Add a new overlay to the list of attached overlay refs. */
971 OverlayOutsideClickDispatcher.prototype.add = function (overlayRef) {
972 _super.prototype.add.call(this, overlayRef);
973 // Safari on iOS does not generate click events for non-interactive
974 // elements. However, we want to receive a click for any element outside
975 // the overlay. We can force a "clickable" state by setting
976 // `cursor: pointer` on the document body. See:
977 // https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event#Safari_Mobile
978 // https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html
979 if (!this._isAttached) {
980 var body = this._document.body;
981 body.addEventListener('click', this._clickListener, true);
982 body.addEventListener('auxclick', this._clickListener, true);
983 body.addEventListener('contextmenu', this._clickListener, true);
984 // click event is not fired on iOS. To make element "clickable" we are
985 // setting the cursor to pointer
986 if (this._platform.IOS && !this._cursorStyleIsSet) {
987 this._cursorOriginalValue = body.style.cursor;
988 body.style.cursor = 'pointer';
989 this._cursorStyleIsSet = true;
990 }
991 this._isAttached = true;
992 }
993 };
994 /** Detaches the global keyboard event listener. */
995 OverlayOutsideClickDispatcher.prototype.detach = function () {
996 if (this._isAttached) {
997 var body = this._document.body;
998 body.removeEventListener('click', this._clickListener, true);
999 body.removeEventListener('auxclick', this._clickListener, true);
1000 body.removeEventListener('contextmenu', this._clickListener, true);
1001 if (this._platform.IOS && this._cursorStyleIsSet) {
1002 body.style.cursor = this._cursorOriginalValue;
1003 this._cursorStyleIsSet = false;
1004 }
1005 this._isAttached = false;
1006 }
1007 };
1008 return OverlayOutsideClickDispatcher;
1009 }(BaseOverlayDispatcher));
1010 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" });
1011 OverlayOutsideClickDispatcher.decorators = [
1012 { type: i0.Injectable, args: [{ providedIn: 'root' },] }
1013 ];
1014 OverlayOutsideClickDispatcher.ctorParameters = function () { return [
1015 { type: undefined, decorators: [{ type: i0.Inject, args: [i1$1.DOCUMENT,] }] },
1016 { type: i2.Platform }
1017 ]; };
1018
1019 /**
1020 * @license
1021 * Copyright Google LLC All Rights Reserved.
1022 *
1023 * Use of this source code is governed by an MIT-style license that can be
1024 * found in the LICENSE file at https://angular.io/license
1025 */
1026 /** Container inside which all overlays will render. */
1027 var OverlayContainer = /** @class */ (function () {
1028 function OverlayContainer(document, _platform) {
1029 this._platform = _platform;
1030 this._document = document;
1031 }
1032 OverlayContainer.prototype.ngOnDestroy = function () {
1033 var container = this._containerElement;
1034 if (container && container.parentNode) {
1035 container.parentNode.removeChild(container);
1036 }
1037 };
1038 /**
1039 * This method returns the overlay container element. It will lazily
1040 * create the element the first time it is called to facilitate using
1041 * the container in non-browser environments.
1042 * @returns the container element
1043 */
1044 OverlayContainer.prototype.getContainerElement = function () {
1045 if (!this._containerElement) {
1046 this._createContainer();
1047 }
1048 return this._containerElement;
1049 };
1050 /**
1051 * Create the overlay container element, which is simply a div
1052 * with the 'cdk-overlay-container' class on the document body.
1053 */
1054 OverlayContainer.prototype._createContainer = function () {
1055 var containerClass = 'cdk-overlay-container';
1056 // TODO(crisbeto): remove the testing check once we have an overlay testing
1057 // module or Angular starts tearing down the testing `NgModule`. See:
1058 // https://github.com/angular/angular/issues/18831
1059 if (this._platform.isBrowser || i2._isTestEnvironment()) {
1060 var oppositePlatformContainers = this._document.querySelectorAll("." + containerClass + "[platform=\"server\"], " +
1061 ("." + containerClass + "[platform=\"test\"]"));
1062 // Remove any old containers from the opposite platform.
1063 // This can happen when transitioning from the server to the client.
1064 for (var i = 0; i < oppositePlatformContainers.length; i++) {
1065 oppositePlatformContainers[i].parentNode.removeChild(oppositePlatformContainers[i]);
1066 }
1067 }
1068 var container = this._document.createElement('div');
1069 container.classList.add(containerClass);
1070 // A long time ago we kept adding new overlay containers whenever a new app was instantiated,
1071 // but at some point we added logic which clears the duplicate ones in order to avoid leaks.
1072 // The new logic was a little too aggressive since it was breaking some legitimate use cases.
1073 // To mitigate the problem we made it so that only containers from a different platform are
1074 // cleared, but the side-effect was that people started depending on the overly-aggressive
1075 // logic to clean up their tests for them. Until we can introduce an overlay-specific testing
1076 // module which does the cleanup, we try to detect that we're in a test environment and we
1077 // always clear the container. See #17006.
1078 // TODO(crisbeto): remove the test environment check once we have an overlay testing module.
1079 if (i2._isTestEnvironment()) {
1080 container.setAttribute('platform', 'test');
1081 }
1082 else if (!this._platform.isBrowser) {
1083 container.setAttribute('platform', 'server');
1084 }
1085 this._document.body.appendChild(container);
1086 this._containerElement = container;
1087 };
1088 return OverlayContainer;
1089 }());
1090 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" });
1091 OverlayContainer.decorators = [
1092 { type: i0.Injectable, args: [{ providedIn: 'root' },] }
1093 ];
1094 OverlayContainer.ctorParameters = function () { return [
1095 { type: undefined, decorators: [{ type: i0.Inject, args: [i1$1.DOCUMENT,] }] },
1096 { type: i2.Platform }
1097 ]; };
1098
1099 /**
1100 * @license
1101 * Copyright Google LLC All Rights Reserved.
1102 *
1103 * Use of this source code is governed by an MIT-style license that can be
1104 * found in the LICENSE file at https://angular.io/license
1105 */
1106 /**
1107 * Reference to an overlay that has been created with the Overlay service.
1108 * Used to manipulate or dispose of said overlay.
1109 */
1110 var OverlayRef = /** @class */ (function () {
1111 function OverlayRef(_portalOutlet, _host, _pane, _config, _ngZone, _keyboardDispatcher, _document, _location, _outsideClickDispatcher) {
1112 var _this = this;
1113 this._portalOutlet = _portalOutlet;
1114 this._host = _host;
1115 this._pane = _pane;
1116 this._config = _config;
1117 this._ngZone = _ngZone;
1118 this._keyboardDispatcher = _keyboardDispatcher;
1119 this._document = _document;
1120 this._location = _location;
1121 this._outsideClickDispatcher = _outsideClickDispatcher;
1122 this._backdropElement = null;
1123 this._backdropClick = new rxjs.Subject();
1124 this._attachments = new rxjs.Subject();
1125 this._detachments = new rxjs.Subject();
1126 this._locationChanges = rxjs.Subscription.EMPTY;
1127 this._backdropClickHandler = function (event) { return _this._backdropClick.next(event); };
1128 /** Stream of keydown events dispatched to this overlay. */
1129 this._keydownEvents = new rxjs.Subject();
1130 /** Stream of mouse outside events dispatched to this overlay. */
1131 this._outsidePointerEvents = new rxjs.Subject();
1132 if (_config.scrollStrategy) {
1133 this._scrollStrategy = _config.scrollStrategy;
1134 this._scrollStrategy.attach(this);
1135 }
1136 this._positionStrategy = _config.positionStrategy;
1137 }
1138 Object.defineProperty(OverlayRef.prototype, "overlayElement", {
1139 /** The overlay's HTML element */
1140 get: function () {
1141 return this._pane;
1142 },
1143 enumerable: false,
1144 configurable: true
1145 });
1146 Object.defineProperty(OverlayRef.prototype, "backdropElement", {
1147 /** The overlay's backdrop HTML element. */
1148 get: function () {
1149 return this._backdropElement;
1150 },
1151 enumerable: false,
1152 configurable: true
1153 });
1154 Object.defineProperty(OverlayRef.prototype, "hostElement", {
1155 /**
1156 * Wrapper around the panel element. Can be used for advanced
1157 * positioning where a wrapper with specific styling is
1158 * required around the overlay pane.
1159 */
1160 get: function () {
1161 return this._host;
1162 },
1163 enumerable: false,
1164 configurable: true
1165 });
1166 /**
1167 * Attaches content, given via a Portal, to the overlay.
1168 * If the overlay is configured to have a backdrop, it will be created.
1169 *
1170 * @param portal Portal instance to which to attach the overlay.
1171 * @returns The portal attachment result.
1172 */
1173 OverlayRef.prototype.attach = function (portal) {
1174 var _this = this;
1175 var attachResult = this._portalOutlet.attach(portal);
1176 // Update the pane element with the given configuration.
1177 if (!this._host.parentElement && this._previousHostParent) {
1178 this._previousHostParent.appendChild(this._host);
1179 }
1180 if (this._positionStrategy) {
1181 this._positionStrategy.attach(this);
1182 }
1183 this._updateStackingOrder();
1184 this._updateElementSize();
1185 this._updateElementDirection();
1186 if (this._scrollStrategy) {
1187 this._scrollStrategy.enable();
1188 }
1189 // Update the position once the zone is stable so that the overlay will be fully rendered
1190 // before attempting to position it, as the position may depend on the size of the rendered
1191 // content.
1192 this._ngZone.onStable
1193 .pipe(operators.take(1))
1194 .subscribe(function () {
1195 // The overlay could've been detached before the zone has stabilized.
1196 if (_this.hasAttached()) {
1197 _this.updatePosition();
1198 }
1199 });
1200 // Enable pointer events for the overlay pane element.
1201 this._togglePointerEvents(true);
1202 if (this._config.hasBackdrop) {
1203 this._attachBackdrop();
1204 }
1205 if (this._config.panelClass) {
1206 this._toggleClasses(this._pane, this._config.panelClass, true);
1207 }
1208 // Only emit the `attachments` event once all other setup is done.
1209 this._attachments.next();
1210 // Track this overlay by the keyboard dispatcher
1211 this._keyboardDispatcher.add(this);
1212 if (this._config.disposeOnNavigation) {
1213 this._locationChanges = this._location.subscribe(function () { return _this.dispose(); });
1214 }
1215 this._outsideClickDispatcher.add(this);
1216 return attachResult;
1217 };
1218 /**
1219 * Detaches an overlay from a portal.
1220 * @returns The portal detachment result.
1221 */
1222 OverlayRef.prototype.detach = function () {
1223 if (!this.hasAttached()) {
1224 return;
1225 }
1226 this.detachBackdrop();
1227 // When the overlay is detached, the pane element should disable pointer events.
1228 // This is necessary because otherwise the pane element will cover the page and disable
1229 // pointer events therefore. Depends on the position strategy and the applied pane boundaries.
1230 this._togglePointerEvents(false);
1231 if (this._positionStrategy && this._positionStrategy.detach) {
1232 this._positionStrategy.detach();
1233 }
1234 if (this._scrollStrategy) {
1235 this._scrollStrategy.disable();
1236 }
1237 var detachmentResult = this._portalOutlet.detach();
1238 // Only emit after everything is detached.
1239 this._detachments.next();
1240 // Remove this overlay from keyboard dispatcher tracking.
1241 this._keyboardDispatcher.remove(this);
1242 // Keeping the host element in the DOM can cause scroll jank, because it still gets
1243 // rendered, even though it's transparent and unclickable which is why we remove it.
1244 this._detachContentWhenStable();
1245 this._locationChanges.unsubscribe();
1246 this._outsideClickDispatcher.remove(this);
1247 return detachmentResult;
1248 };
1249 /** Cleans up the overlay from the DOM. */
1250 OverlayRef.prototype.dispose = function () {
1251 var isAttached = this.hasAttached();
1252 if (this._positionStrategy) {
1253 this._positionStrategy.dispose();
1254 }
1255 this._disposeScrollStrategy();
1256 this._disposeBackdrop(this._backdropElement);
1257 this._locationChanges.unsubscribe();
1258 this._keyboardDispatcher.remove(this);
1259 this._portalOutlet.dispose();
1260 this._attachments.complete();
1261 this._backdropClick.complete();
1262 this._keydownEvents.complete();
1263 this._outsidePointerEvents.complete();
1264 this._outsideClickDispatcher.remove(this);
1265 if (this._host && this._host.parentNode) {
1266 this._host.parentNode.removeChild(this._host);
1267 this._host = null;
1268 }
1269 this._previousHostParent = this._pane = null;
1270 if (isAttached) {
1271 this._detachments.next();
1272 }
1273 this._detachments.complete();
1274 };
1275 /** Whether the overlay has attached content. */
1276 OverlayRef.prototype.hasAttached = function () {
1277 return this._portalOutlet.hasAttached();
1278 };
1279 /** Gets an observable that emits when the backdrop has been clicked. */
1280 OverlayRef.prototype.backdropClick = function () {
1281 return this._backdropClick;
1282 };
1283 /** Gets an observable that emits when the overlay has been attached. */
1284 OverlayRef.prototype.attachments = function () {
1285 return this._attachments;
1286 };
1287 /** Gets an observable that emits when the overlay has been detached. */
1288 OverlayRef.prototype.detachments = function () {
1289 return this._detachments;
1290 };
1291 /** Gets an observable of keydown events targeted to this overlay. */
1292 OverlayRef.prototype.keydownEvents = function () {
1293 return this._keydownEvents;
1294 };
1295 /** Gets an observable of pointer events targeted outside this overlay. */
1296 OverlayRef.prototype.outsidePointerEvents = function () {
1297 return this._outsidePointerEvents;
1298 };
1299 /** Gets the current overlay configuration, which is immutable. */
1300 OverlayRef.prototype.getConfig = function () {
1301 return this._config;
1302 };
1303 /** Updates the position of the overlay based on the position strategy. */
1304 OverlayRef.prototype.updatePosition = function () {
1305 if (this._positionStrategy) {
1306 this._positionStrategy.apply();
1307 }
1308 };
1309 /** Switches to a new position strategy and updates the overlay position. */
1310 OverlayRef.prototype.updatePositionStrategy = function (strategy) {
1311 if (strategy === this._positionStrategy) {
1312 return;
1313 }
1314 if (this._positionStrategy) {
1315 this._positionStrategy.dispose();
1316 }
1317 this._positionStrategy = strategy;
1318 if (this.hasAttached()) {
1319 strategy.attach(this);
1320 this.updatePosition();
1321 }
1322 };
1323 /** Update the size properties of the overlay. */
1324 OverlayRef.prototype.updateSize = function (sizeConfig) {
1325 this._config = Object.assign(Object.assign({}, this._config), sizeConfig);
1326 this._updateElementSize();
1327 };
1328 /** Sets the LTR/RTL direction for the overlay. */
1329 OverlayRef.prototype.setDirection = function (dir) {
1330 this._config = Object.assign(Object.assign({}, this._config), { direction: dir });
1331 this._updateElementDirection();
1332 };
1333 /** Add a CSS class or an array of classes to the overlay pane. */
1334 OverlayRef.prototype.addPanelClass = function (classes) {
1335 if (this._pane) {
1336 this._toggleClasses(this._pane, classes, true);
1337 }
1338 };
1339 /** Remove a CSS class or an array of classes from the overlay pane. */
1340 OverlayRef.prototype.removePanelClass = function (classes) {
1341 if (this._pane) {
1342 this._toggleClasses(this._pane, classes, false);
1343 }
1344 };
1345 /**
1346 * Returns the layout direction of the overlay panel.
1347 */
1348 OverlayRef.prototype.getDirection = function () {
1349 var direction = this._config.direction;
1350 if (!direction) {
1351 return 'ltr';
1352 }
1353 return typeof direction === 'string' ? direction : direction.value;
1354 };
1355 /** Switches to a new scroll strategy. */
1356 OverlayRef.prototype.updateScrollStrategy = function (strategy) {
1357 if (strategy === this._scrollStrategy) {
1358 return;
1359 }
1360 this._disposeScrollStrategy();
1361 this._scrollStrategy = strategy;
1362 if (this.hasAttached()) {
1363 strategy.attach(this);
1364 strategy.enable();
1365 }
1366 };
1367 /** Updates the text direction of the overlay panel. */
1368 OverlayRef.prototype._updateElementDirection = function () {
1369 this._host.setAttribute('dir', this.getDirection());
1370 };
1371 /** Updates the size of the overlay element based on the overlay config. */
1372 OverlayRef.prototype._updateElementSize = function () {
1373 if (!this._pane) {
1374 return;
1375 }
1376 var style = this._pane.style;
1377 style.width = coercion.coerceCssPixelValue(this._config.width);
1378 style.height = coercion.coerceCssPixelValue(this._config.height);
1379 style.minWidth = coercion.coerceCssPixelValue(this._config.minWidth);
1380 style.minHeight = coercion.coerceCssPixelValue(this._config.minHeight);
1381 style.maxWidth = coercion.coerceCssPixelValue(this._config.maxWidth);
1382 style.maxHeight = coercion.coerceCssPixelValue(this._config.maxHeight);
1383 };
1384 /** Toggles the pointer events for the overlay pane element. */
1385 OverlayRef.prototype._togglePointerEvents = function (enablePointer) {
1386 this._pane.style.pointerEvents = enablePointer ? '' : 'none';
1387 };
1388 /** Attaches a backdrop for this overlay. */
1389 OverlayRef.prototype._attachBackdrop = function () {
1390 var _this = this;
1391 var showingClass = 'cdk-overlay-backdrop-showing';
1392 this._backdropElement = this._document.createElement('div');
1393 this._backdropElement.classList.add('cdk-overlay-backdrop');
1394 if (this._config.backdropClass) {
1395 this._toggleClasses(this._backdropElement, this._config.backdropClass, true);
1396 }
1397 // Insert the backdrop before the pane in the DOM order,
1398 // in order to handle stacked overlays properly.
1399 this._host.parentElement.insertBefore(this._backdropElement, this._host);
1400 // Forward backdrop clicks such that the consumer of the overlay can perform whatever
1401 // action desired when such a click occurs (usually closing the overlay).
1402 this._backdropElement.addEventListener('click', this._backdropClickHandler);
1403 // Add class to fade-in the backdrop after one frame.
1404 if (typeof requestAnimationFrame !== 'undefined') {
1405 this._ngZone.runOutsideAngular(function () {
1406 requestAnimationFrame(function () {
1407 if (_this._backdropElement) {
1408 _this._backdropElement.classList.add(showingClass);
1409 }
1410 });
1411 });
1412 }
1413 else {
1414 this._backdropElement.classList.add(showingClass);
1415 }
1416 };
1417 /**
1418 * Updates the stacking order of the element, moving it to the top if necessary.
1419 * This is required in cases where one overlay was detached, while another one,
1420 * that should be behind it, was destroyed. The next time both of them are opened,
1421 * the stacking will be wrong, because the detached element's pane will still be
1422 * in its original DOM position.
1423 */
1424 OverlayRef.prototype._updateStackingOrder = function () {
1425 if (this._host.nextSibling) {
1426 this._host.parentNode.appendChild(this._host);
1427 }
1428 };
1429 /** Detaches the backdrop (if any) associated with the overlay. */
1430 OverlayRef.prototype.detachBackdrop = function () {
1431 var _this = this;
1432 var backdropToDetach = this._backdropElement;
1433 if (!backdropToDetach) {
1434 return;
1435 }
1436 var timeoutId;
1437 var finishDetach = function () {
1438 // It may not be attached to anything in certain cases (e.g. unit tests).
1439 if (backdropToDetach) {
1440 backdropToDetach.removeEventListener('click', _this._backdropClickHandler);
1441 backdropToDetach.removeEventListener('transitionend', finishDetach);
1442 _this._disposeBackdrop(backdropToDetach);
1443 }
1444 if (_this._config.backdropClass) {
1445 _this._toggleClasses(backdropToDetach, _this._config.backdropClass, false);
1446 }
1447 clearTimeout(timeoutId);
1448 };
1449 backdropToDetach.classList.remove('cdk-overlay-backdrop-showing');
1450 this._ngZone.runOutsideAngular(function () {
1451 backdropToDetach.addEventListener('transitionend', finishDetach);
1452 });
1453 // If the backdrop doesn't have a transition, the `transitionend` event won't fire.
1454 // In this case we make it unclickable and we try to remove it after a delay.
1455 backdropToDetach.style.pointerEvents = 'none';
1456 // Run this outside the Angular zone because there's nothing that Angular cares about.
1457 // If it were to run inside the Angular zone, every test that used Overlay would have to be
1458 // either async or fakeAsync.
1459 timeoutId = this._ngZone.runOutsideAngular(function () { return setTimeout(finishDetach, 500); });
1460 };
1461 /** Toggles a single CSS class or an array of classes on an element. */
1462 OverlayRef.prototype._toggleClasses = function (element, cssClasses, isAdd) {
1463 var classList = element.classList;
1464 coercion.coerceArray(cssClasses).forEach(function (cssClass) {
1465 // We can't do a spread here, because IE doesn't support setting multiple classes.
1466 // Also trying to add an empty string to a DOMTokenList will throw.
1467 if (cssClass) {
1468 isAdd ? classList.add(cssClass) : classList.remove(cssClass);
1469 }
1470 });
1471 };
1472 /** Detaches the overlay content next time the zone stabilizes. */
1473 OverlayRef.prototype._detachContentWhenStable = function () {
1474 var _this = this;
1475 // Normally we wouldn't have to explicitly run this outside the `NgZone`, however
1476 // if the consumer is using `zone-patch-rxjs`, the `Subscription.unsubscribe` call will
1477 // be patched to run inside the zone, which will throw us into an infinite loop.
1478 this._ngZone.runOutsideAngular(function () {
1479 // We can't remove the host here immediately, because the overlay pane's content
1480 // might still be animating. This stream helps us avoid interrupting the animation
1481 // by waiting for the pane to become empty.
1482 var subscription = _this._ngZone.onStable
1483 .pipe(operators.takeUntil(rxjs.merge(_this._attachments, _this._detachments)))
1484 .subscribe(function () {
1485 // Needs a couple of checks for the pane and host, because
1486 // they may have been removed by the time the zone stabilizes.
1487 if (!_this._pane || !_this._host || _this._pane.children.length === 0) {
1488 if (_this._pane && _this._config.panelClass) {
1489 _this._toggleClasses(_this._pane, _this._config.panelClass, false);
1490 }
1491 if (_this._host && _this._host.parentElement) {
1492 _this._previousHostParent = _this._host.parentElement;
1493 _this._previousHostParent.removeChild(_this._host);
1494 }
1495 subscription.unsubscribe();
1496 }
1497 });
1498 });
1499 };
1500 /** Disposes of a scroll strategy. */
1501 OverlayRef.prototype._disposeScrollStrategy = function () {
1502 var scrollStrategy = this._scrollStrategy;
1503 if (scrollStrategy) {
1504 scrollStrategy.disable();
1505 if (scrollStrategy.detach) {
1506 scrollStrategy.detach();
1507 }
1508 }
1509 };
1510 /** Removes a backdrop element from the DOM. */
1511 OverlayRef.prototype._disposeBackdrop = function (backdrop) {
1512 if (backdrop) {
1513 if (backdrop.parentNode) {
1514 backdrop.parentNode.removeChild(backdrop);
1515 }
1516 // It is possible that a new portal has been attached to this overlay since we started
1517 // removing the backdrop. If that is the case, only clear the backdrop reference if it
1518 // is still the same instance that we started to remove.
1519 if (this._backdropElement === backdrop) {
1520 this._backdropElement = null;
1521 }
1522 }
1523 };
1524 return OverlayRef;
1525 }());
1526
1527 // TODO: refactor clipping detection into a separate thing (part of scrolling module)
1528 // TODO: doesn't handle both flexible width and height when it has to scroll along both axis.
1529 /** Class to be added to the overlay bounding box. */
1530 var boundingBoxClass = 'cdk-overlay-connected-position-bounding-box';
1531 /** Regex used to split a string on its CSS units. */
1532 var cssUnitPattern = /([A-Za-z%]+)$/;
1533 /**
1534 * A strategy for positioning overlays. Using this strategy, an overlay is given an
1535 * implicit position relative some origin element. The relative position is defined in terms of
1536 * a point on the origin element that is connected to a point on the overlay element. For example,
1537 * a basic dropdown is connecting the bottom-left corner of the origin to the top-left corner
1538 * of the overlay.
1539 */
1540 var FlexibleConnectedPositionStrategy = /** @class */ (function () {
1541 function FlexibleConnectedPositionStrategy(connectedTo, _viewportRuler, _document, _platform, _overlayContainer) {
1542 this._viewportRuler = _viewportRuler;
1543 this._document = _document;
1544 this._platform = _platform;
1545 this._overlayContainer = _overlayContainer;
1546 /** Last size used for the bounding box. Used to avoid resizing the overlay after open. */
1547 this._lastBoundingBoxSize = { width: 0, height: 0 };
1548 /** Whether the overlay was pushed in a previous positioning. */
1549 this._isPushed = false;
1550 /** Whether the overlay can be pushed on-screen on the initial open. */
1551 this._canPush = true;
1552 /** Whether the overlay can grow via flexible width/height after the initial open. */
1553 this._growAfterOpen = false;
1554 /** Whether the overlay's width and height can be constrained to fit within the viewport. */
1555 this._hasFlexibleDimensions = true;
1556 /** Whether the overlay position is locked. */
1557 this._positionLocked = false;
1558 /** Amount of space that must be maintained between the overlay and the edge of the viewport. */
1559 this._viewportMargin = 0;
1560 /** The Scrollable containers used to check scrollable view properties on position change. */
1561 this._scrollables = [];
1562 /** Ordered list of preferred positions, from most to least desirable. */
1563 this._preferredPositions = [];
1564 /** Subject that emits whenever the position changes. */
1565 this._positionChanges = new rxjs.Subject();
1566 /** Subscription to viewport size changes. */
1567 this._resizeSubscription = rxjs.Subscription.EMPTY;
1568 /** Default offset for the overlay along the x axis. */
1569 this._offsetX = 0;
1570 /** Default offset for the overlay along the y axis. */
1571 this._offsetY = 0;
1572 /** Keeps track of the CSS classes that the position strategy has applied on the overlay panel. */
1573 this._appliedPanelClasses = [];
1574 /** Observable sequence of position changes. */
1575 this.positionChanges = this._positionChanges;
1576 this.setOrigin(connectedTo);
1577 }
1578 Object.defineProperty(FlexibleConnectedPositionStrategy.prototype, "positions", {
1579 /** Ordered list of preferred positions, from most to least desirable. */
1580 get: function () {
1581 return this._preferredPositions;
1582 },
1583 enumerable: false,
1584 configurable: true
1585 });
1586 /** Attaches this position strategy to an overlay. */
1587 FlexibleConnectedPositionStrategy.prototype.attach = function (overlayRef) {
1588 var _this = this;
1589 if (this._overlayRef && overlayRef !== this._overlayRef &&
1590 (typeof ngDevMode === 'undefined' || ngDevMode)) {
1591 throw Error('This position strategy is already attached to an overlay');
1592 }
1593 this._validatePositions();
1594 overlayRef.hostElement.classList.add(boundingBoxClass);
1595 this._overlayRef = overlayRef;
1596 this._boundingBox = overlayRef.hostElement;
1597 this._pane = overlayRef.overlayElement;
1598 this._isDisposed = false;
1599 this._isInitialRender = true;
1600 this._lastPosition = null;
1601 this._resizeSubscription.unsubscribe();
1602 this._resizeSubscription = this._viewportRuler.change().subscribe(function () {
1603 // When the window is resized, we want to trigger the next reposition as if it
1604 // was an initial render, in order for the strategy to pick a new optimal position,
1605 // otherwise position locking will cause it to stay at the old one.
1606 _this._isInitialRender = true;
1607 _this.apply();
1608 });
1609 };
1610 /**
1611 * Updates the position of the overlay element, using whichever preferred position relative
1612 * to the origin best fits on-screen.
1613 *
1614 * The selection of a position goes as follows:
1615 * - If any positions fit completely within the viewport as-is,
1616 * choose the first position that does so.
1617 * - If flexible dimensions are enabled and at least one satifies the given minimum width/height,
1618 * choose the position with the greatest available size modified by the positions' weight.
1619 * - If pushing is enabled, take the position that went off-screen the least and push it
1620 * on-screen.
1621 * - If none of the previous criteria were met, use the position that goes off-screen the least.
1622 * @docs-private
1623 */
1624 FlexibleConnectedPositionStrategy.prototype.apply = function () {
1625 var e_1, _a, e_2, _b;
1626 // We shouldn't do anything if the strategy was disposed or we're on the server.
1627 if (this._isDisposed || !this._platform.isBrowser) {
1628 return;
1629 }
1630 // If the position has been applied already (e.g. when the overlay was opened) and the
1631 // consumer opted into locking in the position, re-use the old position, in order to
1632 // prevent the overlay from jumping around.
1633 if (!this._isInitialRender && this._positionLocked && this._lastPosition) {
1634 this.reapplyLastPosition();
1635 return;
1636 }
1637 this._clearPanelClasses();
1638 this._resetOverlayElementStyles();
1639 this._resetBoundingBoxStyles();
1640 // We need the bounding rects for the origin and the overlay to determine how to position
1641 // the overlay relative to the origin.
1642 // We use the viewport rect to determine whether a position would go off-screen.
1643 this._viewportRect = this._getNarrowedViewportRect();
1644 this._originRect = this._getOriginRect();
1645 this._overlayRect = this._pane.getBoundingClientRect();
1646 var originRect = this._originRect;
1647 var overlayRect = this._overlayRect;
1648 var viewportRect = this._viewportRect;
1649 // Positions where the overlay will fit with flexible dimensions.
1650 var flexibleFits = [];
1651 // Fallback if none of the preferred positions fit within the viewport.
1652 var fallback;
1653 try {
1654 // Go through each of the preferred positions looking for a good fit.
1655 // If a good fit is found, it will be applied immediately.
1656 for (var _c = __values(this._preferredPositions), _d = _c.next(); !_d.done; _d = _c.next()) {
1657 var pos = _d.value;
1658 // Get the exact (x, y) coordinate for the point-of-origin on the origin element.
1659 var originPoint = this._getOriginPoint(originRect, pos);
1660 // From that point-of-origin, get the exact (x, y) coordinate for the top-left corner of the
1661 // overlay in this position. We use the top-left corner for calculations and later translate
1662 // this into an appropriate (top, left, bottom, right) style.
1663 var overlayPoint = this._getOverlayPoint(originPoint, overlayRect, pos);
1664 // Calculate how well the overlay would fit into the viewport with this point.
1665 var overlayFit = this._getOverlayFit(overlayPoint, overlayRect, viewportRect, pos);
1666 // If the overlay, without any further work, fits into the viewport, use this position.
1667 if (overlayFit.isCompletelyWithinViewport) {
1668 this._isPushed = false;
1669 this._applyPosition(pos, originPoint);
1670 return;
1671 }
1672 // If the overlay has flexible dimensions, we can use this position
1673 // so long as there's enough space for the minimum dimensions.
1674 if (this._canFitWithFlexibleDimensions(overlayFit, overlayPoint, viewportRect)) {
1675 // Save positions where the overlay will fit with flexible dimensions. We will use these
1676 // if none of the positions fit *without* flexible dimensions.
1677 flexibleFits.push({
1678 position: pos,
1679 origin: originPoint,
1680 overlayRect: overlayRect,
1681 boundingBoxRect: this._calculateBoundingBoxRect(originPoint, pos)
1682 });
1683 continue;
1684 }
1685 // If the current preferred position does not fit on the screen, remember the position
1686 // if it has more visible area on-screen than we've seen and move onto the next preferred
1687 // position.
1688 if (!fallback || fallback.overlayFit.visibleArea < overlayFit.visibleArea) {
1689 fallback = { overlayFit: overlayFit, overlayPoint: overlayPoint, originPoint: originPoint, position: pos, overlayRect: overlayRect };
1690 }
1691 }
1692 }
1693 catch (e_1_1) { e_1 = { error: e_1_1 }; }
1694 finally {
1695 try {
1696 if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
1697 }
1698 finally { if (e_1) throw e_1.error; }
1699 }
1700 // If there are any positions where the overlay would fit with flexible dimensions, choose the
1701 // one that has the greatest area available modified by the position's weight
1702 if (flexibleFits.length) {
1703 var bestFit = null;
1704 var bestScore = -1;
1705 try {
1706 for (var flexibleFits_1 = __values(flexibleFits), flexibleFits_1_1 = flexibleFits_1.next(); !flexibleFits_1_1.done; flexibleFits_1_1 = flexibleFits_1.next()) {
1707 var fit = flexibleFits_1_1.value;
1708 var score = fit.boundingBoxRect.width * fit.boundingBoxRect.height * (fit.position.weight || 1);
1709 if (score > bestScore) {
1710 bestScore = score;
1711 bestFit = fit;
1712 }
1713 }
1714 }
1715 catch (e_2_1) { e_2 = { error: e_2_1 }; }
1716 finally {
1717 try {
1718 if (flexibleFits_1_1 && !flexibleFits_1_1.done && (_b = flexibleFits_1.return)) _b.call(flexibleFits_1);
1719 }
1720 finally { if (e_2) throw e_2.error; }
1721 }
1722 this._isPushed = false;
1723 this._applyPosition(bestFit.position, bestFit.origin);
1724 return;
1725 }
1726 // When none of the preferred positions fit within the viewport, take the position
1727 // that went off-screen the least and attempt to push it on-screen.
1728 if (this._canPush) {
1729 // TODO(jelbourn): after pushing, the opening "direction" of the overlay might not make sense.
1730 this._isPushed = true;
1731 this._applyPosition(fallback.position, fallback.originPoint);
1732 return;
1733 }
1734 // All options for getting the overlay within the viewport have been exhausted, so go with the
1735 // position that went off-screen the least.
1736 this._applyPosition(fallback.position, fallback.originPoint);
1737 };
1738 FlexibleConnectedPositionStrategy.prototype.detach = function () {
1739 this._clearPanelClasses();
1740 this._lastPosition = null;
1741 this._previousPushAmount = null;
1742 this._resizeSubscription.unsubscribe();
1743 };
1744 /** Cleanup after the element gets destroyed. */
1745 FlexibleConnectedPositionStrategy.prototype.dispose = function () {
1746 if (this._isDisposed) {
1747 return;
1748 }
1749 // We can't use `_resetBoundingBoxStyles` here, because it resets
1750 // some properties to zero, rather than removing them.
1751 if (this._boundingBox) {
1752 extendStyles(this._boundingBox.style, {
1753 top: '',
1754 left: '',
1755 right: '',
1756 bottom: '',
1757 height: '',
1758 width: '',
1759 alignItems: '',
1760 justifyContent: '',
1761 });
1762 }
1763 if (this._pane) {
1764 this._resetOverlayElementStyles();
1765 }
1766 if (this._overlayRef) {
1767 this._overlayRef.hostElement.classList.remove(boundingBoxClass);
1768 }
1769 this.detach();
1770 this._positionChanges.complete();
1771 this._overlayRef = this._boundingBox = null;
1772 this._isDisposed = true;
1773 };
1774 /**
1775 * This re-aligns the overlay element with the trigger in its last calculated position,
1776 * even if a position higher in the "preferred positions" list would now fit. This
1777 * allows one to re-align the panel without changing the orientation of the panel.
1778 */
1779 FlexibleConnectedPositionStrategy.prototype.reapplyLastPosition = function () {
1780 if (!this._isDisposed && (!this._platform || this._platform.isBrowser)) {
1781 this._originRect = this._getOriginRect();
1782 this._overlayRect = this._pane.getBoundingClientRect();
1783 this._viewportRect = this._getNarrowedViewportRect();
1784 var lastPosition = this._lastPosition || this._preferredPositions[0];
1785 var originPoint = this._getOriginPoint(this._originRect, lastPosition);
1786 this._applyPosition(lastPosition, originPoint);
1787 }
1788 };
1789 /**
1790 * Sets the list of Scrollable containers that host the origin element so that
1791 * on reposition we can evaluate if it or the overlay has been clipped or outside view. Every
1792 * Scrollable must be an ancestor element of the strategy's origin element.
1793 */
1794 FlexibleConnectedPositionStrategy.prototype.withScrollableContainers = function (scrollables) {
1795 this._scrollables = scrollables;
1796 return this;
1797 };
1798 /**
1799 * Adds new preferred positions.
1800 * @param positions List of positions options for this overlay.
1801 */
1802 FlexibleConnectedPositionStrategy.prototype.withPositions = function (positions) {
1803 this._preferredPositions = positions;
1804 // If the last calculated position object isn't part of the positions anymore, clear
1805 // it in order to avoid it being picked up if the consumer tries to re-apply.
1806 if (positions.indexOf(this._lastPosition) === -1) {
1807 this._lastPosition = null;
1808 }
1809 this._validatePositions();
1810 return this;
1811 };
1812 /**
1813 * Sets a minimum distance the overlay may be positioned to the edge of the viewport.
1814 * @param margin Required margin between the overlay and the viewport edge in pixels.
1815 */
1816 FlexibleConnectedPositionStrategy.prototype.withViewportMargin = function (margin) {
1817 this._viewportMargin = margin;
1818 return this;
1819 };
1820 /** Sets whether the overlay's width and height can be constrained to fit within the viewport. */
1821 FlexibleConnectedPositionStrategy.prototype.withFlexibleDimensions = function (flexibleDimensions) {
1822 if (flexibleDimensions === void 0) { flexibleDimensions = true; }
1823 this._hasFlexibleDimensions = flexibleDimensions;
1824 return this;
1825 };
1826 /** Sets whether the overlay can grow after the initial open via flexible width/height. */
1827 FlexibleConnectedPositionStrategy.prototype.withGrowAfterOpen = function (growAfterOpen) {
1828 if (growAfterOpen === void 0) { growAfterOpen = true; }
1829 this._growAfterOpen = growAfterOpen;
1830 return this;
1831 };
1832 /** Sets whether the overlay can be pushed on-screen if none of the provided positions fit. */
1833 FlexibleConnectedPositionStrategy.prototype.withPush = function (canPush) {
1834 if (canPush === void 0) { canPush = true; }
1835 this._canPush = canPush;
1836 return this;
1837 };
1838 /**
1839 * Sets whether the overlay's position should be locked in after it is positioned
1840 * initially. When an overlay is locked in, it won't attempt to reposition itself
1841 * when the position is re-applied (e.g. when the user scrolls away).
1842 * @param isLocked Whether the overlay should locked in.
1843 */
1844 FlexibleConnectedPositionStrategy.prototype.withLockedPosition = function (isLocked) {
1845 if (isLocked === void 0) { isLocked = true; }
1846 this._positionLocked = isLocked;
1847 return this;
1848 };
1849 /**
1850 * Sets the origin, relative to which to position the overlay.
1851 * Using an element origin is useful for building components that need to be positioned
1852 * relatively to a trigger (e.g. dropdown menus or tooltips), whereas using a point can be
1853 * used for cases like contextual menus which open relative to the user's pointer.
1854 * @param origin Reference to the new origin.
1855 */
1856 FlexibleConnectedPositionStrategy.prototype.setOrigin = function (origin) {
1857 this._origin = origin;
1858 return this;
1859 };
1860 /**
1861 * Sets the default offset for the overlay's connection point on the x-axis.
1862 * @param offset New offset in the X axis.
1863 */
1864 FlexibleConnectedPositionStrategy.prototype.withDefaultOffsetX = function (offset) {
1865 this._offsetX = offset;
1866 return this;
1867 };
1868 /**
1869 * Sets the default offset for the overlay's connection point on the y-axis.
1870 * @param offset New offset in the Y axis.
1871 */
1872 FlexibleConnectedPositionStrategy.prototype.withDefaultOffsetY = function (offset) {
1873 this._offsetY = offset;
1874 return this;
1875 };
1876 /**
1877 * Configures that the position strategy should set a `transform-origin` on some elements
1878 * inside the overlay, depending on the current position that is being applied. This is
1879 * useful for the cases where the origin of an animation can change depending on the
1880 * alignment of the overlay.
1881 * @param selector CSS selector that will be used to find the target
1882 * elements onto which to set the transform origin.
1883 */
1884 FlexibleConnectedPositionStrategy.prototype.withTransformOriginOn = function (selector) {
1885 this._transformOriginSelector = selector;
1886 return this;
1887 };
1888 /**
1889 * Gets the (x, y) coordinate of a connection point on the origin based on a relative position.
1890 */
1891 FlexibleConnectedPositionStrategy.prototype._getOriginPoint = function (originRect, pos) {
1892 var x;
1893 if (pos.originX == 'center') {
1894 // Note: when centering we should always use the `left`
1895 // offset, otherwise the position will be wrong in RTL.
1896 x = originRect.left + (originRect.width / 2);
1897 }
1898 else {
1899 var startX = this._isRtl() ? originRect.right : originRect.left;
1900 var endX = this._isRtl() ? originRect.left : originRect.right;
1901 x = pos.originX == 'start' ? startX : endX;
1902 }
1903 var y;
1904 if (pos.originY == 'center') {
1905 y = originRect.top + (originRect.height / 2);
1906 }
1907 else {
1908 y = pos.originY == 'top' ? originRect.top : originRect.bottom;
1909 }
1910 return { x: x, y: y };
1911 };
1912 /**
1913 * Gets the (x, y) coordinate of the top-left corner of the overlay given a given position and
1914 * origin point to which the overlay should be connected.
1915 */
1916 FlexibleConnectedPositionStrategy.prototype._getOverlayPoint = function (originPoint, overlayRect, pos) {
1917 // Calculate the (overlayStartX, overlayStartY), the start of the
1918 // potential overlay position relative to the origin point.
1919 var overlayStartX;
1920 if (pos.overlayX == 'center') {
1921 overlayStartX = -overlayRect.width / 2;
1922 }
1923 else if (pos.overlayX === 'start') {
1924 overlayStartX = this._isRtl() ? -overlayRect.width : 0;
1925 }
1926 else {
1927 overlayStartX = this._isRtl() ? 0 : -overlayRect.width;
1928 }
1929 var overlayStartY;
1930 if (pos.overlayY == 'center') {
1931 overlayStartY = -overlayRect.height / 2;
1932 }
1933 else {
1934 overlayStartY = pos.overlayY == 'top' ? 0 : -overlayRect.height;
1935 }
1936 // The (x, y) coordinates of the overlay.
1937 return {
1938 x: originPoint.x + overlayStartX,
1939 y: originPoint.y + overlayStartY,
1940 };
1941 };
1942 /** Gets how well an overlay at the given point will fit within the viewport. */
1943 FlexibleConnectedPositionStrategy.prototype._getOverlayFit = function (point, rawOverlayRect, viewport, position) {
1944 // Round the overlay rect when comparing against the
1945 // viewport, because the viewport is always rounded.
1946 var overlay = getRoundedBoundingClientRect(rawOverlayRect);
1947 var x = point.x, y = point.y;
1948 var offsetX = this._getOffset(position, 'x');
1949 var offsetY = this._getOffset(position, 'y');
1950 // Account for the offsets since they could push the overlay out of the viewport.
1951 if (offsetX) {
1952 x += offsetX;
1953 }
1954 if (offsetY) {
1955 y += offsetY;
1956 }
1957 // How much the overlay would overflow at this position, on each side.
1958 var leftOverflow = 0 - x;
1959 var rightOverflow = (x + overlay.width) - viewport.width;
1960 var topOverflow = 0 - y;
1961 var bottomOverflow = (y + overlay.height) - viewport.height;
1962 // Visible parts of the element on each axis.
1963 var visibleWidth = this._subtractOverflows(overlay.width, leftOverflow, rightOverflow);
1964 var visibleHeight = this._subtractOverflows(overlay.height, topOverflow, bottomOverflow);
1965 var visibleArea = visibleWidth * visibleHeight;
1966 return {
1967 visibleArea: visibleArea,
1968 isCompletelyWithinViewport: (overlay.width * overlay.height) === visibleArea,
1969 fitsInViewportVertically: visibleHeight === overlay.height,
1970 fitsInViewportHorizontally: visibleWidth == overlay.width,
1971 };
1972 };
1973 /**
1974 * Whether the overlay can fit within the viewport when it may resize either its width or height.
1975 * @param fit How well the overlay fits in the viewport at some position.
1976 * @param point The (x, y) coordinates of the overlat at some position.
1977 * @param viewport The geometry of the viewport.
1978 */
1979 FlexibleConnectedPositionStrategy.prototype._canFitWithFlexibleDimensions = function (fit, point, viewport) {
1980 if (this._hasFlexibleDimensions) {
1981 var availableHeight = viewport.bottom - point.y;
1982 var availableWidth = viewport.right - point.x;
1983 var minHeight = getPixelValue(this._overlayRef.getConfig().minHeight);
1984 var minWidth = getPixelValue(this._overlayRef.getConfig().minWidth);
1985 var verticalFit = fit.fitsInViewportVertically ||
1986 (minHeight != null && minHeight <= availableHeight);
1987 var horizontalFit = fit.fitsInViewportHorizontally ||
1988 (minWidth != null && minWidth <= availableWidth);
1989 return verticalFit && horizontalFit;
1990 }
1991 return false;
1992 };
1993 /**
1994 * Gets the point at which the overlay can be "pushed" on-screen. If the overlay is larger than
1995 * the viewport, the top-left corner will be pushed on-screen (with overflow occuring on the
1996 * right and bottom).
1997 *
1998 * @param start Starting point from which the overlay is pushed.
1999 * @param overlay Dimensions of the overlay.
2000 * @param scrollPosition Current viewport scroll position.
2001 * @returns The point at which to position the overlay after pushing. This is effectively a new
2002 * originPoint.
2003 */
2004 FlexibleConnectedPositionStrategy.prototype._pushOverlayOnScreen = function (start, rawOverlayRect, scrollPosition) {
2005 // If the position is locked and we've pushed the overlay already, reuse the previous push
2006 // amount, rather than pushing it again. If we were to continue pushing, the element would
2007 // remain in the viewport, which goes against the expectations when position locking is enabled.
2008 if (this._previousPushAmount && this._positionLocked) {
2009 return {
2010 x: start.x + this._previousPushAmount.x,
2011 y: start.y + this._previousPushAmount.y
2012 };
2013 }
2014 // Round the overlay rect when comparing against the
2015 // viewport, because the viewport is always rounded.
2016 var overlay = getRoundedBoundingClientRect(rawOverlayRect);
2017 var viewport = this._viewportRect;
2018 // Determine how much the overlay goes outside the viewport on each
2019 // side, which we'll use to decide which direction to push it.
2020 var overflowRight = Math.max(start.x + overlay.width - viewport.width, 0);
2021 var overflowBottom = Math.max(start.y + overlay.height - viewport.height, 0);
2022 var overflowTop = Math.max(viewport.top - scrollPosition.top - start.y, 0);
2023 var overflowLeft = Math.max(viewport.left - scrollPosition.left - start.x, 0);
2024 // Amount by which to push the overlay in each axis such that it remains on-screen.
2025 var pushX = 0;
2026 var pushY = 0;
2027 // If the overlay fits completely within the bounds of the viewport, push it from whichever
2028 // direction is goes off-screen. Otherwise, push the top-left corner such that its in the
2029 // viewport and allow for the trailing end of the overlay to go out of bounds.
2030 if (overlay.width <= viewport.width) {
2031 pushX = overflowLeft || -overflowRight;
2032 }
2033 else {
2034 pushX = start.x < this._viewportMargin ? (viewport.left - scrollPosition.left) - start.x : 0;
2035 }
2036 if (overlay.height <= viewport.height) {
2037 pushY = overflowTop || -overflowBottom;
2038 }
2039 else {
2040 pushY = start.y < this._viewportMargin ? (viewport.top - scrollPosition.top) - start.y : 0;
2041 }
2042 this._previousPushAmount = { x: pushX, y: pushY };
2043 return {
2044 x: start.x + pushX,
2045 y: start.y + pushY,
2046 };
2047 };
2048 /**
2049 * Applies a computed position to the overlay and emits a position change.
2050 * @param position The position preference
2051 * @param originPoint The point on the origin element where the overlay is connected.
2052 */
2053 FlexibleConnectedPositionStrategy.prototype._applyPosition = function (position, originPoint) {
2054 this._setTransformOrigin(position);
2055 this._setOverlayElementStyles(originPoint, position);
2056 this._setBoundingBoxStyles(originPoint, position);
2057 if (position.panelClass) {
2058 this._addPanelClasses(position.panelClass);
2059 }
2060 // Save the last connected position in case the position needs to be re-calculated.
2061 this._lastPosition = position;
2062 // Notify that the position has been changed along with its change properties.
2063 // We only emit if we've got any subscriptions, because the scroll visibility
2064 // calculcations can be somewhat expensive.
2065 if (this._positionChanges.observers.length) {
2066 var scrollableViewProperties = this._getScrollVisibility();
2067 var changeEvent = new ConnectedOverlayPositionChange(position, scrollableViewProperties);
2068 this._positionChanges.next(changeEvent);
2069 }
2070 this._isInitialRender = false;
2071 };
2072 /** Sets the transform origin based on the configured selector and the passed-in position. */
2073 FlexibleConnectedPositionStrategy.prototype._setTransformOrigin = function (position) {
2074 if (!this._transformOriginSelector) {
2075 return;
2076 }
2077 var elements = this._boundingBox.querySelectorAll(this._transformOriginSelector);
2078 var xOrigin;
2079 var yOrigin = position.overlayY;
2080 if (position.overlayX === 'center') {
2081 xOrigin = 'center';
2082 }
2083 else if (this._isRtl()) {
2084 xOrigin = position.overlayX === 'start' ? 'right' : 'left';
2085 }
2086 else {
2087 xOrigin = position.overlayX === 'start' ? 'left' : 'right';
2088 }
2089 for (var i = 0; i < elements.length; i++) {
2090 elements[i].style.transformOrigin = xOrigin + " " + yOrigin;
2091 }
2092 };
2093 /**
2094 * Gets the position and size of the overlay's sizing container.
2095 *
2096 * This method does no measuring and applies no styles so that we can cheaply compute the
2097 * bounds for all positions and choose the best fit based on these results.
2098 */
2099 FlexibleConnectedPositionStrategy.prototype._calculateBoundingBoxRect = function (origin, position) {
2100 var viewport = this._viewportRect;
2101 var isRtl = this._isRtl();
2102 var height, top, bottom;
2103 if (position.overlayY === 'top') {
2104 // Overlay is opening "downward" and thus is bound by the bottom viewport edge.
2105 top = origin.y;
2106 height = viewport.height - top + this._viewportMargin;
2107 }
2108 else if (position.overlayY === 'bottom') {
2109 // Overlay is opening "upward" and thus is bound by the top viewport edge. We need to add
2110 // the viewport margin back in, because the viewport rect is narrowed down to remove the
2111 // margin, whereas the `origin` position is calculated based on its `ClientRect`.
2112 bottom = viewport.height - origin.y + this._viewportMargin * 2;
2113 height = viewport.height - bottom + this._viewportMargin;
2114 }
2115 else {
2116 // If neither top nor bottom, it means that the overlay is vertically centered on the
2117 // origin point. Note that we want the position relative to the viewport, rather than
2118 // the page, which is why we don't use something like `viewport.bottom - origin.y` and
2119 // `origin.y - viewport.top`.
2120 var smallestDistanceToViewportEdge = Math.min(viewport.bottom - origin.y + viewport.top, origin.y);
2121 var previousHeight = this._lastBoundingBoxSize.height;
2122 height = smallestDistanceToViewportEdge * 2;
2123 top = origin.y - smallestDistanceToViewportEdge;
2124 if (height > previousHeight && !this._isInitialRender && !this._growAfterOpen) {
2125 top = origin.y - (previousHeight / 2);
2126 }
2127 }
2128 // The overlay is opening 'right-ward' (the content flows to the right).
2129 var isBoundedByRightViewportEdge = (position.overlayX === 'start' && !isRtl) ||
2130 (position.overlayX === 'end' && isRtl);
2131 // The overlay is opening 'left-ward' (the content flows to the left).
2132 var isBoundedByLeftViewportEdge = (position.overlayX === 'end' && !isRtl) ||
2133 (position.overlayX === 'start' && isRtl);
2134 var width, left, right;
2135 if (isBoundedByLeftViewportEdge) {
2136 right = viewport.width - origin.x + this._viewportMargin;
2137 width = origin.x - this._viewportMargin;
2138 }
2139 else if (isBoundedByRightViewportEdge) {
2140 left = origin.x;
2141 width = viewport.right - origin.x;
2142 }
2143 else {
2144 // If neither start nor end, it means that the overlay is horizontally centered on the
2145 // origin point. Note that we want the position relative to the viewport, rather than
2146 // the page, which is why we don't use something like `viewport.right - origin.x` and
2147 // `origin.x - viewport.left`.
2148 var smallestDistanceToViewportEdge = Math.min(viewport.right - origin.x + viewport.left, origin.x);
2149 var previousWidth = this._lastBoundingBoxSize.width;
2150 width = smallestDistanceToViewportEdge * 2;
2151 left = origin.x - smallestDistanceToViewportEdge;
2152 if (width > previousWidth && !this._isInitialRender && !this._growAfterOpen) {
2153 left = origin.x - (previousWidth / 2);
2154 }
2155 }
2156 return { top: top, left: left, bottom: bottom, right: right, width: width, height: height };
2157 };
2158 /**
2159 * Sets the position and size of the overlay's sizing wrapper. The wrapper is positioned on the
2160 * origin's connection point and stetches to the bounds of the viewport.
2161 *
2162 * @param origin The point on the origin element where the overlay is connected.
2163 * @param position The position preference
2164 */
2165 FlexibleConnectedPositionStrategy.prototype._setBoundingBoxStyles = function (origin, position) {
2166 var boundingBoxRect = this._calculateBoundingBoxRect(origin, position);
2167 // It's weird if the overlay *grows* while scrolling, so we take the last size into account
2168 // when applying a new size.
2169 if (!this._isInitialRender && !this._growAfterOpen) {
2170 boundingBoxRect.height = Math.min(boundingBoxRect.height, this._lastBoundingBoxSize.height);
2171 boundingBoxRect.width = Math.min(boundingBoxRect.width, this._lastBoundingBoxSize.width);
2172 }
2173 var styles = {};
2174 if (this._hasExactPosition()) {
2175 styles.top = styles.left = '0';
2176 styles.bottom = styles.right = styles.maxHeight = styles.maxWidth = '';
2177 styles.width = styles.height = '100%';
2178 }
2179 else {
2180 var maxHeight = this._overlayRef.getConfig().maxHeight;
2181 var maxWidth = this._overlayRef.getConfig().maxWidth;
2182 styles.height = coercion.coerceCssPixelValue(boundingBoxRect.height);
2183 styles.top = coercion.coerceCssPixelValue(boundingBoxRect.top);
2184 styles.bottom = coercion.coerceCssPixelValue(boundingBoxRect.bottom);
2185 styles.width = coercion.coerceCssPixelValue(boundingBoxRect.width);
2186 styles.left = coercion.coerceCssPixelValue(boundingBoxRect.left);
2187 styles.right = coercion.coerceCssPixelValue(boundingBoxRect.right);
2188 // Push the pane content towards the proper direction.
2189 if (position.overlayX === 'center') {
2190 styles.alignItems = 'center';
2191 }
2192 else {
2193 styles.alignItems = position.overlayX === 'end' ? 'flex-end' : 'flex-start';
2194 }
2195 if (position.overlayY === 'center') {
2196 styles.justifyContent = 'center';
2197 }
2198 else {
2199 styles.justifyContent = position.overlayY === 'bottom' ? 'flex-end' : 'flex-start';
2200 }
2201 if (maxHeight) {
2202 styles.maxHeight = coercion.coerceCssPixelValue(maxHeight);
2203 }
2204 if (maxWidth) {
2205 styles.maxWidth = coercion.coerceCssPixelValue(maxWidth);
2206 }
2207 }
2208 this._lastBoundingBoxSize = boundingBoxRect;
2209 extendStyles(this._boundingBox.style, styles);
2210 };
2211 /** Resets the styles for the bounding box so that a new positioning can be computed. */
2212 FlexibleConnectedPositionStrategy.prototype._resetBoundingBoxStyles = function () {
2213 extendStyles(this._boundingBox.style, {
2214 top: '0',
2215 left: '0',
2216 right: '0',
2217 bottom: '0',
2218 height: '',
2219 width: '',
2220 alignItems: '',
2221 justifyContent: '',
2222 });
2223 };
2224 /** Resets the styles for the overlay pane so that a new positioning can be computed. */
2225 FlexibleConnectedPositionStrategy.prototype._resetOverlayElementStyles = function () {
2226 extendStyles(this._pane.style, {
2227 top: '',
2228 left: '',
2229 bottom: '',
2230 right: '',
2231 position: '',
2232 transform: '',
2233 });
2234 };
2235 /** Sets positioning styles to the overlay element. */
2236 FlexibleConnectedPositionStrategy.prototype._setOverlayElementStyles = function (originPoint, position) {
2237 var styles = {};
2238 var hasExactPosition = this._hasExactPosition();
2239 var hasFlexibleDimensions = this._hasFlexibleDimensions;
2240 var config = this._overlayRef.getConfig();
2241 if (hasExactPosition) {
2242 var scrollPosition = this._viewportRuler.getViewportScrollPosition();
2243 extendStyles(styles, this._getExactOverlayY(position, originPoint, scrollPosition));
2244 extendStyles(styles, this._getExactOverlayX(position, originPoint, scrollPosition));
2245 }
2246 else {
2247 styles.position = 'static';
2248 }
2249 // Use a transform to apply the offsets. We do this because the `center` positions rely on
2250 // being in the normal flex flow and setting a `top` / `left` at all will completely throw
2251 // off the position. We also can't use margins, because they won't have an effect in some
2252 // cases where the element doesn't have anything to "push off of". Finally, this works
2253 // better both with flexible and non-flexible positioning.
2254 var transformString = '';
2255 var offsetX = this._getOffset(position, 'x');
2256 var offsetY = this._getOffset(position, 'y');
2257 if (offsetX) {
2258 transformString += "translateX(" + offsetX + "px) ";
2259 }
2260 if (offsetY) {
2261 transformString += "translateY(" + offsetY + "px)";
2262 }
2263 styles.transform = transformString.trim();
2264 // If a maxWidth or maxHeight is specified on the overlay, we remove them. We do this because
2265 // we need these values to both be set to "100%" for the automatic flexible sizing to work.
2266 // The maxHeight and maxWidth are set on the boundingBox in order to enforce the constraint.
2267 // Note that this doesn't apply when we have an exact position, in which case we do want to
2268 // apply them because they'll be cleared from the bounding box.
2269 if (config.maxHeight) {
2270 if (hasExactPosition) {
2271 styles.maxHeight = coercion.coerceCssPixelValue(config.maxHeight);
2272 }
2273 else if (hasFlexibleDimensions) {
2274 styles.maxHeight = '';
2275 }
2276 }
2277 if (config.maxWidth) {
2278 if (hasExactPosition) {
2279 styles.maxWidth = coercion.coerceCssPixelValue(config.maxWidth);
2280 }
2281 else if (hasFlexibleDimensions) {
2282 styles.maxWidth = '';
2283 }
2284 }
2285 extendStyles(this._pane.style, styles);
2286 };
2287 /** Gets the exact top/bottom for the overlay when not using flexible sizing or when pushing. */
2288 FlexibleConnectedPositionStrategy.prototype._getExactOverlayY = function (position, originPoint, scrollPosition) {
2289 // Reset any existing styles. This is necessary in case the
2290 // preferred position has changed since the last `apply`.
2291 var styles = { top: '', bottom: '' };
2292 var overlayPoint = this._getOverlayPoint(originPoint, this._overlayRect, position);
2293 if (this._isPushed) {
2294 overlayPoint = this._pushOverlayOnScreen(overlayPoint, this._overlayRect, scrollPosition);
2295 }
2296 var virtualKeyboardOffset = this._overlayContainer.getContainerElement().getBoundingClientRect().top;
2297 // Normally this would be zero, however when the overlay is attached to an input (e.g. in an
2298 // autocomplete), mobile browsers will shift everything in order to put the input in the middle
2299 // of the screen and to make space for the virtual keyboard. We need to account for this offset,
2300 // otherwise our positioning will be thrown off.
2301 overlayPoint.y -= virtualKeyboardOffset;
2302 // We want to set either `top` or `bottom` based on whether the overlay wants to appear
2303 // above or below the origin and the direction in which the element will expand.
2304 if (position.overlayY === 'bottom') {
2305 // When using `bottom`, we adjust the y position such that it is the distance
2306 // from the bottom of the viewport rather than the top.
2307 var documentHeight = this._document.documentElement.clientHeight;
2308 styles.bottom = documentHeight - (overlayPoint.y + this._overlayRect.height) + "px";
2309 }
2310 else {
2311 styles.top = coercion.coerceCssPixelValue(overlayPoint.y);
2312 }
2313 return styles;
2314 };
2315 /** Gets the exact left/right for the overlay when not using flexible sizing or when pushing. */
2316 FlexibleConnectedPositionStrategy.prototype._getExactOverlayX = function (position, originPoint, scrollPosition) {
2317 // Reset any existing styles. This is necessary in case the preferred position has
2318 // changed since the last `apply`.
2319 var styles = { left: '', right: '' };
2320 var overlayPoint = this._getOverlayPoint(originPoint, this._overlayRect, position);
2321 if (this._isPushed) {
2322 overlayPoint = this._pushOverlayOnScreen(overlayPoint, this._overlayRect, scrollPosition);
2323 }
2324 // We want to set either `left` or `right` based on whether the overlay wants to appear "before"
2325 // or "after" the origin, which determines the direction in which the element will expand.
2326 // For the horizontal axis, the meaning of "before" and "after" change based on whether the
2327 // page is in RTL or LTR.
2328 var horizontalStyleProperty;
2329 if (this._isRtl()) {
2330 horizontalStyleProperty = position.overlayX === 'end' ? 'left' : 'right';
2331 }
2332 else {
2333 horizontalStyleProperty = position.overlayX === 'end' ? 'right' : 'left';
2334 }
2335 // When we're setting `right`, we adjust the x position such that it is the distance
2336 // from the right edge of the viewport rather than the left edge.
2337 if (horizontalStyleProperty === 'right') {
2338 var documentWidth = this._document.documentElement.clientWidth;
2339 styles.right = documentWidth - (overlayPoint.x + this._overlayRect.width) + "px";
2340 }
2341 else {
2342 styles.left = coercion.coerceCssPixelValue(overlayPoint.x);
2343 }
2344 return styles;
2345 };
2346 /**
2347 * Gets the view properties of the trigger and overlay, including whether they are clipped
2348 * or completely outside the view of any of the strategy's scrollables.
2349 */
2350 FlexibleConnectedPositionStrategy.prototype._getScrollVisibility = function () {
2351 // Note: needs fresh rects since the position could've changed.
2352 var originBounds = this._getOriginRect();
2353 var overlayBounds = this._pane.getBoundingClientRect();
2354 // TODO(jelbourn): instead of needing all of the client rects for these scrolling containers
2355 // every time, we should be able to use the scrollTop of the containers if the size of those
2356 // containers hasn't changed.
2357 var scrollContainerBounds = this._scrollables.map(function (scrollable) {
2358 return scrollable.getElementRef().nativeElement.getBoundingClientRect();
2359 });
2360 return {
2361 isOriginClipped: isElementClippedByScrolling(originBounds, scrollContainerBounds),
2362 isOriginOutsideView: isElementScrolledOutsideView(originBounds, scrollContainerBounds),
2363 isOverlayClipped: isElementClippedByScrolling(overlayBounds, scrollContainerBounds),
2364 isOverlayOutsideView: isElementScrolledOutsideView(overlayBounds, scrollContainerBounds),
2365 };
2366 };
2367 /** Subtracts the amount that an element is overflowing on an axis from its length. */
2368 FlexibleConnectedPositionStrategy.prototype._subtractOverflows = function (length) {
2369 var overflows = [];
2370 for (var _i = 1; _i < arguments.length; _i++) {
2371 overflows[_i - 1] = arguments[_i];
2372 }
2373 return overflows.reduce(function (currentValue, currentOverflow) {
2374 return currentValue - Math.max(currentOverflow, 0);
2375 }, length);
2376 };
2377 /** Narrows the given viewport rect by the current _viewportMargin. */
2378 FlexibleConnectedPositionStrategy.prototype._getNarrowedViewportRect = function () {
2379 // We recalculate the viewport rect here ourselves, rather than using the ViewportRuler,
2380 // because we want to use the `clientWidth` and `clientHeight` as the base. The difference
2381 // being that the client properties don't include the scrollbar, as opposed to `innerWidth`
2382 // and `innerHeight` that do. This is necessary, because the overlay container uses
2383 // 100% `width` and `height` which don't include the scrollbar either.
2384 var width = this._document.documentElement.clientWidth;
2385 var height = this._document.documentElement.clientHeight;
2386 var scrollPosition = this._viewportRuler.getViewportScrollPosition();
2387 return {
2388 top: scrollPosition.top + this._viewportMargin,
2389 left: scrollPosition.left + this._viewportMargin,
2390 right: scrollPosition.left + width - this._viewportMargin,
2391 bottom: scrollPosition.top + height - this._viewportMargin,
2392 width: width - (2 * this._viewportMargin),
2393 height: height - (2 * this._viewportMargin),
2394 };
2395 };
2396 /** Whether the we're dealing with an RTL context */
2397 FlexibleConnectedPositionStrategy.prototype._isRtl = function () {
2398 return this._overlayRef.getDirection() === 'rtl';
2399 };
2400 /** Determines whether the overlay uses exact or flexible positioning. */
2401 FlexibleConnectedPositionStrategy.prototype._hasExactPosition = function () {
2402 return !this._hasFlexibleDimensions || this._isPushed;
2403 };
2404 /** Retrieves the offset of a position along the x or y axis. */
2405 FlexibleConnectedPositionStrategy.prototype._getOffset = function (position, axis) {
2406 if (axis === 'x') {
2407 // We don't do something like `position['offset' + axis]` in
2408 // order to avoid breking minifiers that rename properties.
2409 return position.offsetX == null ? this._offsetX : position.offsetX;
2410 }
2411 return position.offsetY == null ? this._offsetY : position.offsetY;
2412 };
2413 /** Validates that the current position match the expected values. */
2414 FlexibleConnectedPositionStrategy.prototype._validatePositions = function () {
2415 if (typeof ngDevMode === 'undefined' || ngDevMode) {
2416 if (!this._preferredPositions.length) {
2417 throw Error('FlexibleConnectedPositionStrategy: At least one position is required.');
2418 }
2419 // TODO(crisbeto): remove these once Angular's template type
2420 // checking is advanced enough to catch these cases.
2421 this._preferredPositions.forEach(function (pair) {
2422 validateHorizontalPosition('originX', pair.originX);
2423 validateVerticalPosition('originY', pair.originY);
2424 validateHorizontalPosition('overlayX', pair.overlayX);
2425 validateVerticalPosition('overlayY', pair.overlayY);
2426 });
2427 }
2428 };
2429 /** Adds a single CSS class or an array of classes on the overlay panel. */
2430 FlexibleConnectedPositionStrategy.prototype._addPanelClasses = function (cssClasses) {
2431 var _this = this;
2432 if (this._pane) {
2433 coercion.coerceArray(cssClasses).forEach(function (cssClass) {
2434 if (cssClass !== '' && _this._appliedPanelClasses.indexOf(cssClass) === -1) {
2435 _this._appliedPanelClasses.push(cssClass);
2436 _this._pane.classList.add(cssClass);
2437 }
2438 });
2439 }
2440 };
2441 /** Clears the classes that the position strategy has applied from the overlay panel. */
2442 FlexibleConnectedPositionStrategy.prototype._clearPanelClasses = function () {
2443 var _this = this;
2444 if (this._pane) {
2445 this._appliedPanelClasses.forEach(function (cssClass) {
2446 _this._pane.classList.remove(cssClass);
2447 });
2448 this._appliedPanelClasses = [];
2449 }
2450 };
2451 /** Returns the ClientRect of the current origin. */
2452 FlexibleConnectedPositionStrategy.prototype._getOriginRect = function () {
2453 var origin = this._origin;
2454 if (origin instanceof i0.ElementRef) {
2455 return origin.nativeElement.getBoundingClientRect();
2456 }
2457 // Check for Element so SVG elements are also supported.
2458 if (origin instanceof Element) {
2459 return origin.getBoundingClientRect();
2460 }
2461 var width = origin.width || 0;
2462 var height = origin.height || 0;
2463 // If the origin is a point, return a client rect as if it was a 0x0 element at the point.
2464 return {
2465 top: origin.y,
2466 bottom: origin.y + height,
2467 left: origin.x,
2468 right: origin.x + width,
2469 height: height,
2470 width: width
2471 };
2472 };
2473 return FlexibleConnectedPositionStrategy;
2474 }());
2475 /** Shallow-extends a stylesheet object with another stylesheet object. */
2476 function extendStyles(destination, source) {
2477 for (var key in source) {
2478 if (source.hasOwnProperty(key)) {
2479 destination[key] = source[key];
2480 }
2481 }
2482 return destination;
2483 }
2484 /**
2485 * Extracts the pixel value as a number from a value, if it's a number
2486 * or a CSS pixel string (e.g. `1337px`). Otherwise returns null.
2487 */
2488 function getPixelValue(input) {
2489 if (typeof input !== 'number' && input != null) {
2490 var _a = __read(input.split(cssUnitPattern), 2), value = _a[0], units = _a[1];
2491 return (!units || units === 'px') ? parseFloat(value) : null;
2492 }
2493 return input || null;
2494 }
2495 /**
2496 * Gets a version of an element's bounding `ClientRect` where all the values are rounded down to
2497 * the nearest pixel. This allows us to account for the cases where there may be sub-pixel
2498 * deviations in the `ClientRect` returned by the browser (e.g. when zoomed in with a percentage
2499 * size, see #21350).
2500 */
2501 function getRoundedBoundingClientRect(clientRect) {
2502 return {
2503 top: Math.floor(clientRect.top),
2504 right: Math.floor(clientRect.right),
2505 bottom: Math.floor(clientRect.bottom),
2506 left: Math.floor(clientRect.left),
2507 width: Math.floor(clientRect.width),
2508 height: Math.floor(clientRect.height)
2509 };
2510 }
2511
2512 /**
2513 * @license
2514 * Copyright Google LLC All Rights Reserved.
2515 *
2516 * Use of this source code is governed by an MIT-style license that can be
2517 * found in the LICENSE file at https://angular.io/license
2518 */
2519 /**
2520 * A strategy for positioning overlays. Using this strategy, an overlay is given an
2521 * implicit position relative to some origin element. The relative position is defined in terms of
2522 * a point on the origin element that is connected to a point on the overlay element. For example,
2523 * a basic dropdown is connecting the bottom-left corner of the origin to the top-left corner
2524 * of the overlay.
2525 * @deprecated Use `FlexibleConnectedPositionStrategy` instead.
2526 * @breaking-change 8.0.0
2527 */
2528 var ConnectedPositionStrategy = /** @class */ (function () {
2529 function ConnectedPositionStrategy(originPos, overlayPos, connectedTo, viewportRuler, document, platform, overlayContainer) {
2530 /** Ordered list of preferred positions, from most to least desirable. */
2531 this._preferredPositions = [];
2532 // Since the `ConnectedPositionStrategy` is deprecated and we don't want to maintain
2533 // the extra logic, we create an instance of the positioning strategy that has some
2534 // defaults that make it behave as the old position strategy and to which we'll
2535 // proxy all of the API calls.
2536 this._positionStrategy = new FlexibleConnectedPositionStrategy(connectedTo, viewportRuler, document, platform, overlayContainer)
2537 .withFlexibleDimensions(false)
2538 .withPush(false)
2539 .withViewportMargin(0);
2540 this.withFallbackPosition(originPos, overlayPos);
2541 this.onPositionChange = this._positionStrategy.positionChanges;
2542 }
2543 Object.defineProperty(ConnectedPositionStrategy.prototype, "positions", {
2544 /** Ordered list of preferred positions, from most to least desirable. */
2545 get: function () {
2546 return this._preferredPositions;
2547 },
2548 enumerable: false,
2549 configurable: true
2550 });
2551 /** Attach this position strategy to an overlay. */
2552 ConnectedPositionStrategy.prototype.attach = function (overlayRef) {
2553 this._overlayRef = overlayRef;
2554 this._positionStrategy.attach(overlayRef);
2555 if (this._direction) {
2556 overlayRef.setDirection(this._direction);
2557 this._direction = null;
2558 }
2559 };
2560 /** Disposes all resources used by the position strategy. */
2561 ConnectedPositionStrategy.prototype.dispose = function () {
2562 this._positionStrategy.dispose();
2563 };
2564 /** @docs-private */
2565 ConnectedPositionStrategy.prototype.detach = function () {
2566 this._positionStrategy.detach();
2567 };
2568 /**
2569 * Updates the position of the overlay element, using whichever preferred position relative
2570 * to the origin fits on-screen.
2571 * @docs-private
2572 */
2573 ConnectedPositionStrategy.prototype.apply = function () {
2574 this._positionStrategy.apply();
2575 };
2576 /**
2577 * Re-positions the overlay element with the trigger in its last calculated position,
2578 * even if a position higher in the "preferred positions" list would now fit. This
2579 * allows one to re-align the panel without changing the orientation of the panel.
2580 */
2581 ConnectedPositionStrategy.prototype.recalculateLastPosition = function () {
2582 this._positionStrategy.reapplyLastPosition();
2583 };
2584 /**
2585 * Sets the list of Scrollable containers that host the origin element so that
2586 * on reposition we can evaluate if it or the overlay has been clipped or outside view. Every
2587 * Scrollable must be an ancestor element of the strategy's origin element.
2588 */
2589 ConnectedPositionStrategy.prototype.withScrollableContainers = function (scrollables) {
2590 this._positionStrategy.withScrollableContainers(scrollables);
2591 };
2592 /**
2593 * Adds a new preferred fallback position.
2594 * @param originPos
2595 * @param overlayPos
2596 */
2597 ConnectedPositionStrategy.prototype.withFallbackPosition = function (originPos, overlayPos, offsetX, offsetY) {
2598 var position = new ConnectionPositionPair(originPos, overlayPos, offsetX, offsetY);
2599 this._preferredPositions.push(position);
2600 this._positionStrategy.withPositions(this._preferredPositions);
2601 return this;
2602 };
2603 /**
2604 * Sets the layout direction so the overlay's position can be adjusted to match.
2605 * @param dir New layout direction.
2606 */
2607 ConnectedPositionStrategy.prototype.withDirection = function (dir) {
2608 // Since the direction might be declared before the strategy is attached,
2609 // we save the value in a temporary property and we'll transfer it to the
2610 // overlay ref on attachment.
2611 if (this._overlayRef) {
2612 this._overlayRef.setDirection(dir);
2613 }
2614 else {
2615 this._direction = dir;
2616 }
2617 return this;
2618 };
2619 /**
2620 * Sets an offset for the overlay's connection point on the x-axis
2621 * @param offset New offset in the X axis.
2622 */
2623 ConnectedPositionStrategy.prototype.withOffsetX = function (offset) {
2624 this._positionStrategy.withDefaultOffsetX(offset);
2625 return this;
2626 };
2627 /**
2628 * Sets an offset for the overlay's connection point on the y-axis
2629 * @param offset New offset in the Y axis.
2630 */
2631 ConnectedPositionStrategy.prototype.withOffsetY = function (offset) {
2632 this._positionStrategy.withDefaultOffsetY(offset);
2633 return this;
2634 };
2635 /**
2636 * Sets whether the overlay's position should be locked in after it is positioned
2637 * initially. When an overlay is locked in, it won't attempt to reposition itself
2638 * when the position is re-applied (e.g. when the user scrolls away).
2639 * @param isLocked Whether the overlay should locked in.
2640 */
2641 ConnectedPositionStrategy.prototype.withLockedPosition = function (isLocked) {
2642 this._positionStrategy.withLockedPosition(isLocked);
2643 return this;
2644 };
2645 /**
2646 * Overwrites the current set of positions with an array of new ones.
2647 * @param positions Position pairs to be set on the strategy.
2648 */
2649 ConnectedPositionStrategy.prototype.withPositions = function (positions) {
2650 this._preferredPositions = positions.slice();
2651 this._positionStrategy.withPositions(this._preferredPositions);
2652 return this;
2653 };
2654 /**
2655 * Sets the origin element, relative to which to position the overlay.
2656 * @param origin Reference to the new origin element.
2657 */
2658 ConnectedPositionStrategy.prototype.setOrigin = function (origin) {
2659 this._positionStrategy.setOrigin(origin);
2660 return this;
2661 };
2662 return ConnectedPositionStrategy;
2663 }());
2664
2665 /**
2666 * @license
2667 * Copyright Google LLC All Rights Reserved.
2668 *
2669 * Use of this source code is governed by an MIT-style license that can be
2670 * found in the LICENSE file at https://angular.io/license
2671 */
2672 /** Class to be added to the overlay pane wrapper. */
2673 var wrapperClass = 'cdk-global-overlay-wrapper';
2674 /**
2675 * A strategy for positioning overlays. Using this strategy, an overlay is given an
2676 * explicit position relative to the browser's viewport. We use flexbox, instead of
2677 * transforms, in order to avoid issues with subpixel rendering which can cause the
2678 * element to become blurry.
2679 */
2680 var GlobalPositionStrategy = /** @class */ (function () {
2681 function GlobalPositionStrategy() {
2682 this._cssPosition = 'static';
2683 this._topOffset = '';
2684 this._bottomOffset = '';
2685 this._leftOffset = '';
2686 this._rightOffset = '';
2687 this._alignItems = '';
2688 this._justifyContent = '';
2689 this._width = '';
2690 this._height = '';
2691 }
2692 GlobalPositionStrategy.prototype.attach = function (overlayRef) {
2693 var config = overlayRef.getConfig();
2694 this._overlayRef = overlayRef;
2695 if (this._width && !config.width) {
2696 overlayRef.updateSize({ width: this._width });
2697 }
2698 if (this._height && !config.height) {
2699 overlayRef.updateSize({ height: this._height });
2700 }
2701 overlayRef.hostElement.classList.add(wrapperClass);
2702 this._isDisposed = false;
2703 };
2704 /**
2705 * Sets the top position of the overlay. Clears any previously set vertical position.
2706 * @param value New top offset.
2707 */
2708 GlobalPositionStrategy.prototype.top = function (value) {
2709 if (value === void 0) { value = ''; }
2710 this._bottomOffset = '';
2711 this._topOffset = value;
2712 this._alignItems = 'flex-start';
2713 return this;
2714 };
2715 /**
2716 * Sets the left position of the overlay. Clears any previously set horizontal position.
2717 * @param value New left offset.
2718 */
2719 GlobalPositionStrategy.prototype.left = function (value) {
2720 if (value === void 0) { value = ''; }
2721 this._rightOffset = '';
2722 this._leftOffset = value;
2723 this._justifyContent = 'flex-start';
2724 return this;
2725 };
2726 /**
2727 * Sets the bottom position of the overlay. Clears any previously set vertical position.
2728 * @param value New bottom offset.
2729 */
2730 GlobalPositionStrategy.prototype.bottom = function (value) {
2731 if (value === void 0) { value = ''; }
2732 this._topOffset = '';
2733 this._bottomOffset = value;
2734 this._alignItems = 'flex-end';
2735 return this;
2736 };
2737 /**
2738 * Sets the right position of the overlay. Clears any previously set horizontal position.
2739 * @param value New right offset.
2740 */
2741 GlobalPositionStrategy.prototype.right = function (value) {
2742 if (value === void 0) { value = ''; }
2743 this._leftOffset = '';
2744 this._rightOffset = value;
2745 this._justifyContent = 'flex-end';
2746 return this;
2747 };
2748 /**
2749 * Sets the overlay width and clears any previously set width.
2750 * @param value New width for the overlay
2751 * @deprecated Pass the `width` through the `OverlayConfig`.
2752 * @breaking-change 8.0.0
2753 */
2754 GlobalPositionStrategy.prototype.width = function (value) {
2755 if (value === void 0) { value = ''; }
2756 if (this._overlayRef) {
2757 this._overlayRef.updateSize({ width: value });
2758 }
2759 else {
2760 this._width = value;
2761 }
2762 return this;
2763 };
2764 /**
2765 * Sets the overlay height and clears any previously set height.
2766 * @param value New height for the overlay
2767 * @deprecated Pass the `height` through the `OverlayConfig`.
2768 * @breaking-change 8.0.0
2769 */
2770 GlobalPositionStrategy.prototype.height = function (value) {
2771 if (value === void 0) { value = ''; }
2772 if (this._overlayRef) {
2773 this._overlayRef.updateSize({ height: value });
2774 }
2775 else {
2776 this._height = value;
2777 }
2778 return this;
2779 };
2780 /**
2781 * Centers the overlay horizontally with an optional offset.
2782 * Clears any previously set horizontal position.
2783 *
2784 * @param offset Overlay offset from the horizontal center.
2785 */
2786 GlobalPositionStrategy.prototype.centerHorizontally = function (offset) {
2787 if (offset === void 0) { offset = ''; }
2788 this.left(offset);
2789 this._justifyContent = 'center';
2790 return this;
2791 };
2792 /**
2793 * Centers the overlay vertically with an optional offset.
2794 * Clears any previously set vertical position.
2795 *
2796 * @param offset Overlay offset from the vertical center.
2797 */
2798 GlobalPositionStrategy.prototype.centerVertically = function (offset) {
2799 if (offset === void 0) { offset = ''; }
2800 this.top(offset);
2801 this._alignItems = 'center';
2802 return this;
2803 };
2804 /**
2805 * Apply the position to the element.
2806 * @docs-private
2807 */
2808 GlobalPositionStrategy.prototype.apply = function () {
2809 // Since the overlay ref applies the strategy asynchronously, it could
2810 // have been disposed before it ends up being applied. If that is the
2811 // case, we shouldn't do anything.
2812 if (!this._overlayRef || !this._overlayRef.hasAttached()) {
2813 return;
2814 }
2815 var styles = this._overlayRef.overlayElement.style;
2816 var parentStyles = this._overlayRef.hostElement.style;
2817 var config = this._overlayRef.getConfig();
2818 var width = config.width, height = config.height, maxWidth = config.maxWidth, maxHeight = config.maxHeight;
2819 var shouldBeFlushHorizontally = (width === '100%' || width === '100vw') &&
2820 (!maxWidth || maxWidth === '100%' || maxWidth === '100vw');
2821 var shouldBeFlushVertically = (height === '100%' || height === '100vh') &&
2822 (!maxHeight || maxHeight === '100%' || maxHeight === '100vh');
2823 styles.position = this._cssPosition;
2824 styles.marginLeft = shouldBeFlushHorizontally ? '0' : this._leftOffset;
2825 styles.marginTop = shouldBeFlushVertically ? '0' : this._topOffset;
2826 styles.marginBottom = this._bottomOffset;
2827 styles.marginRight = this._rightOffset;
2828 if (shouldBeFlushHorizontally) {
2829 parentStyles.justifyContent = 'flex-start';
2830 }
2831 else if (this._justifyContent === 'center') {
2832 parentStyles.justifyContent = 'center';
2833 }
2834 else if (this._overlayRef.getConfig().direction === 'rtl') {
2835 // In RTL the browser will invert `flex-start` and `flex-end` automatically, but we
2836 // don't want that because our positioning is explicitly `left` and `right`, hence
2837 // why we do another inversion to ensure that the overlay stays in the same position.
2838 // TODO: reconsider this if we add `start` and `end` methods.
2839 if (this._justifyContent === 'flex-start') {
2840 parentStyles.justifyContent = 'flex-end';
2841 }
2842 else if (this._justifyContent === 'flex-end') {
2843 parentStyles.justifyContent = 'flex-start';
2844 }
2845 }
2846 else {
2847 parentStyles.justifyContent = this._justifyContent;
2848 }
2849 parentStyles.alignItems = shouldBeFlushVertically ? 'flex-start' : this._alignItems;
2850 };
2851 /**
2852 * Cleans up the DOM changes from the position strategy.
2853 * @docs-private
2854 */
2855 GlobalPositionStrategy.prototype.dispose = function () {
2856 if (this._isDisposed || !this._overlayRef) {
2857 return;
2858 }
2859 var styles = this._overlayRef.overlayElement.style;
2860 var parent = this._overlayRef.hostElement;
2861 var parentStyles = parent.style;
2862 parent.classList.remove(wrapperClass);
2863 parentStyles.justifyContent = parentStyles.alignItems = styles.marginTop =
2864 styles.marginBottom = styles.marginLeft = styles.marginRight = styles.position = '';
2865 this._overlayRef = null;
2866 this._isDisposed = true;
2867 };
2868 return GlobalPositionStrategy;
2869 }());
2870
2871 /**
2872 * @license
2873 * Copyright Google LLC All Rights Reserved.
2874 *
2875 * Use of this source code is governed by an MIT-style license that can be
2876 * found in the LICENSE file at https://angular.io/license
2877 */
2878 /** Builder for overlay position strategy. */
2879 var OverlayPositionBuilder = /** @class */ (function () {
2880 function OverlayPositionBuilder(_viewportRuler, _document, _platform, _overlayContainer) {
2881 this._viewportRuler = _viewportRuler;
2882 this._document = _document;
2883 this._platform = _platform;
2884 this._overlayContainer = _overlayContainer;
2885 }
2886 /**
2887 * Creates a global position strategy.
2888 */
2889 OverlayPositionBuilder.prototype.global = function () {
2890 return new GlobalPositionStrategy();
2891 };
2892 /**
2893 * Creates a relative position strategy.
2894 * @param elementRef
2895 * @param originPos
2896 * @param overlayPos
2897 * @deprecated Use `flexibleConnectedTo` instead.
2898 * @breaking-change 8.0.0
2899 */
2900 OverlayPositionBuilder.prototype.connectedTo = function (elementRef, originPos, overlayPos) {
2901 return new ConnectedPositionStrategy(originPos, overlayPos, elementRef, this._viewportRuler, this._document, this._platform, this._overlayContainer);
2902 };
2903 /**
2904 * Creates a flexible position strategy.
2905 * @param origin Origin relative to which to position the overlay.
2906 */
2907 OverlayPositionBuilder.prototype.flexibleConnectedTo = function (origin) {
2908 return new FlexibleConnectedPositionStrategy(origin, this._viewportRuler, this._document, this._platform, this._overlayContainer);
2909 };
2910 return OverlayPositionBuilder;
2911 }());
2912 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" });
2913 OverlayPositionBuilder.decorators = [
2914 { type: i0.Injectable, args: [{ providedIn: 'root' },] }
2915 ];
2916 OverlayPositionBuilder.ctorParameters = function () { return [
2917 { type: i1.ViewportRuler },
2918 { type: undefined, decorators: [{ type: i0.Inject, args: [i1$1.DOCUMENT,] }] },
2919 { type: i2.Platform },
2920 { type: OverlayContainer }
2921 ]; };
2922
2923 /**
2924 * @license
2925 * Copyright Google LLC All Rights Reserved.
2926 *
2927 * Use of this source code is governed by an MIT-style license that can be
2928 * found in the LICENSE file at https://angular.io/license
2929 */
2930 /** Next overlay unique ID. */
2931 var nextUniqueId = 0;
2932 // Note that Overlay is *not* scoped to the app root because of the ComponentFactoryResolver
2933 // which needs to be different depending on where OverlayModule is imported.
2934 /**
2935 * Service to create Overlays. Overlays are dynamically added pieces of floating UI, meant to be
2936 * used as a low-level building block for other components. Dialogs, tooltips, menus,
2937 * selects, etc. can all be built using overlays. The service should primarily be used by authors
2938 * of re-usable components rather than developers building end-user applications.
2939 *
2940 * An overlay *is* a PortalOutlet, so any kind of Portal can be loaded into one.
2941 */
2942 var Overlay = /** @class */ (function () {
2943 function Overlay(
2944 /** Scrolling strategies that can be used when creating an overlay. */
2945 scrollStrategies, _overlayContainer, _componentFactoryResolver, _positionBuilder, _keyboardDispatcher, _injector, _ngZone, _document, _directionality, _location, _outsideClickDispatcher) {
2946 this.scrollStrategies = scrollStrategies;
2947 this._overlayContainer = _overlayContainer;
2948 this._componentFactoryResolver = _componentFactoryResolver;
2949 this._positionBuilder = _positionBuilder;
2950 this._keyboardDispatcher = _keyboardDispatcher;
2951 this._injector = _injector;
2952 this._ngZone = _ngZone;
2953 this._document = _document;
2954 this._directionality = _directionality;
2955 this._location = _location;
2956 this._outsideClickDispatcher = _outsideClickDispatcher;
2957 }
2958 /**
2959 * Creates an overlay.
2960 * @param config Configuration applied to the overlay.
2961 * @returns Reference to the created overlay.
2962 */
2963 Overlay.prototype.create = function (config) {
2964 var host = this._createHostElement();
2965 var pane = this._createPaneElement(host);
2966 var portalOutlet = this._createPortalOutlet(pane);
2967 var overlayConfig = new OverlayConfig(config);
2968 overlayConfig.direction = overlayConfig.direction || this._directionality.value;
2969 return new OverlayRef(portalOutlet, host, pane, overlayConfig, this._ngZone, this._keyboardDispatcher, this._document, this._location, this._outsideClickDispatcher);
2970 };
2971 /**
2972 * Gets a position builder that can be used, via fluent API,
2973 * to construct and configure a position strategy.
2974 * @returns An overlay position builder.
2975 */
2976 Overlay.prototype.position = function () {
2977 return this._positionBuilder;
2978 };
2979 /**
2980 * Creates the DOM element for an overlay and appends it to the overlay container.
2981 * @returns Newly-created pane element
2982 */
2983 Overlay.prototype._createPaneElement = function (host) {
2984 var pane = this._document.createElement('div');
2985 pane.id = "cdk-overlay-" + nextUniqueId++;
2986 pane.classList.add('cdk-overlay-pane');
2987 host.appendChild(pane);
2988 return pane;
2989 };
2990 /**
2991 * Creates the host element that wraps around an overlay
2992 * and can be used for advanced positioning.
2993 * @returns Newly-create host element.
2994 */
2995 Overlay.prototype._createHostElement = function () {
2996 var host = this._document.createElement('div');
2997 this._overlayContainer.getContainerElement().appendChild(host);
2998 return host;
2999 };
3000 /**
3001 * Create a DomPortalOutlet into which the overlay content can be loaded.
3002 * @param pane The DOM element to turn into a portal outlet.
3003 * @returns A portal outlet for the given DOM element.
3004 */
3005 Overlay.prototype._createPortalOutlet = function (pane) {
3006 // We have to resolve the ApplicationRef later in order to allow people
3007 // to use overlay-based providers during app initialization.
3008 if (!this._appRef) {
3009 this._appRef = this._injector.get(i0.ApplicationRef);
3010 }
3011 return new portal.DomPortalOutlet(pane, this._componentFactoryResolver, this._appRef, this._injector, this._document);
3012 };
3013 return Overlay;
3014 }());
3015 Overlay.decorators = [
3016 { type: i0.Injectable }
3017 ];
3018 Overlay.ctorParameters = function () { return [
3019 { type: ScrollStrategyOptions },
3020 { type: OverlayContainer },
3021 { type: i0.ComponentFactoryResolver },
3022 { type: OverlayPositionBuilder },
3023 { type: OverlayKeyboardDispatcher },
3024 { type: i0.Injector },
3025 { type: i0.NgZone },
3026 { type: undefined, decorators: [{ type: i0.Inject, args: [i1$1.DOCUMENT,] }] },
3027 { type: bidi.Directionality },
3028 { type: i1$1.Location },
3029 { type: OverlayOutsideClickDispatcher }
3030 ]; };
3031
3032 /**
3033 * @license
3034 * Copyright Google LLC All Rights Reserved.
3035 *
3036 * Use of this source code is governed by an MIT-style license that can be
3037 * found in the LICENSE file at https://angular.io/license
3038 */
3039 /** Default set of positions for the overlay. Follows the behavior of a dropdown. */
3040 var defaultPositionList = [
3041 {
3042 originX: 'start',
3043 originY: 'bottom',
3044 overlayX: 'start',
3045 overlayY: 'top'
3046 },
3047 {
3048 originX: 'start',
3049 originY: 'top',
3050 overlayX: 'start',
3051 overlayY: 'bottom'
3052 },
3053 {
3054 originX: 'end',
3055 originY: 'top',
3056 overlayX: 'end',
3057 overlayY: 'bottom'
3058 },
3059 {
3060 originX: 'end',
3061 originY: 'bottom',
3062 overlayX: 'end',
3063 overlayY: 'top'
3064 }
3065 ];
3066 /** Injection token that determines the scroll handling while the connected overlay is open. */
3067 var CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY = new i0.InjectionToken('cdk-connected-overlay-scroll-strategy');
3068 /**
3069 * Directive applied to an element to make it usable as an origin for an Overlay using a
3070 * ConnectedPositionStrategy.
3071 */
3072 var CdkOverlayOrigin = /** @class */ (function () {
3073 function CdkOverlayOrigin(
3074 /** Reference to the element on which the directive is applied. */
3075 elementRef) {
3076 this.elementRef = elementRef;
3077 }
3078 return CdkOverlayOrigin;
3079 }());
3080 CdkOverlayOrigin.decorators = [
3081 { type: i0.Directive, args: [{
3082 selector: '[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]',
3083 exportAs: 'cdkOverlayOrigin',
3084 },] }
3085 ];
3086 CdkOverlayOrigin.ctorParameters = function () { return [
3087 { type: i0.ElementRef }
3088 ]; };
3089 /**
3090 * Directive to facilitate declarative creation of an
3091 * Overlay using a FlexibleConnectedPositionStrategy.
3092 */
3093 var CdkConnectedOverlay = /** @class */ (function () {
3094 // TODO(jelbourn): inputs for size, scroll behavior, animation, etc.
3095 function CdkConnectedOverlay(_overlay, templateRef, viewContainerRef, scrollStrategyFactory, _dir) {
3096 this._overlay = _overlay;
3097 this._dir = _dir;
3098 this._hasBackdrop = false;
3099 this._lockPosition = false;
3100 this._growAfterOpen = false;
3101 this._flexibleDimensions = false;
3102 this._push = false;
3103 this._backdropSubscription = rxjs.Subscription.EMPTY;
3104 this._attachSubscription = rxjs.Subscription.EMPTY;
3105 this._detachSubscription = rxjs.Subscription.EMPTY;
3106 this._positionSubscription = rxjs.Subscription.EMPTY;
3107 /** Margin between the overlay and the viewport edges. */
3108 this.viewportMargin = 0;
3109 /** Whether the overlay is open. */
3110 this.open = false;
3111 /** Whether the overlay can be closed by user interaction. */
3112 this.disableClose = false;
3113 /** Event emitted when the backdrop is clicked. */
3114 this.backdropClick = new i0.EventEmitter();
3115 /** Event emitted when the position has changed. */
3116 this.positionChange = new i0.EventEmitter();
3117 /** Event emitted when the overlay has been attached. */
3118 this.attach = new i0.EventEmitter();
3119 /** Event emitted when the overlay has been detached. */
3120 this.detach = new i0.EventEmitter();
3121 /** Emits when there are keyboard events that are targeted at the overlay. */
3122 this.overlayKeydown = new i0.EventEmitter();
3123 /** Emits when there are mouse outside click events that are targeted at the overlay. */
3124 this.overlayOutsideClick = new i0.EventEmitter();
3125 this._templatePortal = new portal.TemplatePortal(templateRef, viewContainerRef);
3126 this._scrollStrategyFactory = scrollStrategyFactory;
3127 this.scrollStrategy = this._scrollStrategyFactory();
3128 }
3129 Object.defineProperty(CdkConnectedOverlay.prototype, "offsetX", {
3130 /** The offset in pixels for the overlay connection point on the x-axis */
3131 get: function () { return this._offsetX; },
3132 set: function (offsetX) {
3133 this._offsetX = offsetX;
3134 if (this._position) {
3135 this._updatePositionStrategy(this._position);
3136 }
3137 },
3138 enumerable: false,
3139 configurable: true
3140 });
3141 Object.defineProperty(CdkConnectedOverlay.prototype, "offsetY", {
3142 /** The offset in pixels for the overlay connection point on the y-axis */
3143 get: function () { return this._offsetY; },
3144 set: function (offsetY) {
3145 this._offsetY = offsetY;
3146 if (this._position) {
3147 this._updatePositionStrategy(this._position);
3148 }
3149 },
3150 enumerable: false,
3151 configurable: true
3152 });
3153 Object.defineProperty(CdkConnectedOverlay.prototype, "hasBackdrop", {
3154 /** Whether or not the overlay should attach a backdrop. */
3155 get: function () { return this._hasBackdrop; },
3156 set: function (value) { this._hasBackdrop = coercion.coerceBooleanProperty(value); },
3157 enumerable: false,
3158 configurable: true
3159 });
3160 Object.defineProperty(CdkConnectedOverlay.prototype, "lockPosition", {
3161 /** Whether or not the overlay should be locked when scrolling. */
3162 get: function () { return this._lockPosition; },
3163 set: function (value) { this._lockPosition = coercion.coerceBooleanProperty(value); },
3164 enumerable: false,
3165 configurable: true
3166 });
3167 Object.defineProperty(CdkConnectedOverlay.prototype, "flexibleDimensions", {
3168 /** Whether the overlay's width and height can be constrained to fit within the viewport. */
3169 get: function () { return this._flexibleDimensions; },
3170 set: function (value) {
3171 this._flexibleDimensions = coercion.coerceBooleanProperty(value);
3172 },
3173 enumerable: false,
3174 configurable: true
3175 });
3176 Object.defineProperty(CdkConnectedOverlay.prototype, "growAfterOpen", {
3177 /** Whether the overlay can grow after the initial open when flexible positioning is turned on. */
3178 get: function () { return this._growAfterOpen; },
3179 set: function (value) { this._growAfterOpen = coercion.coerceBooleanProperty(value); },
3180 enumerable: false,
3181 configurable: true
3182 });
3183 Object.defineProperty(CdkConnectedOverlay.prototype, "push", {
3184 /** Whether the overlay can be pushed on-screen if none of the provided positions fit. */
3185 get: function () { return this._push; },
3186 set: function (value) { this._push = coercion.coerceBooleanProperty(value); },
3187 enumerable: false,
3188 configurable: true
3189 });
3190 Object.defineProperty(CdkConnectedOverlay.prototype, "overlayRef", {
3191 /** The associated overlay reference. */
3192 get: function () {
3193 return this._overlayRef;
3194 },
3195 enumerable: false,
3196 configurable: true
3197 });
3198 Object.defineProperty(CdkConnectedOverlay.prototype, "dir", {
3199 /** The element's layout direction. */
3200 get: function () {
3201 return this._dir ? this._dir.value : 'ltr';
3202 },
3203 enumerable: false,
3204 configurable: true
3205 });
3206 CdkConnectedOverlay.prototype.ngOnDestroy = function () {
3207 this._attachSubscription.unsubscribe();
3208 this._detachSubscription.unsubscribe();
3209 this._backdropSubscription.unsubscribe();
3210 this._positionSubscription.unsubscribe();
3211 if (this._overlayRef) {
3212 this._overlayRef.dispose();
3213 }
3214 };
3215 CdkConnectedOverlay.prototype.ngOnChanges = function (changes) {
3216 if (this._position) {
3217 this._updatePositionStrategy(this._position);
3218 this._overlayRef.updateSize({
3219 width: this.width,
3220 minWidth: this.minWidth,
3221 height: this.height,
3222 minHeight: this.minHeight,
3223 });
3224 if (changes['origin'] && this.open) {
3225 this._position.apply();
3226 }
3227 }
3228 if (changes['open']) {
3229 this.open ? this._attachOverlay() : this._detachOverlay();
3230 }
3231 };
3232 /** Creates an overlay */
3233 CdkConnectedOverlay.prototype._createOverlay = function () {
3234 var _this = this;
3235 if (!this.positions || !this.positions.length) {
3236 this.positions = defaultPositionList;
3237 }
3238 var overlayRef = this._overlayRef = this._overlay.create(this._buildConfig());
3239 this._attachSubscription = overlayRef.attachments().subscribe(function () { return _this.attach.emit(); });
3240 this._detachSubscription = overlayRef.detachments().subscribe(function () { return _this.detach.emit(); });
3241 overlayRef.keydownEvents().subscribe(function (event) {
3242 _this.overlayKeydown.next(event);
3243 if (event.keyCode === keycodes.ESCAPE && !_this.disableClose && !keycodes.hasModifierKey(event)) {
3244 event.preventDefault();
3245 _this._detachOverlay();
3246 }
3247 });
3248 this._overlayRef.outsidePointerEvents().subscribe(function (event) {
3249 _this.overlayOutsideClick.next(event);
3250 });
3251 };
3252 /** Builds the overlay config based on the directive's inputs */
3253 CdkConnectedOverlay.prototype._buildConfig = function () {
3254 var positionStrategy = this._position =
3255 this.positionStrategy || this._createPositionStrategy();
3256 var overlayConfig = new OverlayConfig({
3257 direction: this._dir,
3258 positionStrategy: positionStrategy,
3259 scrollStrategy: this.scrollStrategy,
3260 hasBackdrop: this.hasBackdrop
3261 });
3262 if (this.width || this.width === 0) {
3263 overlayConfig.width = this.width;
3264 }
3265 if (this.height || this.height === 0) {
3266 overlayConfig.height = this.height;
3267 }
3268 if (this.minWidth || this.minWidth === 0) {
3269 overlayConfig.minWidth = this.minWidth;
3270 }
3271 if (this.minHeight || this.minHeight === 0) {
3272 overlayConfig.minHeight = this.minHeight;
3273 }
3274 if (this.backdropClass) {
3275 overlayConfig.backdropClass = this.backdropClass;
3276 }
3277 if (this.panelClass) {
3278 overlayConfig.panelClass = this.panelClass;
3279 }
3280 return overlayConfig;
3281 };
3282 /** Updates the state of a position strategy, based on the values of the directive inputs. */
3283 CdkConnectedOverlay.prototype._updatePositionStrategy = function (positionStrategy) {
3284 var _this = this;
3285 var positions = this.positions.map(function (currentPosition) { return ({
3286 originX: currentPosition.originX,
3287 originY: currentPosition.originY,
3288 overlayX: currentPosition.overlayX,
3289 overlayY: currentPosition.overlayY,
3290 offsetX: currentPosition.offsetX || _this.offsetX,
3291 offsetY: currentPosition.offsetY || _this.offsetY,
3292 panelClass: currentPosition.panelClass || undefined,
3293 }); });
3294 return positionStrategy
3295 .setOrigin(this.origin.elementRef)
3296 .withPositions(positions)
3297 .withFlexibleDimensions(this.flexibleDimensions)
3298 .withPush(this.push)
3299 .withGrowAfterOpen(this.growAfterOpen)
3300 .withViewportMargin(this.viewportMargin)
3301 .withLockedPosition(this.lockPosition)
3302 .withTransformOriginOn(this.transformOriginSelector);
3303 };
3304 /** Returns the position strategy of the overlay to be set on the overlay config */
3305 CdkConnectedOverlay.prototype._createPositionStrategy = function () {
3306 var strategy = this._overlay.position().flexibleConnectedTo(this.origin.elementRef);
3307 this._updatePositionStrategy(strategy);
3308 return strategy;
3309 };
3310 /** Attaches the overlay and subscribes to backdrop clicks if backdrop exists */
3311 CdkConnectedOverlay.prototype._attachOverlay = function () {
3312 var _this = this;
3313 if (!this._overlayRef) {
3314 this._createOverlay();
3315 }
3316 else {
3317 // Update the overlay size, in case the directive's inputs have changed
3318 this._overlayRef.getConfig().hasBackdrop = this.hasBackdrop;
3319 }
3320 if (!this._overlayRef.hasAttached()) {
3321 this._overlayRef.attach(this._templatePortal);
3322 }
3323 if (this.hasBackdrop) {
3324 this._backdropSubscription = this._overlayRef.backdropClick().subscribe(function (event) {
3325 _this.backdropClick.emit(event);
3326 });
3327 }
3328 else {
3329 this._backdropSubscription.unsubscribe();
3330 }
3331 this._positionSubscription.unsubscribe();
3332 // Only subscribe to `positionChanges` if requested, because putting
3333 // together all the information for it can be expensive.
3334 if (this.positionChange.observers.length > 0) {
3335 this._positionSubscription = this._position.positionChanges
3336 .pipe(operators.takeWhile(function () { return _this.positionChange.observers.length > 0; }))
3337 .subscribe(function (position) {
3338 _this.positionChange.emit(position);
3339 if (_this.positionChange.observers.length === 0) {
3340 _this._positionSubscription.unsubscribe();
3341 }
3342 });
3343 }
3344 };
3345 /** Detaches the overlay and unsubscribes to backdrop clicks if backdrop exists */
3346 CdkConnectedOverlay.prototype._detachOverlay = function () {
3347 if (this._overlayRef) {
3348 this._overlayRef.detach();
3349 }
3350 this._backdropSubscription.unsubscribe();
3351 this._positionSubscription.unsubscribe();
3352 };
3353 return CdkConnectedOverlay;
3354 }());
3355 CdkConnectedOverlay.decorators = [
3356 { type: i0.Directive, args: [{
3357 selector: '[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]',
3358 exportAs: 'cdkConnectedOverlay'
3359 },] }
3360 ];
3361 CdkConnectedOverlay.ctorParameters = function () { return [
3362 { type: Overlay },
3363 { type: i0.TemplateRef },
3364 { type: i0.ViewContainerRef },
3365 { type: undefined, decorators: [{ type: i0.Inject, args: [CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY,] }] },
3366 { type: bidi.Directionality, decorators: [{ type: i0.Optional }] }
3367 ]; };
3368 CdkConnectedOverlay.propDecorators = {
3369 origin: [{ type: i0.Input, args: ['cdkConnectedOverlayOrigin',] }],
3370 positions: [{ type: i0.Input, args: ['cdkConnectedOverlayPositions',] }],
3371 positionStrategy: [{ type: i0.Input, args: ['cdkConnectedOverlayPositionStrategy',] }],
3372 offsetX: [{ type: i0.Input, args: ['cdkConnectedOverlayOffsetX',] }],
3373 offsetY: [{ type: i0.Input, args: ['cdkConnectedOverlayOffsetY',] }],
3374 width: [{ type: i0.Input, args: ['cdkConnectedOverlayWidth',] }],
3375 height: [{ type: i0.Input, args: ['cdkConnectedOverlayHeight',] }],
3376 minWidth: [{ type: i0.Input, args: ['cdkConnectedOverlayMinWidth',] }],
3377 minHeight: [{ type: i0.Input, args: ['cdkConnectedOverlayMinHeight',] }],
3378 backdropClass: [{ type: i0.Input, args: ['cdkConnectedOverlayBackdropClass',] }],
3379 panelClass: [{ type: i0.Input, args: ['cdkConnectedOverlayPanelClass',] }],
3380 viewportMargin: [{ type: i0.Input, args: ['cdkConnectedOverlayViewportMargin',] }],
3381 scrollStrategy: [{ type: i0.Input, args: ['cdkConnectedOverlayScrollStrategy',] }],
3382 open: [{ type: i0.Input, args: ['cdkConnectedOverlayOpen',] }],
3383 disableClose: [{ type: i0.Input, args: ['cdkConnectedOverlayDisableClose',] }],
3384 transformOriginSelector: [{ type: i0.Input, args: ['cdkConnectedOverlayTransformOriginOn',] }],
3385 hasBackdrop: [{ type: i0.Input, args: ['cdkConnectedOverlayHasBackdrop',] }],
3386 lockPosition: [{ type: i0.Input, args: ['cdkConnectedOverlayLockPosition',] }],
3387 flexibleDimensions: [{ type: i0.Input, args: ['cdkConnectedOverlayFlexibleDimensions',] }],
3388 growAfterOpen: [{ type: i0.Input, args: ['cdkConnectedOverlayGrowAfterOpen',] }],
3389 push: [{ type: i0.Input, args: ['cdkConnectedOverlayPush',] }],
3390 backdropClick: [{ type: i0.Output }],
3391 positionChange: [{ type: i0.Output }],
3392 attach: [{ type: i0.Output }],
3393 detach: [{ type: i0.Output }],
3394 overlayKeydown: [{ type: i0.Output }],
3395 overlayOutsideClick: [{ type: i0.Output }]
3396 };
3397 /** @docs-private */
3398 function CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER_FACTORY(overlay) {
3399 return function () { return overlay.scrollStrategies.reposition(); };
3400 }
3401 /** @docs-private */
3402 var CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER = {
3403 provide: CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY,
3404 deps: [Overlay],
3405 useFactory: CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER_FACTORY,
3406 };
3407
3408 /**
3409 * @license
3410 * Copyright Google LLC All Rights Reserved.
3411 *
3412 * Use of this source code is governed by an MIT-style license that can be
3413 * found in the LICENSE file at https://angular.io/license
3414 */
3415 var OverlayModule = /** @class */ (function () {
3416 function OverlayModule() {
3417 }
3418 return OverlayModule;
3419 }());
3420 OverlayModule.decorators = [
3421 { type: i0.NgModule, args: [{
3422 imports: [bidi.BidiModule, portal.PortalModule, i1.ScrollingModule],
3423 exports: [CdkConnectedOverlay, CdkOverlayOrigin, i1.ScrollingModule],
3424 declarations: [CdkConnectedOverlay, CdkOverlayOrigin],
3425 providers: [
3426 Overlay,
3427 CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER,
3428 ],
3429 },] }
3430 ];
3431
3432 /**
3433 * @license
3434 * Copyright Google LLC All Rights Reserved.
3435 *
3436 * Use of this source code is governed by an MIT-style license that can be
3437 * found in the LICENSE file at https://angular.io/license
3438 */
3439
3440 /**
3441 * Alternative to OverlayContainer that supports correct displaying of overlay elements in
3442 * Fullscreen mode
3443 * https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullScreen
3444 *
3445 * Should be provided in the root component.
3446 */
3447 var FullscreenOverlayContainer = /** @class */ (function (_super) {
3448 __extends(FullscreenOverlayContainer, _super);
3449 function FullscreenOverlayContainer(_document, platform) {
3450 return _super.call(this, _document, platform) || this;
3451 }
3452 FullscreenOverlayContainer.prototype.ngOnDestroy = function () {
3453 _super.prototype.ngOnDestroy.call(this);
3454 if (this._fullScreenEventName && this._fullScreenListener) {
3455 this._document.removeEventListener(this._fullScreenEventName, this._fullScreenListener);
3456 }
3457 };
3458 FullscreenOverlayContainer.prototype._createContainer = function () {
3459 var _this = this;
3460 _super.prototype._createContainer.call(this);
3461 this._adjustParentForFullscreenChange();
3462 this._addFullscreenChangeListener(function () { return _this._adjustParentForFullscreenChange(); });
3463 };
3464 FullscreenOverlayContainer.prototype._adjustParentForFullscreenChange = function () {
3465 if (!this._containerElement) {
3466 return;
3467 }
3468 var fullscreenElement = this.getFullscreenElement();
3469 var parent = fullscreenElement || this._document.body;
3470 parent.appendChild(this._containerElement);
3471 };
3472 FullscreenOverlayContainer.prototype._addFullscreenChangeListener = function (fn) {
3473 var eventName = this._getEventName();
3474 if (eventName) {
3475 if (this._fullScreenListener) {
3476 this._document.removeEventListener(eventName, this._fullScreenListener);
3477 }
3478 this._document.addEventListener(eventName, fn);
3479 this._fullScreenListener = fn;
3480 }
3481 };
3482 FullscreenOverlayContainer.prototype._getEventName = function () {
3483 if (!this._fullScreenEventName) {
3484 var _document = this._document;
3485 if (_document.fullscreenEnabled) {
3486 this._fullScreenEventName = 'fullscreenchange';
3487 }
3488 else if (_document.webkitFullscreenEnabled) {
3489 this._fullScreenEventName = 'webkitfullscreenchange';
3490 }
3491 else if (_document.mozFullScreenEnabled) {
3492 this._fullScreenEventName = 'mozfullscreenchange';
3493 }
3494 else if (_document.msFullscreenEnabled) {
3495 this._fullScreenEventName = 'MSFullscreenChange';
3496 }
3497 }
3498 return this._fullScreenEventName;
3499 };
3500 /**
3501 * When the page is put into fullscreen mode, a specific element is specified.
3502 * Only that element and its children are visible when in fullscreen mode.
3503 */
3504 FullscreenOverlayContainer.prototype.getFullscreenElement = function () {
3505 var _document = this._document;
3506 return _document.fullscreenElement ||
3507 _document.webkitFullscreenElement ||
3508 _document.mozFullScreenElement ||
3509 _document.msFullscreenElement ||
3510 null;
3511 };
3512 return FullscreenOverlayContainer;
3513 }(OverlayContainer));
3514 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" });
3515 FullscreenOverlayContainer.decorators = [
3516 { type: i0.Injectable, args: [{ providedIn: 'root' },] }
3517 ];
3518 FullscreenOverlayContainer.ctorParameters = function () { return [
3519 { type: undefined, decorators: [{ type: i0.Inject, args: [i1$1.DOCUMENT,] }] },
3520 { type: i2.Platform }
3521 ]; };
3522
3523 /**
3524 * @license
3525 * Copyright Google LLC All Rights Reserved.
3526 *
3527 * Use of this source code is governed by an MIT-style license that can be
3528 * found in the LICENSE file at https://angular.io/license
3529 */
3530
3531 /**
3532 * Generated bundle index. Do not edit.
3533 */
3534
3535 Object.defineProperty(exports, 'CdkScrollable', {
3536 enumerable: true,
3537 get: function () {
3538 return i1.CdkScrollable;
3539 }
3540 });
3541 Object.defineProperty(exports, 'ScrollDispatcher', {
3542 enumerable: true,
3543 get: function () {
3544 return i1.ScrollDispatcher;
3545 }
3546 });
3547 Object.defineProperty(exports, 'ViewportRuler', {
3548 enumerable: true,
3549 get: function () {
3550 return i1.ViewportRuler;
3551 }
3552 });
3553 exports.BlockScrollStrategy = BlockScrollStrategy;
3554 exports.CdkConnectedOverlay = CdkConnectedOverlay;
3555 exports.CdkOverlayOrigin = CdkOverlayOrigin;
3556 exports.CloseScrollStrategy = CloseScrollStrategy;
3557 exports.ConnectedOverlayPositionChange = ConnectedOverlayPositionChange;
3558 exports.ConnectedPositionStrategy = ConnectedPositionStrategy;
3559 exports.ConnectionPositionPair = ConnectionPositionPair;
3560 exports.FlexibleConnectedPositionStrategy = FlexibleConnectedPositionStrategy;
3561 exports.FullscreenOverlayContainer = FullscreenOverlayContainer;
3562 exports.GlobalPositionStrategy = GlobalPositionStrategy;
3563 exports.NoopScrollStrategy = NoopScrollStrategy;
3564 exports.Overlay = Overlay;
3565 exports.OverlayConfig = OverlayConfig;
3566 exports.OverlayContainer = OverlayContainer;
3567 exports.OverlayKeyboardDispatcher = OverlayKeyboardDispatcher;
3568 exports.OverlayModule = OverlayModule;
3569 exports.OverlayOutsideClickDispatcher = OverlayOutsideClickDispatcher;
3570 exports.OverlayPositionBuilder = OverlayPositionBuilder;
3571 exports.OverlayRef = OverlayRef;
3572 exports.RepositionScrollStrategy = RepositionScrollStrategy;
3573 exports.ScrollStrategyOptions = ScrollStrategyOptions;
3574 exports.ScrollingVisibility = ScrollingVisibility;
3575 exports.validateHorizontalPosition = validateHorizontalPosition;
3576 exports.validateVerticalPosition = validateVerticalPosition;
3577 exports.ɵangular_material_src_cdk_overlay_overlay_a = CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY;
3578 exports.ɵangular_material_src_cdk_overlay_overlay_b = CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER_FACTORY;
3579 exports.ɵangular_material_src_cdk_overlay_overlay_c = CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER;
3580 exports.ɵangular_material_src_cdk_overlay_overlay_d = BaseOverlayDispatcher;
3581
3582 Object.defineProperty(exports, '__esModule', { value: true });
3583
3584})));
3585//# sourceMappingURL=cdk-overlay.umd.js.map
Note: See TracBrowser for help on using the repository browser.