Repository: exadel-inc/esl
Pull request #1502 (2023-02-24 08:57:50)

refactor: Drop IE11 support
Description:

Remove the full version of the polyfill for ESL UI site renderer Remove shims and targets =ES5 in the site codebase Remove ES5-related OOTB ESL polyfills except es5-target-shim.ts Drop support for IE11 and ES5 target

BREAKING CHANGES:

ESL UI site renderer and ESL polyfills no longer support IE11 and ES5 target.

<!--- Provide a general summary of your changes in the Title above -->
<!--- Describe your changes in detail: purpose, special notes -->

Closes: <!--- #123 -->

Relates to: <!--- #123 -->

<!--- This project only accepts pull requests related to open issues -->
<!--- If suggesting a new feature or change, please discuss it in an issue first -->
<!--- If fixing a bug, there should be an issue describing it with steps to reproduce -->
<!--- Please link to the issue here: -->
<!---  or -->

<!--- Checklist -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

<!--- - My change requires a change to the documentation. -->
<!--- - I have updated the documentation accordingly. -->
<!--- - I have added tests to cover my changes. (Unit tests are strongly advisable for changes under `esl-utils` scope -->


<!--- If you like ESL, please support it with a star on GitHub. Thank you! -->


github-actions[bot]: **CLA Assistant Lite bot:** Thank you for your submission, we really appreciate it. We ask that you sign our  <a href="https://github.com/exadel-inc/esl/blob/main/CLA.md">Contributor Licence Agreement</a> before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.
   - - -
   ***I have read the CLA Document and I hereby sign the CLA***
   - - -
   <sub>You can retrigger this bot by commenting **recheck** in this Pull Request</sub>
HenadzV: I have read the CLA Document and I hereby sign the CLA

Patch:
diff --git a/README.md b/README.md
index 4cc7bd9a7..0fc242556 100644
--- a/README.md
+++ b/README.md
@@ -41,7 +41,6 @@ to meet your project needs.
 
 ESL is based solely on Web API and ECMAScript 6 features, which let our web UI components library work 
 well across all modern browsers such as Firefox, Chrome, Safari, Opera, and Edge. 
-ESL can also work on IE11 when the whole list of polyfills is provided (see [Browser support & Polyfills](https://github.com/exadel-inc/esl/blob/HEAD/docs/BROWSER_SUPPORT.md) for more details).
 
 ## Library Structure
 
diff --git a/docs/BROWSER_SUPPORT.md b/docs/BROWSER_SUPPORT.md
index b1c998b86..06e615e40 100644
--- a/docs/BROWSER_SUPPORT.md
+++ b/docs/BROWSER_SUPPORT.md
@@ -6,17 +6,11 @@ Exadel Smart Library does not have dependencies but uses the following list of n
 
 - ECMAScript 6 features
     - [Array.from](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) (no Iterable Objects support required)
-      ([ESL polyfill](../src/polyfills/list/es6.array.from.ts) provided)
     - [Array.prototype.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
-      ([ESL polyfill](../src/polyfills/list/es6.array.find.ts) provided)
     - [Array.prototype.findIndex](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex)
-      ([ESL polyfill](../src/polyfills/list/es6.array.find.ts) provided)
     - [Array.prototype.include](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes)
-      ([ESL polyfill](../src/polyfills/list/es6.array.includes.ts) provided)
     - [Object.is](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is)
-      ([ESL polyfill](../src/polyfills/list/es6.object.is.ts) provided)
     - [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) (accurate polyfill required)
-      ([ESL polyfill](../src/polyfills/list/es6.object.assign.ts) provided)
     - [ES6 Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
 - Web API
     - [Event](https://developer.mozilla.org/en-US/docs/Web/API/Event) constructor + `preventDefault` polyfill
@@ -30,25 +24,6 @@ Exadel Smart Library does not have dependencies but uses the following list of n
     - [ResizeObserver](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver)
     - [Custom Elements](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements)
 
-All of them are fully supported by modern browsers such as Chrome, Firefox, Safari or Edge (>43).
+All of them are fully supported by modern browsers such as Chrome, Firefox, Safari (>13) or Edge (>43).
 
-In order to make ESL work in older browsers, you can use a "light" polyfills list of IntersectionObserver, ResizeObserver and Custom Elements (for older versions of Edge and Safari).
-
-Or make the library work in IE11 or Edge (<14) by using the "full" polyfills list provided.
-
-See more details on what polyfill approach might look like in the demo pages source code.
-
-Also, ESL has built-in polyfills for some of DOM and ES6 features. They are available under [polyfills](../src/polyfills) directory:
-  - ECMA Script 5: output shim (`HTMLElement` constructor call) - [es5-target-shim.ts](../src/polyfills/es5-target-shim.ts)
-  - ECMA Script 5: IE11, Edge <14 support - [polyfills.es5.ts](../src/polyfills/polyfills.es5.ts)
-    - `Object.is`, `Object.assign` 
-    - `Array.from`, `Array.prototype.find`, `Array.prototype.findIndex`, `Array.prototype.index`
-    - `Event`, `CustomEvent`, `MouseEvent`, `KeyboardEvent`, `FocusEvent` shim
-    - `Event.prototype.preventDefault` shim
-    - `Element.prototype.closest`
-    - `DOMTokenList.prototype.toggle`
-    - *Note: there is no promise polyfill embedded*, use npm:[promise-polyfill](https://www.npmjs.com/package/promise-polyfill) or similar
-  - ECMA Script 6: DOM - [polyfills.es6.ts](../src/polyfills/polyfills.es6.ts)
-    - `Node.isConnected` 
-    - `KeyboardKey.prototype.key` 
-    - `Element.prototype.toggleAttribute` 
+In order to make ESL work in older browsers, you can use polyfill (for older versions of Safari).
diff --git a/package-lock.json b/package-lock.json
index 36639d714..fd0b15fc1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -29,7 +29,6 @@
         "@types/smoothscroll-polyfill": "^0.3.1",
         "@typescript-eslint/eslint-plugin": "^5.55.0",
         "@typescript-eslint/parser": "^5.55.0",
-        "@webcomponents/custom-elements": "1.5.1",
         "chokidar-cli": "^3.0.0",
         "clean-css-cli": "^5.6.2",
         "concurrently": "^7.6.0",
@@ -42,7 +41,6 @@
         "foreach-cli": "^1.8.1",
         "html-minifier": "^4.0.0",
         "husky": "^8.0.3",
-        "intersection-observer": "^0.12.2",
         "jest": "^29.5.0",
         "jest-environment-jsdom": "^29.5.0",
         "js-yaml": "^4.1.0",
@@ -53,7 +51,6 @@
         "postcss": "^8.4.21",
         "postcss-less": "^6.0.0",
         "prismjs": "^1.29.0",
-        "promise-polyfill": "^8.3.0",
         "rimraf": "^4.4.0",
         "semantic-release": "^20.1.1",
         "smoothscroll-polyfill": "^0.4.4",
@@ -2964,12 +2961,6 @@
         "@xtuc/long": "4.2.2"
       }
     },
-    "node_modules/@webcomponents/custom-elements": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/@webcomponents/custom-elements/-/custom-elements-1.5.1.tgz",
-      "integrity": "sha512-6T/XT3S1UHDlRWFSxRXdeSoYWczEl78sygNPS7jDyHVrfZcF/pUtWGYgxF4uviH59iPVw1eOWbhubm8CqO0MpA==",
-      "dev": true
-    },
     "node_modules/@webpack-cli/configtest": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.0.1.tgz",
@@ -7319,12 +7310,6 @@
         "node": ">=10.13.0"
       }
     },
-    "node_modules/intersection-observer": {
-      "version": "0.12.2",
-      "resolved": "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.12.2.tgz",
-      "integrity": "sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg==",
-      "dev": true
-    },
     "node_modules/into-stream": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz",
@@ -19529,12 +19514,6 @@
         "@xtuc/long": "4.2.2"
       }
     },
