UNPKG

@angular/flex-layout

Version:
190 lines 8.06 kB
import 'rxjs/add/operator/map'; import 'rxjs/add/operator/filter'; import { extendObject } from '../../utils/object-extend'; export var KeyOptions = (function () { function KeyOptions(baseKey, defaultValue, inputKeys) { this.baseKey = baseKey; this.defaultValue = defaultValue; this.inputKeys = inputKeys; } return KeyOptions; }()); /** * ResponsiveActivation acts as a proxy between the MonitorMedia service (which emits mediaQuery * changes) and the fx API directives. The MQA proxies mediaQuery change events and notifies the * directive via the specified callback. * * - The MQA also determines which directive property should be used to determine the * current change 'value'... BEFORE the original `onMediaQueryChanges()` method is called. * - The `ngOnDestroy()` method is also head-hooked to enable auto-unsubscribe from the * MediaQueryServices. * * NOTE: these interceptions enables the logic in the fx API directives to remain terse and clean. */ export var ResponsiveActivation = (function () { /** * Constructor */ function ResponsiveActivation(_options, _mediaMonitor, _onMediaChanges) { this._options = _options; this._mediaMonitor = _mediaMonitor; this._onMediaChanges = _onMediaChanges; this._subscribers = []; this._subscribers = this._configureChangeObservers(); } Object.defineProperty(ResponsiveActivation.prototype, "mediaMonitor", { /** * Accessor to the DI'ed directive property * Each directive instance has a reference to the MediaMonitor which is * used HERE to subscribe to mediaQuery change notifications. */ get: function () { return this._mediaMonitor; }, enumerable: true, configurable: true }); Object.defineProperty(ResponsiveActivation.prototype, "activatedInputKey", { /** * Determine which directive @Input() property is currently active (for the viewport size): * The key must be defined (in use) or fallback to the 'closest' overlapping property key * that is defined; otherwise the default property key will be used. * e.g. * if `<div fxHide fxHide.gt-sm="false">` is used but the current activated mediaQuery alias * key is `.md` then `.gt-sm` should be used instead */ get: function () { return this._activatedInputKey || this._options.baseKey; }, enumerable: true, configurable: true }); Object.defineProperty(ResponsiveActivation.prototype, "activatedInput", { /** * Get the currently activated @Input value or the fallback default @Input value */ get: function () { var key = this.activatedInputKey; return this.hasKeyValue(key) ? this._lookupKeyValue(key) : this._options.defaultValue; }, enumerable: true, configurable: true }); /** * Fast validator for presence of attribute on the host element */ ResponsiveActivation.prototype.hasKeyValue = function (key) { var value = this._options.inputKeys[key]; return typeof value !== 'undefined'; }; /** * Remove interceptors, restore original functions, and forward the onDestroy() call */ ResponsiveActivation.prototype.destroy = function () { this._subscribers.forEach(function (link) { link.unsubscribe(); }); this._subscribers = []; }; /** * For each *defined* API property, register a callback to `_onMonitorEvents( )` * Cache 1..n subscriptions for internal auto-unsubscribes when the the directive destructs */ ResponsiveActivation.prototype._configureChangeObservers = function () { var _this = this; var subscriptions = []; this._buildRegistryMap().forEach(function (bp) { if (_this._keyInUse(bp.key)) { // Inject directive default property key name: to let onMediaChange() calls // know which property is being triggered... var buildChanges = function (change) { change.property = _this._options.baseKey; return change; }; subscriptions.push(_this.mediaMonitor.observe(bp.alias) .map(buildChanges) .subscribe(function (change) { _this._onMonitorEvents(change); })); } }); return subscriptions; }; /** * Build mediaQuery key-hashmap; only for the directive properties that are actually defined/used * in the HTML markup */ ResponsiveActivation.prototype._buildRegistryMap = function () { var _this = this; return this.mediaMonitor.breakpoints .map(function (bp) { return extendObject({}, bp, { baseKey: _this._options.baseKey, key: _this._options.baseKey + bp.suffix // e.g. layoutGtSm, layoutMd, layoutGtLg }); }) .filter(function (bp) { return _this._keyInUse(bp.key); }); }; /** * Synchronizes change notifications with the current mq-activated @Input and calculates the * mq-activated input value or the default value */ ResponsiveActivation.prototype._onMonitorEvents = function (change) { if (change.property == this._options.baseKey) { change.value = this._calculateActivatedValue(change); this._onMediaChanges(change); } }; /** * Has the key been specified in the HTML markup and thus is intended * to participate in activation processes. */ ResponsiveActivation.prototype._keyInUse = function (key) { return this._lookupKeyValue(key) !== undefined; }; /** * Map input key associated with mediaQuery activation to closest defined input key * then return the values associated with the targeted input property * * !! change events may arrive out-of-order (activate before deactivate) * so make sure the deactivate is used ONLY when the keys match * (since a different activate may be in use) */ ResponsiveActivation.prototype._calculateActivatedValue = function (current) { var currentKey = this._options.baseKey + current.suffix; // e.g. suffix == 'GtSm', var newKey = this._activatedInputKey; // e.g. newKey == hideGtSm newKey = current.matches ? currentKey : ((newKey == currentKey) ? null : newKey); this._activatedInputKey = this._validateInputKey(newKey); return this.activatedInput; }; /** * For the specified input property key, validate it is defined (used in the markup) * If not see if a overlapping mediaQuery-related input key fallback has been defined * * NOTE: scans in the order defined by activeOverLaps (largest viewport ranges -> smallest ranges) */ ResponsiveActivation.prototype._validateInputKey = function (inputKey) { var _this = this; var items = this.mediaMonitor.activeOverlaps; var isMissingKey = function (key) { return !_this._keyInUse(key); }; if (isMissingKey(inputKey)) { items.some(function (bp) { var key = _this._options.baseKey + bp.suffix; if (!isMissingKey(key)) { inputKey = key; return true; // exit .some() } return false; }); } return inputKey; }; /** * Get the value (if any) for the directive instances @Input property (aka key) */ ResponsiveActivation.prototype._lookupKeyValue = function (key) { return this._options.inputKeys[key]; }; return ResponsiveActivation; }()); //# sourceMappingURL=/usr/local/google/home/tinagao/WebstormProjects/caretaker/flex-layout/src/lib/flexbox/responsive/responsive-activation.js.map