UNPKG

80.2 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular2-material/core'), require('@angular/platform-browser')) :
3 typeof define === 'function' && define.amd ? define(['exports', '@angular/core', '@angular2-material/core', '@angular/platform-browser'], factory) :
4 (factory((global.md = global.md || {}, global.md.core = global.md.core || {}),global.ng.core,global.md.core,global.ng.platformBrowser));
5}(this, (function (exports,_angular_core,_angular2Material_core,_angular_platformBrowser) { 'use strict';
6
7var __decorate$1 = (window && window.__decorate) || function (decorators, target, key, desc) {
8 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
9 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
10 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
11 return c > 3 && r && Object.defineProperty(target, key, r), r;
12};
13var __metadata$1 = (window && window.__metadata) || function (k, v) {
14 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
15};
16/**
17 * Shared directive to count lines inside a text area, such as a list item.
18 * Line elements can be extracted with a @ContentChildren(MdLine) query, then
19 * counted by checking the query list's length.
20 */
21var MdLine = (function () {
22 function MdLine() {
23 }
24 MdLine = __decorate$1([
25 _angular_core.Directive({ selector: '[md-line]' }),
26 __metadata$1('design:paramtypes', [])
27 ], MdLine);
28 return MdLine;
29}());
30/* Helper that takes a query list of lines and sets the correct class on the host */
31var MdLineSetter = (function () {
32 function MdLineSetter(_lines, _renderer, _element) {
33 var _this = this;
34 this._lines = _lines;
35 this._renderer = _renderer;
36 this._element = _element;
37 this._setLineClass(this._lines.length);
38 this._lines.changes.subscribe(function () {
39 _this._setLineClass(_this._lines.length);
40 });
41 }
42 MdLineSetter.prototype._setLineClass = function (count) {
43 this._resetClasses();
44 if (count === 2 || count === 3) {
45 this._setClass("md-" + count + "-line", true);
46 }
47 };
48 MdLineSetter.prototype._resetClasses = function () {
49 this._setClass('md-2-line', false);
50 this._setClass('md-3-line', false);
51 };
52 MdLineSetter.prototype._setClass = function (className, bool) {
53 this._renderer.setElementClass(this._element.nativeElement, className, bool);
54 };
55 return MdLineSetter;
56}());
57var MdLineModule = (function () {
58 function MdLineModule() {
59 }
60 MdLineModule = __decorate$1([
61 _angular_core.NgModule({
62 exports: [MdLine],
63 declarations: [MdLine],
64 }),
65 __metadata$1('design:paramtypes', [])
66 ], MdLineModule);
67 return MdLineModule;
68}());
69
70var __decorate$2 = (window && window.__decorate) || function (decorators, target, key, desc) {
71 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
72 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
73 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
74 return c > 3 && r && Object.defineProperty(target, key, r), r;
75};
76var __metadata$2 = (window && window.__metadata) || function (k, v) {
77 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
78};
79/**
80 * Directive to listen to changes of direction of part of the DOM.
81 *
82 * Applications should use this directive instead of the native attribute so that Material
83 * components can listen on changes of direction.
84 */
85var Dir = (function () {
86 function Dir() {
87 this._dir = 'ltr';
88 this.dirChange = new _angular_core.EventEmitter();
89 }
90 Object.defineProperty(Dir.prototype, "dir", {
91 get: function () {
92 return this._dir;
93 },
94 set: function (v) {
95 var old = this._dir;
96 this._dir = v;
97 if (old != this._dir) {
98 this.dirChange.emit(null);
99 }
100 },
101 enumerable: true,
102 configurable: true
103 });
104 Object.defineProperty(Dir.prototype, "value", {
105 get: function () { return this.dir; },
106 set: function (v) { this.dir = v; },
107 enumerable: true,
108 configurable: true
109 });
110 __decorate$2([
111 _angular_core.Input('dir'),
112 __metadata$2('design:type', String)
113 ], Dir.prototype, "_dir", void 0);
114 __decorate$2([
115 _angular_core.Output(),
116 __metadata$2('design:type', Object)
117 ], Dir.prototype, "dirChange", void 0);
118 __decorate$2([
119 _angular_core.HostBinding('attr.dir'),
120 __metadata$2('design:type', String)
121 ], Dir.prototype, "dir", null);
122 Dir = __decorate$2([
123 _angular_core.Directive({
124 selector: '[dir]',
125 // TODO(hansl): maybe `$implicit` isn't the best option here, but for now that's the best we got.
126 exportAs: '$implicit'
127 }),
128 __metadata$2('design:paramtypes', [])
129 ], Dir);
130 return Dir;
131}());
132var RtlModule = (function () {
133 function RtlModule() {
134 }
135 RtlModule.forRoot = function () {
136 return {
137 ngModule: RtlModule,
138 providers: []
139 };
140 };
141 RtlModule = __decorate$2([
142 _angular_core.NgModule({
143 exports: [Dir],
144 declarations: [Dir]
145 }),
146 __metadata$2('design:paramtypes', [])
147 ], RtlModule);
148 return RtlModule;
149}());
150
151/** TODO: internal */
152var ForegroundRippleState;
153(function (ForegroundRippleState) {
154 ForegroundRippleState[ForegroundRippleState["NEW"] = 0] = "NEW";
155 ForegroundRippleState[ForegroundRippleState["EXPANDING"] = 1] = "EXPANDING";
156 ForegroundRippleState[ForegroundRippleState["FADING_OUT"] = 2] = "FADING_OUT";
157})(ForegroundRippleState || (ForegroundRippleState = {}));
158/**
159 * Wrapper for a foreground ripple DOM element and its animation state.
160 * TODO: internal
161 */
162var ForegroundRipple = (function () {
163 function ForegroundRipple(rippleElement) {
164 this.rippleElement = rippleElement;
165 this.state = ForegroundRippleState.NEW;
166 }
167 return ForegroundRipple;
168}());
169var RIPPLE_SPEED_PX_PER_SECOND = 1000;
170var MIN_RIPPLE_FILL_TIME_SECONDS = 0.1;
171var MAX_RIPPLE_FILL_TIME_SECONDS = 0.3;
172/**
173 * Returns the distance from the point (x, y) to the furthest corner of a rectangle.
174 */
175var distanceToFurthestCorner = function (x, y, rect) {
176 var distX = Math.max(Math.abs(x - rect.left), Math.abs(x - rect.right));
177 var distY = Math.max(Math.abs(y - rect.top), Math.abs(y - rect.bottom));
178 return Math.sqrt(distX * distX + distY * distY);
179};
180/**
181 * Helper service that performs DOM manipulations. Not intended to be used outside this module.
182 * The constructor takes a reference to the ripple directive's host element and a map of DOM
183 * event handlers to be installed on the element that triggers ripple animations.
184 * This will eventually become a custom renderer once Angular support exists.
185 * TODO: internal
186 */
187var RippleRenderer = (function () {
188 function RippleRenderer(_elementRef, _eventHandlers) {
189 this._eventHandlers = _eventHandlers;
190 this._rippleElement = _elementRef.nativeElement;
191 // It might be nice to delay creating the background until it's needed, but doing this in
192 // fadeInRippleBackground causes the first click event to not be handled reliably.
193 this._backgroundDiv = document.createElement('div');
194 this._backgroundDiv.classList.add('md-ripple-background');
195 this._rippleElement.appendChild(this._backgroundDiv);
196 }
197 /**
198 * Installs event handlers on the given trigger element, and removes event handlers from the
199 * previous trigger if needed.
200 */
201 RippleRenderer.prototype.setTriggerElement = function (newTrigger) {
202 var _this = this;
203 if (this._triggerElement !== newTrigger) {
204 if (this._triggerElement) {
205 this._eventHandlers.forEach(function (eventHandler, eventName) {
206 _this._triggerElement.removeEventListener(eventName, eventHandler);
207 });
208 }
209 this._triggerElement = newTrigger;
210 if (this._triggerElement) {
211 this._eventHandlers.forEach(function (eventHandler, eventName) {
212 _this._triggerElement.addEventListener(eventName, eventHandler);
213 });
214 }
215 }
216 };
217 /**
218 * Installs event handlers on the host element of the md-ripple directive.
219 */
220 RippleRenderer.prototype.setTriggerElementToHost = function () {
221 this.setTriggerElement(this._rippleElement);
222 };
223 /**
224 * Removes event handlers from the current trigger element if needed.
225 */
226 RippleRenderer.prototype.clearTriggerElement = function () {
227 this.setTriggerElement(null);
228 };
229 /**
230 * Creates a foreground ripple and sets its animation to expand and fade in from the position
231 * given by rippleOriginLeft and rippleOriginTop (or from the center of the <md-ripple>
232 * bounding rect if centered is true).
233 */
234 RippleRenderer.prototype.createForegroundRipple = function (rippleOriginLeft, rippleOriginTop, color, centered, radius, speedFactor, transitionEndCallback) {
235 var parentRect = this._rippleElement.getBoundingClientRect();
236 // Create a foreground ripple div with the size and position of the fully expanded ripple.
237 // When the div is created, it's given a transform style that causes the ripple to be displayed
238 // small and centered on the event location (or the center of the bounding rect if the centered
239 // argument is true). Removing that transform causes the ripple to animate to its natural size.
240 var startX = centered ? (parentRect.left + parentRect.width / 2) : rippleOriginLeft;
241 var startY = centered ? (parentRect.top + parentRect.height / 2) : rippleOriginTop;
242 var offsetX = startX - parentRect.left;
243 var offsetY = startY - parentRect.top;
244 var maxRadius = radius > 0 ? radius : distanceToFurthestCorner(startX, startY, parentRect);
245 var rippleDiv = document.createElement('div');
246 this._rippleElement.appendChild(rippleDiv);
247 rippleDiv.classList.add('md-ripple-foreground');
248 rippleDiv.style.left = (offsetX - maxRadius) + "px";
249 rippleDiv.style.top = (offsetY - maxRadius) + "px";
250 rippleDiv.style.width = 2 * maxRadius + "px";
251 rippleDiv.style.height = rippleDiv.style.width;
252 // If color input is not set, this will default to the background color defined in CSS.
253 rippleDiv.style.backgroundColor = color;
254 // Start the ripple tiny.
255 rippleDiv.style.transform = "scale(0.001)";
256 var fadeInSeconds = (1 / (speedFactor || 1)) * Math.max(MIN_RIPPLE_FILL_TIME_SECONDS, Math.min(MAX_RIPPLE_FILL_TIME_SECONDS, maxRadius / RIPPLE_SPEED_PX_PER_SECOND));
257 rippleDiv.style.transitionDuration = fadeInSeconds + "s";
258 // https://timtaubert.de/blog/2012/09/css-transitions-for-dynamically-created-dom-elements/
259 window.getComputedStyle(rippleDiv).opacity;
260 rippleDiv.classList.add('md-ripple-fade-in');
261 // Clearing the transform property causes the ripple to animate to its full size.
262 rippleDiv.style.transform = '';
263 var ripple = new ForegroundRipple(rippleDiv);
264 ripple.state = ForegroundRippleState.EXPANDING;
265 rippleDiv.addEventListener('transitionend', function (event) { return transitionEndCallback(ripple, event); });
266 };
267 /**
268 * Fades out a foreground ripple after it has fully expanded and faded in.
269 */
270 RippleRenderer.prototype.fadeOutForegroundRipple = function (ripple) {
271 ripple.classList.remove('md-ripple-fade-in');
272 ripple.classList.add('md-ripple-fade-out');
273 };
274 /**
275 * Removes a foreground ripple from the DOM after it has faded out.
276 */
277 RippleRenderer.prototype.removeRippleFromDom = function (ripple) {
278 ripple.parentElement.removeChild(ripple);
279 };
280 /**
281 * Fades in the ripple background.
282 */
283 RippleRenderer.prototype.fadeInRippleBackground = function (color) {
284 this._backgroundDiv.classList.add('md-ripple-active');
285 // If color is not set, this will default to the background color defined in CSS.
286 this._backgroundDiv.style.backgroundColor = color;
287 };
288 /**
289 * Fades out the ripple background.
290 */
291 RippleRenderer.prototype.fadeOutRippleBackground = function () {
292 if (this._backgroundDiv) {
293 this._backgroundDiv.classList.remove('md-ripple-active');
294 }
295 };
296 return RippleRenderer;
297}());
298
299var __decorate$3 = (window && window.__decorate) || function (decorators, target, key, desc) {
300 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
301 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
302 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
303 return c > 3 && r && Object.defineProperty(target, key, r), r;
304};
305var __metadata$3 = (window && window.__metadata) || function (k, v) {
306 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
307};
308var MdRipple = (function () {
309 function MdRipple(_elementRef) {
310 var _this = this;
311 /**
312 * If set, the radius in pixels of foreground ripples when fully expanded. If unset, the radius
313 * will be the distance from the center of the ripple to the furthest corner of the host element's
314 * bounding rectangle.
315 */
316 this.maxRadius = 0;
317 /**
318 * If set, the normal duration of ripple animations is divided by this value. For example,
319 * setting it to 0.5 will cause the animations to take twice as long.
320 */
321 this.speedFactor = 1;
322 // These event handlers are attached to the element that triggers the ripple animations.
323 var eventHandlers = new Map();
324 eventHandlers.set('mousedown', function (event) { return _this._mouseDown(event); });
325 eventHandlers.set('click', function (event) { return _this._click(event); });
326 eventHandlers.set('mouseleave', function (event) { return _this._mouseLeave(event); });
327 this._rippleRenderer = new RippleRenderer(_elementRef, eventHandlers);
328 }
329 /** TODO: internal */
330 MdRipple.prototype.ngOnInit = function () {
331 // If no trigger element was explicity set, use the host element
332 if (!this.trigger) {
333 this._rippleRenderer.setTriggerElementToHost();
334 }
335 };
336 /** TODO: internal */
337 MdRipple.prototype.ngOnDestroy = function () {
338 // Remove event listeners on the trigger element.
339 this._rippleRenderer.clearTriggerElement();
340 };
341 /** TODO: internal */
342 MdRipple.prototype.ngOnChanges = function (changes) {
343 // If the trigger element changed (or is being initially set), add event listeners to it.
344 var changedInputs = Object.keys(changes);
345 if (changedInputs.indexOf('trigger') !== -1) {
346 this._rippleRenderer.setTriggerElement(this.trigger);
347 }
348 };
349 /**
350 * Responds to the start of a ripple animation trigger by fading the background in.
351 */
352 MdRipple.prototype.start = function () {
353 this._rippleRenderer.fadeInRippleBackground(this.backgroundColor);
354 };
355 /**
356 * Responds to the end of a ripple animation trigger by fading the background out, and creating a
357 * foreground ripple that expands from the event location (or from the center of the element if
358 * the "centered" property is set or forceCenter is true).
359 */
360 MdRipple.prototype.end = function (left, top, forceCenter) {
361 var _this = this;
362 if (forceCenter === void 0) { forceCenter = true; }
363 this._rippleRenderer.createForegroundRipple(left, top, this.color, this.centered || forceCenter, this.maxRadius, this.speedFactor, function (ripple, e) { return _this._rippleTransitionEnded(ripple, e); });
364 this._rippleRenderer.fadeOutRippleBackground();
365 };
366 MdRipple.prototype._rippleTransitionEnded = function (ripple, event) {
367 if (event.propertyName === 'opacity') {
368 // If the ripple finished expanding, start fading it out. If it finished fading out,
369 // remove it from the DOM.
370 switch (ripple.state) {
371 case ForegroundRippleState.EXPANDING:
372 this._rippleRenderer.fadeOutForegroundRipple(ripple.rippleElement);
373 ripple.state = ForegroundRippleState.FADING_OUT;
374 break;
375 case ForegroundRippleState.FADING_OUT:
376 this._rippleRenderer.removeRippleFromDom(ripple.rippleElement);
377 break;
378 }
379 }
380 };
381 /**
382 * Called when the trigger element receives a mousedown event. Starts the ripple animation by
383 * fading in the background.
384 */
385 MdRipple.prototype._mouseDown = function (event) {
386 if (!this.disabled && event.button === 0) {
387 this.start();
388 }
389 };
390 /**
391 * Called when the trigger element receives a click event. Creates a foreground ripple and
392 * runs its animation.
393 */
394 MdRipple.prototype._click = function (event) {
395 if (!this.disabled && event.button === 0) {
396 // If screen and page positions are all 0, this was probably triggered by a keypress.
397 // In that case, use the center of the bounding rect as the ripple origin.
398 // FIXME: This fails on IE11, which still sets pageX/Y and screenX/Y on keyboard clicks.
399 var isKeyEvent = (event.screenX === 0 && event.screenY === 0 && event.pageX === 0 && event.pageY === 0);
400 this.end(event.pageX, event.pageY, isKeyEvent);
401 }
402 };
403 /**
404 * Called when the trigger element receives a mouseleave event. Fades out the background.
405 */
406 MdRipple.prototype._mouseLeave = function (event) {
407 // We can always fade out the background here; It's a no-op if it was already inactive.
408 this._rippleRenderer.fadeOutRippleBackground();
409 };
410 __decorate$3([
411 _angular_core.Input('md-ripple-trigger'),
412 __metadata$3('design:type', Object)
413 ], MdRipple.prototype, "trigger", void 0);
414 __decorate$3([
415 _angular_core.Input('md-ripple-centered'),
416 __metadata$3('design:type', Boolean)
417 ], MdRipple.prototype, "centered", void 0);
418 __decorate$3([
419 _angular_core.Input('md-ripple-disabled'),
420 __metadata$3('design:type', Boolean)
421 ], MdRipple.prototype, "disabled", void 0);
422 __decorate$3([
423 _angular_core.Input('md-ripple-max-radius'),
424 __metadata$3('design:type', Number)
425 ], MdRipple.prototype, "maxRadius", void 0);
426 __decorate$3([
427 _angular_core.Input('md-ripple-speed-factor'),
428 __metadata$3('design:type', Number)
429 ], MdRipple.prototype, "speedFactor", void 0);
430 __decorate$3([
431 _angular_core.Input('md-ripple-color'),
432 __metadata$3('design:type', String)
433 ], MdRipple.prototype, "color", void 0);
434 __decorate$3([
435 _angular_core.Input('md-ripple-background-color'),
436 __metadata$3('design:type', String)
437 ], MdRipple.prototype, "backgroundColor", void 0);
438 __decorate$3([
439 _angular_core.HostBinding('class.md-ripple-focused'),
440 _angular_core.Input('md-ripple-focused'),
441 __metadata$3('design:type', Boolean)
442 ], MdRipple.prototype, "focused", void 0);
443 __decorate$3([
444 _angular_core.HostBinding('class.md-ripple-unbounded'),
445 _angular_core.Input('md-ripple-unbounded'),
446 __metadata$3('design:type', Boolean)
447 ], MdRipple.prototype, "unbounded", void 0);
448 MdRipple = __decorate$3([
449 _angular_core.Directive({
450 selector: '[md-ripple]',
451 }),
452 __metadata$3('design:paramtypes', [_angular_core.ElementRef])
453 ], MdRipple);
454 return MdRipple;
455}());
456var MdRippleModule = (function () {
457 function MdRippleModule() {
458 }
459 MdRippleModule.forRoot = function () {
460 return {
461 ngModule: MdRippleModule,
462 providers: []
463 };
464 };
465 MdRippleModule = __decorate$3([
466 _angular_core.NgModule({
467 exports: [MdRipple],
468 declarations: [MdRipple],
469 }),
470 __metadata$3('design:paramtypes', [])
471 ], MdRippleModule);
472 return MdRippleModule;
473}());
474
475// TODO(kara): Revisit why error messages are not being properly set.
476var __extends$3 = (window && window.__extends) || function (d, b) {
477 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
478 function __() { this.constructor = d; }
479 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
480};
481/**
482 * Wrapper around Error that sets the error message.
483 */
484var MdError = (function (_super) {
485 __extends$3(MdError, _super);
486 function MdError(value) {
487 _super.call(this);
488 this.message = value;
489 }
490 return MdError;
491}(Error));
492
493var __extends$2 = (window && window.__extends) || function (d, b) {
494 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
495 function __() { this.constructor = d; }
496 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
497};
498/** Exception thrown when a ComponentPortal is attached to a DomPortalHost without an origin. */
499var MdComponentPortalAttachedToDomWithoutOriginError = (function (_super) {
500 __extends$2(MdComponentPortalAttachedToDomWithoutOriginError, _super);
501 function MdComponentPortalAttachedToDomWithoutOriginError() {
502 _super.call(this, 'A ComponentPortal must have an origin set when attached to a DomPortalHost ' +
503 'because the DOM element is not part of the Angular application context.');
504 }
505 return MdComponentPortalAttachedToDomWithoutOriginError;
506}(MdError));
507/** Exception thrown when attempting to attach a null portal to a host. */
508var MdNullPortalError = (function (_super) {
509 __extends$2(MdNullPortalError, _super);
510 function MdNullPortalError() {
511 _super.call(this, 'Must provide a portal to attach');
512 }
513 return MdNullPortalError;
514}(MdError));
515/** Exception thrown when attempting to attach a portal to a host that is already attached. */
516var MdPortalAlreadyAttachedError = (function (_super) {
517 __extends$2(MdPortalAlreadyAttachedError, _super);
518 function MdPortalAlreadyAttachedError() {
519 _super.call(this, 'Host already has a portal attached');
520 }
521 return MdPortalAlreadyAttachedError;
522}(MdError));
523/** Exception thrown when attempting to attach a portal to an already-disposed host. */
524var MdPortalHostAlreadyDisposedError = (function (_super) {
525 __extends$2(MdPortalHostAlreadyDisposedError, _super);
526 function MdPortalHostAlreadyDisposedError() {
527 _super.call(this, 'This PortalHost has already been disposed');
528 }
529 return MdPortalHostAlreadyDisposedError;
530}(MdError));
531/** Exception thrown when attempting to attach an unknown portal type. */
532var MdUnknownPortalTypeError = (function (_super) {
533 __extends$2(MdUnknownPortalTypeError, _super);
534 function MdUnknownPortalTypeError() {
535 _super.call(this, 'Attempting to attach an unknown Portal type. ' +
536 'BasePortalHost accepts either a ComponentPortal or a TemplatePortal.');
537 }
538 return MdUnknownPortalTypeError;
539}(MdError));
540/** Exception thrown when attempting to attach a portal to a null host. */
541var MdNullPortalHostError = (function (_super) {
542 __extends$2(MdNullPortalHostError, _super);
543 function MdNullPortalHostError() {
544 _super.call(this, 'Attempting to attach a portal to a null PortalHost');
545 }
546 return MdNullPortalHostError;
547}(MdError));
548/** Exception thrown when attempting to detach a portal that is not attached. */
549var MdNoPortalAttachedError = (function (_super) {
550 __extends$2(MdNoPortalAttachedError, _super);
551 function MdNoPortalAttachedError() {
552 _super.call(this, 'Attempting to detach a portal that is not attached to a host');
553 }
554 return MdNoPortalAttachedError;
555}(MdError));
556
557var __extends$1 = (window && window.__extends) || function (d, b) {
558 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
559 function __() { this.constructor = d; }
560 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
561};
562/**
563 * A `Portal` is something that you want to render somewhere else.
564 * It can be attach to / detached from a `PortalHost`.
565 */
566var Portal = (function () {
567 function Portal() {
568 }
569 /** Attach this portal to a host. */
570 Portal.prototype.attach = function (host) {
571 if (host == null) {
572 throw new MdNullPortalHostError();
573 }
574 if (host.hasAttached()) {
575 throw new MdPortalAlreadyAttachedError();
576 }
577 this._attachedHost = host;
578 return host.attach(this);
579 };
580 /** Detach this portal from its host */
581 Portal.prototype.detach = function () {
582 var host = this._attachedHost;
583 if (host == null) {
584 throw new MdNoPortalAttachedError();
585 }
586 this._attachedHost = null;
587 return host.detach();
588 };
589 Object.defineProperty(Portal.prototype, "isAttached", {
590 /** Whether this portal is attached to a host. */
591 get: function () {
592 return this._attachedHost != null;
593 },
594 enumerable: true,
595 configurable: true
596 });
597 /**
598 * Sets the PortalHost reference without performing `attach()`. This is used directly by
599 * the PortalHost when it is performing an `attach()` or `detatch()`.
600 */
601 Portal.prototype.setAttachedHost = function (host) {
602 this._attachedHost = host;
603 };
604 return Portal;
605}());
606/**
607 * A `ComponentPortal` is a portal that instantiates some Component upon attachment.
608 */
609var ComponentPortal = (function (_super) {
610 __extends$1(ComponentPortal, _super);
611 function ComponentPortal(component, viewContainerRef, injector) {
612 if (viewContainerRef === void 0) { viewContainerRef = null; }
613 if (injector === void 0) { injector = null; }
614 _super.call(this);
615 this.component = component;
616 this.viewContainerRef = viewContainerRef;
617 this.injector = injector;
618 }
619 return ComponentPortal;
620}(Portal));
621/**
622 * A `TemplatePortal` is a portal that represents some embedded template (TemplateRef).
623 */
624var TemplatePortal = (function (_super) {
625 __extends$1(TemplatePortal, _super);
626 function TemplatePortal(template, viewContainerRef) {
627 _super.call(this);
628 /**
629 * Additional locals for the instantiated embedded view.
630 * These locals can be seen as "exports" for the template, such as how ngFor has
631 * index / event / odd.
632 * See https://angular.io/docs/ts/latest/api/core/EmbeddedViewRef-class.html
633 */
634 this.locals = new Map();
635 this.templateRef = template;
636 this.viewContainerRef = viewContainerRef;
637 }
638 Object.defineProperty(TemplatePortal.prototype, "origin", {
639 get: function () {
640 return this.templateRef.elementRef;
641 },
642 enumerable: true,
643 configurable: true
644 });
645 TemplatePortal.prototype.attach = function (host, locals) {
646 this.locals = locals == null ? new Map() : locals;
647 return _super.prototype.attach.call(this, host);
648 };
649 TemplatePortal.prototype.detach = function () {
650 this.locals = new Map();
651 return _super.prototype.detach.call(this);
652 };
653 return TemplatePortal;
654}(Portal));
655/**
656 * Partial implementation of PortalHost that only deals with attaching either a
657 * ComponentPortal or a TemplatePortal.
658 */
659var BasePortalHost = (function () {
660 function BasePortalHost() {
661 /** Whether this host has already been permanently disposed. */
662 this._isDisposed = false;
663 }
664 /** Whether this host has an attached portal. */
665 BasePortalHost.prototype.hasAttached = function () {
666 return this._attachedPortal != null;
667 };
668 BasePortalHost.prototype.attach = function (portal) {
669 if (portal == null) {
670 throw new MdNullPortalError();
671 }
672 if (this.hasAttached()) {
673 throw new MdPortalAlreadyAttachedError();
674 }
675 if (this._isDisposed) {
676 throw new MdPortalHostAlreadyDisposedError();
677 }
678 if (portal instanceof ComponentPortal) {
679 this._attachedPortal = portal;
680 return this.attachComponentPortal(portal);
681 }
682 else if (portal instanceof TemplatePortal) {
683 this._attachedPortal = portal;
684 return this.attachTemplatePortal(portal);
685 }
686 throw new MdUnknownPortalTypeError();
687 };
688 BasePortalHost.prototype.detach = function () {
689 if (this._attachedPortal) {
690 this._attachedPortal.setAttachedHost(null);
691 }
692 this._attachedPortal = null;
693 if (this._disposeFn != null) {
694 this._disposeFn();
695 this._disposeFn = null;
696 }
697 };
698 BasePortalHost.prototype.dispose = function () {
699 if (this.hasAttached()) {
700 this.detach();
701 }
702 this._isDisposed = true;
703 };
704 BasePortalHost.prototype.setDisposeFn = function (fn) {
705 this._disposeFn = fn;
706 };
707 return BasePortalHost;
708}());
709
710var __extends = (window && window.__extends) || function (d, b) {
711 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
712 function __() { this.constructor = d; }
713 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
714};
715var __decorate$4 = (window && window.__decorate) || function (decorators, target, key, desc) {
716 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
717 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
718 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
719 return c > 3 && r && Object.defineProperty(target, key, r), r;
720};
721var __metadata$4 = (window && window.__metadata) || function (k, v) {
722 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
723};
724/**
725 * Directive version of a `TemplatePortal`. Because the directive *is* a TemplatePortal,
726 * the directive instance itself can be attached to a host, enabling declarative use of portals.
727 *
728 * Usage:
729 * <template portal #greeting>
730 * <p> Hello {{name}} </p>
731 * </template>
732 */
733var TemplatePortalDirective = (function (_super) {
734 __extends(TemplatePortalDirective, _super);
735 function TemplatePortalDirective(templateRef, viewContainerRef) {
736 _super.call(this, templateRef, viewContainerRef);
737 }
738 TemplatePortalDirective = __decorate$4([
739 _angular_core.Directive({
740 selector: '[portal]',
741 exportAs: 'portal',
742 }),
743 __metadata$4('design:paramtypes', [_angular_core.TemplateRef, _angular_core.ViewContainerRef])
744 ], TemplatePortalDirective);
745 return TemplatePortalDirective;
746}(TemplatePortal));
747/**
748 * Directive version of a PortalHost. Because the directive *is* a PortalHost, portals can be
749 * directly attached to it, enabling declarative use.
750 *
751 * Usage:
752 * <template [portalHost]="greeting"></template>
753 */
754var PortalHostDirective = (function (_super) {
755 __extends(PortalHostDirective, _super);
756 function PortalHostDirective(_componentFactoryResolver, _viewContainerRef) {
757 _super.call(this);
758 this._componentFactoryResolver = _componentFactoryResolver;
759 this._viewContainerRef = _viewContainerRef;
760 }
761 Object.defineProperty(PortalHostDirective.prototype, "portal", {
762 get: function () {
763 return this._portal;
764 },
765 set: function (p) {
766 this._replaceAttachedPortal(p);
767 },
768 enumerable: true,
769 configurable: true
770 });
771 /** Attach the given ComponentPortal to this PortlHost using the ComponentFactoryResolver. */
772 PortalHostDirective.prototype.attachComponentPortal = function (portal) {
773 portal.setAttachedHost(this);
774 // If the portal specifies an origin, use that as the logical location of the component
775 // in the application tree. Otherwise use the location of this PortalHost.
776 var viewContainerRef = portal.viewContainerRef != null ?
777 portal.viewContainerRef :
778 this._viewContainerRef;
779 var componentFactory = this._componentFactoryResolver.resolveComponentFactory(portal.component);
780 var ref = viewContainerRef.createComponent(componentFactory, viewContainerRef.length, portal.injector || viewContainerRef.parentInjector);
781 this.setDisposeFn(function () { return ref.destroy(); });
782 return ref;
783 };
784 /** Attach the given TemplatePortal to this PortlHost as an embedded View. */
785 PortalHostDirective.prototype.attachTemplatePortal = function (portal) {
786 var _this = this;
787 portal.setAttachedHost(this);
788 this._viewContainerRef.createEmbeddedView(portal.templateRef);
789 this.setDisposeFn(function () { return _this._viewContainerRef.clear(); });
790 // TODO(jelbourn): return locals from view
791 return new Map();
792 };
793 /** Detatches the currently attached Portal (if there is one) and attaches the given Portal. */
794 PortalHostDirective.prototype._replaceAttachedPortal = function (p) {
795 if (this.hasAttached()) {
796 this.detach();
797 }
798 if (p) {
799 this.attach(p);
800 this._portal = p;
801 }
802 };
803 PortalHostDirective = __decorate$4([
804 _angular_core.Directive({
805 selector: '[portalHost]',
806 inputs: ['portal: portalHost']
807 }),
808 __metadata$4('design:paramtypes', [_angular_core.ComponentFactoryResolver, _angular_core.ViewContainerRef])
809 ], PortalHostDirective);
810 return PortalHostDirective;
811}(BasePortalHost));
812var PortalModule = (function () {
813 function PortalModule() {
814 }
815 PortalModule.forRoot = function () {
816 return {
817 ngModule: PortalModule,
818 providers: []
819 };
820 };
821 PortalModule = __decorate$4([
822 _angular_core.NgModule({
823 exports: [TemplatePortalDirective, PortalHostDirective],
824 declarations: [TemplatePortalDirective, PortalHostDirective],
825 }),
826 __metadata$4('design:paramtypes', [])
827 ], PortalModule);
828 return PortalModule;
829}());
830
831/**
832 * OverlayState is a bag of values for either the initial configuration or current state of an
833 * overlay.
834 */
835var OverlayState = (function () {
836 function OverlayState() {
837 }
838 return OverlayState;
839}());
840
841var __extends$4 = (window && window.__extends) || function (d, b) {
842 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
843 function __() { this.constructor = d; }
844 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
845};
846/**
847 * A PortalHost for attaching portals to an arbitrary DOM element outside of the Angular
848 * application context.
849 *
850 * This is the only part of the portal core that directly touches the DOM.
851 */
852var DomPortalHost = (function (_super) {
853 __extends$4(DomPortalHost, _super);
854 function DomPortalHost(_hostDomElement, _componentFactoryResolver) {
855 _super.call(this);
856 this._hostDomElement = _hostDomElement;
857 this._componentFactoryResolver = _componentFactoryResolver;
858 }
859 /** Attach the given ComponentPortal to DOM element using the ComponentFactoryResolver. */
860 DomPortalHost.prototype.attachComponentPortal = function (portal) {
861 if (portal.viewContainerRef == null) {
862 throw new MdComponentPortalAttachedToDomWithoutOriginError();
863 }
864 var componentFactory = this._componentFactoryResolver.resolveComponentFactory(portal.component);
865 var ref = portal.viewContainerRef.createComponent(componentFactory, portal.viewContainerRef.length, portal.injector || portal.viewContainerRef.parentInjector);
866 var hostView = ref.hostView;
867 this._hostDomElement.appendChild(hostView.rootNodes[0]);
868 this.setDisposeFn(function () { return ref.destroy(); });
869 return ref;
870 };
871 DomPortalHost.prototype.attachTemplatePortal = function (portal) {
872 var _this = this;
873 var viewContainer = portal.viewContainerRef;
874 var viewRef = viewContainer.createEmbeddedView(portal.templateRef);
875 viewRef.rootNodes.forEach(function (rootNode) { return _this._hostDomElement.appendChild(rootNode); });
876 this.setDisposeFn((function () {
877 var index = viewContainer.indexOf(viewRef);
878 if (index != -1) {
879 viewContainer.remove(index);
880 }
881 }));
882 // TODO(jelbourn): Return locals from view.
883 return new Map();
884 };
885 DomPortalHost.prototype.dispose = function () {
886 _super.prototype.dispose.call(this);
887 if (this._hostDomElement.parentNode != null) {
888 this._hostDomElement.parentNode.removeChild(this._hostDomElement);
889 }
890 };
891 return DomPortalHost;
892}(BasePortalHost));
893
894/**
895 * Reference to an overlay that has been created with the Overlay service.
896 * Used to manipulate or dispose of said overlay.
897 */
898var OverlayRef = (function () {
899 function OverlayRef(_portalHost, _pane, _state) {
900 this._portalHost = _portalHost;
901 this._pane = _pane;
902 this._state = _state;
903 }
904 OverlayRef.prototype.attach = function (portal) {
905 var attachResult = this._portalHost.attach(portal);
906 this.updatePosition();
907 return attachResult;
908 };
909 OverlayRef.prototype.detach = function () {
910 return this._portalHost.detach();
911 };
912 OverlayRef.prototype.dispose = function () {
913 this._portalHost.dispose();
914 };
915 OverlayRef.prototype.hasAttached = function () {
916 return this._portalHost.hasAttached();
917 };
918 /** Gets the current state config of the overlay. */
919 OverlayRef.prototype.getState = function () {
920 return this._state;
921 };
922 /** Updates the position of the overlay based on the position strategy. */
923 OverlayRef.prototype.updatePosition = function () {
924 if (this._state.positionStrategy) {
925 this._state.positionStrategy.apply(this._pane);
926 }
927 };
928 return OverlayRef;
929}());
930
931var __decorate$8 = (window && window.__decorate) || function (decorators, target, key, desc) {
932 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
933 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
934 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
935 return c > 3 && r && Object.defineProperty(target, key, r), r;
936};
937var __metadata$8 = (window && window.__metadata) || function (k, v) {
938 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
939};
940/**
941 * Simple utility for getting the bounds of the browser viewport.
942 * TODO: internal
943 */
944var ViewportRuler = (function () {
945 function ViewportRuler() {
946 }
947 // TODO(jelbourn): cache the document's bounding rect and only update it when the window
948 // is resized (debounced).
949 /** Gets a ClientRect for the viewport's bounds. */
950 ViewportRuler.prototype.getViewportRect = function () {
951 // Use the document element's bounding rect rather than the window scroll properties
952 // (e.g. pageYOffset, scrollY) due to in issue in Chrome and IE where window scroll
953 // properties and client coordinates (boundingClientRect, clientX/Y, etc.) are in different
954 // conceptual viewports. Under most circumstances these viewports are equivalent, but they
955 // can disagree when the page is pinch-zoomed (on devices that support touch).
956 // See https://bugs.chromium.org/p/chromium/issues/detail?id=489206#c4
957 // We use the documentElement instead of the body because, by default (without a css reset)
958 // browsers typically give the document body an 8px margin, which is not included in
959 // getBoundingClientRect().
960 var documentRect = document.documentElement.getBoundingClientRect();
961 var scrollPosition = this.getViewportScrollPosition(documentRect);
962 var height = window.innerHeight;
963 var width = window.innerWidth;
964 return {
965 top: scrollPosition.top,
966 left: scrollPosition.left,
967 bottom: scrollPosition.top + height,
968 right: scrollPosition.left + width,
969 height: height,
970 width: width,
971 };
972 };
973 /**
974 * Gets the (top, left) scroll position of the viewport.
975 * @param documentRect
976 */
977 ViewportRuler.prototype.getViewportScrollPosition = function (documentRect) {
978 if (documentRect === void 0) { documentRect = document.documentElement.getBoundingClientRect(); }
979 // The top-left-corner of the viewport is determined by the scroll position of the document
980 // body, normally just (scrollLeft, scrollTop). However, Chrome and Firefox disagree about
981 // whether `document.body` or `document.documentElement` is the scrolled element, so reading
982 // `scrollTop` and `scrollLeft` is inconsistent. However, using the bounding rect of
983 // `document.documentElement` works consistently, where the `top` and `left` values will
984 // equal negative the scroll position.
985 var top = documentRect.top < 0 && document.body.scrollTop == 0 ?
986 -documentRect.top :
987 document.body.scrollTop;
988 var left = documentRect.left < 0 && document.body.scrollLeft == 0 ?
989 -documentRect.left :
990 document.body.scrollLeft;
991 return { top: top, left: left };
992 };
993 ViewportRuler = __decorate$8([
994 _angular_core.Injectable(),
995 __metadata$8('design:paramtypes', [])
996 ], ViewportRuler);
997 return ViewportRuler;
998}());
999
1000/** The points of the origin element and the overlay element to connect. */
1001var ConnectionPositionPair = (function () {
1002 function ConnectionPositionPair(origin, overlay) {
1003 this.originX = origin.originX;
1004 this.originY = origin.originY;
1005 this.overlayX = overlay.overlayX;
1006 this.overlayY = overlay.overlayY;
1007 }
1008 return ConnectionPositionPair;
1009}());
1010
1011/**
1012 * A strategy for positioning overlays. Using this strategy, an overlay is given an
1013 * implict position relative some origin element. The relative position is defined in terms of
1014 * a point on the origin element that is connected to a point on the overlay element. For example,
1015 * a basic dropdown is connecting the bottom-left corner of the origin to the top-left corner
1016 * of the overlay.
1017 */
1018var ConnectedPositionStrategy = (function () {
1019 function ConnectedPositionStrategy(_connectedTo, _originPos, _overlayPos, _viewportRuler) {
1020 this._connectedTo = _connectedTo;
1021 this._originPos = _originPos;
1022 this._overlayPos = _overlayPos;
1023 this._viewportRuler = _viewportRuler;
1024 // TODO(jelbourn): set RTL to the actual value from the app.
1025 /** Whether the we're dealing with an RTL context */
1026 this._isRtl = false;
1027 /** Ordered list of preferred positions, from most to least desirable. */
1028 this._preferredPositions = [];
1029 this._origin = this._connectedTo.nativeElement;
1030 this.withFallbackPosition(_originPos, _overlayPos);
1031 }
1032 Object.defineProperty(ConnectedPositionStrategy.prototype, "positions", {
1033 get: function () {
1034 return this._preferredPositions;
1035 },
1036 enumerable: true,
1037 configurable: true
1038 });
1039 /**
1040 * Updates the position of the overlay element, using whichever preferred position relative
1041 * to the origin fits on-screen.
1042 * TODO: internal
1043 */
1044 ConnectedPositionStrategy.prototype.apply = function (element) {
1045 // We need the bounding rects for the origin and the overlay to determine how to position
1046 // the overlay relative to the origin.
1047 var originRect = this._origin.getBoundingClientRect();
1048 var overlayRect = element.getBoundingClientRect();
1049 // We use the viewport rect to determine whether a position would go off-screen.
1050 var viewportRect = this._viewportRuler.getViewportRect();
1051 var firstOverlayPoint = null;
1052 // We want to place the overlay in the first of the preferred positions such that the
1053 // overlay fits on-screen.
1054 for (var _i = 0, _a = this._preferredPositions; _i < _a.length; _i++) {
1055 var pos = _a[_i];
1056 // Get the (x, y) point of connection on the origin, and then use that to get the
1057 // (top, left) coordinate for the overlay at `pos`.
1058 var originPoint = this._getOriginConnectionPoint(originRect, pos);
1059 var overlayPoint = this._getOverlayPoint(originPoint, overlayRect, pos);
1060 firstOverlayPoint = firstOverlayPoint || overlayPoint;
1061 // If the overlay in the calculated position fits on-screen, put it there and we're done.
1062 if (this._willOverlayFitWithinViewport(overlayPoint, overlayRect, viewportRect)) {
1063 this._setElementPosition(element, overlayPoint);
1064 return Promise.resolve(null);
1065 }
1066 }
1067 // TODO(jelbourn): fallback behavior for when none of the preferred positions fit on-screen.
1068 // For now, just stick it in the first position and let it go off-screen.
1069 this._setElementPosition(element, firstOverlayPoint);
1070 return Promise.resolve(null);
1071 };
1072 ConnectedPositionStrategy.prototype.withFallbackPosition = function (originPos, overlayPos) {
1073 this._preferredPositions.push(new ConnectionPositionPair(originPos, overlayPos));
1074 return this;
1075 };
1076 /**
1077 * Gets the horizontal (x) "start" dimension based on whether the overlay is in an RTL context.
1078 * @param rect
1079 */
1080 ConnectedPositionStrategy.prototype._getStartX = function (rect) {
1081 return this._isRtl ? rect.right : rect.left;
1082 };
1083 /**
1084 * Gets the horizontal (x) "end" dimension based on whether the overlay is in an RTL context.
1085 * @param rect
1086 */
1087 ConnectedPositionStrategy.prototype._getEndX = function (rect) {
1088 return this._isRtl ? rect.left : rect.right;
1089 };
1090 /**
1091 * Gets the (x, y) coordinate of a connection point on the origin based on a relative position.
1092 * @param originRect
1093 * @param pos
1094 */
1095 ConnectedPositionStrategy.prototype._getOriginConnectionPoint = function (originRect, pos) {
1096 var originStartX = this._getStartX(originRect);
1097 var originEndX = this._getEndX(originRect);
1098 var x;
1099 if (pos.originX == 'center') {
1100 x = originStartX + (originRect.width / 2);
1101 }
1102 else {
1103 x = pos.originX == 'start' ? originStartX : originEndX;
1104 }
1105 var y;
1106 if (pos.originY == 'center') {
1107 y = originRect.top + (originRect.height / 2);
1108 }
1109 else {
1110 y = pos.originY == 'top' ? originRect.top : originRect.bottom;
1111 }
1112 return { x: x, y: y };
1113 };
1114 /**
1115 * Gets the (x, y) coordinate of the top-left corner of the overlay given a given position and
1116 * origin point to which the overlay should be connected.
1117 * @param originPoint
1118 * @param overlayRect
1119 * @param pos
1120 */
1121 ConnectedPositionStrategy.prototype._getOverlayPoint = function (originPoint, overlayRect, pos) {
1122 // Calculate the (overlayStartX, overlayStartY), the start of the potential overlay position
1123 // relative to the origin point.
1124 var overlayStartX;
1125 if (pos.overlayX == 'center') {
1126 overlayStartX = -overlayRect.width / 2;
1127 }
1128 else {
1129 overlayStartX = pos.overlayX == 'start' ? 0 : -overlayRect.width;
1130 }
1131 var overlayStartY;
1132 if (pos.overlayY == 'center') {
1133 overlayStartY = -overlayRect.height / 2;
1134 }
1135 else {
1136 overlayStartY = pos.overlayY == 'top' ? 0 : -overlayRect.height;
1137 }
1138 return {
1139 x: originPoint.x + overlayStartX,
1140 y: originPoint.y + overlayStartY
1141 };
1142 };
1143 /**
1144 * Gets whether the overlay positioned at the given point will fit on-screen.
1145 * @param overlayPoint The top-left coordinate of the overlay.
1146 * @param overlayRect Bounding rect of the overlay, used to get its size.
1147 * @param viewportRect The bounding viewport.
1148 */
1149 ConnectedPositionStrategy.prototype._willOverlayFitWithinViewport = function (overlayPoint, overlayRect, viewportRect) {
1150 // TODO(jelbourn): probably also want some space between overlay edge and viewport edge.
1151 return overlayPoint.x >= viewportRect.left &&
1152 overlayPoint.x + overlayRect.width <= viewportRect.right &&
1153 overlayPoint.y >= viewportRect.top &&
1154 overlayPoint.y + overlayRect.height <= viewportRect.bottom;
1155 };
1156 /**
1157 * Physically positions the overlay element to the given coordinate.
1158 * @param element
1159 * @param overlayPoint
1160 */
1161 ConnectedPositionStrategy.prototype._setElementPosition = function (element, overlayPoint) {
1162 var scrollPos = this._viewportRuler.getViewportScrollPosition();
1163 var x = overlayPoint.x + scrollPos.left;
1164 var y = overlayPoint.y + scrollPos.top;
1165 // TODO(jelbourn): we don't want to always overwrite the transform property here,
1166 // because it will need to be used for animations.
1167 _angular2Material_core.applyCssTransform(element, "translateX(" + x + "px) translateY(" + y + "px)");
1168 };
1169 return ConnectedPositionStrategy;
1170}());
1171
1172/**
1173 * A strategy for positioning overlays. Using this strategy, an overlay is given an
1174 * explicit position relative to the browser's viewport.
1175 */
1176var GlobalPositionStrategy = (function () {
1177 function GlobalPositionStrategy() {
1178 this._cssPosition = 'absolute';
1179 this._top = '';
1180 this._bottom = '';
1181 this._left = '';
1182 this._right = '';
1183 /** Array of individual applications of translateX(). Currently only for centering. */
1184 this._translateX = [];
1185 /** Array of individual applications of translateY(). Currently only for centering. */
1186 this._translateY = [];
1187 }
1188 /** Sets the element to usee CSS position: fixed */
1189 GlobalPositionStrategy.prototype.fixed = function () {
1190 this._cssPosition = 'fixed';
1191 return this;
1192 };
1193 /** Sets the element to usee CSS position: absolute. This is the default. */
1194 GlobalPositionStrategy.prototype.absolute = function () {
1195 this._cssPosition = 'absolute';
1196 return this;
1197 };
1198 /** Sets the top position of the overlay. Clears any previously set vertical position. */
1199 GlobalPositionStrategy.prototype.top = function (value) {
1200 this._bottom = '';
1201 this._translateY = [];
1202 this._top = value;
1203 return this;
1204 };
1205 /** Sets the left position of the overlay. Clears any previously set horizontal position. */
1206 GlobalPositionStrategy.prototype.left = function (value) {
1207 this._right = '';
1208 this._translateX = [];
1209 this._left = value;
1210 return this;
1211 };
1212 /** Sets the bottom position of the overlay. Clears any previously set vertical position. */
1213 GlobalPositionStrategy.prototype.bottom = function (value) {
1214 this._top = '';
1215 this._translateY = [];
1216 this._bottom = value;
1217 return this;
1218 };
1219 /** Sets the right position of the overlay. Clears any previously set horizontal position. */
1220 GlobalPositionStrategy.prototype.right = function (value) {
1221 this._left = '';
1222 this._translateX = [];
1223 this._right = value;
1224 return this;
1225 };
1226 /**
1227 * Centers the overlay horizontally with an optional offset.
1228 * Clears any previously set horizontal position.
1229 */
1230 GlobalPositionStrategy.prototype.centerHorizontally = function (offset) {
1231 if (offset === void 0) { offset = '0px'; }
1232 this._left = '50%';
1233 this._right = '';
1234 this._translateX = ['-50%', offset];
1235 return this;
1236 };
1237 /**
1238 * Centers the overlay vertically with an optional offset.
1239 * Clears any previously set vertical position.
1240 */
1241 GlobalPositionStrategy.prototype.centerVertically = function (offset) {
1242 if (offset === void 0) { offset = '0px'; }
1243 this._top = '50%';
1244 this._bottom = '';
1245 this._translateY = ['-50%', offset];
1246 return this;
1247 };
1248 /**
1249 * Apply the position to the element.
1250 * TODO: internal
1251 */
1252 GlobalPositionStrategy.prototype.apply = function (element) {
1253 element.style.position = this._cssPosition;
1254 element.style.top = this._top;
1255 element.style.left = this._left;
1256 element.style.bottom = this._bottom;
1257 element.style.right = this._right;
1258 // TODO(jelbourn): we don't want to always overwrite the transform property here,
1259 // because it will need to be used for animations.
1260 var tranlateX = this._reduceTranslateValues('translateX', this._translateX);
1261 var translateY = this._reduceTranslateValues('translateY', this._translateY);
1262 _angular2Material_core.applyCssTransform(element, tranlateX + " " + translateY);
1263 return Promise.resolve(null);
1264 };
1265 /** Reduce a list of translate values to a string that can be used in the transform property */
1266 GlobalPositionStrategy.prototype._reduceTranslateValues = function (translateFn, values) {
1267 return values.map(function (t) { return (translateFn + "(" + t + ")"); }).join(' ');
1268 };
1269 return GlobalPositionStrategy;
1270}());
1271
1272var __decorate$7 = (window && window.__decorate) || function (decorators, target, key, desc) {
1273 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1274 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1275 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1276 return c > 3 && r && Object.defineProperty(target, key, r), r;
1277};
1278var __metadata$7 = (window && window.__metadata) || function (k, v) {
1279 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1280};
1281/** Builder for overlay position strategy. */
1282var OverlayPositionBuilder = (function () {
1283 function OverlayPositionBuilder(_viewportRuler) {
1284 this._viewportRuler = _viewportRuler;
1285 }
1286 /** Creates a global position strategy. */
1287 OverlayPositionBuilder.prototype.global = function () {
1288 return new GlobalPositionStrategy();
1289 };
1290 /** Creates a relative position strategy. */
1291 OverlayPositionBuilder.prototype.connectedTo = function (elementRef, originPos, overlayPos) {
1292 return new ConnectedPositionStrategy(elementRef, originPos, overlayPos, this._viewportRuler);
1293 };
1294 OverlayPositionBuilder = __decorate$7([
1295 _angular_core.Injectable(),
1296 __metadata$7('design:paramtypes', [ViewportRuler])
1297 ], OverlayPositionBuilder);
1298 return OverlayPositionBuilder;
1299}());
1300
1301/**
1302 * The OverlayContainer is the container in which all overlays will load.
1303 * It should be provided in the root component to ensure it is properly shared.
1304 */
1305var OverlayContainer = (function () {
1306 function OverlayContainer() {
1307 }
1308 /**
1309 * This method returns the overlay container element. It will lazily
1310 * create the element the first time it is called to facilitate using
1311 * the container in non-browser environments.
1312 * @returns {HTMLElement} the container element
1313 */
1314 OverlayContainer.prototype.getContainerElement = function () {
1315 if (!this._containerElement) {
1316 this._createContainer();
1317 }
1318 return this._containerElement;
1319 };
1320 /**
1321 * Create the overlay container element, which is simply a div
1322 * with the 'md-overlay-container' class on the document body.
1323 */
1324 OverlayContainer.prototype._createContainer = function () {
1325 var container = document.createElement('div');
1326 container.classList.add('md-overlay-container');
1327 document.body.appendChild(container);
1328 this._containerElement = container;
1329 };
1330 return OverlayContainer;
1331}());
1332
1333var __decorate$6 = (window && window.__decorate) || function (decorators, target, key, desc) {
1334 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1335 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1336 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1337 return c > 3 && r && Object.defineProperty(target, key, r), r;
1338};
1339var __metadata$6 = (window && window.__metadata) || function (k, v) {
1340 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1341};
1342/** Next overlay unique ID. */
1343var nextUniqueId = 0;
1344/** The default state for newly created overlays. */
1345var defaultState = new OverlayState();
1346/**
1347 * Service to create Overlays. Overlays are dynamically added pieces of floating UI, meant to be
1348 * used as a low-level building building block for other components. Dialogs, tooltips, menus,
1349 * selects, etc. can all be built using overlays. The service should primarily be used by authors
1350 * of re-usable components rather than developers building end-user applications.
1351 *
1352 * An overlay *is* a PortalHost, so any kind of Portal can be loaded into one.
1353 */
1354var Overlay = (function () {
1355 function Overlay(_overlayContainer, _componentFactoryResolver, _positionBuilder) {
1356 this._overlayContainer = _overlayContainer;
1357 this._componentFactoryResolver = _componentFactoryResolver;
1358 this._positionBuilder = _positionBuilder;
1359 }
1360 /**
1361 * Creates an overlay.
1362 * @param state State to apply to the overlay.
1363 * @returns A reference to the created overlay.
1364 */
1365 Overlay.prototype.create = function (state) {
1366 if (state === void 0) { state = defaultState; }
1367 return this._createOverlayRef(this._createPaneElement(), state);
1368 };
1369 /**
1370 * Returns a position builder that can be used, via fluent API,
1371 * to construct and configure a position strategy.
1372 */
1373 Overlay.prototype.position = function () {
1374 return this._positionBuilder;
1375 };
1376 /**
1377 * Creates the DOM element for an overlay and appends it to the overlay container.
1378 * @returns Promise resolving to the created element.
1379 */
1380 Overlay.prototype._createPaneElement = function () {
1381 var pane = document.createElement('div');
1382 pane.id = "md-overlay-" + nextUniqueId++;
1383 pane.classList.add('md-overlay-pane');
1384 this._overlayContainer.getContainerElement().appendChild(pane);
1385 return pane;
1386 };
1387 /**
1388 * Create a DomPortalHost into which the overlay content can be loaded.
1389 * @param pane The DOM element to turn into a portal host.
1390 * @returns A portal host for the given DOM element.
1391 */
1392 Overlay.prototype._createPortalHost = function (pane) {
1393 return new DomPortalHost(pane, this._componentFactoryResolver);
1394 };
1395 /**
1396 * Creates an OverlayRef for an overlay in the given DOM element.
1397 * @param pane DOM element for the overlay
1398 * @param state
1399 * @returns {OverlayRef}
1400 */
1401 Overlay.prototype._createOverlayRef = function (pane, state) {
1402 return new OverlayRef(this._createPortalHost(pane), pane, state);
1403 };
1404 Overlay = __decorate$6([
1405 _angular_core.Injectable(),
1406 __metadata$6('design:paramtypes', [OverlayContainer, _angular_core.ComponentFactoryResolver, OverlayPositionBuilder])
1407 ], Overlay);
1408 return Overlay;
1409}());
1410/** Providers for Overlay and its related injectables. */
1411var OVERLAY_PROVIDERS = [
1412 ViewportRuler,
1413 OverlayPositionBuilder,
1414 Overlay,
1415 OverlayContainer,
1416];
1417
1418var __decorate$5 = (window && window.__decorate) || function (decorators, target, key, desc) {
1419 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1420 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1421 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1422 return c > 3 && r && Object.defineProperty(target, key, r), r;
1423};
1424var __metadata$5 = (window && window.__metadata) || function (k, v) {
1425 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1426};
1427/** Default set of positions for the overlay. Follows the behavior of a dropdown. */
1428var defaultPositionList = [
1429 new ConnectionPositionPair({ originX: 'start', originY: 'bottom' }, { overlayX: 'start', overlayY: 'top' }),
1430 new ConnectionPositionPair({ originX: 'start', originY: 'top' }, { overlayX: 'start', overlayY: 'bottom' }),
1431];
1432/**
1433 * Directive applied to an element to make it usable as an origin for an Overlay using a
1434 * ConnectedPositionStrategy.
1435 */
1436var OverlayOrigin = (function () {
1437 function OverlayOrigin(_elementRef) {
1438 this._elementRef = _elementRef;
1439 }
1440 Object.defineProperty(OverlayOrigin.prototype, "elementRef", {
1441 get: function () {
1442 return this._elementRef;
1443 },
1444 enumerable: true,
1445 configurable: true
1446 });
1447 OverlayOrigin = __decorate$5([
1448 _angular_core.Directive({
1449 selector: '[overlay-origin]',
1450 exportAs: 'overlayOrigin',
1451 }),
1452 __metadata$5('design:paramtypes', [_angular_core.ElementRef])
1453 ], OverlayOrigin);
1454 return OverlayOrigin;
1455}());
1456/**
1457 * Directive to facilitate declarative creation of an Overlay using a ConnectedPositionStrategy.
1458 */
1459var ConnectedOverlayDirective = (function () {
1460 // TODO(jelbourn): inputs for size, scroll behavior, animation, etc.
1461 function ConnectedOverlayDirective(_overlay, templateRef, viewContainerRef) {
1462 this._overlay = _overlay;
1463 this._templatePortal = new TemplatePortal(templateRef, viewContainerRef);
1464 }
1465 Object.defineProperty(ConnectedOverlayDirective.prototype, "overlayRef", {
1466 get: function () {
1467 return this._overlayRef;
1468 },
1469 enumerable: true,
1470 configurable: true
1471 });
1472 /** TODO: internal */
1473 ConnectedOverlayDirective.prototype.ngOnInit = function () {
1474 this._createOverlay();
1475 };
1476 /** TODO: internal */
1477 ConnectedOverlayDirective.prototype.ngOnDestroy = function () {
1478 this._destroyOverlay();
1479 };
1480 /** Creates an overlay and attaches this directive's template to it. */
1481 ConnectedOverlayDirective.prototype._createOverlay = function () {
1482 if (!this.positions || !this.positions.length) {
1483 this.positions = defaultPositionList;
1484 }
1485 var overlayConfig = new OverlayState();
1486 overlayConfig.positionStrategy =
1487 this._overlay.position().connectedTo(this.origin.elementRef, { originX: this.positions[0].overlayX, originY: this.positions[0].originY }, { overlayX: this.positions[0].overlayX, overlayY: this.positions[0].overlayY });
1488 this._overlayRef = this._overlay.create(overlayConfig);
1489 this._overlayRef.attach(this._templatePortal);
1490 };
1491 /** Destroys the overlay created by this directive. */
1492 ConnectedOverlayDirective.prototype._destroyOverlay = function () {
1493 this._overlayRef.dispose();
1494 };
1495 __decorate$5([
1496 _angular_core.Input(),
1497 __metadata$5('design:type', OverlayOrigin)
1498 ], ConnectedOverlayDirective.prototype, "origin", void 0);
1499 __decorate$5([
1500 _angular_core.Input(),
1501 __metadata$5('design:type', Array)
1502 ], ConnectedOverlayDirective.prototype, "positions", void 0);
1503 ConnectedOverlayDirective = __decorate$5([
1504 _angular_core.Directive({
1505 selector: '[connected-overlay]'
1506 }),
1507 __metadata$5('design:paramtypes', [Overlay, _angular_core.TemplateRef, _angular_core.ViewContainerRef])
1508 ], ConnectedOverlayDirective);
1509 return ConnectedOverlayDirective;
1510}());
1511var OverlayModule = (function () {
1512 function OverlayModule() {
1513 }
1514 OverlayModule.forRoot = function () {
1515 return {
1516 ngModule: OverlayModule,
1517 providers: OVERLAY_PROVIDERS,
1518 };
1519 };
1520 OverlayModule = __decorate$5([
1521 _angular_core.NgModule({
1522 imports: [PortalModule],
1523 exports: [ConnectedOverlayDirective, OverlayOrigin],
1524 declarations: [ConnectedOverlayDirective, OverlayOrigin],
1525 }),
1526 __metadata$5('design:paramtypes', [])
1527 ], OverlayModule);
1528 return OverlayModule;
1529}());
1530
1531var __decorate$9 = (window && window.__decorate) || function (decorators, target, key, desc) {
1532 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1533 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1534 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1535 return c > 3 && r && Object.defineProperty(target, key, r), r;
1536};
1537var __metadata$9 = (window && window.__metadata) || function (k, v) {
1538 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1539};
1540var __param = (window && window.__param) || function (paramIndex, decorator) {
1541 return function (target, key) { decorator(target, key, paramIndex); }
1542};
1543var LIVE_ANNOUNCER_ELEMENT_TOKEN = new _angular_core.OpaqueToken('mdLiveAnnouncerElement');
1544var MdLiveAnnouncer = (function () {
1545 function MdLiveAnnouncer(elementToken) {
1546 // We inject the live element as `any` because the constructor signature cannot reference
1547 // browser globals (HTMLElement) on non-browser environments, since having a class decorator
1548 // causes TypeScript to preserve the constructor signature types.
1549 this._liveElement = elementToken || this._createLiveElement();
1550 }
1551 /**
1552 * @param message Message to be announced to the screenreader
1553 * @param politeness The politeness of the announcer element.
1554 */
1555 MdLiveAnnouncer.prototype.announce = function (message, politeness) {
1556 var _this = this;
1557 if (politeness === void 0) { politeness = 'polite'; }
1558 this._liveElement.textContent = '';
1559 // TODO: ensure changing the politeness works on all environments we support.
1560 this._liveElement.setAttribute('aria-live', politeness);
1561 // This 100ms timeout is necessary for some browser + screen-reader combinations:
1562 // - Both JAWS and NVDA over IE11 will not announce anything without a non-zero timeout.
1563 // - With Chrome and IE11 with NVDA or JAWS, a repeated (identical) message won't be read a
1564 // second time without clearing and then using a non-zero delay.
1565 // (using JAWS 17 at time of this writing).
1566 setTimeout(function () { return _this._liveElement.textContent = message; }, 100);
1567 };
1568 MdLiveAnnouncer.prototype._createLiveElement = function () {
1569 var liveEl = document.createElement('div');
1570 liveEl.classList.add('md-live-announcer');
1571 liveEl.setAttribute('aria-atomic', 'true');
1572 liveEl.setAttribute('aria-live', 'polite');
1573 document.body.appendChild(liveEl);
1574 return liveEl;
1575 };
1576 MdLiveAnnouncer = __decorate$9([
1577 _angular_core.Injectable(),
1578 __param(0, _angular_core.Optional()),
1579 __param(0, _angular_core.Inject(LIVE_ANNOUNCER_ELEMENT_TOKEN)),
1580 __metadata$9('design:paramtypes', [Object])
1581 ], MdLiveAnnouncer);
1582 return MdLiveAnnouncer;
1583}());
1584
1585var __extends$5 = (window && window.__extends) || function (d, b) {
1586 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
1587 function __() { this.constructor = d; }
1588 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
1589};
1590var __decorate$10 = (window && window.__decorate) || function (decorators, target, key, desc) {
1591 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1592 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1593 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1594 return c > 3 && r && Object.defineProperty(target, key, r), r;
1595};
1596var __metadata$10 = (window && window.__metadata) || function (k, v) {
1597 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1598};
1599/* Adjusts configuration of our gesture library, Hammer. */
1600var MdGestureConfig = (function (_super) {
1601 __extends$5(MdGestureConfig, _super);
1602 function MdGestureConfig() {
1603 _super.apply(this, arguments);
1604 /* List of new event names to add to the gesture support list */
1605 this.events = [
1606 'drag',
1607 'dragstart',
1608 'dragend',
1609 'dragright',
1610 'dragleft',
1611 'longpress',
1612 'slide',
1613 'slidestart',
1614 'slideend',
1615 'slideright',
1616 'slideleft'
1617 ];
1618 }
1619 /*
1620 * Builds Hammer instance manually to add custom recognizers that match the Material Design spec.
1621 *
1622 * Our gesture names come from the Material Design gestures spec:
1623 * https://www.google.com/design/spec/patterns/gestures.html#gestures-touch-mechanics
1624 *
1625 * More information on default recognizers can be found in Hammer docs:
1626 * http://hammerjs.github.io/recognizer-pan/
1627 * http://hammerjs.github.io/recognizer-press/
1628 *
1629 * TODO: Confirm threshold numbers with Material Design UX Team
1630 * */
1631 MdGestureConfig.prototype.buildHammer = function (element) {
1632 var mc = new Hammer(element);
1633 // Default Hammer Recognizers.
1634 var pan = new Hammer.Pan();
1635 var swipe = new Hammer.Swipe();
1636 var press = new Hammer.Press();
1637 // Notice that a HammerJS recognizer can only depend on one other recognizer once.
1638 // Otherwise the previous `recognizeWith` will be dropped.
1639 var slide = this._createRecognizer(pan, { event: 'slide', threshold: 0 }, swipe);
1640 var drag = this._createRecognizer(slide, { event: 'drag', threshold: 6 }, swipe);
1641 var longpress = this._createRecognizer(press, { event: 'longpress', time: 500 });
1642 // Overwrite the default `pan` event to use the swipe event.
1643 pan.recognizeWith(swipe);
1644 // Add customized gestures to Hammer manager
1645 mc.add([swipe, press, pan, drag, slide, longpress]);
1646 return mc;
1647 };
1648 /** Creates a new recognizer, without affecting the default recognizers of HammerJS */
1649 MdGestureConfig.prototype._createRecognizer = function (base, options) {
1650 var inheritances = [];
1651 for (var _i = 2; _i < arguments.length; _i++) {
1652 inheritances[_i - 2] = arguments[_i];
1653 }
1654 var recognizer = new base.constructor(options);
1655 inheritances.push(base);
1656 inheritances.forEach(function (item) { return recognizer.recognizeWith(item); });
1657 return recognizer;
1658 };
1659 MdGestureConfig = __decorate$10([
1660 _angular_core.Injectable(),
1661 __metadata$10('design:paramtypes', [])
1662 ], MdGestureConfig);
1663 return MdGestureConfig;
1664}(_angular_platformBrowser.HammerGestureConfig));
1665
1666var __decorate$11 = (window && window.__decorate) || function (decorators, target, key, desc) {
1667 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1668 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1669 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1670 return c > 3 && r && Object.defineProperty(target, key, r), r;
1671};
1672var __metadata$11 = (window && window.__metadata) || function (k, v) {
1673 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1674};
1675/**
1676 * Class to coordinate unique selection based on name.
1677 * Intended to be consumed as an Angular service.
1678 * This service is needed because native radio change events are only fired on the item currently
1679 * being selected, and we still need to uncheck the previous selection.
1680 *
1681 * This service does not *store* any IDs and names because they may change at any time, so it is
1682 * less error-prone if they are simply passed through when the events occur.
1683 */
1684var MdUniqueSelectionDispatcher = (function () {
1685 function MdUniqueSelectionDispatcher() {
1686 this._listeners = [];
1687 }
1688 /** Notify other items that selection for the given name has been set. */
1689 MdUniqueSelectionDispatcher.prototype.notify = function (id, name) {
1690 for (var _i = 0, _a = this._listeners; _i < _a.length; _i++) {
1691 var listener = _a[_i];
1692 listener(id, name);
1693 }
1694 };
1695 /** Listen for future changes to item selection. */
1696 MdUniqueSelectionDispatcher.prototype.listen = function (listener) {
1697 this._listeners.push(listener);
1698 };
1699 MdUniqueSelectionDispatcher = __decorate$11([
1700 _angular_core.Injectable(),
1701 __metadata$11('design:paramtypes', [])
1702 ], MdUniqueSelectionDispatcher);
1703 return MdUniqueSelectionDispatcher;
1704}());
1705
1706/**
1707 * Applies a CSS transform to an element, including browser-prefixed properties.
1708 * @param element
1709 * @param transformValue
1710 */
1711function applyCssTransform$1(element, transformValue) {
1712 // It's important to trim the result, because the browser will ignore the set operation
1713 // if the string contains only whitespace.
1714 var value = transformValue.trim();
1715 element.style.transform = value;
1716 element.style.webkitTransform = value;
1717}
1718
1719/**
1720 * Annotation Factory that allows HTML style boolean attributes. For example,
1721 * a field declared like this:
1722
1723 * @Directive({ selector: 'component' }) class MyComponent {
1724 * @Input() @BooleanFieldValueFactory() myField: boolean;
1725 * }
1726 *
1727 * You could set it up this way:
1728 * <component myField>
1729 * or:
1730 * <component myField="">
1731 * @deprecated
1732 */
1733function booleanFieldValueFactory() {
1734 return function booleanFieldValueMetadata(target, key) {
1735 var defaultValue = target[key];
1736 var localKey = "__md_private_symbol_" + key;
1737 target[localKey] = defaultValue;
1738 Object.defineProperty(target, key, {
1739 get: function () { return this[localKey]; },
1740 set: function (value) {
1741 this[localKey] = value != null && "" + value !== 'false';
1742 }
1743 });
1744 };
1745}
1746
1747// Due to a bug in the ChromeDriver, Angular 2 keyboard events are not triggered by `sendKeys`
1748// during E2E tests when using dot notation such as `(keydown.rightArrow)`. To get around this,
1749// we are temporarily using a single (keydown) handler.
1750// See: https://github.com/angular/angular/issues/9419
1751var UP_ARROW = 38;
1752var DOWN_ARROW = 40;
1753var RIGHT_ARROW = 39;
1754var LEFT_ARROW = 37;
1755var ENTER = 13;
1756var TAB = 9;
1757
1758var __decorate = (window && window.__decorate) || function (decorators, target, key, desc) {
1759 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1760 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1761 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1762 return c > 3 && r && Object.defineProperty(target, key, r), r;
1763};
1764var __metadata = (window && window.__metadata) || function (k, v) {
1765 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1766};
1767var MdCoreModule = (function () {
1768 function MdCoreModule() {
1769 }
1770 MdCoreModule.forRoot = function () {
1771 return {
1772 ngModule: MdCoreModule,
1773 providers: [MdLiveAnnouncer]
1774 };
1775 };
1776 MdCoreModule = __decorate([
1777 _angular_core.NgModule({
1778 imports: [MdLineModule, RtlModule, MdRippleModule, PortalModule, OverlayModule],
1779 exports: [MdLineModule, RtlModule, MdRippleModule, PortalModule, OverlayModule],
1780 }),
1781 __metadata('design:paramtypes', [])
1782 ], MdCoreModule);
1783 return MdCoreModule;
1784}());
1785
1786exports.MdCoreModule = MdCoreModule;
1787exports.Dir = Dir;
1788exports.RtlModule = RtlModule;
1789exports.Portal = Portal;
1790exports.BasePortalHost = BasePortalHost;
1791exports.ComponentPortal = ComponentPortal;
1792exports.TemplatePortal = TemplatePortal;
1793exports.PortalHostDirective = PortalHostDirective;
1794exports.TemplatePortalDirective = TemplatePortalDirective;
1795exports.PortalModule = PortalModule;
1796exports.DomPortalHost = DomPortalHost;
1797exports.Overlay = Overlay;
1798exports.OVERLAY_PROVIDERS = OVERLAY_PROVIDERS;
1799exports.OverlayContainer = OverlayContainer;
1800exports.OverlayRef = OverlayRef;
1801exports.OverlayState = OverlayState;
1802exports.ConnectedOverlayDirective = ConnectedOverlayDirective;
1803exports.OverlayOrigin = OverlayOrigin;
1804exports.OverlayModule = OverlayModule;
1805exports.MdGestureConfig = MdGestureConfig;
1806exports.MdRipple = MdRipple;
1807exports.MdRippleModule = MdRippleModule;
1808exports.MdLiveAnnouncer = MdLiveAnnouncer;
1809exports.LIVE_ANNOUNCER_ELEMENT_TOKEN = LIVE_ANNOUNCER_ELEMENT_TOKEN;
1810exports.MdUniqueSelectionDispatcher = MdUniqueSelectionDispatcher;
1811exports.MdLineModule = MdLineModule;
1812exports.MdLine = MdLine;
1813exports.MdLineSetter = MdLineSetter;
1814exports.applyCssTransform = applyCssTransform$1;
1815exports.MdError = MdError;
1816exports.BooleanFieldValue = booleanFieldValueFactory;
1817exports.ConnectedPositionStrategy = ConnectedPositionStrategy;
1818exports.ConnectionPositionPair = ConnectionPositionPair;
1819exports.UP_ARROW = UP_ARROW;
1820exports.DOWN_ARROW = DOWN_ARROW;
1821exports.RIGHT_ARROW = RIGHT_ARROW;
1822exports.LEFT_ARROW = LEFT_ARROW;
1823exports.ENTER = ENTER;
1824exports.TAB = TAB;
1825
1826Object.defineProperty(exports, '__esModule', { value: true });
1827
1828})));
\No newline at end of file