Skip to content

Commit

Permalink
v1.1.2
Browse files Browse the repository at this point in the history
  • Loading branch information
orstavik committed Aug 6, 2020
1 parent 60320fa commit e1d07fc
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 57 deletions.
39 changes: 4 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,43 +39,12 @@ import {addEventTargetRegistry} from "https://cdn.jsdelivr.net/gh/orstavik/getEv
window.getEventListeners = addEventTargetRegistry();
```

### 2. `getEventListener(eventTarget)` polyfill with added support to `first` and `last` event listener options.

```javascript
import {addEventTargetRegistry} from "https://cdn.jsdelivr.net/gh/orstavik/getEventListeners@1.0.1/src/getEventListeners_once_last_first.js";

window.getEventListeners = addEventTargetRegistry();
```
### 2. `last`, `first`, `unstoppable`, scoped `stopPropagation()` and `getEventListener(eventTarget)` polyfill

### 3. scoped `.stopPropagation()`

Make `stopPropagation()` and `stopImmediatePropagation()` only apply to the current DOM context, to avoid shadowTorpedoes, captureTorpedoes, etc. Returns a method `isStopped(event)` that can check whether or not an event's propagation has been stopped.
To enable full development of web components that act like native web components you MUST have something like this.

```javascript
import {addEventIsStoppedScoped} from "https://cdn.jsdelivr.net/gh/orstavik/getEventListeners@1.0.1/src/ScopedStopPropagation.js";

const isStopped = addEventIsStoppedScoped(Event.prototype);
```

### 4. `unstoppable` and `isScoped` event listener options

This method require the scoped `stopPropagation()` #3.

```javascript
import {addEventIsStoppedScoped} from "https://cdn.jsdelivr.net/gh/orstavik/getEventListeners@1.0.1/src/ScopedStopPropagation.js";
import {addEventListenerOptionScopedUnstoppable} from "https://cdn.jsdelivr.net/gh/orstavik/getEventListeners@1.0.1/src/EventListenersOptionUnstoppableScoped.js";

const scopedByDefault = true;

const isStopped = addEventIsStoppedScoped(Event.prototype);
addEventListenerOptionScopedUnstoppable(EventTarget.prototype, isStopped);
scopedByDefault && Object.defineProperty(Event.prototype, "isScoped", {value: true});
```

### 5. Everything

```javascript
import {addGetEventListeners_allOptions} from "https://cdn.jsdelivr.net/gh/orstavik/getEventListeners@1.0.1/src/getEventListeners_allOptions.js";
import {addGetEventListeners_allOptions} from "https://cdn.jsdelivr.net/gh/orstavik/getEventListeners@1.1.2/src/getEventListeners_allOptions.js";