-    "@webcomponents/custom-elements": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/@webcomponents/custom-elements/-/custom-elements-1.5.1.tgz",
-      "integrity": "sha512-6T/XT3S1UHDlRWFSxRXdeSoYWczEl78sygNPS7jDyHVrfZcF/pUtWGYgxF4uviH59iPVw1eOWbhubm8CqO0MpA==",
-      "dev": true
-    },
     "@webpack-cli/configtest": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.0.1.tgz",
@@ -22816,12 +22795,6 @@
       "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
       "dev": true
     },
-    "intersection-observer": {
-      "version": "0.12.2",
-      "resolved": "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.12.2.tgz",
-      "integrity": "sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg==",
-      "dev": true
-    },
     "into-stream": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz",
diff --git a/package.json b/package.json
index c84744dd6..70efe8645 100644
--- a/package.json
+++ b/package.json
@@ -97,7 +97,6 @@
     "@types/smoothscroll-polyfill": "^0.3.1",
     "@typescript-eslint/eslint-plugin": "^5.55.0",
     "@typescript-eslint/parser": "^5.55.0",
-    "@webcomponents/custom-elements": "1.5.1",
     "chokidar-cli": "^3.0.0",
     "clean-css-cli": "^5.6.2",
     "concurrently": "^7.6.0",
@@ -110,7 +109,6 @@
     "foreach-cli": "^1.8.1",
     "html-minifier": "^4.0.0",
     "husky": "^8.0.3",
-    "intersection-observer": "^0.12.2",
     "jest": "^29.5.0",
     "jest-environment-jsdom": "^29.5.0",
     "js-yaml": "^4.1.0",
diff --git a/pages/src/localdev.ts b/pages/src/localdev.ts
index abd431ab3..cd9ae53dd 100644
--- a/pages/src/localdev.ts
+++ b/pages/src/localdev.ts
@@ -1,7 +1,5 @@
 // Support for ES5 bundle target
 import '../../src/polyfills/es5-target-shim';
-// Builtin polyfills
-import '../../src/polyfills/polyfills.es6';
 // Validate environment
 import '../../src/polyfills/polyfills.validate';
 
diff --git a/pages/src/polyfill-full.ts b/pages/src/polyfill-full.ts
deleted file mode 100644
index b89dbe5fe..000000000
--- a/pages/src/polyfill-full.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
- * Target: IE11, Edge\<14
- */
-import 'promise-polyfill/dist/polyfill';
-
-import '../../src/polyfills/polyfills.es5';
-
-import './polyfill-medium';
diff --git a/pages/src/polyfill-medium.ts b/pages/src/polyfill-medium.ts
deleted file mode 100644
index a75b910c6..000000000
--- a/pages/src/polyfill-medium.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * Target: iOS, Safari 13.0.0
- */
-// IE, Edge < 18
-import '@webcomponents/custom-elements/custom-elements.min';
-
-// IE, Safari <12, Edge < 14
-import 'intersection-observer/intersection-observer';
-
-import './polyfill-light';
diff --git a/pages/src/polyfill-light.ts b/pages/src/polyfill.ts
similarity index 68%
rename from pages/src/polyfill-light.ts
rename to pages/src/polyfill.ts
index d3e2432de..f376e50f1 100644
--- a/pages/src/polyfill-light.ts
+++ b/pages/src/polyfill.ts
@@ -1,9 +1,4 @@
-/**
- * Target: Edge, Safari 9
- */
-import '../../src/polyfills/polyfills.es6';
-
-// IE, Safari <13.3
+// Safari <13.3
 import {ResizeObserver} from '@juggle/resize-observer';
 window.ResizeObserver = window.ResizeObserver || ResizeObserver;
 
