{% if collectionIcon %}{% include "static/assets/" + collectionIcon %}{% endif %}
diff --git a/site/views/blogs/ESL v5.0.0 Migartion Guide.md b/site/views/blogs/ESL v5.0.0 Migartion Guide.md
new file mode 100644
index 0000000000..428c5d925a
--- /dev/null
+++ b/site/views/blogs/ESL v5.0.0 Migartion Guide.md
@@ -0,0 +1,80 @@
+---
+layout: content
+name: ESL v5.0.0 Migration Guide
+title: Migrating from ESL v4.*.* to ESL v5.0.0
+tags: [news, blogs, draft]
+date: 2024-10-31
+---
+
+The ESL version 5.0.0 has just been released and comes with a lot of new features and improvements.
+This guide will help you to migrate your existing ESL v4.\*.* project to ESL v5.0.0.
+
+---
+
+## Preparation
+We recommend that you consider using the ESL ESLint plugin to check your codebase for compatibility with ESL v5.0.0.
+It will help you to find and fix most of the issues before you start the migration process.
+The points not marked with `🔧` in the breaking changes section are covered by the ESLint plugin checks and could be fixed automatically.
+
+---
+
+## Breaking Changes
+
+- ### Browser Support
+ ESL v5.0.0 no longer supports IE11 and ES5 target.
+ ESL UI site renderer and ESL polyfills no longer support Edge old versions and ES6 polyfils.
+ In case for some reason you still need to support IE11 or ES5 target you should use proper transpilation and polyfilling tools on your side.
+
+- ### ESL Core / ESL Utils
+ - #### Direct imports changes
+ - 🔧 `prop`, `attr`, `boolAttr`, `jsonAttr`, `listen` are no longer available in `esl-base-element` and `esl-mixin-element` exports,
+ to use them you should import them from `esl-utils/decorators` directly or from the library root.
+ - #### ESL Utils API Changes
+ - `Rect` utility object is now immutable, so you can't change its properties directly.
+ If you modify the `Rect` object trough builtin methods, you will get a new object with the updated properties.
+ - #### ESL Utils Retired Functionality
+ - `DeviceDetector.TOUCH_EVENTS` and `TOUCH_EVENTS` are retired from the `device-detector` module.
+ - Note that the `DeviceDetector` class is now deprecated. Use direct checks instead.
+ - `createZIndexIframe` and `is-fixes` module are no longer available due to drop of IE11 support.
+ - `RTLUtils` and `TraversingUtils` are retired. Use separate methods instead.
+ - 🔧 `TraversingQuery` is retired as alias. Use `ESLTraversingQuery` instead.
+ - 🔧 `deepCompare` is retired as alias. Use `isEqual` instead.
+ - 🔧 `generateUId` is retired as alias. Use `randUID` instead.
+ - 🔧 `EventUtils` is retired as alias. Use `ESLEventUtils` instead.
+ - #### `SynteticEventTarget` API Changes
+ - `addListener` and `removeListener` shorthand are no longer supported. Use `addEventListener` and `removeEventListener` instead.
+ - `dispatchEvent` no longer accepts the target argument.
+ You can override the target using `overrideEvent` method from `esl-utils/dom/events`.
+ - 🔧 `ESLEventUtils.descriptors` alias of `ESLEventUtils.getAutoDescriptors` is no longer supported, use full method name instead.
+ - #### ESL Media Query
+ - ESL Media Query consume functionality of `SynteticEventTarget` so `addListener` and `removeListener` shorthand are no longer supported.
+ Use `addEventListener` and `removeEventListener` instead.
+
+- ### ESL Toggleables and Triggers
+ - #### ESL Toggleables API Changes
+ - `ToggleableActionParams` alias of `ESLToggleableActionParams` is no longer supported.
+ - `onBeforeShow` and `onBeforeHide` have retired. The constraint now inside `shouldShow`/`shouldHide` methods.
+ Note that `activator` property change now is the part of main toggleable flow.
+ - `this.open` of Toggleables doesn't update until super.onShow/super.onHide is called.
+ Make sure you update `this.open` synchronously or manually notify consumers in case the super call of `onShow/onHide` should be postponed.
+ - #### A11y improvements and focus management (affects ESlPopup)
+ - `a11y` option introduced and now used to control the focus management and a11y for `esl-popup`, `esl-tooltip` (footnotes), `esl-share`, `esl-select` (dropdown).
+ Option available on `ESLToggleable` level and controls focus flow and close on outside action feature.
+ - #### ESL Triggers API Changes
+ - `ESLTrigger` does not have target defined to `::next` by default. You should always define the target explicitly.
+ - #### ESL Panel and Panel Group
+ - `fallback-duration` is no longer in the JSX shape of `ESLPanel` and `ESLPanelGroup`.
+ - #### ESL Popup
+ - Attribute `disable-arrow` no longer supported. Use class `disable-arrow` instead.
+
+- ### ESL Footnotes
+ - `ESLNote` now based on `ESLBaseTrigger` so active marker now called `active` instead of `tooltip-shown`.
+
+- ### ESL Image
+ - CSS aspect-ratio styles are no longer distributed with ESL Image.
+ You should define them in your project styles or use a separate package for that.
+ - Note that ESL Image is now deprecated. Consider using native Image element with optional help from `esl-image-utils` module.
+
+- ### ESL Media
+ - `load-cls-target`, `load-cls-accepted` and `load-cls-declined` use `load-condition-class` and `load-condition-class-target` instead.
+ - `disabled` marker is no longer supported, use `lazy="manual"` instead (the `force` option of `play` method works the same way with the new lazy option).
diff --git a/site/views/core/esl-eslint-plugin.njk b/site/views/core/esl-eslint-plugin.njk
index d7a14e6c8f..618f3bc7be 100644
--- a/site/views/core/esl-eslint-plugin.njk
+++ b/site/views/core/esl-eslint-plugin.njk
@@ -3,7 +3,7 @@ layout: content
title: 'Support and Migration: ESL ESLint Deprecation Rules'
seoTitle: Custom ESLint deprecation rules to assist ESL version migration
name: Support and Migration (ESLint Rules)
-tags: [core, new]
+tags: [core]
order: 10
---
diff --git a/site/views/core/esl-event-listener/core-support.njk b/site/views/core/esl-event-listener/core-support.njk
new file mode 100644
index 0000000000..7d624f67e8
--- /dev/null
+++ b/site/views/core/esl-event-listener/core-support.njk
@@ -0,0 +1,13 @@
+---
+layout: content
+title: ESL Event Listeners - Embedded behavior of `ESLBaseElement` / `ESLMixinElement`
+seoTitle: ESL Event Listeners - Embedded behavior of `ESLBaseElement` / `ESLMixinElement`
+name: Embedded behavior of ESL Element
+tags: [core]
+parent: ESL Event Listeners
+order: 4
+aside:
+source: src/modules/esl-event-listener
+---
+
+{% mdRender 'src/modules/esl-event-listener/docs/4-core-support.md' %}
diff --git a/site/views/core/esl-event-listener/extended-targets.njk b/site/views/core/esl-event-listener/extended-targets.njk
new file mode 100644
index 0000000000..999a5962a9
--- /dev/null
+++ b/site/views/core/esl-event-listener/extended-targets.njk
@@ -0,0 +1,13 @@
+---
+layout: content
+title: ESL Event Listeners - Extended `EventTarget`s and standard optimizations
+seoTitle: ESL Event Listeners - Extended `EventTarget`s and standard optimizations
+name: Extended `EventTarget`s
+tags: [core]
+parent: ESL Event Listeners
+order: 3
+aside:
+source: src/modules/esl-event-listener
+---
+
+{% mdRender 'src/modules/esl-event-listener/docs/3-extended-targets.md' %}
diff --git a/site/views/core/esl-event-listener.njk b/site/views/core/esl-event-listener/index.njk
similarity index 91%
rename from site/views/core/esl-event-listener.njk
rename to site/views/core/esl-event-listener/index.njk
index 4cdfb1b8af..cf2896e2ce 100644
--- a/site/views/core/esl-event-listener.njk
+++ b/site/views/core/esl-event-listener/index.njk
@@ -3,7 +3,7 @@ layout: content
title: ESL Event Listeners
seoTitle: Built-in ESL EventListeners
name: ESL Event Listeners
-tags: [core]
+tags: [core, updated]
order: 2
aside:
source: src/modules/esl-event-listener
diff --git a/site/views/core/esl-event-listener/overview.njk b/site/views/core/esl-event-listener/overview.njk
new file mode 100644
index 0000000000..d86bf3e805
--- /dev/null
+++ b/site/views/core/esl-event-listener/overview.njk
@@ -0,0 +1,13 @@
+---
+layout: content
+title: ESL Event Listeners - Basic concepts
+seoTitle: ESL Event Listeners - Basic concepts
+name: Basic concepts
+tags: [core]
+parent: ESL Event Listeners
+order: 1
+aside:
+ source: src/modules/esl-event-listener
+---
+
+{% mdRender 'src/modules/esl-event-listener/docs/1-overview.md' %}
diff --git a/site/views/core/esl-event-listener/public-api.njk b/site/views/core/esl-event-listener/public-api.njk
new file mode 100644
index 0000000000..3650f625d9
--- /dev/null
+++ b/site/views/core/esl-event-listener/public-api.njk
@@ -0,0 +1,13 @@
+---
+layout: content
+title: ESL Event Listeners - Public API (`ESLEventUtils`)
+seoTitle: ESL Event Listeners - Public API (`ESLEventUtils`)
+name: Public API
+tags: [core]
+parent: ESL Event Listeners
+order: 2
+aside:
+ source: src/modules/esl-event-listener
+---
+
+{% mdRender 'src/modules/esl-event-listener/docs/2-public-api.md' %}
diff --git a/site/views/draft/footnotes-regression.njk b/site/views/draft/footnotes-regression.njk
new file mode 100644
index 0000000000..aa893a03af
--- /dev/null
+++ b/site/views/draft/footnotes-regression.njk
@@ -0,0 +1,135 @@
+---
+layout: content
+title: Footnotes (Regression)
+name: Footnotes (Regression)
+tags: [draft]
+icon: examples/footnotes.svg
+aside:
+components:
+- esl-footnotes
+---
+
+
+
+ Text with notes inside the container
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Donec massa sapien faucibus et molestie ac. Mi sit amet mauris commodo quis imperdiet massa. Viverra nibh cras pulvinar mattis nunc sed blandit. In nisl nisi scelerisque eu. Vel turpis nunc eget lorem dolor sed. Nisl pretium fusce id velit. Quam id leo in vitae turpis massa sed. Mauris sit amet massa vitae eiusmod tortor . Ut aliquam purus sit amet luctus venenatis lectus magna.
+ Tincidunt arcu non sodales neque. Lectus quam id leo in vitae turpis massa sed. Iaculis at erat pellentesque adipiscing. Cras pulvinar mattis nunc sed blandit. Vel orci porta non pulvinar neque laoreet suspendisse. A arcu cursus vitae congue mauris rhoncus aenean Mattis cursus mattis molestie vel. Integer vitae justo eget magna fermentum iaculis. Et leo duis ut diam quam nulla porttitor. Blandit volutpat maecenas volutpat blandit aliquam etiam erat velit scelerisque. Nibh nisl condimentum id venenatis a condimentum vitae sapien pellentesque. Pellentesque habitant morbi tristique senectus et netus. Nisl vel pretium lectus quam id leo in vitae. Ac odio tempor orci dapibus ultrices in iaculis nunc sed. Laoreet id donec ultrices tincidunt arcu non sodales neque. Fames ac turpis egestas sed tempus urna et. Nisi scelerisque eu ultrices vitae.
+
+
+ Dolor magna eget est lorem ipsum dolor sit amet. Vel orci porta non pulvinar neque laoreet suspendisse interdum consectetur. In vitae turpis massa sed elementum tempus egestas sed. Dui accumsan sit amet nulla facilisi morbi tempus. Diam quam nulla porttitor massa. Aliquet enim tortor at auctor urna nunc id cursus metus. Volutpat maecenas volutpat blandit aliquam etiam erat. Est pellentesque elit ullamcorper dignissim cras tincidunt lobortis feugiat. Sagittis purus sit amet volutpat consequat. Sit amet porttitor eget dolor morbi. Et netus et malesuada fames ac turpis. Egestas egestas fringilla phasellus faucibus scelerisque eleifend donec pretium vulputate. Pulvinar pellentesque habitant morbi tristique senectus et netus et malesuada. Sit amet cursus sit amet dictum. Potenti nullam ac tortor vitae purus faucibus ornare. In nulla posuere sollicitudin aliquam ultrices sagittis orci. Blandit volutpat maecenas volutpat blandit aliquam etiam erat. Aliquam ultrices sagittis orci aet dolore magna . Sit amet consectetur adipiscing elit pellentesque habitant.
+
+
+ Mattis molestie a iaculis at erat pellentesque adipiscing commodo. Massa tincidunt nunc pulvinar sapien et ligula. Lectus urna duis convallis convallis tellus id interdum. Elit sed vulputate mi sit. Adipiscing commodo elit at imperdiet dui accumsan sit amet nulla. Lacus viverra vitae congue eu consequat ac felis donec et. Eget mauris pharetra et ultrices neque ornare aenean euismod elementum . Mattis aliquam faucibus purus in massa tempor nec feugiat nisl. Est ante in nibh mauris cursus mattis molestie . Velit dignissim sodales ut eu. Quam lacus suspendisse faucibus interdum posuere. Pellentesque habitant morbi tristique senectus et netus. Nisl vel pretium lectus quam id leo in vitae. Magna fringilla urna porttitor rhoncus dolor purus non enim praesent. Vulputate enim nulla aliquet porttitor. Facilisi etiam dignissim diam quis enim lobortis scelerisque fermentum dui. Arcu non sodales neque sodales ut etiam. Adipiscing enim eu turpis egestas pretium aenean pharetra magna ac. A scelerisque purus semper eget duis at tellus at Adipiscing elit pellentesque habitant urna. Feugiat nibh sed pulvinar proin gravida hendrerit lectus. Arcu bibendum at varius Tellus urna cursus mattis molestie vel pharetra vel turpis.
+
+
+
+
+
+
+
+
+
+
+ Components with footnotes inside
+
+ Simple Menu:
+
+
+ Accordion with notes
+
+
+
+ Toggle Accordion #1
+
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore I am note 1 from accordion aliqua.
+ Donec massa sapien faucibus I am note 2 from accordion et molestie ac. Mi sit amet mauris commodo quis imperdiet massa.
+ Viverra nibh cras pulvinar mattis nunc sed blandit. In nisl nisi scelerisque eu. Vel turpis nunc eget lorem dolor sed.
+
+
+
+
+
+
+ Toggle Accordion #2
+
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore I am note 3 from accordion aliqua.
+ Donec massa sapien faucibus et molestie ac. Mi sit amet mauris commodo I am note 4 from accordion quis imperdiet massa.
+ Viverra nibh cras pulvinar mattis nunc sed blandit. In nisl nisi scelerisque eu. Vel turpis nunc eget lorem dolor sed. Nisl pretium fusce id velit.
+ Quam id leo in vitae turpis massa sed. Mauris sit amet. Ut aliquam purus sit amet luctus venenatis lectus magna.
+
+
+
+
+
+
+ Toggle Accordion #3
+
+
+
+
+ Nam libero justo laoreet sit amet cursus. Nibh ipsum consequat nisl vel pretium. Elit sed vulputate mi sit amet.
+ Urna condimentum mattis pellentesque id. Non nisi est sit amet facilisis magna etiam tempor. Arcu risus quis varius quam quisque.
+ At auctor urna nunc id cursus metus aliquam eleifend. Dignissim suspendisse in est ante in nibh mauris cursus mattis.
+ Phasellus vestibulum lorem sed risus ultricies tristique nulla. Cursus risus at ultrices mi tempus imperdiet nulla malesuada.
+ Ultrices dui sapien eget mi proin sed libero. Quis risus sed vulputate odio ut enim. Morbi tristique senectus et netus.
+ Tellus mauris a diam maecenas sed enim ut. Id leo in vitae turpis massa sed.
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore I am note 5 from accordion aliqua.
+ Donec massa sapien faucibus et molestie ac. Mi sit amet mauris commodo quis imperdiet massa. Viverra nibh I am note 6 from accordion cras pulvinar mattis nunc sed blandit.
+ In nisl nisi scelerisque eu. Vel turpis nunc eget lorem dolor sed. Nisl pretium fusce id velit. Quam id leo in vitae turpis massa sed. Mauris sit amet.
+ Ut aliquam purus sit amet luctus venenatis lectus magna.
+
+
+
+
+
+
+
+
+
diff --git a/site/views/examples/footnotes.njk b/site/views/examples/footnotes.njk
index ba6187b687..b3df713e9b 100644
--- a/site/views/examples/footnotes.njk
+++ b/site/views/examples/footnotes.njk
@@ -3,7 +3,7 @@ layout: content
title: Footnotes
seoTitle: Auto-collected footnotes custom elements example based on ESL web components
name: Footnotes
-tags: [examples, beta]
+tags: [examples]
icon: examples/footnotes.svg
aside:
components:
@@ -14,465 +14,309 @@ aside:
- Text with notes (disabled grouping and used custom back to note label)
-
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
- Donec massa sapien faucibus et molestie ac. Mi sit amet mauris commodo quis imperdiet massa. Viverra nibh cras pulvinar mattis nunc sed blandit.
- In nisl nisi scelerisque eu. Vel turpis nunc eget lorem dolor sed. Nisl pretium fusce id velit. Quam id leo in vitae turpis massa sed.
- Mauris sit amet massa vitae tortor . Ut aliquam purus sit amet luctus venenatis lectus magna.
-
-
- Dolor magna eget est lorem ipsum dolor sit amet. Vel orci porta non pulvinar neque laoreet suspendisse interdum consectetur.
- In vitae turpis massa sed elementum tempus egestas sed. Dui accumsan sit amet nulla facilisi morbi tempus.
- Diam quam nulla porttitor massa. Aliquet enim tortor at auctor urna nunc id cursus metus. Volutpat maecenas volutpat blandit aliquam etiam erat.
- Est pellentesque elit ullamcorper dignissim cras tincidunt lobortis feugiat. Sagittis purus sit amet volutpat consequat.
- Sit amet porttitor eget dolor morbi. Et netus et malesuada fames ac turpis. Egestas egestas fringilla phasellus faucibus scelerisque eleifend donec pretium vulputate.
- Pulvinar pellentesque habitant morbi tristique senectus et netus et malesuada. Sit amet cursus sit amet dictum.
- Potenti nullam ac tortor vitae purus faucibus ornare. In nulla posuere sollicitudin aliquam ultrices sagittis orci.
- Blandit volutpat maecenas volutpat blandit aliquam etiam erat. Aliquam ultrices sagittis orci a.
- Sit amet consectetur adipiscing elit pellentesque habitant.
-
-
- Mattis molestie a iaculis at erat pellentesque adipiscing commodo. Massa tincidunt nunc pulvinar sapien et ligula.
- Lectus urna duis convallis convallis tellus id interdum. Elit sed vulputate mi sit. Adipiscing commodo elit at imperdiet dui accumsan sit amet nulla.
- Lacus viverra vitae congue eu consequat ac felis donec et. Eget mauris pharetra et ultrices neque ornare aenean euismod elementum .
- Mattis aliquam faucibus purus in massa tempor nec feugiat nisl. Est ante in nibh mauris cursus mattis molestie .
- Velit dignissim sodales ut eu. Quam lacus suspendisse faucibus interdum posuere. Magna fringilla urna porttitor rhoncus dolor purus non enim praesent.
- Vulputate enim nulla aliquet porttitor. Facilisi etiam dignissim diam quis enim lobortis scelerisque fermentum dui.
- Arcu non sodales neque sodales ut etiam. Adipiscing enim eu turpis egestas pretium aenean pharetra magna ac.
- A scelerisque purus semper eget duis at tellus at urna. Feugiat nibh sed pulvinar proin gravida hendrerit lectus.
- Arcu bibendum at varius et dolore magna vel pharetra vel turpis.
-
-
-
-
-
-
-
-
-
-
- Text without footnotes container
-
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
- et dolore magna aliqua. Donec massa sapien faucibus et molestie ac.
- Mi sit amet mauris commodo quis imperdiet massa. Viverra nibh cras pulvinar mattis nunc sed blandit.
- In nisl nisi scelerisque eu. Vel turpis nunc eget lorem dolor sed. Nisl pretium fusce id velit.
- Quam id leo in vitae turpis massa sed. Mauris sit amet massa vitae tortor .
- Ut aliquam purus sit amet luctus venenatis lectus magna.
-
-
-
-
-
-
-
-
- Text with nested notes
-
-
-
+
+
+
-
- יש המון גרסאות זמינות לפסקאות של Lorem Ipsum. אבל רובם עברו שינויים בצורה זו או
- את אחת אחרת, על ידי השתלת הומור או מילים אקראיות שלאראות אפילו מעט אמינות. אם אתה הולך להשתמש במקטעים של של Lorem Ipsum
- אתה צריך להיות בטוח שאין משהו מביך חבוי בתוך הטקסט. כל מחוללי הטקסט של Lorem Ipsum שנמצאים ברשת האינטרנט מכוונים לחזור על טקסטים מוגדרים מראש לפי הנדרש.
- וזה הופך אותנו למחוללי טקסט אמיתיים ראשונים באינטרנט. אנו משתמשים במילון עם מעל 200 ערכים בלטינית משולבים במבני
- משפטים על מנת לשוות לטקט מראה הגיוני. ולכן הטקסט של Lorem Ipsum לעולם לא יכיל טקסטים חוזרים, הומור, או מילים לא מאופייניות וכדומה
-
+
-
-
- Text with notes which ignores on different breakpoints
-
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore I am always ignored aliqua.
- Donec massa sapien faucibus I am never ignored et molestie ac. Mi sit amet mauris commodo quis imperdiet massa.
- Viverra nibh cras pulvinar mattis nunc sed blandit. In nisl nisi scelerisque eu. Vel turpis nunc eget lorem dolor sed. Nisl pretium fusce id velit.
- Quam id leo in vitae turpis massa sed. Mauris sit amet. Ut aliquam purus sit amet luctus venenatis lectus magna.
-
-
- Arcu cursus vitae congue mauris. Orci a scelerisque purus semper eget duis at tellus at. Metus aliquam eleifend mi in. Vitae justo eget magna fermentum iaculis eu non. Iaculis nunc sed augue lacus viverra.
- Et netus et malesuada fames ac turpis. Sed vulputate mi sit amet mauris. Varius morbi enim nunc faucibus. At erat pellentesque adipiscing commodo elit at imperdiet.
- Feugiat pretium nibh ipsum consequat. Ipsum dolor sit amet consectetur. Id porta nibh venenatis cras sed felis. Nam aliquam sem et tortor consequat. Vestibulum sed arcu non odio euismod lacinia at quis risus.
- Augue ut lectus arcu bibendum at varius I am ignored at a XS, SM breakpoint vel pharetra.
- Felis eget velit aliquet I am ignored at a MD, LG, XL breakpoints sagittis id consectetur purus.
- At I am ignored at a XL breakpoint lectus urna duis I am ignored at a LG breakpoint convallis.
- Tempus quam pellentesque I am ignored at a MD breakpoint nec nam aliquam.
-
-
- Bibendum I am ignored at a SM breakpoint neque egestas congue I am ignored at a XS breakpoint quisque egestas diam in arcu cursus.
- Enim tortor at auctor urna nunc id cursus metus. Et malesuada fames ac turpis. Duis tristique sollicitudin nibh sit amet commodo nulla facilisi nullam. Massa id neque aliquam vestibulum morbi.
- In mollis nunc sed id semper. Massa tincidunt dui ut ornare lectus sit amet est placerat. Nunc congue nisi vitae suscipit tellus mauris a. Lobortis scelerisque fermentum dui faucibus in ornare.
- Maecenas ultricies mi eget mauris pharetra et ultrices neque ornare. A iaculis at erat pellentesque adipiscing commodo. Lacus laoreet non curabitur gravida arcu. Diam vel quam elementum pulvinar.
- Sed viverra tellus in hac habitasse. Id porta nibh venenatis cras sed felis. Enim blandit volutpat maecenas volutpat.
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/esl-event-listener/README.md b/src/modules/esl-event-listener/README.md
index 6e66daa1f5..0eb64c55dd 100644
--- a/src/modules/esl-event-listener/README.md
+++ b/src/modules/esl-event-listener/README.md
@@ -18,768 +18,8 @@ And most importantly, you do not need the original callback handler to do this.
---
-## Basic concepts
-
-The ESL event listener module is based on the following major terms and classes:
-
-### The `host`
-
-Everything that happens with ESL event listeners should be associated with a `host` object.
-The `host` is an object that "owns" (registers / deletes) the subscription.
-
-By default, the `host` is used as an `EventTarget` (or an object implementing `EventTarget` interface) to subscribe.
-But the `host` object is not necessarily related to an `EventTarget`.
-We have at least two options to change the target. First of all, you can define the target explicitly.
-Another way is to specify the default DOM target of the host object by providing a special `$host` key
-(see `ESLMixinElement` implementation).
-
-The `host` object is also used as a context to call the handler function of the subscription.
-
-### The `handler`
-
-The `handler` is a function that is used to process the subscription event.
-ESL declares a generic type to describe such functions - `ESLListenerHandler`;
-
-```typescript
-export type ESLListenerHandler = (
- event: EType
-) => void;
-```
-
-### The `ESLEventListener` class and _subscription_
-
-The subscriptions created by the ESL event listener module are instances of `ESLEventListener` class.
-All active subscriptions are stored in a hidden property of the `host` object.
-
-`ESLEventListener` has the following basic properties:
-
-- `event` - event type that the subscription is listening to;
-- `handler` - reference for the function to call to handle the event (see [The handler](#the-handler));
-- `host` - reference for the object that holds the subscription (see [The host](#the-host));
-- `target` - definition of `EventTarget` element (or string `TraversingQuery` to find it, see details in [`ESLEventDesriptor`](#descriptors-esleventdesriptor-esleventdesriptorfn));
-- `selector` - CSS selector to use built-in event delegation;
-- `capture` - marker to use the capture phase of the DOM event life-cycle;
-- `passive` - marker to use passive (non-blocking) subscription of the native event (if supported);
-- `once` - marker to destroy the subscription after the first event catch.
-- `group` - auxiliary property to group subscriptions. Does not affect the subscription behavior. Can be used for filtering and bulk operations.
-
-All of the `ESLEventListener` instance fields are read-only; the subscription can't be changed once created.
-
-The `ESLEventListener`, as a class, describes the subscription behavior and
-contains static methods to create and manage subscriptions.
-
-### Descriptors (`ESLEventDesriptor`, `ESLEventDesriptorFn`)
-
-The event listener _Descriptor_ is an object to describe future subscriptions.
-The ESL event listeners module has a few special details regarding such objects.
-
-A simple descriptor is an object that is passed to ESL event listener API to create a subscription.
-It contains almost the same set of keys as the `ESLEventListener` instance.
-
-In addition to that, ESL allows you to combine the `ESLEventDesriptor` data with the handler function.
-`ESLEventDesriptorFn` is a function handler that is decorated with the `ESLEventDesriptor` properties.
-
-Here is the list of supported keys of `ESLEventDesriptor`:
-
-- #### `event` key
-
- Type: `string | PropertyProvider`
- Description: the event type for subscription.
- Can be provided as a string or via provider function that will be called right before the subscription.
-
- The event string (as a literal, or returned by `PropertyProvider`) can declare multiple event types separated by space.
- ESL will create a subscription (`ESLEventListener` object) for each event type in this case.
-
-- #### `target` key
-
- Type: `string | EventTarget | EventTarget[] | PropertyProvider`
- Default Value: `host` object itself or `$host` key of the `host` object
- Description: the key to declare exact EventTarget for the subscription.
- In case the `target` key is a string it is considered as a [`TraversingQuery`](../esl-traversing-query/README.md).
- The query finds a target relatively to `host | host.$host` object, or in bounds of the DOM tree if it is absolute.
- The `target` key also supports an exact reference for `EventTarget`(s).
-
- ⚠ Any `EventTarget` or even ESL `SynteticEventTarget` (including [`ESLMediaQuery`](../esl-media-query/README.md))
- can be a target for listener API.
-
- ⚠ See [OOTB Extended Event Targets](#extended-event-targets) of ESL to know how to optimize handling of frequent events.
-
- The `target` property can be declared via `PropertyProvider` as well.
-
-- #### `selector` key
-
- Type: `string | PropertyProvider`
- Default Value: `null`
- Description: the CSS selector to filter event targets for event delegation mechanism.
-
- ⚠ If you want to get the currently delegated event target, you can access the `$delegate` key under the received event
- instance. In order to have access to `$delegate` strictly typed use the `DelegatedEvent` type decorator.
-
- E.g.:
- ```typescript
- @listen({ event: 'click', selector: 'button' })
- onClick(e: DelegatedEvent /* instead of MouseEvent */) {
- const delegate = e.$delegate; //instaead of e.target && e.target.closest('button');
- ...
- }
- ```
-
- Supports `PropertyProvider` to declare the computed value as well.
-
-- #### `condition` key
-
- Type: `bollean | PropertyProvider`
- Default Value: `true`
- Description: the function predicate or boolean flag to check if the subscription should be created. Resolves right before the subscription.
-
- Useful in combination with `@listen` decorator to declare subscriptions.
-
- ```typescript
- class MyEl extends ESLBaseElement {
- @attr() enabled = true;
-
- @listen({event: 'click', condition: (that) => that.enabled})
- onClick(e) {}
-
- attributeChangedCallback(name, oldValue, newValue) {
- if (name === 'enabled') {
- ESLEventUtils.unsubscribe(this, this.onClick);
- ESLEventUtils.subscribe(this, this.onClick);
- }
- }
- }
- ```
-
-- #### `capture` key
-
- Type: `boolean`
- Default Value: `false`
- Description: marker to use capturing phase of the DOM event to handle.
-
-- #### `passive` key
-
- Type: `boolean`
- Default Value: `true` if the event type is `wheel`, `mousewheel`, `touchstart` or `touchmove`
- Description: marker to use passive subscription to the native event.
-
- ⚠ ESL uses passive subscription by default for `wheel`, `mousewheel`, `touchstart`, `touchmove` events.
- You need to declare `passive` key explicitly to override this behavior.
-
-- #### `once` key
-
- Type: `boolean`
- Default Value: `false`
- Description: marker to unsubscribe the listener after the first successful handling of the event.
-
-
-- #### `group` key
- Type: `string`
- Description: auxiliary property to group subscriptions. Does not affect the subscription behavior. Can be used for filtering and bulk operations.
-
- E.g.:
- ```typescript
- ESLEventUtils.subscribe(host, {event: 'click', group: 'group'}, handler1);
- ESLEventUtils.subscribe(host, {event: 'click', group: 'group'}, handler2);
- // ...
- ESLEventUtils.unsubscribe(host, {group: 'group'}); // Unsubscribes all subscriptions with the 'group' key
- ```
-
-- #### `auto` key (for `ESLEventDesriptorFn` declaration only)
- Type: `boolean`
- Default Value: `false` for `ESLEventUtils.initDescriptor`, `true` for `@listen` decorator
- Description: marker to make an auto-subscribable descriptor. See [Automatic (collectable) descriptors](#automatic-collectable-descriptors).
-- #### `inherit` key (for `ESLEventDesriptorExt` only)
- Type: `boolean`
- Description: available in extended version of `ESLEventDesriptor` that is used in the descriptor declaration API.
- Allows to inherit `ESLEventDesriptor` data from the `ESLEventDesriptorFn` from the prototype chain.
- See [`initDescriptor`](#-esleventutilsinitdescriptor) usages example.
-
-
-### Automatic (collectable) descriptors
-
-Auto-collectable (or auto-subscribable) descriptors can be subscribed at once during the initialization of the `host` object.
-
-To make an `ESLEventDesriptorFn` auto-collectable, the consumer should declare it with the `auto` marker using
-`ESLEventUtils.initDescriptor` or `@listen` decorator.
-
-⚠ `ESLEventUtils.initDescriptor` (or `@listen`) stores the auto-collectable descriptors in the internal collection on the `host`.
-
-The `ESLBaseElment` and the `ESLMixinElement` subscribes all auto-collectable descriptors in the `connectedCallback`.
-See the usage of [`ESLEventUtils.subscibe`](#-esleventutilssubscribe) for more details.
-
-### `PropertyProvider` for `event`, `selector`, or `target`
-
-The descriptor declaration usually happens with the class declaration when the instance and its subscription
-do not exist. We might have a problem if we want to pass subscription parameters that depend on the instance.
-
-To resolve such a case, the `event`, `selector`, and `target` keys of ESL event listener API support
-`PropertyProvider` mechanism:
-
-```typescript
-type PropertyProvider = (this: unknown, that: unknown) => T;
-```
-
-See examples in the [ESLEventUtils.initDescriptor](#-esleventutilsinitdescriptor) section.
-
----
-
-## Public API (`ESLEventUtils`)
-
-The units mentioned earlier are mostly implementation details of the module.
-
-`ESLEventUtils` is a facade for all ESL event listener module capabilities.
-
-Here is the module Public API:
-
-
-
-### ⚡ `ESLEventUtils.subscribe`
-
-Creates and subscribes an `ESLEventListener`.
-
-- Subscribes all auto-collectable (subscribable) descriptors of the `host` object:
- ```typescript
- ESLEventUtils.subscribe(host: object)
- ```
-- Subscribes `handler` function to the DOM event declared by `eventType` string:
- ```typescript
- ESLEventUtils.subscribe(host: object, eventType: string, handler: ESLListenerHandler)
- ```
-- Subscribes `handler` instance of `ESLEventDescriptorFn` using embedded meta-information:
- ```typescript
- ESLEventUtils.subscribe(host: object, handler: ESLEventDescriptorFn)
- ```
-- Subscribes `handler` function using `ESLEventDescriptor`:
- ```typescript
- ESLEventUtils.subscribe(host: object, descriptor: ESLEventDescriptor, handler: ESLListenerHandler)
- ```
-- Subscribes `handler` instance of `ESLEventDescriptorFn` with `ESLEventDescriptor` overriding meta-data:
- ```typescript
- ESLEventUtils.subscribe(host: object, descriptor: ESLEventDescriptor, handler: ESLEventDescriptorFn)
- ```
-
-**Parameters**:
-
-- `host` - host element to store subscription (event target by default);
-- `eventType` - string DOM event type;
-- `descriptor` - event description data (`ESLEventDescriptor`);
-- `handler` - function callback handler or instance of `ESLEventDescriptorFn`
-
-Examples:
-
-- `ESLEventUtils.subscribe(host);` -
- subscribes all auto-subscriptions of the `host`;
-- `ESLEventUtils.subscribe(host, handlerFn);` -
- subscribes `handlerFn` method (decorated as an `ESLEventDescriptorFn`) to the `handlerFn.target`;
-- `ESLEventUtils.subscribe(host, 'click', handlerFn);` -
- subscribes `handlerFn` function with the passed event type;
-- `ESLEventUtils.subscribe(host, {event: 'scroll', target: window}, handlerFn);` -
- subscribes `handlerFn` function with the passed additional descriptor data.
-
-
-
-### ⚡ `ESLEventUtils.unsubscribe`
-
-Allows unsubscribing existing subscriptions.
-
-```typescript
-unsubscribe(host: HTMLElement, ...criteria: ESLListenerCriteria[]): ESLEventListener[];
-```
-
-**Parameters**:
-
-- `host` - host element to find subscriptions;
-- `criteria` - optional set of criteria to filter listeners to remove.
-
-Examples:
-
-- `ESLEventUtils.unsubscribe(host);` - unsubscribes everything bound to the `host`
-- `ESLEventUtils.unsubscribe(host, handlerFn);` - unsubscribes everything that is bound to the `host` and is handled by the `handlerFn`
-- `ESLEventUtils.unsubscribe(host, 'click');` - unsubscribes everything bound to the `host` and processing `click` event
-- `ESLEventUtils.unsubscribe(host, 'click', handlerFn);` - unsubscribes everything that is bound to the `host`, processing `click` event and is handled by the `handlerFn`
-- There can be any number of criteria.
-
-
-
-### ⚡ `ESLEventUtils.isEventDescriptor`
-
-Predicate to check if the passed argument is a type of `ESLListenerDescriptorFn = ESLEventHandler & Partial`.
-
-```typescript
-ESLEventUtils.isEventDescriptor(obj: any): obj is ESLListenerDescriptorFn;
-```
-
-
-
-### ⚡ `ESLEventUtils.descriptors`
-
-Gathers descriptors from the passed object.
-Accepts criteria to filter the descriptors list.
-
-```typescript
- ESLEventUtils.descriptors(host?: any): ESLListenerDescriptorFn[];
- ESLEventUtils.descriptors(host?: any, ...criteria: ESLListenerDescriptorCriteria[]): ESLListenerDescriptorFn[];
-```
-
-**Parameters**:
-
-- `host` - object to get auto-collectable descriptors from;
-
-
-
-
-### ⚡ `ESLEventUtils.getAutoDescriptors`
-
-Gathers auto-subscribable (collectable) descriptors from the passed object.
-
-Deprecated: prefer using `ESLEventUtils.descriptors` with the `{auto: true}` criteria. As the `getAutoDescriptors` method is going to be removed in 6th release.
-
-```typescript
-ESLEventUtils.getAutoDescriptors(host?: any): ESLListenerDescriptorFn[]
-```
-
-**Parameters**:
-
-- `host` - object to get auto-collectable descriptors from;
-
-
-
-
-### ⚡ `ESLEventUtils.initDescriptor`
-
-Decorates the passed key of the host object as `ESLEventDescriptorFn`
-
-```typescript
-ESLEventUtils.initDescriptor(
- host: T,
- key: keyof T & string,
- desc: ESLEventDescriptorExt
-): ESLEventDescriptorFn;
-```
-
-**Parameters**:
-
-- `host` - host object holder of decorated function;
-- `key` - key of the `host` object that contains a function to decorate;
-- `desc` - `ESLEventDescriptor` (extended) meta information to describe future subscriptions.
-
-The extended `ESLEventDescriptor` information allows passing `inherit` marker to create a new descriptor instance
-based on the descriptor declared in the prototype chain for the same key.
-
-⚠ If such a key is not found, a `ReferenceError` will be thrown.
-
-Example:
- ```typescript
- class MyElement {
- onEvent() {}
- }
- ESLEventUtils.initDescriptor(MyElement.prototype, 'onEvent', {event: 'event'});
-```
-
-#### `@listen` decorator
-
-The `@listen` decorator (available under `esl-utils/decorators`) is syntax sugar above `ESLEventUtils.initDescriptor` method.
-It allows you to declare class methods as an `ESLEventDescriptorFn` using TS `experimentalDecorators` feature.
-
-Listeners described by `@listen` are auto-subscribable if they are not inherited and not declared as manual explicitly.
-In case of inheritance the `auto` marker will be inherited from the parent descriptor.
-
-Example:
-
-```typescript
-class MyEl extends ESLBaseElement {
- private event: string;
- private selector: string;
- // Shortcut with just an event type
- @listen('click')
- onClick() {}
- // Shortcut with event type declared by PropertyProvider
- @listen((that: MyEl) => that.event)
- onEventProvided() {}
- // Full list of options is available
- @listen({event: 'click', target: 'body', capture: true})
- onBodyClick(e) {}
- // Property Providers example
- @listen({
- event: (that: MyEl) => that.event,
- seletor: (that: MyEl) => that.selector
- })
- onEventProvidedExt(e) {}
- // Will not subscribe authomatically
- @listen({event: 'click', auto: false})
- onClickManual(e) {}
-}
-```
-
-
-
-### ⚡ `ESLEventUtils.listeners`
-
-Gathers listeners currently subscribed to the passed `host` object.
-
-```typescript
-ESLEventUtils.listeners(host: object, ...criteria: ESLListenerCriteria[]): ESLEventListener[];
-```
-
-**Parameters**:
-
-- `host` - object that stores and relates to the handlers;
-- `criteria` - optional set of criteria to filter the listeners list.
-
-
-
-### ⚡ `ESLEventUtils.dispatch`
-
-Dispatches custom DOM events.
-The dispatched event is bubbling and cancelable by default.
-
-```typescript
-ESLEventUtils.dispatch(
- el: EventTarget,
- eventName: string,
- eventInit?: CustomEventInit
-): boolean;
-```
-
-**Parameters**:
-
-- `el` - `EventTarget` to dispatch event;
-- `eventName` - name of the event to dispatch;
-- `eventInit` - object that specifies characteristics of the event.
-
-### Listeners Full Showcase Example
-
-```typescript
-class TestCases {
- bind() {
- // Subcribes all auto descriptors (onEventAutoDescSugar and onEventAutoDesc)
- ESLEventUtils.subscribe(this);
-
- // Subscribes onEventManualFn on click
- ESLEventUtils.subscribe(this, 'click', this.onEventManualFn);
-
- // Subscribes onEventManualFn on window resize
- ESLEventUtils.subscribe(this, {event: 'resize', target: window}, this.onEventManualFn);
-
- // Subscribes onEventManualDesc using embeded information
- ESLEventUtils.subscribe(this, this.onEventManualDesc);
-
- // Subscribes onEventManualDesc using merged embeded and passed information
- ESLEventUtils.subscribe(this, {target: window}, this.onEventManualDesc);
- }
-
- unbind() {
- // Unsubcribes all subscriptions
- ESLEventUtils.unsubscribe(this);
-
- // Unsubcribes just onEventAutoDesc
- ESLEventUtils.unsubscribe(this, this.onEventAutoDesc);
- }
-
- @listen('event')
- onEventAutoDescSugar() {}
-
- onEventAutoDesc() {}
-
- onEventManualFn() {}
-
- onEventManualDesc() {}
-}
-
-ESLEventUtils.initDescriptor(TestCases.prototype, 'onEventAutoDesc', {event: 'event', auto: true});
-ESLEventUtils.initDescriptor(TestCases.prototype, 'onEventManualDesc', {event: 'event'});
-```
-
----
-
-## Extended `EventTarget`s and standard optimizations beta
-
-
-
-### ⚡ `ESLDecoratedEventTarget.for`
-
-In cases where the original event of the target happens too frequently to be handled every time,
-it might be helpful to limit its processing. In purpose to do that ESL allows the creation of decorated `EventTargets`.
-The decorated target will process the original target events dispatching with the passed async call decoration function
-(such as debounce or throttle).
-
-The `ESLDecoratedEventTarget.for` creates an instance that decorates passed original `EventTarget` event emitting.
-The instances of `ESLDecoratedEventTarget` are lazy and do not subscribe to the original event
-until they have their own subscriptions of the same event type.
-
-⚠ Note `ESLDecoratedEventTarget.for` method is cached, so created instances will be reused if the inner cache does not
-refuse additional arguments of the decorator. The cache does not handle multiple and non-primitive arguments.
-
-```typescript
-ESLDecoratedEventTarget.for(
- target: EventTarget,
- decorator: (fn: EventListener, ...args: any[]) => EventListener,
- ...args: any[]
-): ESLDecoratedEventTarget;
-```
-
-**Parameters**:
-
-- `target` - original `EventTarget` to consume events;
-- `decorator` - decoration function to decorate original target `EventListener`s;
-- `args` - optional arguments to pass to `decorator`.
-
-**Example:**
-```typescript
-class Component {
- @listen({
- event: 'scroll',
- target: ESLDecoratedEventTarget.for(window, throttle)
- })
- onScroll() {}
-}
-```
-
-#### Sharing of the decorated targets
-
-As was mentioned above, the method `ESLDecoratedEventTarget.for` works with
-a cache for simple cases. But in some cases, we might be interested in creating wrappers with a complex
-param, or we want to limit params usage across the project.
-
-It might sound obvious, but there are no restrictions on sharing exact instances instead of using the method cache.
-
-```typescript
-// shared-event-targets.ts
-export const DEBOUNCED_WINDOW = ESLDecoratedEventTarget.for(window, debounce, 1000);
-```
-
-```typescript
-// module.ts
-class Component {
- @listen({event: 'resize', target: DEBOUNCED_WINDOW})
- onResize() {}
-}
-```
-
-#### Optimize `window.resize` handling with debouncing
-
-```typescript
-import {debounce} from '.../debounce';
-
-ESLEventUtils.subscribe(host, {
- event: 'resize',
- target: /* instead just window */ ESLDecoratedEventTarget.for(window, debounce, 250)
-}, onResizeDebounced);
-```
-
-The sample above allows you to reuse debounced by 250 milliseconds version of the window,
-to receive fewer `resize` events
-(same as any other event types observed on debounced window version)
-
-#### Optimize `window.scroll` handling with throttling
-
-```typescript
-import {throttle} from '.../throttle';
-
-ESLEventUtils.subscribe(host, {
- event: 'scroll',
- target: /* instead just window */ ESLDecoratedEventTarget.for(window, throttle, 250)
-}, onScrollThrottled);
-```
-
-The sample above allows you to reuse throttled by 250 milliseconds version of the window,
-to receive no more than one event per 250 milliseconds `scroll` events
-(same as any other event types observed on debounced window version)
-
-
-
-### ⚡ `ESLResizeObserverTarget.for`
-
-When you deal with responsive interfaces, you might need to observe an element resizes instead of
-responding to the whole window change. There is a tool for this in the native DOM API - `ResizeObserver'.
-The only problem is that it does not use events, while in practice, we work with it in the same way.
-
-`ESLResizeObserverTarget.for` creates cached `ResizeObserver` adaptation to `EventTarget` (`ESLResizeObserverTarget`)
-that allows you to get `resize` events when the observed element changes its size.
-
-```typescript
-ESLResizeObserverTarget.for(el: Element): ESLResizeObserverTarget;
-```
-
-**Parameters**:
-
-- `el` - `Element` to observe size changes.
-
-`ESLResizeObserverTarget` creates itself once for an observed object with a weak reference-based cache.
-So any way of creating `ESLResizeObserverTarget` will always produce the same instance.
-
-`ESLResizeObserverTarget.for(el) /**always*/ === ESLResizeObserverTarget.for(el)`
-So there is no reason to cache it manually.
-
-Usage example:
-
-```typescript
-ESLEventUtils.subscribe(host, {
- event: 'resize',
- target: ESLResizeObserverTarget.for(el)
-}, onResize);
-// or
-ESLEventUtils.subscribe(host, {
- event: 'resize',
- target: (host) => ESLResizeObserverTarget.for(host.el)
-}, onResize);
-```
-
-
-
-### ⚡ `ESLSwipeGestureTarget.for` new
-
-`ESLSwipeGestureTarget.for` is a simple and easy-to-use way to listen for swipe events on any element.
-
-`ESLSwipeGestureTarget.for` creates a synthetic target that produces `swipe` events. It detects `pointerdown` and
-`pointerup` events and based on the distance (`threshold`) between start and end points and time (`timeout`) between
-`pointerdown` and `pointerup` events, triggers `swipe` event on the target element.
-
-```typescript
-ESLSwipeGestureTarget.for(el: Element, settings?: ESLSwipeGestureSetting): ESLSwipeGestureTarget;
-```
-
-**Parameters**:
-
-- `el` - `Element` to listen for swipe events on.
-- `settings` - optional settings (`ESLSwipeGestureSetting`)
-
-Usage example:
-
-```typescript
-ESLEventUtils.subscribe(host, {
- event: 'swipe',
- target: ESLSwipeGestureTarget.for(el)
-}, onSwipe);
-// or
-ESLEventUtils.subscribe(host, {
- event: 'swipe',
- target: (host) => ESLSwipeGestureTarget.for(host.el, {
- threshold: '30px',
- timeout: 1000
- })
-}, onSwipe);
-```
-
-
-
-### ⚡ `ESLWheelTarget.for` new
-
-`ESLWheelTarget.for` is a simple way to listen for 'inert' (long wheel) scrolls events on any element.
-This utility detects `wheel` events, and based on the total amount (distance) of `wheel` events and time (`timeout`) between the first and the last events, it triggers `longwheel` event on the target element.
-
-```typescript
-ESLWheelTarget.for(el: Element, settings?: ESLWheelTargetSetting): ESLWheelTarget;
-```
-
-**Parameters**:
-
-- `el` - `Element` to listen for long wheel events
-- `settings` - optional settings (`ESLWheelTargetSetting`)
-
-The `ESLWheelTargetSetting` configuration includes these optional attributes:
-- `distance` - the minimum distance to accept as a long scroll in pixels (400 by default)
-- `timeout` - the maximum duration of the wheel events to consider it inertial in milliseconds (100 by default)
-
-Usage example:
-
-```typescript
-ESLEventUtils.subscribe(host, {
- event: 'longwheel',
- target: ESLWheelTarget.for(el)
-}, onWheel);
-// or
-ESLEventUtils.subscribe(host, {
- event: 'longwheel',
- target: (host) => ESLWheelTarget.for(host.el, {
- threshold: 30,
- timeout: 1000
- })
-}, onWheel);
-```
-
-
-
-### ⚡ `ESLIntersectionTarget.for` new
-
-`ESLIntersectionTarget.for` is a way to listen for intersections using Intersection Observer API but in an EventTarget
-way.
-
-`ESLIntersectionTarget.for` creates a synthetic target that produces `intersection` events. It detects intersections by
-creating `IntersectionObserver` instance, created using passed `settings: IntersectionObserverInit`.
-
-Note: `ESLIntersectionTarget` does not share `IntersectionObserver` instances unlike caching capabilities of adapters
-mentioned above.
-
-```typescript
-ESLIntersectionTarget.for(el: Element | Element[], settings?: IntersectionObserverInit): ESLIntersectionTarget;
-```
-
-**Parameters**:
-- `el` - `Element` or `Element[]` to listen for intersection events on;
-- `settings` - optional settings (`ESLIntersectionSetting`)
-
-Event API:
-Throws `ESLIntersectionEvent` that implements `IntersectionObserverEntry` original interface.
-
-
----
-
-## Embedded behavior of `ESLBaseElement` / `ESLMixinElement`
-
-### Shortcuts
-
-All the inheritors of `ESLBaseElement` and `ESLMixinElement` contain the short aliases for some `ESLEventUtils` methods.
-The host parameter of the shortcut methods is always targeting the current element/mixin.
-
-- `$$on` ~ `ESLEventUtils.subscribe(this, ...)`
-- `$$off` ~ `ESLEventUtils.unsubscribe(this, ...)`
-- `$$fire` ~ `ESLEventUtils.dispatch(this, ...)`
-
-Example:
-
-```typescript
-this.$$on('click', this.onClick); // ESLEventUtils.subscribe(this, 'click', this.onClick)
-this.$$off('click'); // ESLEventUtils.unsubscribe(this, 'click')
-```
-
-### Auto-subscription / Auto-unbinding
-
-All the inheritors of `ESLBaseElement` and `ESLMixinElement` automatically subscribe to all declared auto-subscribable descriptors
-of their prototype chain.
-
-They also unsubscribe all own listeners attached via ESL automatically on `disconnectedCallback`.
-
-The following short snippet of code describes a listener that will automatically subscribe and unsubscribe
-on connected/disconnected callback inside `ESLBaseElement`:
-
-```typescript
-class MyEl extends ESLBaseElement {
- // connectedCallback() {
- // super.connectedCallback(); // - already contains ESLEventUtils.subscribe(this) call
- // }
-
- // Will be subscribed automatically on connectedCallback and unsubscribed on disconnectedCallback
- @listen('click')
- onClick(e) {
- //...
- }
-}
-```
-
-You can manage the subscription manually and link the whole meta information or part of it with the handler itself
-
-```typescript
-class MyEl extends ESLBaseElement {
- @listen({event: 'click', auto: false}) // Won`t be subscribed automatically
- onClick(e) {
- // ...
- }
-
- myMethod() {
- this.$$on(this.onClick); // Manual subscription
- this.$$on({target: 'body'}, this.onClick); // Manual subscription with parameters (will be merged)
- this.$$off(this.onClick); // Unsubscribes this.onClick method
- }
-}
-```
+Navigation:
+1. [Overview](./docs/1-overview.md)
+2. [Public API, `ESLEventUtils`](./docs/2-public-api.md)
+3. [Extended `EventTarget`s and standard optimizations](./docs/3-extended-targets.md)
+4. [Embedded behavior of `ESLBaseElement` / `ESLMixinElement`](./docs/4-core-support.md)
diff --git a/src/modules/esl-event-listener/docs/1-overview.md b/src/modules/esl-event-listener/docs/1-overview.md
new file mode 100644
index 0000000000..09f535d62c
--- /dev/null
+++ b/src/modules/esl-event-listener/docs/1-overview.md
@@ -0,0 +1,202 @@
+## Basic concepts
+
+The `esl-event-listener` module is based on the following major terms and classes:
+
+### The `host`
+
+Everything that happens with ESL event listeners should be associated with a `host` object.
+The `host` is an object that "owns" (registers / deletes) the subscription.
+
+By default, the `host` is used as an `EventTarget` (or an object implementing `EventTarget` interface) to subscribe.
+But the `host` object is not necessarily related to an `EventTarget`.
+We have at least two options to change the target. First of all, you can define the target explicitly.
+Another way is to specify the default DOM target of the host object by providing a special `$host` key
+(see `ESLMixinElement` implementation).
+
+The `host` object is also used as a context to call the handler function of the subscription.
+
+### The `handler`
+
+The `handler` is a function that is used to process the subscription event.
+ESL declares a generic type to describe such functions - `ESLListenerHandler`;
+
+```typescript
+export type ESLListenerHandler = (
+ event: EType
+) => void;
+```
+
+### The `ESLEventListener` class and _subscription_
+
+The subscriptions created by the ESL event listener module are instances of `ESLEventListener` class.
+All active subscriptions are stored in a hidden property of the `host` object.
+
+`ESLEventListener` has the following basic properties:
+
+- `event` - event type that the subscription is listening to;
+- `handler` - reference for the function to call to handle the event (see [The handler](#the-handler));
+- `host` - reference for the object that holds the subscription (see [The host](#the-host));
+- `target` - definition of `EventTarget` element (or string `TraversingQuery` to find it, see details in [`ESLEventDesriptor`](#descriptors-esleventdesriptor-esleventdesriptorfn));
+- `selector` - CSS selector to use built-in event delegation;
+- `capture` - marker to use the capture phase of the DOM event life-cycle;
+- `passive` - marker to use passive (non-blocking) subscription of the native event (if supported);
+- `once` - marker to destroy the subscription after the first event catch.
+- `group` - auxiliary property to group subscriptions. Does not affect the subscription behavior. Can be used for filtering and bulk operations.
+
+All of the `ESLEventListener` instance fields are read-only; the subscription can't be changed once created.
+
+The `ESLEventListener`, as a class, describes the subscription behavior and
+contains static methods to create and manage subscriptions.
+
+### Descriptors (`ESLEventDesriptor`, `ESLEventDesriptorFn`)
+
+The event listener _Descriptor_ is an object to describe future subscriptions.
+The ESL event listeners module has a few special details regarding such objects.
+
+A simple descriptor is an object that is passed to ESLEventListener API to create a subscription.
+It contains almost the same set of keys as the `ESLEventListener` instance.
+
+In addition to that, ESL allows you to combine the `ESLEventDesriptor` data with the handler function.
+`ESLEventDesriptorFn` is a function handler that is decorated with the `ESLEventDesriptor` properties.
+
+Here is the list of supported keys of `ESLEventDesriptor`:
+
+- #### `event` key
+
+ Type: `string | PropertyProvider`
+ Description: the event type for subscription.
+ Can be provided as a string or via provider function that will be called right before the subscription.
+
+ The event string (as a literal, or returned by `PropertyProvider`) can declare multiple event types separated by space.
+ ESL will create a subscription (`ESLEventListener` object) for each event type in this case.
+
+- #### `target` key
+
+ Type: `string | EventTarget | EventTarget[] | PropertyProvider`
+ Default Value: `host` object itself or `$host` key of the `host` object
+ Description: the key to declare exact EventTarget for the subscription.
+ In case the `target` key is a string it is considered as a [`TraversingQuery`](../esl-traversing-query/README.md).
+ The query finds a target relatively to `host | host.$host` object, or in bounds of the DOM tree if it is absolute.
+ The `target` key also supports an exact reference for `EventTarget`(s).
+
+ ⚠ Any `EventTarget` or even ESL `SynteticEventTarget` (including [`ESLMediaQuery`](../esl-media-query/README.md))
+ can be a target for listener API.
+
+ ⚠ See [OOTB Extended Event Targets](./3-extended-targets.md) of ESL to know how to optimize handling of frequent events.
+
+ The `target` property can be declared via `PropertyProvider` as well.
+
+- #### `selector` key
+
+ Type: `string | PropertyProvider`
+ Default Value: `null`
+ Description: the CSS selector to filter event targets for event delegation mechanism.
+
+ ⚠ If you want to get the currently delegated event target, you can access the `$delegate` key under the received event
+ instance. In order to have access to `$delegate` strictly typed use the `DelegatedEvent` type decorator.
+
+ E.g.:
+ ```typescript
+ @listen({ event: 'click', selector: 'button' })
+ onClick(e: DelegatedEvent /* instead of MouseEvent */) {
+ const delegate = e.$delegate; //instaead of e.target && e.target.closest('button');
+ ...
+ }
+ ```
+
+ Supports `PropertyProvider` to declare the computed value as well.
+
+- #### `condition` key
+
+ Type: `boolean | PropertyProvider`
+ Default Value: `true`
+ Description: the function predicate or boolean flag to check if the subscription should be created. Resolves right before the subscription.
+
+ Useful in combination with `@listen` decorator to declare subscriptions.
+
+ ```typescript
+ class MyEl extends ESLBaseElement {
+ @attr() enabled = true;
+
+ @listen({event: 'click', condition: (that) => that.enabled})
+ onClick(e) {}
+
+ attributeChangedCallback(name, oldValue, newValue) {
+ if (name === 'enabled') {
+ ESLEventUtils.unsubscribe(this, this.onClick);
+ ESLEventUtils.subscribe(this, this.onClick);
+ }
+ }
+ }
+ ```
+
+- #### `capture` key
+
+ Type: `boolean`
+ Default Value: `false`
+ Description: marker to use the capturing phase of the DOM event to handle.
+
+- #### `passive` key
+
+ Type: `boolean`
+ Default Value: `true` if the event type is `wheel`, `mousewheel`, `touchstart` or `touchmove`
+ Description: marker to use passive subscription to the native event.
+
+ ⚠ ESL uses passive subscription by default for `wheel`, `mousewheel`, `touchstart`, `touchmove` events.
+ You need to declare `passive` key explicitly to override this behavior.
+
+- #### `once` key
+
+ Type: `boolean`
+ Default Value: `false`
+ Description: marker to unsubscribe the listener after the first successful handling of the event.
+
+
+- #### `group` key
+ Type: `string`
+ Description: auxiliary property to group subscriptions. Does not affect the subscription behavior. Can be used for filtering and bulk operations.
+
+ E.g.:
+ ```typescript
+ ESLEventUtils.subscribe(host, {event: 'click', group: 'group'}, handler1);
+ ESLEventUtils.subscribe(host, {event: 'click', group: 'group'}, handler2);
+ // ...
+ ESLEventUtils.unsubscribe(host, {group: 'group'}); // Unsubscribes all subscriptions with the 'group' key
+ ```
+
+- #### `auto` key (for `ESLEventDesriptorFn` declaration only)
+ Type: `boolean`
+ Default Value: `false` for `ESLEventUtils.initDescriptor`, `true` for `@listen` decorator
+ Description: marker to make an auto-subscribable descriptor. See [Automatic (collectable) descriptors](#automatic-collectable-descriptors).
+- #### `inherit` key (for `ESLEventDesriptorExt` only)
+ Type: `boolean`
+ Description: available in extended version of `ESLEventDesriptor` that is used in the descriptor declaration API.
+ Allows to inherit `ESLEventDesriptor` data from the `ESLEventDesriptorFn` from the prototype chain.
+ See [`initDescriptor`](#-esleventutilsinitdescriptor) usages example.
+
+
+### Automatic (collectable) descriptors
+
+Auto-collectable (or auto-subscribable) descriptors can be subscribed at once during the initialization of the `host` object.
+
+To make an `ESLEventDesriptorFn` auto-collectable, the consumer should declare it with the `auto` marker using
+`ESLEventUtils.initDescriptor` or `@listen` decorator.
+
+⚠ `ESLEventUtils.initDescriptor` (or `@listen`) stores the auto-collectable descriptors in the internal collection on the `host`.
+
+The `ESLBaseElment` and the `ESLMixinElement` subscribe all auto-collectable descriptors in the `connectedCallback`.
+See the usage of [`ESLEventUtils.subscibe`](#-esleventutilssubscribe) for more details.
+
+### `PropertyProvider` for `event`, `selector`, or `target`
+
+The descriptor declaration usually happens with the class declaration when the instance and its subscription
+do not exist. We might have a problem if we want to pass subscription parameters that depend on the instance.
+
+To resolve such a case, the `event`, `selector`, and `target` keys of ESL event listener API support
+`PropertyProvider` mechanism:
+
+```typescript
+type PropertyProvider = (this: unknown, that: unknown) => T;
+```
+
+See examples in the [ESLEventUtils.initDescriptor](#-esleventutilsinitdescriptor) section.
diff --git a/src/modules/esl-event-listener/docs/2-public-api.md b/src/modules/esl-event-listener/docs/2-public-api.md
new file mode 100644
index 0000000000..c08aa15a29
--- /dev/null
+++ b/src/modules/esl-event-listener/docs/2-public-api.md
@@ -0,0 +1,266 @@
+## Public API (`ESLEventUtils`)
+
+The units mentioned earlier are mostly implementation details of the module.
+
+`ESLEventUtils` is a facade for all ESL event listener module capabilities.
+
+Here is the module Public API:
+
+
+
+### ⚡ `ESLEventUtils.subscribe`
+
+Creates and subscribes an `ESLEventListener`.
+
+- Subscribes all auto-collectable (subscribable) descriptors of the `host` object:
+ ```typescript
+ ESLEventUtils.subscribe(host: object)
+ ```
+- Subscribes `handler` function to the DOM event declared by `eventType` string:
+ ```typescript
+ ESLEventUtils.subscribe(host: object, eventType: string, handler: ESLListenerHandler)
+ ```
+- Subscribes `handler` instance of `ESLEventDescriptorFn` using embedded meta-information:
+ ```typescript
+ ESLEventUtils.subscribe(host: object, handler: ESLEventDescriptorFn)
+ ```
+- Subscribes `handler` function using `ESLEventDescriptor`:
+ ```typescript
+ ESLEventUtils.subscribe(host: object, descriptor: ESLEventDescriptor, handler: ESLListenerHandler)
+ ```
+- Subscribes `handler` instance of `ESLEventDescriptorFn` with `ESLEventDescriptor` overriding meta-data:
+ ```typescript
+ ESLEventUtils.subscribe(host: object, descriptor: ESLEventDescriptor, handler: ESLEventDescriptorFn)
+ ```
+
+**Parameters**:
+
+- `host` - host element to store subscription (event target by default);
+- `eventType` - string DOM event type;
+- `descriptor` - event description data (`ESLEventDescriptor`);
+- `handler` - function callback handler or instance of `ESLEventDescriptorFn`
+
+Examples:
+
+- `ESLEventUtils.subscribe(host);` -
+ subscribes all auto-subscriptions of the `host`;
+- `ESLEventUtils.subscribe(host, handlerFn);` -
+ subscribes `handlerFn` method (decorated as an `ESLEventDescriptorFn`) to the `handlerFn.target`;
+- `ESLEventUtils.subscribe(host, 'click', handlerFn);` -
+ subscribes `handlerFn` function with the passed event type;
+- `ESLEventUtils.subscribe(host, {event: 'scroll', target: window}, handlerFn);` -
+ subscribes `handlerFn` function with the passed additional descriptor data.
+
+
+
+### ⚡ `ESLEventUtils.unsubscribe`
+
+Allows unsubscribing existing subscriptions.
+
+```typescript
+unsubscribe(host: HTMLElement, ...criteria: ESLListenerCriteria[]): ESLEventListener[];
+```
+
+**Parameters**:
+
+- `host` - host element to find subscriptions;
+- `criteria` - optional set of criteria to filter listeners to remove.
+
+Examples:
+
+- `ESLEventUtils.unsubscribe(host);` - unsubscribes everything bound to the `host`
+- `ESLEventUtils.unsubscribe(host, handlerFn);` - unsubscribes everything that is bound to the `host` and is handled by the `handlerFn`
+- `ESLEventUtils.unsubscribe(host, 'click');` - unsubscribes everything bound to the `host` and processing `click` event
+- `ESLEventUtils.unsubscribe(host, 'click', handlerFn);` - unsubscribes everything that is bound to the `host`, processing `click` event and is handled by the `handlerFn`
+- There can be any number of criteria.
+
+
+
+### ⚡ `ESLEventUtils.isEventDescriptor`
+
+Predicate to check if the passed argument is a type of `ESLListenerDescriptorFn = ESLEventHandler & Partial`.
+
+```typescript
+ESLEventUtils.isEventDescriptor(obj: any): obj is ESLListenerDescriptorFn;
+```
+
+
+
+### ⚡ `ESLEventUtils.descriptors`
+
+Gathers descriptors from the passed object.
+Accepts criteria to filter the descriptors list.
+
+```typescript
+ ESLEventUtils.descriptors(host?: any): ESLListenerDescriptorFn[];
+ ESLEventUtils.descriptors(host?: any, ...criteria: ESLListenerDescriptorCriteria[]): ESLListenerDescriptorFn[];
+```
+
+**Parameters**:
+
+- `host` - object to get auto-collectable descriptors from;
+
+
+
+
+### ⚡ `ESLEventUtils.getAutoDescriptors`
+
+Gathers auto-subscribable (collectable) descriptors from the passed object.
+
+Deprecated: prefer using `ESLEventUtils.descriptors` with the `{auto: true}` criteria. As the `getAutoDescriptors` method is going to be removed in 6th release.
+
+```typescript
+ESLEventUtils.getAutoDescriptors(host?: any): ESLListenerDescriptorFn[]
+```
+
+**Parameters**:
+
+- `host` - object to get auto-collectable descriptors from;
+
+
+
+
+### ⚡ `ESLEventUtils.initDescriptor`
+
+Decorates the passed key of the host object as `ESLEventDescriptorFn`
+
+```typescript
+ESLEventUtils.initDescriptor(
+ host: T,
+ key: keyof T & string,
+ desc: ESLEventDescriptorExt
+): ESLEventDescriptorFn;
+```
+
+**Parameters**:
+
+- `host` - host object holder of decorated function;
+- `key` - key of the `host` object that contains a function to decorate;
+- `desc` - `ESLEventDescriptor` (extended) meta information to describe future subscriptions.
+
+The extended `ESLEventDescriptor` information allows passing `inherit` marker to create a new descriptor instance
+based on the descriptor declared in the prototype chain for the same key.
+
+⚠ If such a key is not found, a `ReferenceError` will be thrown.
+
+Example:
+ ```typescript
+ class MyElement {
+ onEvent() {}
+ }
+ ESLEventUtils.initDescriptor(MyElement.prototype, 'onEvent', {event: 'event'});
+```
+
+#### `@listen` decorator
+
+The `@listen` decorator (available under `esl-utils/decorators`) is syntax sugar above `ESLEventUtils.initDescriptor` method.
+It allows you to declare class methods as an `ESLEventDescriptorFn` using TS `experimentalDecorators` feature.
+
+Listeners described by `@listen` are auto-subscribable if they are not inherited and not declared as manual explicitly.
+In case of inheritance, the `auto` marker will be inherited from the parent descriptor.
+
+Example:
+
+```typescript
+class MyEl extends ESLBaseElement {
+ private event: string;
+ private selector: string;
+ // Shortcut with just an event type
+ @listen('click')
+ onClick() {}
+ // Shortcut with event type declared by PropertyProvider
+ @listen((that: MyEl) => that.event)
+ onEventProvided() {}
+ // Full list of options is available
+ @listen({event: 'click', target: 'body', capture: true})
+ onBodyClick(e) {}
+ // Property Providers example
+ @listen({
+ event: (that: MyEl) => that.event,
+ selector: (that: MyEl) => that.selector
+ })
+ onEventProvidedExt(e) {}
+ // Will not subscribe automatically
+ @listen({event: 'click', auto: false})
+ onClickManual(e) {}
+}
+```
+
+
+
+### ⚡ `ESLEventUtils.listeners`
+
+Gathers listeners currently subscribed to the passed `host` object.
+
+```typescript
+ESLEventUtils.listeners(host: object, ...criteria: ESLListenerCriteria[]): ESLEventListener[];
+```
+
+**Parameters**:
+
+- `host` - object that stores and relates to the handlers;
+- `criteria` - optional set of criteria to filter the listeners list.
+
+
+
+### ⚡ `ESLEventUtils.dispatch`
+
+Dispatches custom DOM events.
+The dispatched event is bubbling and cancelable by default.
+
+```typescript
+ESLEventUtils.dispatch(
+ el: EventTarget,
+ eventName: string,
+ eventInit?: CustomEventInit
+): boolean;
+```
+
+**Parameters**:
+
+- `el` - `EventTarget` to dispatch event;
+- `eventName` - name of the event to dispatch;
+- `eventInit` - object that specifies characteristics of the event.
+
+### Listeners Full Showcase Example
+
+```typescript
+class TestCases {
+ bind() {
+ // Subcribes all auto descriptors (onEventAutoDescSugar and onEventAutoDesc)
+ ESLEventUtils.subscribe(this);
+
+ // Subscribes onEventManualFn on click
+ ESLEventUtils.subscribe(this, 'click', this.onEventManualFn);
+
+ // Subscribes onEventManualFn on window resize
+ ESLEventUtils.subscribe(this, {event: 'resize', target: window}, this.onEventManualFn);
+
+ // Subscribes onEventManualDesc using embedded information
+ ESLEventUtils.subscribe(this, this.onEventManualDesc);
+
+ // Subscribes onEventManualDesc using merged embedded and passed information
+ ESLEventUtils.subscribe(this, {target: window}, this.onEventManualDesc);
+ }
+
+ unbind() {
+ // Unsubcribes all subscriptions
+ ESLEventUtils.unsubscribe(this);
+
+ // Unsubcribes just onEventAutoDesc
+ ESLEventUtils.unsubscribe(this, this.onEventAutoDesc);
+ }
+
+ @listen('event')
+ onEventAutoDescSugar() {}
+
+ onEventAutoDesc() {}
+
+ onEventManualFn() {}
+
+ onEventManualDesc() {}
+}
+
+ESLEventUtils.initDescriptor(TestCases.prototype, 'onEventAutoDesc', {event: 'event', auto: true});
+ESLEventUtils.initDescriptor(TestCases.prototype, 'onEventManualDesc', {event: 'event'});
+```
diff --git a/src/modules/esl-event-listener/docs/3-extended-targets.md b/src/modules/esl-event-listener/docs/3-extended-targets.md
new file mode 100644
index 0000000000..5bdd4e98ab
--- /dev/null
+++ b/src/modules/esl-event-listener/docs/3-extended-targets.md
@@ -0,0 +1,230 @@
+## Extended `EventTarget`s and standard optimizations
+
+
+
+### ⚡ `ESLDecoratedEventTarget.for`
+
+In cases where the original event of the target happens too frequently to be handled every time,
+it might be helpful to limit its processing. In purpose to do that ESL allows the creation of decorated `EventTargets`.
+The decorated target will process the original target events dispatching with the passed async call decoration function
+(such as debounce or throttle).
+
+The `ESLDecoratedEventTarget.for` creates an instance that decorates the passed original `EventTarget` event emitting.
+The instances of `ESLDecoratedEventTarget` are lazy and do not subscribe to the original event
+until they have their own subscriptions of the same event type.
+
+⚠ Note `ESLDecoratedEventTarget.for` method is cached, so created instances will be reused if the inner cache does not
+refuse additional arguments of the decorator. The cache does not handle multiple and non-primitive arguments.
+
+```typescript
+ESLDecoratedEventTarget.for(
+ target: EventTarget,
+ decorator: (fn: EventListener, ...args: any[]) => EventListener,
+ ...args: any[]
+): ESLDecoratedEventTarget;
+```
+
+**Parameters**:
+
+- `target` - original `EventTarget` to consume events;
+- `decorator` - decoration function to decorate original target `EventListener`s;
+- `args` - optional arguments to pass to `decorator`.
+
+**Example:**
+```typescript
+class Component {
+ @listen({
+ event: 'scroll',
+ target: ESLDecoratedEventTarget.for(window, throttle)
+ })
+ onScroll() {}
+}
+```
+
+#### Sharing of the decorated targets
+
+As was mentioned above, the method `ESLDecoratedEventTarget.for` works with
+a cache for simple cases. But in some cases, we might be interested in creating wrappers with a complex
+param, or we want to limit params usage across the project.
+
+It might sound obvious, but there are no restrictions on sharing exact instances instead of using the method cache.
+
+```typescript
+// shared-event-targets.ts
+export const DEBOUNCED_WINDOW = ESLDecoratedEventTarget.for(window, debounce, 1000);
+```
+
+```typescript
+// module.ts
+class Component {
+ @listen({event: 'resize', target: DEBOUNCED_WINDOW})
+ onResize() {}
+}
+```
+
+#### Optimize `window.resize` handling with debouncing
+
+```typescript
+import {debounce} from '.../debounce';
+
+ESLEventUtils.subscribe(host, {
+ event: 'resize',
+ target: /* instead just window */ ESLDecoratedEventTarget.for(window, debounce, 250)
+}, onResizeDebounced);
+```
+
+The sample above allows you to reuse the debounced by 250 milliseconds version of the window,
+to receive fewer `resize` events
+(same as any other event types observed on the debounced window version)
+
+#### Optimize `window.scroll` handling with throttling
+
+```typescript
+import {throttle} from '.../throttle';
+
+ESLEventUtils.subscribe(host, {
+ event: 'scroll',
+ target: /* instead just window */ ESLDecoratedEventTarget.for(window, throttle, 250)
+}, onScrollThrottled);
+```
+
+The sample above allows you to reuse throttled by 250 milliseconds version of the window,
+to receive no more than one event per 250 milliseconds `scroll` events
+(same as any other event types observed on the debounced window version)
+
+
+
+### ⚡ `ESLResizeObserverTarget.for`
+
+When you deal with responsive interfaces, you might need to observe an element resize instead of
+responding to the whole window change. There is a tool for this in the native DOM API - `ResizeObserver'.
+The only problem is that it does not use events, while in practice, we work with it in the same way.
+
+`ESLResizeObserverTarget.for` creates cached `ResizeObserver` adaptation to `EventTarget` (`ESLResizeObserverTarget`)
+that allows you to get `resize` events when the observed element changes its size.
+
+```typescript
+ESLResizeObserverTarget.for(el: Element): ESLResizeObserverTarget;
+```
+
+**Parameters**:
+
+- `el` - `Element` to observe size changes.
+
+`ESLResizeObserverTarget` creates itself once for an observed object with a weak reference-based cache.
+So any way of creating `ESLResizeObserverTarget` will always produce the same instance.
+
+`ESLResizeObserverTarget.for(el) /**always*/ === ESLResizeObserverTarget.for(el)`
+So there is no reason to cache it manually.
+
+Usage example:
+
+```typescript
+ESLEventUtils.subscribe(host, {
+ event: 'resize',
+ target: ESLResizeObserverTarget.for(el)
+}, onResize);
+// or
+ESLEventUtils.subscribe(host, {
+ event: 'resize',
+ target: (host) => ESLResizeObserverTarget.for(host.el)
+}, onResize);
+```
+
+
+
+### ⚡ `ESLSwipeGestureTarget.for` new
+
+`ESLSwipeGestureTarget.for` is a simple and easy-to-use way to listen for swipe events on any element.
+
+`ESLSwipeGestureTarget.for` creates a synthetic target that produces `swipe` events. It detects `pointerdown` and
+`pointerup` events and based on the distance (`threshold`) between start and end points and time (`timeout`) between
+`pointerdown` and `pointerup` events, trigger `swipe` event on the target element.
+
+```typescript
+ESLSwipeGestureTarget.for(el: Element, settings?: ESLSwipeGestureSetting): ESLSwipeGestureTarget;
+```
+
+**Parameters**:
+
+- `el` - `Element` to listen for swipe events on.
+- `settings` - optional settings (`ESLSwipeGestureSetting`)
+
+Usage example:
+
+```typescript
+ESLEventUtils.subscribe(host, {
+ event: 'swipe',
+ target: ESLSwipeGestureTarget.for(el)
+}, onSwipe);
+// or
+ESLEventUtils.subscribe(host, {
+ event: 'swipe',
+ target: (host) => ESLSwipeGestureTarget.for(host.el, {
+ threshold: '30px',
+ timeout: 1000
+ })
+}, onSwipe);
+```
+
+
+
+### ⚡ `ESLWheelTarget.for` new
+
+`ESLWheelTarget.for` is a simple way to listen for 'inert' (long wheel) scroll events on any element.
+This utility detects `wheel` events, and based on the total amount (distance) of `wheel` events and time (`timeout`) between the first and the last events, it triggers `longwheel` event on the target element.
+
+```typescript
+ESLWheelTarget.for(el: Element, settings?: ESLWheelTargetSetting): ESLWheelTarget;
+```
+
+**Parameters**:
+
+- `el` - `Element` to listen for long wheel events
+- `settings` - optional settings (`ESLWheelTargetSetting`)
+
+The `ESLWheelTargetSetting` configuration includes these optional attributes:
+- `distance` - the minimum distance to accept as a long scroll in pixels (400 by default)
+- `timeout` - the maximum duration of the wheel events to consider it inertial in milliseconds (100 by default)
+
+Usage example:
+
+```typescript
+ESLEventUtils.subscribe(host, {
+ event: 'longwheel',
+ target: ESLWheelTarget.for(el)
+}, onWheel);
+// or
+ESLEventUtils.subscribe(host, {
+ event: 'longwheel',
+ target: (host) => ESLWheelTarget.for(host.el, {
+ threshold: 30,
+ timeout: 1000
+ })
+}, onWheel);
+```
+
+
+
+### ⚡ `ESLIntersectionTarget.for` new
+
+`ESLIntersectionTarget.for` is a way to listen for intersections using Intersection Observer API but in an EventTarget
+way.
+
+`ESLIntersectionTarget.for` creates a synthetic target that produces `intersection` events. It detects intersections by
+creating `IntersectionObserver` instance, created using passed `settings: IntersectionObserverInit`.
+
+Note: `ESLIntersectionTarget` does not share `IntersectionObserver` instances unlike caching capabilities of adapters
+mentioned above.
+
+```typescript
+ESLIntersectionTarget.for(el: Element | Element[], settings?: IntersectionObserverInit): ESLIntersectionTarget;
+```
+
+**Parameters**:
+- `el` - `Element` or `Element[]` to listen for intersection events on;
+- `settings` - optional settings (`ESLIntersectionSetting`)
+
+Event API:
+Throws `ESLIntersectionEvent` that implements `IntersectionObserverEntry` original interface.
+
diff --git a/src/modules/esl-event-listener/docs/4-core-support.md b/src/modules/esl-event-listener/docs/4-core-support.md
new file mode 100644
index 0000000000..c0e6458c28
--- /dev/null
+++ b/src/modules/esl-event-listener/docs/4-core-support.md
@@ -0,0 +1,58 @@
+## Embedded behavior of `ESLBaseElement` / `ESLMixinElement`
+
+### Shortcuts
+
+All the inheritors of `ESLBaseElement` and `ESLMixinElement` contain the short aliases for some `ESLEventUtils` methods.
+The host parameter of the shortcut methods is always targeting the current element/mixin.
+
+- `$$on` ~ `ESLEventUtils.subscribe(this, ...)`
+- `$$off` ~ `ESLEventUtils.unsubscribe(this, ...)`
+- `$$fire` ~ `ESLEventUtils.dispatch(this, ...)`
+
+Example:
+
+```typescript
+this.$$on('click', this.onClick); // ESLEventUtils.subscribe(this, 'click', this.onClick)
+this.$$off('click'); // ESLEventUtils.unsubscribe(this, 'click')
+```
+
+### Auto-subscription / Auto-unbinding
+
+All the inheritors of `ESLBaseElement` and `ESLMixinElement` automatically subscribe to all declared auto-subscribable descriptors
+of their prototype chain.
+
+They also unsubscribe all own listeners attached via ESL automatically on `disconnectedCallback`.
+
+The following short snippet of code describes a listener that will automatically subscribe and unsubscribe
+on connected/disconnected callback inside `ESLBaseElement`:
+
+```typescript
+class MyEl extends ESLBaseElement {
+ // connectedCallback() {
+ // super.connectedCallback(); // - already contains ESLEventUtils.subscribe(this) call
+ // }
+
+ // Will be subscribed automatically on connectedCallback and unsubscribed on disconnectedCallback
+ @listen('click')
+ onClick(e) {
+ //...
+ }
+}
+```
+
+You can manage the subscription manually and link the whole meta information or part of it with the handler itself
+
+```typescript
+class MyEl extends ESLBaseElement {
+ @listen({event: 'click', auto: false}) // Won`t be subscribed automatically
+ onClick(e) {
+ // ...
+ }
+
+ myMethod() {
+ this.$$on(this.onClick); // Manual subscription
+ this.$$on({target: 'body'}, this.onClick); // Manual subscription with parameters (will be merged)
+ this.$$off(this.onClick); // Unsubscribes this.onClick method
+ }
+}
+```
Text with notes inside the container
+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
Tincidunt arcu non sodales neque. Lectus quam id leo in vitae turpis massa sed. Iaculis at erat pellentesque adipiscing. Cras pulvinar mattis nunc sed blandit. Vel orci porta non pulvinar neque laoreet suspendisse. A arcu cursus vitae congue mauris rhoncus aenean
Dolor magna eget est lorem ipsum dolor sit amet. Vel orci porta non pulvinar neque laoreet suspendisse interdum consectetur. In vitae turpis massa sed elementum tempus egestas sed. Dui accumsan sit amet nulla facilisi morbi tempus. Diam quam nulla porttitor massa. Aliquet enim tortor at auctor urna nunc id cursus metus. Volutpat maecenas volutpat blandit aliquam etiam erat. Est pellentesque elit
Mattis molestie a iaculis at erat pellentesque adipiscing commodo. Massa tincidunt nunc pulvinar sapien et ligula. Lectus urna duis convallis convallis tellus id interdum. Elit sed vulputate mi sit. Adipiscing commodo elit at imperdiet dui accumsan sit amet nulla. Lacus viverra vitae congue eu consequat ac felis donec et. Eget mauris pharetra et ultrices neque ornare
Components with footnotes inside
+ +Simple Menu:
+ + +Accordion with notes
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
+ Nam libero justo laoreet sit amet cursus. Nibh ipsum consequat nisl vel pretium. Elit sed vulputate mi sit amet. + Urna condimentum mattis pellentesque id. Non nisi est sit amet facilisis magna etiam tempor. Arcu risus quis varius quam quisque. + At auctor urna nunc id cursus metus aliquam eleifend. Dignissim suspendisse in est ante in nibh mauris cursus mattis. + Phasellus vestibulum lorem sed risus ultricies tristique nulla. Cursus risus at ultrices mi tempus imperdiet nulla malesuada. + Ultrices dui sapien eget mi proin sed libero. Quis risus sed vulputate odio ut enim. Morbi tristique senectus et netus. + Tellus mauris a diam maecenas sed enim ut. Id leo in vitae turpis massa sed. +
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
Text with notes (disabled grouping and used custom back to note label)
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
- Dolor magna eget est lorem ipsum dolor sit amet. Vel orci porta non pulvinar neque laoreet suspendisse interdum consectetur.
- In vitae turpis massa sed elementum tempus egestas sed. Dui accumsan sit amet nulla facilisi morbi tempus.
- Diam quam nulla porttitor massa. Aliquet enim tortor at auctor urna nunc id cursus metus. Volutpat maecenas volutpat blandit aliquam etiam erat.
- Est pellentesque elit
- Mattis molestie a iaculis at erat pellentesque adipiscing commodo. Massa tincidunt nunc pulvinar sapien et ligula.
- Lectus urna duis convallis convallis tellus id interdum. Elit sed vulputate mi sit. Adipiscing commodo elit at imperdiet dui accumsan sit amet nulla.
- Lacus viverra vitae congue eu consequat ac felis donec et. Eget mauris pharetra et ultrices neque ornare
Text without footnotes container
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
-
Text with nested notes
-
- יש המון גרסאות זמינות לפסקאות של Lorem Ipsum. אבל רובם עברו שינויים בצורה זו או
-
Text with notes which ignores on different breakpoints
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
- Arcu cursus vitae congue mauris. Orci a scelerisque purus semper eget duis at tellus at. Metus aliquam eleifend mi in. Vitae justo eget magna fermentum iaculis eu non. Iaculis nunc sed augue lacus viverra.
- Et netus et malesuada fames ac turpis. Sed vulputate mi sit amet mauris. Varius morbi enim nunc faucibus. At erat pellentesque adipiscing commodo elit at imperdiet.
- Feugiat pretium nibh ipsum consequat. Ipsum dolor sit amet consectetur. Id porta nibh venenatis cras sed felis. Nam aliquam sem et tortor consequat. Vestibulum sed arcu non odio euismod lacinia at quis risus.
- Augue ut lectus arcu bibendum at varius
- Bibendum