Skip to content

Commit

Permalink
v1.2.0 cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
orstavik committed Aug 20, 2020
1 parent e1d07fc commit 2be9e84
Show file tree
Hide file tree
Showing 28 changed files with 1,861 additions and 543 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {addEventIsStoppedScoped, removeEventIsStoppedScoped} from "../src/ScopedStopPropagation.js";
import {addEventIsStoppedScoped, removeEventIsStoppedScoped} from "./ScopedStopPropagation.js";

//target* => cb* => type+" "+capture => cbOnce
const targetCbWrappers = new WeakMap();
Expand Down
36 changes: 31 additions & 5 deletions src/ScopedStopPropagation.js → src/old/ScopedStopPropagation.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,33 @@
export function currentEventContext(event) {//todo rename to getPropagationRootNode(event)?? //todo move to computePaths.js??
if (!event.currentTarget)
return null;
const two = currentEventContext2(event);
const root = event.currentTarget.getRootNode ? event.currentTarget.getRootNode() : event.currentTarget;
return root === document ? window : root;
let one = root === document ? window : root;
if (two !== one)
debugger
return one;
}

export function currentEventContext2(event) {//todo rename to getPropagationRootNode(event)?? //todo move to computePaths.js??
if (!event.currentTarget)
return null;
const path = event.composedPath();
let root = event.currentTarget;

let i = path.indexOf(root) + 1;
let slots = 0;
while (i < path.length){
if (root instanceof HTMLSlotElement){
slots++;
} else if(root instanceof ShadowRoot){
if (slots === 0)
return root;
slots--;
}
root = path[i++];
}
return root;
}

