Repository: exadel-inc/esl
Pull request #240 (2021-06-08 11:07:38)

refactor: esl-media-query cleanup for API and usages
BREAKING CHANGE: 
ESLMediaQuery API no longer provide meta information like DPR or type of expected device

Preparation for #232 updates.

github-actions[bot]: ****CLA Assistant Lite bot**** All contributors have signed the CLA  ✍️ 

Patch:
diff --git a/package-lock.json b/package-lock.json
index 602208350..b5a8ab500 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1974,13 +1974,13 @@
       "integrity": "sha512-Nqo3HMPFPcNyZ7HNFZJjpH+N4yXqpxBItG+41e7nL9zednovMRZMXWj36CctSznbBcbj6ucvkJDo5iZ8SKqLIw=="
     },
     "@typescript-eslint/eslint-plugin": {
-      "version": "4.26.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.0.tgz",
-      "integrity": "sha512-yA7IWp+5Qqf+TLbd8b35ySFOFzUfL7i+4If50EqvjT6w35X8Lv0eBHb6rATeWmucks37w+zV+tWnOXI9JlG6Eg==",
+      "version": "4.26.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.1.tgz",
+      "integrity": "sha512-aoIusj/8CR+xDWmZxARivZjbMBQTT9dImUtdZ8tVCVRXgBUuuZyM5Of5A9D9arQPxbi/0rlJLcuArclz/rCMJw==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/experimental-utils": "4.26.0",
-        "@typescript-eslint/scope-manager": "4.26.0",
+        "@typescript-eslint/experimental-utils": "4.26.1",
+        "@typescript-eslint/scope-manager": "4.26.1",
         "debug": "^4.3.1",
         "functional-red-black-tree": "^1.0.1",
         "lodash": "^4.17.21",
@@ -2016,15 +2016,15 @@
       }
     },
     "@typescript-eslint/experimental-utils": {
-      "version": "4.26.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.26.0.tgz",
-      "integrity": "sha512-TH2FO2rdDm7AWfAVRB5RSlbUhWxGVuxPNzGT7W65zVfl8H/WeXTk1e69IrcEVsBslrQSTDKQSaJD89hwKrhdkw==",
+      "version": "4.26.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.26.1.tgz",
+      "integrity": "sha512-sQHBugRhrXzRCs9PaGg6rowie4i8s/iD/DpTB+EXte8OMDfdCG5TvO73XlO9Wc/zi0uyN4qOmX9hIjQEyhnbmQ==",
       "dev": true,
       "requires": {
         "@types/json-schema": "^7.0.7",
-        "@typescript-eslint/scope-manager": "4.26.0",
-        "@typescript-eslint/types": "4.26.0",
-        "@typescript-eslint/typescript-estree": "4.26.0",
+        "@typescript-eslint/scope-manager": "4.26.1",
+        "@typescript-eslint/types": "4.26.1",
+        "@typescript-eslint/typescript-estree": "4.26.1",
         "eslint-scope": "^5.1.1",
         "eslint-utils": "^3.0.0"
       },
@@ -2041,14 +2041,14 @@
       }
     },
     "@typescript-eslint/parser": {
-      "version": "4.26.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.26.0.tgz",
-      "integrity": "sha512-b4jekVJG9FfmjUfmM4VoOItQhPlnt6MPOBUL0AQbiTmm+SSpSdhHYlwayOm4IW9KLI/4/cRKtQCmDl1oE2OlPg==",
+      "version": "4.26.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.26.1.tgz",
+      "integrity": "sha512-q7F3zSo/nU6YJpPJvQveVlIIzx9/wu75lr6oDbDzoeIRWxpoc/HQ43G4rmMoCc5my/3uSj2VEpg/D83LYZF5HQ==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/scope-manager": "4.26.0",
-        "@typescript-eslint/types": "4.26.0",
-        "@typescript-eslint/typescript-estree": "4.26.0",
+        "@typescript-eslint/scope-manager": "4.26.1",
+        "@typescript-eslint/types": "4.26.1",
+        "@typescript-eslint/typescript-estree": "4.26.1",
         "debug": "^4.3.1"
       },
       "dependencies": {
@@ -2070,29 +2070,29 @@
       }
     },
     "@typescript-eslint/scope-manager": {
-      "version": "4.26.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.26.0.tgz",
-      "integrity": "sha512-G6xB6mMo4xVxwMt5lEsNTz3x4qGDt0NSGmTBNBPJxNsrTXJSm21c6raeYroS2OwQsOyIXqKZv266L/Gln1BWqg==",
+      "version": "4.26.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.26.1.tgz",
+      "integrity": "sha512-TW1X2p62FQ8Rlne+WEShyd7ac2LA6o27S9i131W4NwDSfyeVlQWhw8ylldNNS8JG6oJB9Ha9Xyc+IUcqipvheQ==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "4.26.0",
-        "@typescript-eslint/visitor-keys": "4.26.0"
+        "@typescript-eslint/types": "4.26.1",
+        "@typescript-eslint/visitor-keys": "4.26.1"
       }
     },
     "@typescript-eslint/types": {
-      "version": "4.26.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.26.0.tgz",
-      "integrity": "sha512-rADNgXl1kS/EKnDr3G+m7fB9yeJNnR9kF7xMiXL6mSIWpr3Wg5MhxyfEXy/IlYthsqwBqHOr22boFbf/u6O88A==",
+      "version": "4.26.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.26.1.tgz",
+      "integrity": "sha512-STyMPxR3cS+LaNvS8yK15rb8Y0iL0tFXq0uyl6gY45glyI7w0CsyqyEXl/Fa0JlQy+pVANeK3sbwPneCbWE7yg==",
       "dev": true
     },
     "@typescript-eslint/typescript-estree": {
-      "version": "4.26.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.0.tgz",
-      "integrity": "sha512-GHUgahPcm9GfBuy3TzdsizCcPjKOAauG9xkz9TR8kOdssz2Iz9jRCSQm6+aVFa23d5NcSpo1GdHGSQKe0tlcbg==",
+      "version": "4.26.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz",
+      "integrity": "sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "4.26.0",
-        "@typescript-eslint/visitor-keys": "4.26.0",
+        "@typescript-eslint/types": "4.26.1",
+        "@typescript-eslint/visitor-keys": "4.26.1",
         "debug": "^4.3.1",
         "globby": "^11.0.3",
         "is-glob": "^4.0.1",
@@ -2127,12 +2127,12 @@
       }
     },
     "@typescript-eslint/visitor-keys": {
-      "version": "4.26.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.0.tgz",
-      "integrity": "sha512-cw4j8lH38V1ycGBbF+aFiLUls9Z0Bw8QschP3mkth50BbWzgFS33ISIgBzUMuQ2IdahoEv/rXstr8Zhlz4B1Zg==",
+      "version": "4.26.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.1.tgz",
+      "integrity": "sha512-IGouNSSd+6x/fHtYRyLOM6/C+QxMDzWlDtN41ea+flWuSF9g02iqcIlX8wM53JkfljoIjP0U+yp7SiTS1onEkw==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "4.26.0",
+        "@typescript-eslint/types": "4.26.1",
         "eslint-visitor-keys": "^2.0.0"
       }
     },
