diff --git a/.eslintrc.yml b/.eslintrc.yml index eaf170754..0ed717b16 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -51,3 +51,6 @@ rules: 'editorconfig/eol-last': warn # Require no trailing spaces 'editorconfig/no-trailing-spaces': warn + + # Exclude migration rules for 5.0.0-beta.24 revision + '@exadel/esl/deprecated-4/media-rule-list-parse': off diff --git a/src/modules/esl-media-query/README.md b/src/modules/esl-media-query/README.md index 1f990f131..e8390f0ef 100644 --- a/src/modules/esl-media-query/README.md +++ b/src/modules/esl-media-query/README.md @@ -204,20 +204,21 @@ ESLMediaRuleList.parse('1 | @XS => 2', String); // the same as sample above ESLMediaRuleList.parse('1 | @XS => 2', Number); // first query from the sample above that store numeric values ESLMediaRuleList.parse('@XS => {option: 1} | @+SM => {option: 2}', ESLMediaRuleList.OBJECT_PARSER); // second query from the sample above with an object payloads ESLMediaRuleList.parse('@XS => {option: 1} | @+SM => {option: 2}', evaluate); // the same as the sample above +ESLMediaRuleList.parse('1|2|3|4|5', '@xs|@sm|@md|@lg|@xl') // parses tuple payloads +ESLMediaRuleList.parse('@mqAlt1 => value1| @mqAlt2 => value2', '@mq1|@mq2'); // parses first argument as an arrow syntax without default tuple consideration. // Tupple parsing ESLMediaRuleList.parseTuple('@xs|@sm|@md|@lg|@xl', '1|2|3|4|5') // String payload example ESLMediaRuleList.parseTuple('@xs|@sm|@md|@lg|@xl', '1|2|3|4|5', Number) // Numeric payload sample ``` -**Note**: Method `ESLMediaRuleList.parse` is deprecated, and will be reintroduced in ESL v5.0.0 with a different signature. For now use `ESLMediaRuleList.parseTuple` or `ESLMediaRuleList.parseQuery` instead. #### ESLMediaRuleList API -- `ESLMediaRuleList.parse(ruleset: string)` - parse media ruleset defined with classic syntax mentioned in section above. -Rules separated by `|` symbol, query and value separated by `=>` for each rule, query is optional. +- `ESLMediaRuleList.parseTuple(queries: string, values: string)` - parse media ruleset from tuple of queries and values, all separated via `|` symbol. -- `ESLMediaRuleList.parseTuple(queries: string, values: string)` - parse media ruleset from tuple of -queries and values, all separated via `|` symbol +- `ESLMediaRuleList.parseQuery(ruleset: string)` - parse media ruleset defined with syntax, where query and value are a single argument separated by `=>` for each rule. + +- `ESLMediaRuleList.parse(values: string, queries: string)` - parse media ruleset adaptively. Method can support both notations with a ruleset from tuple of queries and values, all separated via `|` symbol, and can parse cases where query syntax with rules separated by `=>` is being used as a value for a tuple. - `ESLMediaRuleList.prototype.rules` - array of rules that defines `ESLMediaRuleList` object - `ESLMediaRuleList.prototype.active` - array of active (matched) rules diff --git a/src/modules/esl-media-query/core/esl-media-rule-list.ts b/src/modules/esl-media-query/core/esl-media-rule-list.ts index 1831102f1..0b8bd7b29 100644 --- a/src/modules/esl-media-query/core/esl-media-rule-list.ts +++ b/src/modules/esl-media-query/core/esl-media-rule-list.ts @@ -35,9 +35,7 @@ export class ESLMediaRuleList extends SyntheticEventTarget { public static OBJECT_PARSER = (val: string): U | undefined => evaluate(val); /** - * @deprecated Method will be reintroduced in v5.0.0 with a different signature. For now use ESLMediaRuleList.parseQuery instead - * - * Creates `ESLMediaRuleList` from string query representation + * Creates {@link ESLMediaRuleList} from string query representation * Expect serialized {@link ESLMediaRule}s separated by '|' * Uses exact strings as rule list values * @@ -45,9 +43,7 @@ export class ESLMediaRuleList extends SyntheticEventTarget { */ public static parse(query: string): ESLMediaRuleList; /** - * @deprecated Method will be reintroduced in v5.0.0 with a different signature. For now use ESLMediaRuleList.parseQuery instead - * - * Creates `ESLMediaRuleList` from string query representation. + * Creates {@link ESLMediaRuleList} from string query representation. * Expect serialized {@link ESLMediaRule}s separated by '|' * * @param query - query string @@ -55,26 +51,22 @@ export class ESLMediaRuleList extends SyntheticEventTarget { */ public static parse(query: string, parser: RulePayloadParser): ESLMediaRuleList; /** - * @deprecated Method will be reintroduced in v5.0.0 with a different signature. For now use ESLMediaRuleList.parseTuple instead - - * Creates `ESLMediaRuleList` from two strings with conditions and values sequences + * Creates {@link ESLMediaRuleList} from two strings with conditions and values sequences * - * @param mask - media conditions tuple string (uses '|' as separator) * @param values - values tuple string (uses '|' as separator) + * @param mask - media conditions tuple string (uses '|' as separator) * * @example * ```ts * ESLMediaRuleList.parse('@XS|@SM|@MD|@LG|@XL', '1|2|3|4|5') * ``` */ - public static parse(mask: string, values: string): ESLMediaRuleList; + public static parse(values: string, mask: string): ESLMediaRuleList; /** - * @deprecated Method will be reintroduced in v5.0.0 with a different signature. For now use ESLMediaRuleList.parseTuple instead - * - * Creates `ESLMediaRuleList` from two strings with conditions and values sequences + * Creates {@link ESLMediaRuleList} from two strings with conditions and values sequences * - * @param mask - media conditions tuple string (uses '|' as separator) * @param values - values tuple string (uses '|' as separator) + * @param mask - media conditions tuple string (uses '|' as separator) * @param parser - value parser function * * @example @@ -82,17 +74,16 @@ export class ESLMediaRuleList extends SyntheticEventTarget { * ESLMediaRuleList.parseTuple('@XS|@SM|@MD|@LG|@XL', '1|2|3|4|5', Number) * ``` */ - public static parse(mask: string, values: string, parser: RulePayloadParser): ESLMediaRuleList; + public static parse(values: string, mask: string, parser: RulePayloadParser): ESLMediaRuleList; public static parse(query: string, ...common: (string | RulePayloadParser)[]): ESLMediaRuleList { const parser: RulePayloadParser = typeof common[common.length - 1] === 'function' ? common.pop() as any : String; - const value = common.pop(); - return typeof value === 'string' ? - ESLMediaRuleList.parseTuple(query, value, parser) : - ESLMediaRuleList.parseQuery(query, parser); + const mask = common.pop(); + if (query.includes('=>') || typeof mask !== 'string') return ESLMediaRuleList.parseQuery(query, parser); + return ESLMediaRuleList.parseTuple(mask, query, parser); } /** - * Creates `ESLMediaRuleList` from string query representation + * Creates {@link ESLMediaRuleList} from string query representation * Uses exact strings as rule list values * @param query - query string */ @@ -111,7 +102,7 @@ export class ESLMediaRuleList extends SyntheticEventTarget { } /** - * Creates `ESLMediaRuleList` from two strings with conditions and values sequences + * Creates {@link ESLMediaRuleList} from two strings with conditions and values sequences * * @param mask - media conditions tuple string (uses '|' as separator) * @param values - values tuple string (uses '|' as separator) @@ -123,7 +114,7 @@ export class ESLMediaRuleList extends SyntheticEventTarget { */ public static parseTuple(mask: string, values: string): ESLMediaRuleList; /** - * Creates `ESLMediaRuleList` from two strings with conditions and values sequences + * Creates {@link ESLMediaRuleList} from two strings with conditions and values sequences * * @param mask - media conditions tuple string (uses '|' as separator) * @param values - values tuple string (uses '|' as separator) @@ -216,7 +207,7 @@ export class ESLMediaRuleList extends SyntheticEventTarget { /** @returns serialized {@link ESLMediaRuleList} object representation*/ public override toString(): string { - return this.rules.join('|'); + return this.rules.join(' | '); } } diff --git a/src/modules/esl-media-query/test/esl-media-rule-list.test.ts b/src/modules/esl-media-query/test/esl-media-rule-list.test.ts index cce13af4d..192ad729b 100644 --- a/src/modules/esl-media-query/test/esl-media-rule-list.test.ts +++ b/src/modules/esl-media-query/test/esl-media-rule-list.test.ts @@ -178,4 +178,29 @@ describe('ESLMediaRuleList', () => { expect(() => ESLMediaRuleList.parseTuple('@xs', '1|2|3')).toThrowError(); }); }); + + describe('Adaptive cases parsing', () => { + test.each([ + // [ [.. Call Args], 'Canonical form'] + [['1'], 'all => 1'], + + // Tuples + [['1', '@-sm'], '(max-width: 991px) => 1'], + [['1', '@+sm'], '(min-width: 768px) => 1'], + [['1', '@sm'], '(min-width: 768px) and (max-width: 991px) => 1'], + [['0 | 1', '@+xs | @+sm'], '(min-width: 1px) => 0 | (min-width: 768px) => 1'], + [['1|2|3', 'all|@sm|@md'], 'all => 1 | (min-width: 768px) and (max-width: 991px) => 2 | (min-width: 992px) and (max-width: 1199px) => 3'], + [['f=|s>|t<', 'all | @-xs | @-sm',], 'all => f= | (max-width: 767px) => s> | (max-width: 991px) => t<'], + + // Arrow syntax + [['0 | (min-width: 100px) => 1 | (min-width: 200px) => 2'], 'all => 0 | (min-width: 100px) => 1 | (min-width: 200px) => 2'], + [['1 | @+sm => 2 | @+md => 3'], 'all => 1 | (min-width: 768px) => 2 | (min-width: 992px) => 3'], + [['1 | @+sm => 2', '@sm'], 'all => 1 | (min-width: 768px) => 2'], + [['1 | screen and @sm => 2'], 'all => 1 | screen and (min-width: 768px) and (max-width: 991px) => 2'], + [['1 | @-xs or @+md => 2'], 'all => 1 | (max-width: 767px), (min-width: 992px) => 2'], + [['@-xs => hello | @+sm => world'], '(max-width: 767px) => hello | (min-width: 768px) => world'], + ])('Should correctly parse "%s" with media condition "%s"', (params: any[], canonical: string) => { + expect(ESLMediaRuleList.parse.apply(null, params).toString()).toBe(canonical); + }); + }); });