//whenStopPropWasCalled:
Expand All @@ -37,7 +62,7 @@ function stopListener(e, stop) {
* it can be set to true on the Event.prototype to force all events to be isScoped by default.
*
* @param event whose propagation is to be checked if it has been stopped.
* @param listenerIsScoped if true, then only check if the propagation has been stopped in the current DOM context.
* @param listenerIsScoped if true, then only check if the propagation has been stopped in the current DOM context. todo always true now
* @returns {boolean} true if somebody has called stopPropagation on it before the event has begun propagaton,
* true if the event is stopped in this current DOM context, and if a previous event listener
* on the same target node has called stopImmediatePropagation, and
Expand All @@ -46,10 +71,11 @@ function stopListener(e, stop) {
* in the main dom outside a web component that the event currently propagates in.
*/
function isStopped(event, listenerIsScoped) {
listenerIsScoped = true;
if (beforeStops.has(event))
return true;
if (!listenerIsScoped && !event.isScoped && stopListener(event, globalStops.get(event))) //check if it is non-scoped first, as that is cheapest
return true;
// if (!true && !event.isScoped && stopListener(event, globalStops.get(event))) //check if it is non-scoped first, as that is cheapest
// return true;
const scope = currentEventContext(event); //check if stopped in current context. Applies to all.
return !!stopListener(event, localStops.get(event)?.get(scope));
}
Expand Down Expand Up @@ -133,7 +159,7 @@ export function addEventIsStoppedScoped() {
return isStopped;
}

export function removeEventIsStoppedScoped(){
export function removeEventIsStoppedScoped() {
Object.defineProperties(Event.prototype, {
"stopPropagation": stopPropagationOG,
"stopImmediatePropagation": stopImmediatePropagationOG,
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
163 changes: 163 additions & 0 deletions src/old/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<script>

function nextTick2(cb) {
let r;
const p = new Promise(function (resolve) {
r = resolve;
});
setTimeout(function () {
cb();
setTimeout(function () {
r();
})//todo i need setTimeout(..., 1) for this to work in ff?
}); //todo i need 1 for this to work in ff?
return p;
}

function setValue(obj, a, b, value) {
!obj[a] && (obj[a] = {});
!obj[a][b] && (obj[a][b] = {});
obj[a][b] = value;
}

function printResults(results) {
for (let [testName, testResults] of Object.entries(results)) {
const expected = testResults.expected;
delete testResults.expected;
const native = testResults.NATIVE;
for (let [systemName, result] of Object.entries(testResults)) {
if (systemName === "NATIVE")
testResults[systemName] = result === expected ? 1 : result;
else
testResults[systemName] =
(result === expected && result === native) ? null :
(result === expected) ? 1 :
(result === native) ? undefined :
result;
}
}
console.table(results);
}

async function runTests(eventSystems, tests) {
const results = {};
for (let [system, reset] of eventSystems) {
system();
for (const {name: testName, fun, expect} of tests) {

const expected = expect instanceof Function ? expect() : expect;
setValue(results, testName, "expected", expected);

let result = [];
fun(result);
await nextTick2(() => 1); //just wait a t1ck, for any queued propagation to complete
setValue(results, testName, system.name, result.join(""));
await nextTick2(() => 1); //just wait a t0ck, for any queued tasks of the propagation to complete
}
reset();
}
return nextTick2(function () {
printResults(results);
});
}
</script>

<script type="module">
import {
addEventTargetRegistry as addEventTargetRegistry1,
removeEventTargetRegistry as removeEventTargetRegistry1
} from "./getEventListeners.js";
import {
addEventTargetRegistry as addEventTargetRegistry2,
removeEventTargetRegistry as removeEventTargetRegistry2
} from "./getEventListeners_once.js";
import {
addEventTargetRegistry as addEventTargetRegistry3,
removeEventTargetRegistry as removeEventTargetRegistry3
} from "./getEventListeners_once_last.js";
import {addEventTargetRegistry, removeEventTargetRegistry} from "./getEventListeners_once_last_first.js";
import {
addEventListenerOptionScopedUnstoppable,
removeEventListenerOptionScopedUnstoppable
} from "./EventListenersOptionUnstoppableScoped.js";
import {addEventIsStoppedScoped, removeEventIsStoppedScoped} from "./ScopedStopPropagation.js";
import {
addGetEventListeners_allOptions,
removeGetEventListeners_allOptions
} from "./getEventListeners_allOptions.js"

/**
* @param byDefault, if true, then all events are isScoped=true by default/globally
*/
function NATIVE() {
}

function REGISTER_once_last_first() {//once, last, first
window.getEventListeners = addEventTargetRegistry();
}

function REGISTER_no_options() {
window.getEventListeners = addEventTargetRegistry1();
}

function REGISTER_once() {
window.getEventListeners = addEventTargetRegistry2();
}

function REGISTER_once_last() {
window.getEventListeners = addEventTargetRegistry3();
}

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

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

function SCOPED_STOP_REGISTER() {
window.getEventListeners = addGetEventListeners_allOptions();
}

const registers = [
[REGISTER_once_last_first, removeEventTargetRegistry],
[REGISTER_no_options, removeEventTargetRegistry1],
[REGISTER_once, removeEventTargetRegistry2],
[REGISTER_once_last, removeEventTargetRegistry3]
];

const eventSystems = [
[NATIVE, NATIVE],
[REGISTER_once_last_first, removeEventTargetRegistry],
[SCOPED_STOP, REMOVE_SCOPED_STOP],
[SCOPED_STOP_REGISTER, removeGetEventListeners_allOptions]
];

import {testBasic} from "./unitTests/testBasic.js";
import {dynamicTest} from "./unitTests/testDynamic.js";
import {testRegistry} from "./unitTests/testRegistry.js";
import {testOnce} from "./unitTests/testOnce.js";
import {lastTest, lastErrorsTest, last2} from "./unitTests/testLast.js";
import {firstTest, firstErrorsTest, first2} from "./unitTests/testFirst.js";

(async function () {
await runTests(eventSystems, testBasic);
await runTests(eventSystems, dynamicTest);
await runTests(registers, testRegistry);
await runTests(eventSystems, testOnce);
await runTests(eventSystems, lastTest);
await runTests(eventSystems, last2);
await runTests(eventSystems, lastErrorsTest);
await runTests(eventSystems, firstTest);
await runTests(eventSystems, first2);
await runTests(eventSystems, firstErrorsTest);
// // await runTests(eventSystems, testIsStopped);
})();
//todo
// 1. test stopPropagation thoroughly
</script>
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
32 changes: 20 additions & 12 deletions test/unitTests/testOnce.js → src/old/unitTests/testOnce.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ function c(e) {
res.push("c");
}

function getResult() {
return res;
}

export const testOnce = [{
name: "once: true",
fun: function(res) {
Expand All @@ -33,7 +29,7 @@ export const testOnce = [{
h1.dispatchEvent(new Event("click", {bubbles: true, composed: true}));
},
expect: "a",
result: getResult

}, {
name: "once: false",
fun: function(res) {
Expand All @@ -49,7 +45,7 @@ export const testOnce = [{
h1.dispatchEvent(new Event("click", {bubbles: true, composed: true}));
},
expect: "aaa",
result: getResult

}, {
name: "once: adding same listener object to the same target",
fun: function(res) {
Expand All @@ -76,7 +72,7 @@ export const testOnce = [{
h1.dispatchEvent(new Event("click"));
},
expect: "aab",
result: getResult

}, {
name: "once: removeEventListener twice",
fun: function(res) {
Expand All @@ -93,7 +89,7 @@ export const testOnce = [{
h1.dispatchEvent(new Event("click", {bubbles: true}));
},
expect: "",
result: getResult

}, {
name: "once: two multiple listeners to the same target, not once added first",
fun: function(res) {
Expand All @@ -116,7 +112,7 @@ export const testOnce = [{
h1.dispatchEvent(new Event("click", {bubbles: true}));
},
expect: "ababab",
result: getResult

}, {
name: "once: {capture:true, once: true}",
fun: function(res) {
Expand All @@ -143,7 +139,7 @@ export const testOnce = [{
h1.dispatchEvent(new Event("click", {bubbles: true}));
},
expect: "abcaa", //c is after ab, because the h1 is in the lowestmost AT_TARGET phase
result: getResult

}, {
name: "once: slotted element", //todo move these last two tests to the test of propagation
fun: function(res) {
Expand All @@ -164,7 +160,7 @@ export const testOnce = [{
dom.shadowComp.dispatchEvent(new Event("click", {bubbles: true}));
},
expect: "abbb",
result: getResult

}, {
name: "once: composed: false does not propagates through shadowRoot",
fun: function(res) {
Expand All @@ -184,5 +180,17 @@ export const testOnce = [{
dom.shadowH1.dispatchEvent(new Event("click", {bubbles: true}));
},
expect: "a",
result: getResult
}, {
name: "click dispatched within click",
fun: function(res) {
const h1 = document.createElement("h1");
function a(e) {
res.push("a");
e.target.click();
}

h1.addEventListener("click", a, {once: true});
h1.dispatchEvent(new Event("click", {bubbles: true}));
},
expect: "a",
}];
File renamed without changes.
File renamed without changes.

0 comments on commit 2be9e84

Please sign in to comment.