@@ -2295,24 +2295,24 @@
       "dev": true
     },
     "@webpack-cli/configtest": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.3.tgz",
-      "integrity": "sha512-WQs0ep98FXX2XBAfQpRbY0Ma6ADw8JR6xoIkaIiJIzClGOMqVRvPCWqndTxf28DgFopWan0EKtHtg/5W1h0Zkw==",
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.4.tgz",
+      "integrity": "sha512-cs3XLy+UcxiP6bj0A6u7MLLuwdXJ1c3Dtc0RkKg+wiI1g/Ti1om8+/2hc2A2B60NbBNAbMgyBMHvyymWm/j4wQ==",
       "dev": true
     },
     "@webpack-cli/info": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.4.tgz",
-      "integrity": "sha512-ogE2T4+pLhTTPS/8MM3IjHn0IYplKM4HbVNMCWA9N4NrdPzunwenpCsqKEXyejMfRu6K8mhauIPYf8ZxWG5O6g==",
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.3.0.tgz",
+      "integrity": "sha512-ASiVB3t9LOKHs5DyVUcxpraBXDOKubYu/ihHhU+t1UPpxsivg6Od2E2qU4gJCekfEddzRBzHhzA/Acyw/mlK/w==",
       "dev": true,
       "requires": {
         "envinfo": "^7.7.3"
       }
     },
     "@webpack-cli/serve": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.4.0.tgz",