const {getEventListeners, isStopped} = addGetEventListeners_allOptions(true); //isScoped is set as default value for all event listeners
const {getEventListeners, isStopped} = addGetEventListeners_allOptions();
```
8 changes: 7 additions & 1 deletion src/EventListenersOptionUnstoppableScoped.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import {addEventIsStoppedScoped, removeEventIsStoppedScoped} from "../src/ScopedStopPropagation.js";

//target* => cb* => type+" "+capture => cbOnce
const targetCbWrappers = new WeakMap();

Expand Down Expand Up @@ -34,10 +36,12 @@ let addEventListenerOG;
let removeEventListenerOG;
//scoped event listeners will only obey stopPropagations called inside the same scope.
//unstoppable event listeners will not obey any stopPropagations.
export function addEventListenerOptionScopedUnstoppable(isStopped) {
export function addEventListenerOptionScopedUnstoppable() {
addEventListenerOG = EventTarget.prototype.addEventListener;
removeEventListenerOG = EventTarget.prototype.removeEventListener;

const isStopped = addEventIsStoppedScoped();

function addEventListenerUnstoppable(type, cb, options) {
if (hasWrapper(this, type, cb, options))
return;
Expand Down Expand Up @@ -68,11 +72,13 @@ export function addEventListenerOptionScopedUnstoppable(isStopped) {
addEventListener: {value: addEventListenerUnstoppable},
removeEventListener: {value: removeEventListenerUnstoppable}
});
return isStopped;
}

export function removeEventListenerOptionScopedUnstoppable(){
Object.defineProperties(EventTarget.prototype, {
addEventListener: {value: addEventListenerOG},
removeEventListener: {value: removeEventListenerOG}
});
removeEventIsStoppedScoped();
}
11 changes: 7 additions & 4 deletions src/ScopedStopPropagation.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,9 @@ let cancelBubbleOG;
* When .stopPropagation(true) or .stopImmediatePropagation(true)is called, then
* the propagation should only be blocked for event listeners in the same DOM context
* that the event currently propagates.
* //todo we want this to apply by default.. so that all stopPropagation() calls are scoped..
*
* addEventIsStoppedScoped can be applied to:
* 1. the Event.prototype,
* 2. the prototype of a specific event type(class), or
* 3. a specific event object.
* addEventIsStoppedScoped is applied to the Event.prototype,
*
* cancelBubble mostly echoes the native `stopPropagation()`.
* event.cancelBubble = false === event.stopPropagation(false)
Expand Down Expand Up @@ -125,6 +123,10 @@ export function addEventIsStoppedScoped() {
}, set: function (value) {
return value && this.stopPropagation();
}
},
"isScoped": {
value: true,
configurable: true
}
});

Expand All @@ -137,4 +139,5 @@ export function removeEventIsStoppedScoped(){
"stopImmediatePropagation": stopImmediatePropagationOG,
"cancelBubble": cancelBubbleOG
});
delete Event.prototype.isScoped;
}
19 changes: 7 additions & 12 deletions src/getEventListeners_allOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,16 @@ import {
addEventListenerOptionScopedUnstoppable,
removeEventListenerOptionScopedUnstoppable
} from "./EventListenersOptionUnstoppableScoped.js";
import {addEventIsStoppedScoped, removeEventIsStoppedScoped} from "./ScopedStopPropagation.js";

let isScopedSettings;

export function addGetEventListeners_allOptions(scopedByDefault) {
const isStopped = addEventIsStoppedScoped();
addEventListenerOptionScopedUnstoppable(isStopped);
isScopedSettings = Object.getOwnPropertyDescriptor(Event.prototype, "isScoped");
scopedByDefault && Object.defineProperty(Event.prototype, "isScoped", {value: true});
return {isStopped, getEventListeners: addEventTargetRegistry()};
export function addGetEventListeners_allOptions() {
const isStopped = addEventListenerOptionScopedUnstoppable();
const getEventListeners = addEventTargetRegistry(); //must be added last of the two, as they both upgrade the EventTarget prototype.
//todo configurable: true is added to be able to remove the isScoped value afterwards.
//todo this is done for testing purposes, to fit into the testing framework, but it should not remain in the production ready code.
return {isStopped, getEventListeners};
}

export function removeGetEventListeners_allOptions() {
removeEventTargetRegistry();
removeEventListenerOptionScopedUnstoppable()
removeEventIsStoppedScoped();
isScopedSettings ? Object.defineProperty(Event.prototype, "isScoped", isScopedSettings) : (Event.prototype.isScoped = undefined);
removeEventListenerOptionScopedUnstoppable();
}
5 changes: 1 addition & 4 deletions test/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -108,21 +108,18 @@
window.getEventListeners = addEventTargetRegistry3();
}

const isScopedOG = Object.getOwnPropertyDescriptor(Event.prototype, "isScoped");

function SCOPED_STOP(byDefault) {
const isStopped = addEventIsStoppedScoped();
addEventListenerOptionScopedUnstoppable(isStopped);
byDefault && Object.defineProperty(Event.prototype, "isScoped", {value: true});
}

function REMOVE_SCOPED_STOP() {
delete Event.prototype.isScoped;
Object.defineProperty(Event.prototype, "isScoped", {value: undefined});
removeEventListenerOptionScopedUnstoppable();
removeEventIsStoppedScoped();
}

//todo _allOptions
function SCOPED_STOP_REGISTER() {
window.getEventListeners = addGetEventListeners_allOptions();
}
Expand Down
2 changes: 1 addition & 1 deletion test/unitTests/testStopPropagation.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ export const testStopProp2 = [{
res.push("SameScope");
});
const event = new Event("click", {composed: true, bubbles: true});
event.isScoped = true;
// event.isScoped = true; is always true
dom.shadowH1.dispatchEvent(event);
},
expect: "DifferentScope",
Expand Down

0 comments on commit e1d07fc

Please sign in to comment.