@exadel/esl
Version:
Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components
94 lines (93 loc) • 4.36 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
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;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var ESLMediaQuery_1;
import { memoize } from '../../esl-utils/decorators';
import { isObject } from '../../esl-utils/misc/object/types';
import { ExportNs } from '../../esl-utils/environment/export-ns';
import { ESLScreenDPR } from './common/screen-dpr';
import { ESLScreenBreakpoints } from './common/screen-breakpoint';
import { ESLMediaShortcuts } from './common/media-shortcuts';
import { ALL, NOT_ALL } from './conditions/media-query-const';
import { MediaQueryCondition } from './conditions/media-query-condition';
import { MediaQueryNegation } from './conditions/media-query-negation';
import { MediaQueryConjunction, MediaQueryDisjunction } from './conditions/media-query-containers';
/**
* ESL Media Query
* @implements EventTarget
* Provides special media condition syntax - ESLMediaQuery
* @author Alexey Stsefanovich (ala'n), Yuliya Adamskaya, Natallia Harshunova
*
* Utility to support extended MediaQuery features
* Supports
* - CSS MediaQuery matching check
* - DPR display queries (`@x1|@x2|@x3`)
* - Registered screen default sizes (breakpoints) shortcuts (`@[-|+](XS|SM|MD|LG|XL)`)
* - Device and browser shortcuts (`@MOBILE|@DESKTOP|@IE`)
* - Custom static shortcuts and custom query preprocessors
* - `not` logic operation (can have multiple not operators before any term of the query)
* - `or` or `,` logical operator (have a lowest priority)
* - Query matching change listeners
* - Implements {@link EventTarget}, compatible with {@link ESLEventListener}
*
* Building query process:
*
* [Building query logical tree] - [preprocess nodes queries] - [building native MediaQueryList nodes] - [query tree optimization]
*/
let ESLMediaQuery = ESLMediaQuery_1 = class ESLMediaQuery {
/** Adds {@link IMediaQueryPreprocessor} instance for query preprocessing step */
static use(preprocessor) {
this._preprocessors.unshift(preprocessor);
return this;
}
/** Cached method to create {@link ESLMediaQuery} condition instance from query string */
static for(query) {
return ESLMediaQuery_1.from(query);
}
/** Creates {@link ESLMediaQuery} condition instance from query string */
static from(query) {
const conjunctions = query.split(/\sor\s|,/).map((term) => {
const conditions = term.split(/\sand\s/).map(this.parseSingleQuery, this);
return new MediaQueryConjunction(conditions);
});
return new MediaQueryDisjunction(conjunctions).optimize();
}
/** Creates simple {@link ESLMediaQuery} condition */
static parseSingleQuery(term) {
// Wrap `not` operator
const query = term.replace(/^\s*not\s+/, '');
if (query !== term)
return new MediaQueryNegation(this.parseSingleQuery(query));
// Check for shortcuts
if (this.SHORTCUT_PATTERN.test(term)) {
const shortcut = term.trim().substring(1).toLowerCase();
for (const replacer of this._preprocessors) {
const result = replacer.process(shortcut);
if (isObject(result))
return result;
}
return ESLMediaShortcuts.process(shortcut);
}
// Otherwise, wrap as MediaQueryCondition
return new MediaQueryCondition(term.trim());
}
};
/** Always true condition */
ESLMediaQuery.ALL = ALL;
/** Always false condition */
ESLMediaQuery.NOT_ALL = NOT_ALL;
ESLMediaQuery.SHORTCUT_PATTERN = /@([a-z0-9.+-]+)/i;
ESLMediaQuery._preprocessors = [];
__decorate([
memoize()
], ESLMediaQuery, "for", null);
ESLMediaQuery = ESLMediaQuery_1 = __decorate([
ExportNs('MediaQuery')
], ESLMediaQuery);
export { ESLMediaQuery };
// Register otb preprocessors
ESLMediaQuery.use(ESLScreenDPR);
ESLMediaQuery.use(ESLScreenBreakpoints);