-      "integrity": "sha512-xgT/HqJ+uLWGX+Mzufusl3cgjAcnqYYskaB7o0vRcwOEfuu6hMzSILQpnIzFMGsTaeaX4Nnekl+6fadLbl1/Vg==",
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.5.1.tgz",
+      "integrity": "sha512-4vSVUiOPJLmr45S8rMGy7WDvpWxfFxfP/Qx/cxZFCfvoypTYpPPL1X8VIZMe0WTA+Jr7blUxwUSEZNkjoMTgSw==",
       "dev": true
     },
     "@xtuc/ieee754": {
@@ -13712,9 +13712,9 @@
       "dev": true
     },
     "trim-newlines": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz",
-      "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
+      "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==",
       "dev": true
     },
     "trim-off-newlines": {
@@ -14166,15 +14166,15 @@
       }
     },
     "webpack-cli": {
-      "version": "4.7.0",
-      "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.7.0.tgz",
-      "integrity": "sha512-7bKr9182/sGfjFm+xdZSwgQuFjgEcy0iCTIBxRUeteJ2Kr8/Wz0qNJX+jw60LU36jApt4nmMkep6+W5AKhok6g==",
+      "version": "4.7.2",
+      "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.7.2.tgz",
+      "integrity": "sha512-mEoLmnmOIZQNiRl0ebnjzQ74Hk0iKS5SiEEnpq3dRezoyR3yPaeQZCMCe+db4524pj1Pd5ghZXjT41KLzIhSLw==",
       "dev": true,
       "requires": {
         "@discoveryjs/json-ext": "^0.5.0",
-        "@webpack-cli/configtest": "^1.0.3",
-        "@webpack-cli/info": "^1.2.4",
-        "@webpack-cli/serve": "^1.4.0",
+        "@webpack-cli/configtest": "^1.0.4",
+        "@webpack-cli/info": "^1.3.0",
+        "@webpack-cli/serve": "^1.5.1",
         "colorette": "^1.2.1",
         "commander": "^7.0.0",
         "execa": "^5.0.0",
@@ -14193,9 +14193,9 @@
           "dev": true
         },
         "execa": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz",
-          "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==",
+          "version": "5.1.1",
+          "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+          "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
           "dev": true,
           "requires": {
             "cross-spawn": "^7.0.3",
@@ -14224,9 +14224,9 @@
       }
     },
     "webpack-merge": {
-      "version": "5.7.3",
-      "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz",
-      "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==",
+      "version": "5.8.0",
+      "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz",
+      "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==",
       "dev": true,
       "requires": {
         "clone-deep": "^4.0.1",
diff --git a/package.json b/package.json
index 301a9d9cc..c419c6c6b 100644
--- a/package.json
+++ b/package.json
@@ -77,8 +77,8 @@
     "@semantic-release/release-notes-generator": "^9.0.2",
     "@types/jest": "^26.0.23",
     "@types/smoothscroll-polyfill": "^0.3.1",
-    "@typescript-eslint/eslint-plugin": "^4.26.0",
-    "@typescript-eslint/parser": "^4.26.0",
+    "@typescript-eslint/eslint-plugin": "^4.26.1",
+    "@typescript-eslint/parser": "^4.26.1",
     "@webcomponents/custom-elements": "^1.4.3",
     "@webcomponents/webcomponents-platform": "^1.0.1",
     "axios": "^0.21.1",
@@ -106,7 +106,7 @@
     "ts-loader": "^9.2.3",
     "typescript": "4.3.2",
     "webpack": "^5.38.1",
-    "webpack-cli": "^4.7.0"
+    "webpack-cli": "^4.7.2"
   },
   "browserslist": [
     "last 3 versions",
diff --git a/src/modules/esl-image/core/esl-image-strategies.ts b/src/modules/esl-image/core/esl-image-strategies.ts
index 1d486fc8e..c996d93b8 100644
--- a/src/modules/esl-image/core/esl-image-strategies.ts
+++ b/src/modules/esl-image/core/esl-image-strategies.ts
@@ -5,7 +5,7 @@ import {ESLImage} from './esl-image';
  */
 export interface ESLImageRenderStrategy {
   /** Apply image from shadow loader */
-  apply: (img: ESLImage, shadowImg: ShadowImageElement) => void;
+  apply: (img: ESLImage, shadowImg: HTMLImageElement) => void;
   /** Clean strategy specific changes from ESLImage */
   clear: (img: ESLImage) => void;
 }
@@ -17,13 +17,6 @@ export interface ESLImageStrategyMap {
   [mode: string]: ESLImageRenderStrategy;
 }
 
-/**
- * Mixed image element that used as shadow loader for ESLImage
- */
-export interface ShadowImageElement extends HTMLImageElement {
-  dpr?: number
-}
-
 export const STRATEGIES: ESLImageStrategyMap = {
   'cover': {
     apply(img, shadowImg) {
@@ -62,7 +55,7 @@ export const STRATEGIES: ESLImageStrategyMap = {
     apply(img, shadowImg) {
       const innerImg = img.attachInnerImage();
       innerImg.src = shadowImg.src;
-      innerImg.width = shadowImg.width / (shadowImg.dpr || 1);
+      innerImg.width = shadowImg.width / window.devicePixelRatio;
     },
     clear(img) {
       img.removeInnerImage();
diff --git a/src/modules/esl-image/core/esl-image.ts b/src/modules/esl-image/core/esl-image.ts
index bd2480744..96deaf284 100644
--- a/src/modules/esl-image/core/esl-image.ts
+++ b/src/modules/esl-image/core/esl-image.ts
@@ -9,7 +9,7 @@ import {TraversingQuery} from '../../esl-traversing-query/core/esl-traversing-qu
 import {getIObserver} from './esl-image-iobserver';
 import {STRATEGIES} from './esl-image-strategies';
 
-import type {ESLImageRenderStrategy, ShadowImageElement} from './esl-image-strategies';
+import type {ESLImageRenderStrategy} from './esl-image-strategies';
 
 type LoadState = 'error' | 'loaded' | 'ready';
 const isLoadState = (state: string): state is LoadState => ['error', 'loaded', 'ready'].includes(state);
@@ -61,7 +61,7 @@ export class ESLImage extends ESLBaseElement {
   private _srcRules: ESLMediaRuleList<string>;
   private _currentSrc: string;
   private _detachLazyTrigger: () => void;
-  private _shadowImageElement: ShadowImageElement;
+  private _shadowImageElement: HTMLImageElement;
 
   protected connectedCallback() {
     super.connectedCallback();
@@ -172,14 +172,11 @@ export class ESLImage extends ESLBaseElement {
   protected update(force: boolean = false) {
     if (!this.canUpdate) return;
 
-    const rule = this.srcRules.active;
-    const src = this.getPath(rule.payload);
-    const dpr = rule.dpr;
+    const src = this.getPath(this.srcRules.activeValue);
 
     if (this._currentSrc !== src || !this.ready || force) {
       this._currentSrc = src;
       this._shadowImg.src = src;
-      this._shadowImg.dpr = dpr;
 
       if (this.refreshOnUpdate || !this.ready) {
         this.syncImage();
diff --git a/src/modules/esl-media-query/core/esl-media-query.ts b/src/modules/esl-media-query/core/esl-media-query.ts
index 2a78b077b..34fbf4147 100644
--- a/src/modules/esl-media-query/core/esl-media-query.ts
+++ b/src/modules/esl-media-query/core/esl-media-query.ts
@@ -30,6 +30,7 @@ export class ESLMediaQuery {
   }
 
   static buildDprQuery(dpr: number) {
+    if (ESLMediaQuery.ignoreBotsDpr && DeviceDetector.isBot && dpr !== 1) return ESLMediaQuery.NOT_ALL;
     if (DeviceDetector.isSafari) return `(-webkit-min-device-pixel-ratio: ${dpr})`;
     return `(min-resolution: ${(96 * dpr).toFixed(1)}dpi)`;
   }
@@ -42,8 +43,6 @@ export class ESLMediaQuery {
    */
   static ignoreBotsDpr = false;
 
-  private _dpr: number;
-  private _mobileOnly: boolean | undefined;
   private readonly _query: MediaQueryList;
 
   constructor(query: string) {
@@ -51,19 +50,14 @@ export class ESLMediaQuery {
     query = ESLMediaBreakpoints.apply(query);
 
     // Applying dpr shortcut
-    this._dpr = 1;
-    query = query.replace(/@(\d(\.\d)?)x/g, (match, ratio) => {
-      this._dpr = +ratio;
-      if (ESLMediaQuery.ignoreBotsDpr && DeviceDetector.isBot && this._dpr !== 1) {
-        return ESLMediaQuery.NOT_ALL;
-      }
-      return ESLMediaQuery.buildDprQuery(ratio);
-    });
+    query = query.replace(
+      /@(\d(\.\d)?)x/g,
+      (match, ratio) => ESLMediaQuery.buildDprQuery(+ratio)
+    );
 
     // Applying dpr shortcut for device detection
     query = query.replace(/(and )?(@MOBILE|@DESKTOP)( and)?/ig, (match, pre, type, post) => {
-      this._mobileOnly = (type.toUpperCase() === '@MOBILE');
-      if (DeviceDetector.isMobile !== this._mobileOnly) {
+      if (DeviceDetector.isMobile !== (type.toUpperCase() === '@MOBILE')) {
         return ESLMediaQuery.NOT_ALL; // whole query became invalid
       }
       return pre && post ? 'and' : '';
@@ -72,21 +66,6 @@ export class ESLMediaQuery {
     this._query = ESLMediaQuery.matchMediaCached(query.trim() || ESLMediaQuery.ALL);
   }
 
-  /** Accepts only mobile devices */
-  public get isMobileOnly(): boolean {
-    return this._mobileOnly === true;
-  }
-
-  /** Accepts only desktop devices */
-  public get isDesktopOnly(): boolean {
-    return this._mobileOnly === false;
-  }
-
-  /** Current query dpr */
-  public get dpr(): number {
-    return this._dpr;
-  }
-
   /** inner MediaQueryList instance */
   public get query(): MediaQueryList {
     return this._query;


Test patch:
diff --git a/src/modules/esl-media-query/test/esl-media-query.test.ts b/src/modules/esl-media-query/test/esl-media-query.test.ts
index a3aa14fff..454861ed5 100644
--- a/src/modules/esl-media-query/test/esl-media-query.test.ts
+++ b/src/modules/esl-media-query/test/esl-media-query.test.ts
@@ -109,24 +109,6 @@ describe('ESLMediaQuery tests', () => {
   })
 
   describe('API tests', () => {
-    test('DPR getters', () => {
-      expect(new ESLMediaQuery('@sm').dpr).toBe(1);
-      expect(new ESLMediaQuery('@2x').dpr).toBe(2);
-      expect(new ESLMediaQuery('@2.3x').dpr).toBe(2.3);
-    });
-
-    test('Mobile/Desktop getters', () => {
-      const mqMob = new ESLMediaQuery('@Mobile');
-      const mqDesk = new ESLMediaQuery('@Desktop');
-
-      expect(mqMob.isMobileOnly).toBeTruthy();
-      expect(mqMob.isDesktopOnly).toBeFalsy();
-
-      expect(mqDesk.isDesktopOnly).toBeTruthy();
-      expect(mqDesk.isMobileOnly).toBeFalsy();
-
-    });
-
     test('Listeners', () => {
       const mq = new ESLMediaQuery('@xs');
       const listener = jest.fn();