diff --git a/pages/views/_includes/polyfill.njk b/pages/views/_includes/polyfill.njk
index c01d5dc6a..6f5a8bb73 100644
--- a/pages/views/_includes/polyfill.njk
+++ b/pages/views/_includes/polyfill.njk
@@ -1,13 +1,7 @@
 <script>
   (function () {
-    var version = '';
-    if (!window.Promise || !window.CustomEvent){
-      version = 'full';
-    } else if (!('getRootNode' in Element.prototype) || !window.customElements){
-      version = 'medium';
-    } else if (!window.scrollBy || !window.IntersectionObserver || !window.ResizeObserver || !window.ResizeObserver) {
-      version = 'light';
+    if (!window.scrollBy || !window.ResizeObserver) {
+      document.write('<script type="text/javascript" src="{{ '/bundles/polyfill.js' | url }}"><\/script>');
     }
-    (version) && document.write('<script type="text/javascript" src="{{ '/bundles/polyfill-' | url }}' + version + '.js"><\/script>');
   })();
 </script>
diff --git a/pages/webpack.config.js b/pages/webpack.config.js
index 3f71fd799..d3588a53a 100644
--- a/pages/webpack.config.js
+++ b/pages/webpack.config.js
@@ -5,9 +5,7 @@ module.exports = {
   devtool: 'source-map',
   entry: {
     'localdev': './src/localdev.ts',
-    'polyfill-full': './src/polyfill-full.ts',
-    'polyfill-medium': './src/polyfill-medium.ts',
-    'polyfill-light': './src/polyfill-light.ts'
+    'polyfill': './src/polyfill.ts'
   },
   resolve: {
     modules: ['../node_modules'],
diff --git a/src/modules/draft/esl-carousel/core/esl-carousel-arrows.less b/src/modules/draft/esl-carousel/core/esl-carousel-arrows.less
index f3ca2f1bf..55147eafd 100644
--- a/src/modules/draft/esl-carousel/core/esl-carousel-arrows.less
+++ b/src/modules/draft/esl-carousel/core/esl-carousel-arrows.less
@@ -19,8 +19,6 @@ esl-carousel {
     border: none;
     opacity: .5;
     cursor: pointer;
-
-    // TODO: IE11 support
     appearance: none;
   }
   button.arrow-next {
diff --git a/src/modules/esl-tab/core/esl-tabs.arrows.less b/src/modules/esl-tab/core/esl-tabs.arrows.less
index 19d703006..588716d44 100644
--- a/src/modules/esl-tab/core/esl-tabs.arrows.less
+++ b/src/modules/esl-tab/core/esl-tabs.arrows.less
@@ -19,8 +19,6 @@ esl-tabs[scrollable] {
     border: none;
     opacity: .5;
     cursor: pointer;
-
-    // TODO: IE11 support
     appearance: none;
   }
   .arrow-next {
diff --git a/src/polyfills/list/dom.element.closest.ts b/src/polyfills/list/dom.element.closest.ts
deleted file mode 100644
index 45ca9868b..000000000
--- a/src/polyfills/list/dom.element.closest.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * Group: DOM API shims ~ ES6 shim group
- * Target Browsers: `IE11`, `Edge < 14`
- * Element.closest polyfill
- */
-(function (e: ElementEx): void {
-  e.matches = e.matches || e.msMatchesSelector || e.mozMatchesSelector || e.webkitMatchesSelector;
-  e.closest = e.closest || function (css: string): Element | null {
-    // eslint-disable-next-line @typescript-eslint/no-this-alias
-    let node = this;
-    while (node) {
-      if (node.matches(css)) return node;
-      node = node.parentElement;
-    }
-    return null;
-  };
-})(Element.prototype as ElementEx);
-
-interface ElementEx extends Element {
-  msMatchesSelector?(selectors: string): boolean;
-  mozMatchesSelector?(selectors: string): boolean;
-}
diff --git a/src/polyfills/list/dom.element.toggleAttribute.ts b/src/polyfills/list/dom.element.toggleAttribute.ts
deleted file mode 100644
index fc794a33b..000000000
--- a/src/polyfills/list/dom.element.toggleAttribute.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-/**
- * Group: DOM API shims
- * Target Browsers: `IE11`, `Edge < 18`, `Safari < 13`
- * Element.toggleAttribute polyfill
- */
-if (!Element.prototype.toggleAttribute) {
-  Element.prototype.toggleAttribute = function (name: string, force: boolean | undefined): boolean {
-    const has = this.hasAttribute(name);
-    const state = force === void 0 ? !has : !!force;
-
-    if (has !== state) {
-      (state) ? this.setAttribute(name, '') : this.removeAttribute(name);
-    }
-    return state;
-  };
-}
diff --git a/src/polyfills/list/dom.event.base.ts b/src/polyfills/list/dom.event.base.ts
deleted file mode 100644
index 49ad7c8fa..000000000
--- a/src/polyfills/list/dom.event.base.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * Group: DOM API shims
- * Target Browsers: `IE11`, `Edge < 18`
- * Event constructor & prevent default polyfill
- */
-try {
-  new window.Event('event', {bubbles: true, cancelable: true});
-} catch (error) {
-  const EventOriginal = window.CustomEvent || window.Event;
-  const preventDefaultOriginal = EventOriginal.prototype.preventDefault;
-  const Event = function (eventName: string, params: EventInit): Event {
-    params = params || {};
-    const event = document.createEvent('Event');
-    event.initEvent(
-      eventName,
-      (params.bubbles === void 0) ? false : params.bubbles,
-      (params.cancelable === void 0) ? false : params.cancelable
-    );
-    return event;
-  };
-  Event.prototype = EventOriginal.prototype;
-  // defaultPrevented is broken in IE.
-  // https://connect.microsoft.com/IE/feedback/details/790389/event-defaultprevented-returns-false-after-preventdefault-was-called
-  Event.prototype.preventDefault = function (): void {
-    if (!this.cancelable) return;
-    preventDefaultOriginal.call(this);
-    Object.defineProperty(this, 'defaultPrevented', {
-      get() {
-        return true;
-      },
-      configurable: true
-    });
-  };
-  Object.defineProperty(window, 'Event', {
-    value: Event,
-    writable: true,
-    configurable: true
-  });
-}
-
diff --git a/src/polyfills/list/dom.event.custom.ts b/src/polyfills/list/dom.event.custom.ts
deleted file mode 100644
index de39ee31a..000000000
--- a/src/polyfills/list/dom.event.custom.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Group: DOM API shims
- * Target Browsers: `IE11`, `Edge < 18`
- * CustomEvent polyfill
- */
-try {
-  new window.CustomEvent('event', {bubbles: true, cancelable: true});
-} catch (error) {
-  const CustomEventOriginal = window.CustomEvent || window.Event;
-  const CustomEvent = function (eventName: string, params: CustomEventInit): CustomEvent {
-    params = params || {};
-    const event = document.createEvent('CustomEvent');
-    event.initCustomEvent(
-      eventName,
-      (params.bubbles === void 0) ? false : params.bubbles,
-      (params.cancelable === void 0) ? false : params.cancelable,
-      (params.detail === void 0) ? {} : params.detail
-    );
-    return event;
-  };
-  CustomEvent.prototype = CustomEventOriginal.prototype;
-  Object.defineProperty(window, 'CustomEvent', {
-    value: CustomEvent,
-    writable: true,
-    configurable: true
-  });
-}
diff --git a/src/polyfills/list/dom.event.focus.ts b/src/polyfills/list/dom.event.focus.ts
deleted file mode 100644
index 7c2a28801..000000000
--- a/src/polyfills/list/dom.event.focus.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Group: DOM API shims
- * Target Browsers: `IE11`, `Edge < 18`
- * FocusEvent polyfill: https://developer.mozilla.org/en-US/docs/Web/API/FocusEvent/FocusEvent
- */
-try {
-  new window.FocusEvent('event', {bubbles: true, cancelable: true});
-} catch (error) {
-  const FocusEventOriginal = window.FocusEvent || window.Event;
-  const FocusEvent = function (eventName: string, params: FocusEventInit): FocusEvent {
-    params = params || {};
-    const event: any = document.createEvent('FocusEvent');
-
-    // https://msdn.microsoft.com/en-us/library/ff975954(v=vs.85).aspx
-    event.initFocusEvent(
-      eventName,
-      (params.bubbles === void 0) ? false : params.bubbles,
-      (params.cancelable === void 0) ? false : params.cancelable,
-      (params.view === void 0) ? window : params.view,
-      (params.detail === void 0) ? {} : params.detail,
-      (params.relatedTarget === void 0) ? null : params.relatedTarget
-    );
-
-    return event;
-  };
-  FocusEvent.prototype = FocusEventOriginal.prototype;
-  Object.defineProperty(window, 'FocusEvent', {
-    value: FocusEvent,
-    writable: true,
-    configurable: true
-  });
-}
diff --git a/src/polyfills/list/dom.event.keyboard.ts b/src/polyfills/list/dom.event.keyboard.ts
deleted file mode 100644
index ae16d6b55..000000000
--- a/src/polyfills/list/dom.event.keyboard.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * Group: DOM API shims
- * Target Browsers: `IE11`, `Edge < 18`
- * KeyboardEvent polyfill: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/KeyboardEvent
- */
-try {
-  new window.KeyboardEvent('event', {bubbles: true, cancelable: true});
-} catch (error) {
-  const KeyboardEventOriginal = window.KeyboardEvent || window.Event;
-  // eslint-disable-next-line sonarjs/cognitive-complexity
-  const KeyboardEvent = function (eventName: string, params: KeyboardEventInit): KeyboardEvent {
-    params = params || {};
-    const event: any = document.createEvent('KeyboardEvent');
-
-    // https://msdn.microsoft.com/en-us/library/ff975297(v=vs.85).aspx
-    event.initKeyboardEvent(
-      eventName,
-      (params.bubbles === void 0) ? false : params.bubbles,
-      (params.cancelable === void 0) ? false : params.cancelable,
-      (params.view === void 0) ? window : params.view,
-      (params.key === void 0) ? '' : params.key,
-      (params.location === void 0) ? 0 : params.location,
-      params.ctrlKey === true,
-      params.altKey === true,
-      params.shiftKey === true,
-      params.metaKey === true
-    );
-
-    event.keyCode   = (params.keyCode === void 0) ? 0 : params.keyCode;
-    event.code      = (params.code === void 0) ? '' : params.code;
-    event.charCode  = (params.charCode === void 0) ? 0 : params.charCode;
-    event.char      = (params.charCode === void 0) ? '' : params.charCode;
-    event.which     = (params.which === void 0) ? 0 : params.which;
-
-    return event;
-  };
-  KeyboardEvent.prototype = KeyboardEventOriginal.prototype;
-  Object.defineProperty(window, 'KeyboardEvent', {
-    value: KeyboardEvent,
-    writable: true,
-    configurable: true
-  });
-}
diff --git a/src/polyfills/list/dom.event.mouse.ts b/src/polyfills/list/dom.event.mouse.ts
deleted file mode 100644
index fc2c5ec39..000000000
--- a/src/polyfills/list/dom.event.mouse.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * Group: DOM API shims
- * Target Browsers: `IE11`, `Edge < 18`
- * MouseEvent polyfill: https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/MouseEvent
- */
-try {
-  new window.MouseEvent('event', {bubbles: true, cancelable: true});
-} catch (error) {
-  const MouseEventOriginal = window.MouseEvent || window.Event;
-  // eslint-disable-next-line sonarjs/cognitive-complexity
-  const MouseEvent = function (eventName: string, params: MouseEventInit): MouseEvent {
-    params = params || {};
-    const event: any = document.createEvent('MouseEvent');
-
-    // https://msdn.microsoft.com/en-us/library/ff975292(v=vs.85).aspx
-    event.initMouseEvent(
-      eventName,
-      (params.bubbles === void 0) ? false : params.bubbles,
-      (params.cancelable === void 0) ? false : params.cancelable,
-      (params.view === void 0) ? window : params.view!,
-      (params.detail === void 0) ? 0 : params.detail,
-      (params.screenX === void 0) ? 0 : params.screenX,
-      (params.screenY === void 0) ? 0 : params.screenY,
-      (params.clientX === void 0) ? 0 : params.clientX,
-      (params.clientY === void 0) ? 0 : params.clientY,
-      (params.ctrlKey === void 0) ? false : params.ctrlKey,
-      (params.altKey === void 0) ? false : params.altKey,
-      (params.shiftKey === void 0) ? false : params.shiftKey,
-      (params.metaKey === void 0) ? false : params.metaKey,
-      (params.button === void 0) ? 0 : params.button,
-      (params.relatedTarget === void 0) ? null : params.relatedTarget
-    );
-
-    event.buttons = (params.buttons === void 0) ? 0 : params.buttons;
-    event.region  = ((params as any).region === void 0) ? null : (params as any).region;
-
-    return event;
-  };
-  MouseEvent.prototype = MouseEventOriginal.prototype;
-  Object.defineProperty(window, 'MouseEvent', {
-    value: MouseEvent,
-    writable: true,
-    configurable: true
-  });
-}
diff --git a/src/polyfills/list/dom.keyboard.key.ts b/src/polyfills/list/dom.keyboard.key.ts
deleted file mode 100644
index 984846913..000000000
--- a/src/polyfills/list/dom.keyboard.key.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * Group: DOM API shims
- * Target Browsers: `IE11`, `Edge < 18`
- * KeyboardEvent.prototype.key shim to normalize key values to W3C spec
- * Based on published shim https://www.npmjs.com/package/shim-keyboard-event-key
- */
-(function (KeyboardEventProto): void {
-  const desc = Object.getOwnPropertyDescriptor(KeyboardEventProto, 'key');
-  if (!desc) return;
-
-  const keyMap: Record<string, string> = {
-    Win: 'Meta',
-    Scroll: 'ScrollLock',
-    Spacebar: ' ',
-
-    Down: 'ArrowDown',
-    Left: 'ArrowLeft',
-    Right: 'ArrowRight',
-    Up: 'ArrowUp',
-
-    Del: 'Delete',
-    Apps: 'ContextMenu',
-    Esc: 'Escape',
-
-    Multiply: '*',
-    Add: '+',
-    Subtract: '-',
-    Decimal: '.',
-    Divide: '/',
-  };
-
-  Object.defineProperty(KeyboardEventProto, 'key', {
-    get() {
-      const key = desc.get!.call(this);
-      return Object.prototype.hasOwnProperty.call(keyMap, key) ? keyMap[key] : key;
-    },
-  });
-})(KeyboardEvent.prototype);
diff --git a/src/polyfills/list/dom.node.isConnected.ts b/src/polyfills/list/dom.node.isConnected.ts
deleted file mode 100644
index 3044301e6..000000000
--- a/src/polyfills/list/dom.node.isConnected.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * Group: DOM polyfills
- * Target browsers: `IE11`, `Edge <= 18`
- * Node.isConnected polyfill
- */
-if (!('isConnected' in Node.prototype)) {
-  Object.defineProperty(Node.prototype, 'isConnected', {
-    get() {
-      return !this.ownerDocument ||
-        // eslint-disable-next-line no-bitwise
-        !(this.ownerDocument.compareDocumentPosition(this) & this.DOCUMENT_POSITION_DISCONNECTED);
-    }
-  });
-}
diff --git a/src/polyfills/list/dom.tokenList.toggle.ts b/src/polyfills/list/dom.tokenList.toggle.ts
deleted file mode 100644
index 67257dcab..000000000
--- a/src/polyfills/list/dom.tokenList.toggle.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * Group: ES6 shims
- * Target Browsers: `IE11`
- * DOMTokenList.toggle polyfill to support force option
- */
-(function (DOMTokenListProto): void {
-  const nativeToggle = DOMTokenListProto.toggle;
-  const testTokenList = window.document.createElement('div').classList;
-
-  if (!DOMTokenListProto.toggle) return;
-  // eslint-disable-next-line
-  if (testTokenList.toggle('a', false) === false) return;
-
-  DOMTokenListProto.toggle = function toggle(val: string, force?: boolean): boolean {
-    if (arguments.length > 1) {
-      this[force ? 'add' : 'remove'](val);
-      return !!force;
-    }
-    return nativeToggle.call(this, val);
-  };
-})(window.DOMTokenList.prototype);
diff --git a/src/polyfills/list/es6.array.find.ts b/src/polyfills/list/es6.array.find.ts
deleted file mode 100644
index 62a6d79fc..000000000
--- a/src/polyfills/list/es6.array.find.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-type FindPredicate<T> = (T: any, index: number, array: T[]) => boolean;
-
-/**
- * Group: ES6 shim
- * Target Browsers: `IE11`, `Edge < 14`
- * Array.prototype.findIndex && Array.prototype.findIndex
- */
-if (typeof Array.prototype.findIndex !== 'function') {
-  const findHelper = function <T> (array: T[], predicate: FindPredicate<T>, context: any): {item: T | null, index: number} {
-    if (typeof predicate !== 'function') throw new TypeError('predicate must be a function');
-
-    const list = Object(array);
-    // eslint-disable-next-line no-bitwise
-    const length = list.length >>> 0;
-
-    for (let i = 0; i < length; i++) {
-      if (predicate.call(context, list[i], i, list)) {
-        return {item: list[i], index: i};
-      }
-    }
-    return {item: null, index: -1};
-  };
-
-  Array.prototype.find = function <T> (predicate: FindPredicate<T>, context: any = window): T | null {
-    if (!this) throw new TypeError('Array.prototype.find called on null or undefined');
-    return findHelper(this, predicate, context).item;
-  };
-  Array.prototype.findIndex = function <T> (predicate: FindPredicate<T>, context: any = window): number {
-    if (!this) throw new TypeError('Array.prototype.findIndex called on null or undefined');
-    return findHelper(this, predicate, context).index;
-  };
-}
diff --git a/src/polyfills/list/es6.array.from.ts b/src/polyfills/list/es6.array.from.ts
deleted file mode 100644
index 05ac0684c..000000000
--- a/src/polyfills/list/es6.array.from.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * Group: ES6 shim
- * Target Browsers: `IE11`
- * Array.from polyfill
- * Note: does not support Iterables, consider polyfill from https://github.com/rousan/symbol-es6
- */
-if (!Array.from) {
-  Array.from = function <T>(object: ArrayLike<T>): T[] {
-    return [].slice.call(object);
-  };
-}
diff --git a/src/polyfills/list/es6.array.includes.ts b/src/polyfills/list/es6.array.includes.ts
deleted file mode 100644
index 1a7475b1e..000000000
--- a/src/polyfills/list/es6.array.includes.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * Group: ES6 shim
- * Target Browsers: `IE11`, `Edge < 14`
- * Array.prototype.includes polyfill
- */
-if (!Array.prototype.includes) {
-  Array.prototype.includes = function <T> (item: T, fromIndex?: number): boolean {
-    if (item !== item) {
-      // NaN case
-      return Array.prototype.slice.call(this, fromIndex).some((i: T) => i !== i);
-    }
-    return Array.prototype.indexOf.call(this, item, fromIndex) !== -1;
-  };
-}
diff --git a/src/polyfills/list/es6.object.assign.ts b/src/polyfills/list/es6.object.assign.ts
deleted file mode 100644
index 61aaa5576..000000000
--- a/src/polyfills/list/es6.object.assign.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * Group: ES6 shim
- * Target Browsers: `IE11`
- * Object.assign polyfill
- */
-function toObject(value: any): any {
-  if (value === undefined || value === null) throw new TypeError('Cannot convert undefined or null to object');
-  if (typeof value === 'boolean') return new Boolean(value);
-  if (typeof value === 'number') return new Number(value);
-  if (typeof value === 'string') return new String(value);
-  if (typeof value === 'symbol') return Object(value);
-  return value;
-}
-
-function copyProperty(from: any, to: any, name: string): void {
-  const desc = Object.getOwnPropertyDescriptor(from, name);
-  if (desc !== undefined && desc.enumerable) to[name] = from[name];
-}
-
-if (!Object.assign) {
-  Object.assign = function assign(target: any, ...sources: any[]): any {
-    if (this instanceof Object.assign) throw new TypeError('Invoked as a constructor');
-    const to = toObject(target);
-    for (let i = 0; i < sources.length; i++) {
-      const nextSource = sources[i];
-      if (nextSource !== undefined && nextSource !== null) {
-        const from = toObject(nextSource);
-        const keys = Object.getOwnPropertyNames(from);
-        keys.forEach(copyProperty.bind(null, from, to));
-        if (Object.getOwnPropertySymbols) {
-          const symbols = Object.getOwnPropertySymbols(from);
-          symbols.forEach(copyProperty.bind(null, from, to));
-        }
-      }
-    }
-    return to;
-  };
-}
diff --git a/src/polyfills/list/es6.object.is.ts b/src/polyfills/list/es6.object.is.ts
deleted file mode 100644
index e34fba24c..000000000
--- a/src/polyfills/list/es6.object.is.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * Group: ES6 shims
- * Target Browsers: `IE11`
- * Object.is support
- * Blatantly stolen from ES6 specs. Kept here for reference.
- * http://wiki.ecmascript.org/doku.php?id=harmony:egal
- */
-if (!Object.is) {
-  Object.defineProperty(Object, 'is', {
-    value(x: any, y: any) {
-      return (x === y) ? (x !== 0 || 1 / x === 1 / y) : (x !== x && y !== y);
-    },
-    enumerable: false
-  });
-}
diff --git a/src/polyfills/polyfills.es5.ts b/src/polyfills/polyfills.es5.ts
deleted file mode 100644
index 8256d1c08..000000000
--- a/src/polyfills/polyfills.es5.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import './list/es6.object.is';
-import './list/es6.object.assign';
-
-import './list/es6.array.from';
-import './list/es6.array.find';
-import './list/es6.array.includes';
-
-import './list/dom.event.base';
-import './list/dom.event.custom';
-import './list/dom.event.mouse';
-import './list/dom.event.keyboard';
-import './list/dom.event.focus';
-
-import './list/dom.element.closest';
-import './list/dom.tokenList.toggle';
diff --git a/src/polyfills/polyfills.es6.ts b/src/polyfills/polyfills.es6.ts
deleted file mode 100644
index 075c9002f..000000000
--- a/src/polyfills/polyfills.es6.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import './list/dom.node.isConnected';
-import './list/dom.keyboard.key';
-import './list/dom.element.toggleAttribute';


Test patch:
diff --git a/src/polyfills/test/es6.object.assign.test.ts b/src/polyfills/test/es6.object.assign.test.ts
deleted file mode 100644
index 58d1aa741..000000000
--- a/src/polyfills/test/es6.object.assign.test.ts
+++ /dev/null
@@ -1,394 +0,0 @@
-const originalAssignFn = Object.assign;
-Object.defineProperty(Object, 'assign', {writable: true, value: undefined});
-import '../list/es6.object.assign';
-
-class TestError extends Error {}
-
-afterAll(() => {
-  Object.assign = originalAssignFn;
-});
-
-describe('Object.assign() polyfill', () => {
-  test('object override sameproperty', () => {
-    // Object properties are assigned to target in ascending index order,
-    // i.e. a later assignment to the same property overrides an earlier assignment.
-    const target = {a: 1};
-    const result = Object.assign(target, {a: 2}, {a: 'c'});
-    expect(result.a).toBe('c');
-  });
-
-  test('only one argument', () => {
-    // Should return ToObject(target)
-    const target = 'a';
-    const result = Object.assign(target as any);
-    expect(typeof result).toBe('object');
-    expect(result.valueOf()).toEqual('a');
-  });
-
-  test('override notstringtarget', () => {
-    // Every string from sources will be wrapped to objects, and override from the first letter(result[0]) all the time
-    const target = 12;
-    const result = Object.assign(target, 'aaa', 'bb2b', '1c');
-    expect(Object.getOwnPropertyNames(result).length).toBe(4);
-    expect(result[0]).toBe('1');
-    expect(result[1]).toBe('c');
-    expect(result[2]).toBe('2');
-    expect(result[3]).toBe('b');
-  });
-
-  test('override', () => {
-    const target = {a: 1};
-    /*
-    '1a2c3' have own enumerable properties, so it Should be wrapped to objects;
-    {b:6} is an object,should be assigned to final object.
-    undefined and null should be ignored;
-    125 is a number,it cannot has own enumerable properties;
-    {a:'c'},{a:5} will override property a, the value should be 5.
-    */
-    const result = Object.assign(target, '1a2c3', {a: 'c'}, undefined, {b: 6}, null, 125, {a: 5});
-    expect(Object.getOwnPropertyNames(result).length).toBe(7);
-    expect(result.a).toBe(5);
-    expect(result[0]).toBe('1');
-    expect(result[1]).toBe('a');
-    expect(result[2]).toBe('2');
-    expect(result[3]).toBe('c');
-    expect(result[4]).toBe('3');
-    expect(result.b).toBe(6);
-  });
-
-  test('source is Null Undefined', () => {
-    const target = new Object();
-    // null and undefined source should be ignored, result should be original object.
-    const result = Object.assign(target, undefined, null);
-    expect(result).toEqual(target);
-  });
-
-  test('source is Number Boolean Symbol', () => {
-    const target = new Object();
-    /*
-    Number, Boolean, and Symbol cannot have their own enumerable properties,
-    so cannot be Assigned. Here result should be the original object.
-    */
-    const result = Object.assign(target, 123, true, Symbol('foo'));
-    expect(result).toEqual(target);
-  });
-
-  test('source is String', () => {
-    const target = new Object();
-    // string have own enumerable properties, so it can be wrapped to objects.
-    const result = Object.assign(target, '123');
-    expect(result[0]).toBe('1');
-    expect(result[1]).toBe('2');
-    expect(result[2]).toBe('3');
-  });
-
-  test('target is Boolean', () => {
-    // if target is Boolean,the return value should be a new object whose value is target.
-    const result = Object.assign(true, {a: 2});
-    expect(typeof result).toBe('object');
-    expect(result.valueOf()).toEqual(true);
-  });
-
-  test('target is Null', () => {
-    // if target is null, should throw a TypeError exception.
-    // @ts-ignore
-    expect(() => Object.assign(null, {a: 1})).toThrow(TypeError);
-  });
-
-  test('target is Number', () => {
-    // if target is Number, the return value should be a new object whose value is target.
-    const result = Object.assign(1, {a: 2});
-    expect(typeof result).toBe('object');
-    expect(result.valueOf()).toEqual(1);
-  });
-
-  test('target is Object', () => {
-    const target = {foo: 1};
-    // if target is Object, its properties will be the properties of new object.
-    const result = Object.assign(target, {a: 2});
-    expect(typeof result).toBe('object');
-    expect(result.a).toEqual(2);
-    expect(result.foo).toEqual(1);
-  });
-
-  test('target is String', () => {
-    // if target is String, the return value should be a new object whose value is target.
-    const result = Object.assign('1', {a: 2});
-    expect(typeof result).toBe('object');
-    expect(result.valueOf()).toEqual('1');
-  });
-
-  test('target is Symbol', () => {
-    // if target is Symbol, the return value should be a new Symbol object whose [[SymbolData]] value is target.
-    const target = Symbol('foo');
-    const result = Object.assign(target, {a: 1});
-    expect(typeof result).toBe('object');
-    expect(result.toString()).toEqual('Symbol(foo)');
-  });
-
-  test('target is Undefined', () => {
-    // if target is Undefined, should throw a TypeError exception.
-    // @ts-ignore
-    expect(() => Object.assign(undefined, {a: 1})).toThrow(TypeError);
-  });
-
-  test('assign descriptor', () => {
-    const descriptor = Object.getOwnPropertyDescriptor(Object, 'assign');
-    expect(descriptor).toHaveProperty('writable', true);
-    expect(descriptor).toHaveProperty('enumerable', false);
-    expect(descriptor).toHaveProperty('configurable', true);
-  });
-
-  test('assignment to readonly property of target must throw a typeerror exception', () => {
-    // Assignment to readonly property of target must throw a TypeError exception
-    expect(() => Object.assign('a', [1])).toThrow(TypeError);
-  });
-
-  test('invoked as constructor', () => {
-    /*
-    Built-in function objects that are not identified as constructors do not
-    implement the [[Construct]] internal method unless otherwise specified in
-    the description of a particular function.
-    */
-    expect(() => {
-      // @ts-ignore
-      new Object.assign({});
-    }).toThrow(TypeError);
-  });
-
-  test('assign name', () => {
-    /*
-    ES6 Section 17:
-    Every built-in Function object, including constructors, that is not
-    identified as an anonymous function has a name property whose value is a
-    String. Unless otherwise specified, this value is the name that is given to
-    the function in this specification.
-    [...]
-    Unless otherwise specified, the name property of a built-in Function
-    object, if it exists, has the attributes { [[Writable]]: false,
-    [[Enumerable]]: false, [[Configurable]]: true }.
-    */
-    expect(Object.assign.name).toBe('assign');
-    const descriptor = Object.getOwnPropertyDescriptor(Object.assign, 'name');
-    expect(descriptor).toHaveProperty('writable', false);
-    expect(descriptor).toHaveProperty('enumerable', false);
-    expect(descriptor).toHaveProperty('configurable', true);
-  });
-
-  test('source - get attributes error', () => {
-    // Errors thrown during retrieval of source object attributes
-    const source = {
-      get attr() {throw new TestError();}
-    };
-    expect(() => Object.assign({}, source)).toThrow(TestError);
-  });
-
-  test('source - non-enumerable', () => {
-    // Does not assign non-enumerable source properties
-    const target = {};
-    const source = Object.defineProperty({}, 'attr', {value: 1, enumerable: false});
-    const result = Object.assign(target, source);
-
-    expect(Object.hasOwnProperty.call(target, 'attr')).toBe(false);
-    expect(result).toEqual(target);
-  });
-
-  test('source - own property error', () => {
-    // Invoked with a source whose own property descriptor cannot be retrieved
-    const source = new Proxy({
-      attr: null
-    }, {
-      getOwnPropertyDescriptor: () => {
-        throw new TestError();
-      }
-    });
-    expect(() => Object.assign({}, source)).toThrow(TestError);
-  });
-
-  test('source - own property keys error', () => {
-    // Invoked with a source whose own property keys cannot be retrieved
-    const source = new Proxy({}, {
-      ownKeys: () => { throw new TestError(); }
-    });
-    expect(() => Object.assign({}, source)).toThrow(TestError);
-  });
-
-  test('strings and symbol order', () => {
-    // Symbol-valued properties are copied after String-valued properties.
-    const log: string[] = [];
-    const sym1 = Symbol('x');
-    const sym2 = Symbol('y');
-    const source = {};
-
-    Object.defineProperty(source, sym1, {
-      get: () => log.push('get sym(x)'),
-      enumerable: true, configurable: true,
-    });
-    Object.defineProperty(source, 'a', {
-      get: () => log.push('get a'),
-      enumerable: true, configurable: true,
-    });
-    Object.defineProperty(source, sym2, {
-      get: () => log.push('get sym(y)'),
-      enumerable: true, configurable: true,
-    });
-    Object.defineProperty(source, 'b', {
-      get: () => log.push('get b'),
-      enumerable: true, configurable: true,
-    });
-
-    Object.assign({}, source);
-    expect(log).toEqual(['get a', 'get b', 'get sym(x)', 'get sym(y)']);
-  });
-
-  test('target is frozen accessor property set succeeds', () => {
-    // [[Set]] to accessor property of frozen `target` succeeds.
-    let value1 = 1;
-    const target1 = {
-      set foo(val: any) { value1 = val; },
-    };
-    Object.freeze(target1);
-    Object.assign(target1, {foo: 2});
-    expect(value1).toBe(2);
-
-    const sym = Symbol();
-    let value2 = 1;
-    const target2 = Object.freeze({
-      set [sym](val: any) { value2 = val; },
-    });
-    Object.freeze(target2);
-    Object.assign(target2, {[sym]: 2});
-    expect(value2).toBe(2);
-  });
-
-  test('target is frozen data property set throws', () => {
-    // [[Set]] to data property of frozen `target` fails with TypeError.
-    const sym = Symbol();
-    const target1 = {[sym]: 1};
-    Object.freeze(target1);
-    expect(() => Object.assign(target1, {[sym]: 1})).toThrow(TypeError);
-
-    const target2 = Object.freeze({foo: 1});
-    expect(() => Object.assign(target2, {foo: 1})).toThrow(TypeError);
-  });
-
-  test('target is non extensible existing accessor property', () => {
-    // [[Set]] to existing accessor property of non-extensible `target` is successful.
-    let value1 = 1;
-    const target1 = Object.preventExtensions({
-      set foo(val: any) { value1 = val; },
-    });
-    Object.assign(target1, {foo: 2});
-    expect(value1).toBe(2);
-
-    const sym = Symbol();
-    let value2 = 1;
-    const target2 = {
-      set [sym](val: any) { value2 = val; },
-    };
-    Object.preventExtensions(target2);
-    Object.assign(target2, {[sym]: 2});
-    expect(value2).toBe(2);
-  });
-
-  test('target is non extensible existing data property', () => {
-    // [[Set]] to existing data property of non-extensible `target` is successful.
-    const target1 = Object.preventExtensions({foo: 1});
-    Object.assign(target1, {foo: 2});
-    expect(target1.foo).toBe(2);
-
-    const sym = Symbol();
-    const target2 = {[sym]: 1};
-    Object.preventExtensions(target2);
-    Object.assign(target2, {[sym]: 2});
-    expect(target2[sym]).toBe(2);
-  });
-
-  test('target is non-extensible property creation throws', () => {
-    // [[Set]] to non-existing property of non-extensible `target` fails with TypeError.
-    const target1 = Object.preventExtensions({foo: 1});
-    expect(() => Object.assign(target1, {get bar() {return;}})).toThrow(TypeError);
-
-    const target2 = {};
-    Object.preventExtensions(target2);
-    expect(() => Object.assign(target2, {[Symbol()]: 1})).toThrow(TypeError);
-  });
-
-  test('target is sealed existing accessor property', () => {
-    // [[Set]] to existing accessor property of sealed `target` is successful.
-    let value1 = 1;
-    const target1 = Object.seal({
-      set foo(val: any) { value1 = val; }
-    });
-    Object.assign(target1, {foo: 2});
-    expect(value1).toBe(2);
-
-    const sym = Symbol();
-    let value2 = 1;
-    const target2 = {
-      set [sym](val: any) { value2 = val; }
-    };
-    Object.seal(target2);
-    Object.assign(target2, {[sym]: 2});
-    expect(value2).toBe(2);
-  });
-
-  test('target is sealed existing data property', () => {
-    // [[Set]] to existing data property of sealed `target` is successful.
-    const target1 = Object.seal({foo: 1});
-    Object.assign(target1, {foo: 2});
-    expect(target1.foo).toBe(2);
-
-    const sym = Symbol();
-    const target2 = {[sym]: 1};
-    Object.seal(target2);
-    Object.assign(target2, {[sym]: 2});
-    expect(target2[sym]).toBe(2);
-  });
-
-  test('target is sealed property creation throws', () => {
-    // [[Set]] to non-existing property of sealed `target` fails with TypeError.
-    const target1 = Object.seal({foo: 1});
-    expect(() => Object.assign(target1, {get bar() {return;}})).toThrow(TypeError);
-
-    const target2 = {};
-    Object.seal(target2);
-    expect(() => Object.assign(target2, {[Symbol()]: 1})).toThrow(TypeError);
-  });
-
-  test('target set not-writable', () => {
-    // Errors thrown during definition of target object attributes
-    const target = {};
-    Object.defineProperty(target, 'attr', {writable: false});
-    expect(() => Object.assign(target, {attr: 1})).toThrow(TypeError);
-  });
-
-  test('target set user error', () => {
-    // Errors thrown during definition of target object attributes
-    const target = {};
-    Object.defineProperty(target, 'attr', {
-      set: (_) => { throw new TestError(); }
-    });
-    expect(() => Object.assign(target, {attr: 1})).toThrow(TestError);
-  });
-
-  test('prototype pollution via __proto__', () => {
-    const maliciousPayload = '{"a": 1, "__proto__": {"polluted": true}}';
-    const a: any = {};
-    const result = Object.assign({}, JSON.parse(maliciousPayload));
-
-    expect(({} as any).polluted).not.toBe(true); // safe Plain Old Javascript Object
-    expect(a.polluted).not.toBe(true); // safe a input
-    expect(result.polluted).toBe(true);
-  });
-
-  test('prototype pollution via constructor', () => {
-    const maliciousPayload = '{"a": 1, "constructor": {"prototype": {"polluted": true}}}';
-    const a: any = {};
-    const result = Object.assign({}, JSON.parse(maliciousPayload));
-
-    expect(result.constructor.prototype.polluted).toBe(true);
-    expect(a.constructor.prototype.polluted).toBe(undefined);
-    expect(({} as any).constructor.prototype.polluted).toBe(undefined);
-  });
-});