UNPKG

@exadel/esl

Version:

Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components

102 lines (101 loc) 4.71 kB
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 { ExportNs } from '../../esl-utils/environment/export-ns'; import { ESLScreenDPR } from './common/screen-dpr'; import { ESLScreenBreakpoints } from './common/screen-breakpoint'; import { ESLEnvShortcuts } from './common/env-shortcuts'; import { ALL, NOT_ALL } from './conditions/media-query-const'; import { MediaQueryCondition } from './conditions/media-query-condition'; 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(ESLMediaQuery_1.parseSimpleQuery); return new MediaQueryConjunction(conditions); }); return new MediaQueryDisjunction(conjunctions).optimize(); } /** Preprocess simple query term by applying replacers and shortcuts rules */ static preprocess(term) { if (!this.SHORTCUT_PATTERN.test(term)) return term; const shortcut = term.trim().substring(1).toLowerCase(); for (const replacer of this._preprocessors) { const result = replacer.process(shortcut); if (typeof result === 'string') return result; if (typeof result === 'boolean') return result ? 'all' : 'not all'; } return term; } /** Creates simple {@link ESLMediaQuery} condition */ static parseSimpleQuery(term) { const query = term.replace(/^\s*not\s+/, ''); const queryInverted = query !== term; const processedQuery = ESLMediaQuery_1.preprocess(query); const sanitizedQuery = processedQuery.replace(/^\s*not\s+/, ''); const resultInverted = processedQuery !== sanitizedQuery; const invert = queryInverted !== resultInverted; if (ALL.eq(sanitizedQuery)) return invert ? NOT_ALL : ALL; if (NOT_ALL.eq(sanitizedQuery)) return invert ? ALL : NOT_ALL; return new MediaQueryCondition(sanitizedQuery, invert); } }; /** 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); ESLMediaQuery.use(ESLEnvShortcuts);