76 lines
2.4 KiB
JavaScript
76 lines
2.4 KiB
JavaScript
const assert = require("node:assert/strict")
|
|
const fs = require("node:fs")
|
|
const path = require("node:path")
|
|
const vm = require("node:vm")
|
|
|
|
class EventTargetStub {
|
|
constructor() {
|
|
this.listeners = new Map()
|
|
}
|
|
|
|
addEventListener(type, callback) {
|
|
if (!this.listeners.has(type)) this.listeners.set(type, new Set())
|
|
this.listeners.get(type).add(callback)
|
|
}
|
|
|
|
removeEventListener(type, callback) {
|
|
if (this.listeners.has(type)) this.listeners.get(type).delete(callback)
|
|
}
|
|
|
|
dispatch(type, event) {
|
|
for (const callback of Array.from(this.listeners.get(type) || [])) callback(event)
|
|
}
|
|
|
|
listenerCount(type) {
|
|
return this.listeners.has(type) ? this.listeners.get(type).size : 0
|
|
}
|
|
}
|
|
|
|
const root = path.resolve(__dirname, "..")
|
|
const source = fs.readFileSync(path.join(root, "public/src/js/pageevents.js"), "utf8")
|
|
const window = new EventTargetStub()
|
|
const context = vm.createContext({window, Map, Date})
|
|
vm.runInContext(source + "; this.PageEvents = PageEvents", context)
|
|
|
|
const pageEvents = new context.PageEvents()
|
|
let keyboardCalls = 0
|
|
let firstOverlayCalls = 0
|
|
let secondOverlayCalls = 0
|
|
|
|
pageEvents.keyAdd({}, "all", "both", () => keyboardCalls++)
|
|
assert.equal(window.listenerCount("keydown"), 1)
|
|
|
|
pageEvents.add(window, "keydown", () => firstOverlayCalls++, "library-escape")
|
|
assert.equal(window.listenerCount("keydown"), 2, "a named overlay listener must not replace the global keyboard dispatcher")
|
|
|
|
const keydown = {
|
|
key: "d",
|
|
keyCode: 68,
|
|
type: "keydown",
|
|
target: {tagName: "DIV"},
|
|
ctrlKey: false,
|
|
preventDefault() {}
|
|
}
|
|
window.dispatch("keydown", keydown)
|
|
assert.equal(keyboardCalls, 1)
|
|
assert.equal(firstOverlayCalls, 1)
|
|
|
|
pageEvents.add(window, "keydown", () => secondOverlayCalls++, "library-escape")
|
|
assert.equal(window.listenerCount("keydown"), 2, "replacing a named listener must not create duplicates")
|
|
window.dispatch("keydown", keydown)
|
|
assert.equal(keyboardCalls, 2)
|
|
assert.equal(firstOverlayCalls, 1)
|
|
assert.equal(secondOverlayCalls, 1)
|
|
|
|
pageEvents.remove(window, "keydown", "library-escape")
|
|
assert.equal(window.listenerCount("keydown"), 1)
|
|
window.dispatch("keydown", keydown)
|
|
assert.equal(keyboardCalls, 3, "removing an overlay listener must leave keyboard input active")
|
|
|
|
let keyupCalls = 0
|
|
pageEvents.keyAdd({}, "all", "up", () => keyupCalls++)
|
|
window.dispatch("keyup", {...keydown, type: "keyup"})
|
|
assert.equal(keyupCalls, 1)
|
|
|
|
console.log("page event listener isolation ok")
|