| import { CommonModule } from '@angular/common'; |
| import { BehaviorSubject, fromEvent } from 'rxjs'; |
| import { Injectable, NgZone, SkipSelf, Optional, Directive, ElementRef, Input, Renderer2, NgModule } from '@angular/core'; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc |
| */ |
| class TdMediaService { |
| /** |
| * @param {?} _ngZone |
| */ |
| constructor(_ngZone) { |
| this._ngZone = _ngZone; |
| this._resizing = false; |
| this._queryMap = new Map(); |
| this._querySources = {}; |
| this._queryObservables = {}; |
| this._queryMap.set('xs', '(max-width: 599px)'); |
| this._queryMap.set('gt-xs', '(min-width: 600px)'); |
| this._queryMap.set('sm', '(min-width: 600px) and (max-width: 959px)'); |
| this._queryMap.set('gt-sm', '(min-width: 960px)'); |
| this._queryMap.set('md', '(min-width: 960px) and (max-width: 1279px)'); |
| this._queryMap.set('gt-md', '(min-width: 1280px)'); |
| this._queryMap.set('lg', '(min-width: 1280px) and (max-width: 1919px)'); |
| this._queryMap.set('gt-lg', '(min-width: 1920px)'); |
| this._queryMap.set('xl', '(min-width: 1920px)'); |
| this._queryMap.set('landscape', '(orientation: landscape)'); |
| this._queryMap.set('portrait', '(orientation: portrait)'); |
| this._queryMap.set('print', 'print'); |
| this._resizing = false; |
| // we make sure that the resize checking happend outside of Angular since it happens often |
| this._globalSubscription = this._ngZone.runOutsideAngular(() => { |
| return fromEvent(window, 'resize').subscribe(() => { |
| // way to prevent the resize event from triggering the match media if there is already one event running already. |
| if (!this._resizing) { |
| this._resizing = true; |
| setTimeout(() => { |
| this._onResize(); |
| this._resizing = false; |
| }, 100); |
| } |
| }); |
| }); |
| } |
| /** |
| * Deregisters a query so its stops being notified or used. |
| * @param {?} query |
| * @return {?} |
| */ |
| deregisterQuery(query) { |
| if (this._queryMap.get(query.toLowerCase())) { |
| query = this._queryMap.get(query.toLowerCase()); |
| } |
| this._querySources[query].unsubscribe(); |
| delete this._querySources[query]; |
| delete this._queryObservables[query]; |
| } |
| /** |
| * Used to evaluate whether a given media query is true or false given the current device's screen / window size. |
| * @param {?} query |
| * @return {?} |
| */ |
| query(query) { |
| if (this._queryMap.get(query.toLowerCase())) { |
| query = this._queryMap.get(query.toLowerCase()); |
| } |
| return this._ngZone.run(() => { |
| return matchMedia(query).matches; |
| }); |
| } |
| /** |
| * Registers a media query and returns an [Observable] that will re-evaluate and |
| * return if the given media query matches on window resize. |
| * Note: don't forget to unsubscribe from [Observable] when finished watching. |
| * @param {?} query |
| * @return {?} |
| */ |
| registerQuery(query) { |
| if (this._queryMap.get(query.toLowerCase())) { |
| query = this._queryMap.get(query.toLowerCase()); |
| } |
| if (!this._querySources[query]) { |
| this._querySources[query] = new BehaviorSubject(matchMedia(query).matches); |
| this._queryObservables[query] = this._querySources[query].asObservable(); |
| } |
| return this._queryObservables[query]; |
| } |
| /** |
| * Trigger a match media event on all subscribed observables. |
| * @return {?} |
| */ |
| broadcast() { |
| this._onResize(); |
| } |
| /** |
| * @return {?} |
| */ |
| _onResize() { |
| for (let query in this._querySources) { |
| this._ngZone.run(() => { |
| this._matchMediaTrigger(query); |
| }); |
| } |
| } |
| /** |
| * @param {?} query |
| * @return {?} |
| */ |
| _matchMediaTrigger(query) { |
| this._querySources[query].next(matchMedia(query).matches); |
| } |
| } |
| TdMediaService.decorators = [ |
| { type: Injectable } |
| ]; |
| /** @nocollapse */ |
| TdMediaService.ctorParameters = () => [ |
| { type: NgZone } |
| ]; |
| /** |
| * @param {?} parent |
| * @param {?} ngZone |
| * @return {?} |
| */ |
| function MEDIA_PROVIDER_FACTORY(parent, ngZone) { |
| return parent || new TdMediaService(ngZone); |
| } |
| /** @type {?} */ |
| const MEDIA_PROVIDER = { |
| // If there is already a service available, use that. Otherwise, provide a new one. |
| provide: TdMediaService, |
| deps: [[new Optional(), new SkipSelf(), TdMediaService], NgZone], |
| useFactory: MEDIA_PROVIDER_FACTORY, |
| }; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc |
| */ |
| class TdMediaToggleDirective { |
| /** |
| * @param {?} _renderer |
| * @param {?} _elementRef |
| * @param {?} _mediaService |
| */ |
| constructor(_renderer, _elementRef, _mediaService) { |
| this._renderer = _renderer; |
| this._elementRef = _elementRef; |
| this._mediaService = _mediaService; |
| this._matches = false; |
| this._attributes = {}; |
| this._styles = {}; |
| this._classes = []; |
| } |
| /** |
| * tdMediaToggle: string |
| * Media query used to evaluate screen/window size. |
| * Toggles attributes, classes and styles if media query is matched. |
| * @param {?} query |
| * @return {?} |
| */ |
| set query(query) { |
| if (!query) { |
| throw new Error('Query needed for [tdMediaToggle] directive.'); |
| } |
| this._query = query; |
| } |
| /** |
| * mediaAttributes: {[key: string]: string} |
| * Attributes to be toggled when media query matches. |
| * @param {?} attributes |
| * @return {?} |
| */ |
| set attributes(attributes) { |
| this._attributes = attributes; |
| } |
| /** |
| * mediaClasses: string[] |
| * CSS Classes to be toggled when media query matches. |
| * @param {?} classes |
| * @return {?} |
| */ |
| set classes(classes) { |
| this._classes = classes; |
| } |
| /** |
| * mediaStyles: {[key: string]: string} |
| * CSS Styles to be toggled when media query matches. |
| * @param {?} styles |
| * @return {?} |
| */ |
| set styles(styles) { |
| this._styles = styles; |
| } |
| /** |
| * @return {?} |
| */ |
| ngOnInit() { |
| this._mediaChange(this._mediaService.query(this._query)); |
| this._subscription = this._mediaService.registerQuery(this._query).subscribe((matches) => { |
| this._mediaChange(matches); |
| }); |
| } |
| /** |
| * @return {?} |
| */ |
| ngOnDestroy() { |
| if (this._subscription) { |
| this._subscription.unsubscribe(); |
| } |
| } |
| /** |
| * @param {?} matches |
| * @return {?} |
| */ |
| _mediaChange(matches) { |
| this._matches = matches; |
| this._changeAttributes(); |
| this._changeClasses(); |
| this._changeStyles(); |
| } |
| /** |
| * @return {?} |
| */ |
| _changeAttributes() { |
| for (let attr in this._attributes) { |
| if (this._matches) { |
| this._renderer.setAttribute(this._elementRef.nativeElement, attr, this._attributes[attr]); |
| } |
| else { |
| this._renderer.removeAttribute(this._elementRef.nativeElement, attr); |
| } |
| } |
| } |
| /** |
| * @return {?} |
| */ |
| _changeClasses() { |
| this._classes.forEach((className) => { |
| if (this._matches) { |
| this._renderer.addClass(this._elementRef.nativeElement, className); |
| } |
| else { |
| this._renderer.removeClass(this._elementRef.nativeElement, className); |
| } |
| }); |
| } |
| /** |
| * @return {?} |
| */ |
| _changeStyles() { |
| for (let style in this._styles) { |
| if (this._matches) { |
| this._renderer.setStyle(this._elementRef.nativeElement, style, this._styles[style]); |
| } |
| else { |
| this._renderer.removeStyle(this._elementRef.nativeElement, style); |
| } |
| } |
| } |
| } |
| TdMediaToggleDirective.decorators = [ |
| { type: Directive, args: [{ |
| selector: '[tdMediaToggle]', |
| },] } |
| ]; |
| /** @nocollapse */ |
| TdMediaToggleDirective.ctorParameters = () => [ |
| { type: Renderer2 }, |
| { type: ElementRef }, |
| { type: TdMediaService } |
| ]; |
| TdMediaToggleDirective.propDecorators = { |
| query: [{ type: Input, args: ['tdMediaToggle',] }], |
| attributes: [{ type: Input, args: ['mediaAttributes',] }], |
| classes: [{ type: Input, args: ['mediaClasses',] }], |
| styles: [{ type: Input, args: ['mediaStyles',] }] |
| }; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc |
| */ |
| /** @type {?} */ |
| const TD_MEDIA = [ |
| TdMediaToggleDirective, |
| ]; |
| class CovalentMediaModule { |
| } |
| CovalentMediaModule.decorators = [ |
| { type: NgModule, args: [{ |
| imports: [ |
| CommonModule, |
| ], |
| declarations: [ |
| TD_MEDIA, |
| ], |
| exports: [ |
| TD_MEDIA, |
| ], |
| providers: [ |
| MEDIA_PROVIDER, |
| ], |
| },] } |
| ]; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc |
| */ |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc |
| */ |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc |
| */ |
| |
| export { CovalentMediaModule, TdMediaToggleDirective, MEDIA_PROVIDER_FACTORY, TdMediaService, MEDIA_PROVIDER }; |
| |
| //# sourceMappingURL=covalent-core-media.js.map |