Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(event-manager): shadow dom event bubbling #758

Merged
69 changes: 39 additions & 30 deletions dist/amd/aurelia-binding.js
Original file line number Diff line number Diff line change
Expand Up @@ -3377,51 +3377,55 @@ define(['exports', 'aurelia-logging', 'aurelia-pal', 'aurelia-task-queue', 'aure
return CapturedHandlerEntry;
}();

function handleDelegatedEvent(event) {
event.propagationStopped = false;
var target = findOriginalEventTarget(event);

while (target && !event.propagationStopped) {
if (target.delegatedCallbacks) {
var callback = target.delegatedCallbacks[event.type];
if (callback) {
if (event.stopPropagation !== stopPropagation) {
event.standardStopPropagation = event.stopPropagation;
event.stopPropagation = stopPropagation;
}
if ('handleEvent' in callback) {
callback.handleEvent(event);
} else {
callback(event);
}
}
}

target = target.parentNode;
}
}

var DelegateHandlerEntry = function () {
function DelegateHandlerEntry(eventName) {
function DelegateHandlerEntry(eventName, eventManager) {


this.eventName = eventName;
this.count = 0;
this.eventManager = eventManager;
}

DelegateHandlerEntry.prototype.handleDelegatedEvent = function handleDelegatedEvent(event) {
event.propagationStopped = false;
var target = findOriginalEventTarget(event);

while (target && !event.propagationStopped) {
if (target.delegatedCallbacks) {
var callback = target.delegatedCallbacks[event.type];
if (callback) {
if (event.stopPropagation !== stopPropagation) {
event.standardStopPropagation = event.stopPropagation;
event.stopPropagation = stopPropagation;
}
if ('handleEvent' in callback) {
callback.handleEvent(event);
} else {
callback(event);
}
}
}

var parent = target.parentNode;
var shouldEscapeShadowRoot = this.eventManager.escapeShadowRoot && parent && parent instanceof ShadowRoot;

target = shouldEscapeShadowRoot ? parent.host : parent;
}
};

DelegateHandlerEntry.prototype.increment = function increment() {
this.count++;

if (this.count === 1) {
_aureliaPal.DOM.addEventListener(this.eventName, handleDelegatedEvent, false);
_aureliaPal.DOM.addEventListener(this.eventName, this.handleDelegatedEvent, false);
}
};

DelegateHandlerEntry.prototype.decrement = function decrement() {
if (this.count === 0) {
emLogger.warn('The same EventListener was disposed multiple times.');
} else if (--this.count === 0) {
_aureliaPal.DOM.removeEventListener(this.eventName, handleDelegatedEvent, false);
_aureliaPal.DOM.removeEventListener(this.eventName, this.handleDelegatedEvent, false);
}
};

Expand Down Expand Up @@ -3466,11 +3470,13 @@ define(['exports', 'aurelia-logging', 'aurelia-pal', 'aurelia-task-queue', 'aure
}();

var DefaultEventStrategy = function () {
function DefaultEventStrategy() {
function DefaultEventStrategy(eventManager) {


this.delegatedHandlers = {};
this.capturedHandlers = {};

this.eventManager = eventManager;
}

DefaultEventStrategy.prototype.subscribe = function subscribe(target, targetEvent, callback, strategy, disposable) {
Expand All @@ -3480,7 +3486,7 @@ define(['exports', 'aurelia-logging', 'aurelia-pal', 'aurelia-task-queue', 'aure

if (strategy === delegationStrategy.bubbling) {
delegatedHandlers = this.delegatedHandlers;
handlerEntry = delegatedHandlers[targetEvent] || (delegatedHandlers[targetEvent] = new DelegateHandlerEntry(targetEvent));
handlerEntry = delegatedHandlers[targetEvent] || (delegatedHandlers[targetEvent] = new DelegateHandlerEntry(targetEvent, this.eventManager));
var delegatedCallbacks = target.delegatedCallbacks || (target.delegatedCallbacks = {});
if (!delegatedCallbacks[targetEvent]) {
handlerEntry.increment();
Expand Down Expand Up @@ -3541,10 +3547,13 @@ define(['exports', 'aurelia-logging', 'aurelia-pal', 'aurelia-task-queue', 'aure

var EventManager = exports.EventManager = function () {
function EventManager() {
var escapeShadowRoot = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;



this.elementHandlerLookup = {};
this.eventStrategyLookup = {};
this.escapeShadowRoot = escapeShadowRoot;

this.registerElementConfig({
tagName: 'input',
Expand Down Expand Up @@ -3584,7 +3593,7 @@ define(['exports', 'aurelia-logging', 'aurelia-pal', 'aurelia-task-queue', 'aure
}
});

this.defaultEventStrategy = new DefaultEventStrategy();
this.defaultEventStrategy = new DefaultEventStrategy(this);
}

EventManager.prototype.registerElementConfig = function registerElementConfig(config) {
Expand Down
65 changes: 37 additions & 28 deletions dist/aurelia-binding.js
Original file line number Diff line number Diff line change
Expand Up @@ -3282,49 +3282,53 @@ class CapturedHandlerEntry {
}
}

function handleDelegatedEvent(event) {
event.propagationStopped = false;
let target = findOriginalEventTarget(event);
class DelegateHandlerEntry {
constructor(eventName, eventManager) {
this.eventName = eventName;
this.count = 0;
this.eventManager = eventManager;
}

while (target && !event.propagationStopped) {
if (target.delegatedCallbacks) {
let callback = target.delegatedCallbacks[event.type];
if (callback) {
if (event.stopPropagation !== stopPropagation) {
event.standardStopPropagation = event.stopPropagation;
event.stopPropagation = stopPropagation;
}
if ('handleEvent' in callback) {
callback.handleEvent(event);
} else {
callback(event);
handleDelegatedEvent(event) {
event.propagationStopped = false;
let target = findOriginalEventTarget(event);

while (target && !event.propagationStopped) {
if (target.delegatedCallbacks) {
let callback = target.delegatedCallbacks[event.type];
if (callback) {
if (event.stopPropagation !== stopPropagation) {
event.standardStopPropagation = event.stopPropagation;
event.stopPropagation = stopPropagation;
}
if ('handleEvent' in callback) {
callback.handleEvent(event);
} else {
callback(event);
}
}
}
}

target = target.parentNode;
}
}
const parent = target.parentNode;
const shouldEscapeShadowRoot = this.eventManager.escapeShadowRoot && parent && parent instanceof ShadowRoot;

class DelegateHandlerEntry {
constructor(eventName) {
this.eventName = eventName;
this.count = 0;
target = shouldEscapeShadowRoot ? parent.host : parent;
}
}

increment() {
this.count++;

if (this.count === 1) {
DOM.addEventListener(this.eventName, handleDelegatedEvent, false);
DOM.addEventListener(this.eventName, this.handleDelegatedEvent, false);
}
}

decrement() {
if (this.count === 0) {
emLogger.warn('The same EventListener was disposed multiple times.');
} else if (--this.count === 0) {
DOM.removeEventListener(this.eventName, handleDelegatedEvent, false);
DOM.removeEventListener(this.eventName, this.handleDelegatedEvent, false);
}
}
}
Expand Down Expand Up @@ -3378,6 +3382,10 @@ class DefaultEventStrategy {
delegatedHandlers = {};
capturedHandlers = {};

constructor(eventManager) {
this.eventManager = eventManager;
}

/**
* @param {Element} target
* @param {string} targetEvent
Expand All @@ -3392,7 +3400,7 @@ class DefaultEventStrategy {

if (strategy === delegationStrategy.bubbling) {
delegatedHandlers = this.delegatedHandlers;
handlerEntry = delegatedHandlers[targetEvent] || (delegatedHandlers[targetEvent] = new DelegateHandlerEntry(targetEvent));
handlerEntry = delegatedHandlers[targetEvent] || (delegatedHandlers[targetEvent] = new DelegateHandlerEntry(targetEvent, this.eventManager));
let delegatedCallbacks = target.delegatedCallbacks || (target.delegatedCallbacks = {});
if (!delegatedCallbacks[targetEvent]) {
handlerEntry.increment();
Expand Down Expand Up @@ -3450,9 +3458,10 @@ export const delegationStrategy = {
};

export class EventManager {
constructor() {
constructor(escapeShadowRoot = false) {
this.elementHandlerLookup = {};
this.eventStrategyLookup = {};
this.escapeShadowRoot = escapeShadowRoot;

this.registerElementConfig({
tagName: 'input',
Expand Down Expand Up @@ -3492,7 +3501,7 @@ export class EventManager {
}
});

this.defaultEventStrategy = new DefaultEventStrategy();
this.defaultEventStrategy = new DefaultEventStrategy(this);
}

registerElementConfig(config) {
Expand Down
69 changes: 39 additions & 30 deletions dist/commonjs/aurelia-binding.js
Original file line number Diff line number Diff line change
Expand Up @@ -3330,51 +3330,55 @@ var CapturedHandlerEntry = function () {
return CapturedHandlerEntry;
}();

function handleDelegatedEvent(event) {
event.propagationStopped = false;
var target = findOriginalEventTarget(event);

while (target && !event.propagationStopped) {
if (target.delegatedCallbacks) {
var callback = target.delegatedCallbacks[event.type];
if (callback) {
if (event.stopPropagation !== stopPropagation) {
event.standardStopPropagation = event.stopPropagation;
event.stopPropagation = stopPropagation;
}
if ('handleEvent' in callback) {
callback.handleEvent(event);
} else {
callback(event);
}
}
}

target = target.parentNode;
}
}

var DelegateHandlerEntry = function () {
function DelegateHandlerEntry(eventName) {
function DelegateHandlerEntry(eventName, eventManager) {


this.eventName = eventName;
this.count = 0;
this.eventManager = eventManager;
}

DelegateHandlerEntry.prototype.handleDelegatedEvent = function handleDelegatedEvent(event) {
event.propagationStopped = false;
var target = findOriginalEventTarget(event);

while (target && !event.propagationStopped) {
if (target.delegatedCallbacks) {
var callback = target.delegatedCallbacks[event.type];
if (callback) {
if (event.stopPropagation !== stopPropagation) {
event.standardStopPropagation = event.stopPropagation;
event.stopPropagation = stopPropagation;
}
if ('handleEvent' in callback) {
callback.handleEvent(event);
} else {
callback(event);
}
}
}

var parent = target.parentNode;
var shouldEscapeShadowRoot = this.eventManager.escapeShadowRoot && parent && parent instanceof ShadowRoot;

target = shouldEscapeShadowRoot ? parent.host : parent;
}
};

DelegateHandlerEntry.prototype.increment = function increment() {
this.count++;

if (this.count === 1) {
_aureliaPal.DOM.addEventListener(this.eventName, handleDelegatedEvent, false);
_aureliaPal.DOM.addEventListener(this.eventName, this.handleDelegatedEvent, false);
}
};

DelegateHandlerEntry.prototype.decrement = function decrement() {
if (this.count === 0) {
emLogger.warn('The same EventListener was disposed multiple times.');
} else if (--this.count === 0) {
_aureliaPal.DOM.removeEventListener(this.eventName, handleDelegatedEvent, false);
_aureliaPal.DOM.removeEventListener(this.eventName, this.handleDelegatedEvent, false);
}
};

Expand Down Expand Up @@ -3419,11 +3423,13 @@ var EventHandler = function () {
}();

var DefaultEventStrategy = function () {
function DefaultEventStrategy() {
function DefaultEventStrategy(eventManager) {


this.delegatedHandlers = {};
this.capturedHandlers = {};

this.eventManager = eventManager;
}

DefaultEventStrategy.prototype.subscribe = function subscribe(target, targetEvent, callback, strategy, disposable) {
Expand All @@ -3433,7 +3439,7 @@ var DefaultEventStrategy = function () {

if (strategy === delegationStrategy.bubbling) {
delegatedHandlers = this.delegatedHandlers;
handlerEntry = delegatedHandlers[targetEvent] || (delegatedHandlers[targetEvent] = new DelegateHandlerEntry(targetEvent));
handlerEntry = delegatedHandlers[targetEvent] || (delegatedHandlers[targetEvent] = new DelegateHandlerEntry(targetEvent, this.eventManager));
var delegatedCallbacks = target.delegatedCallbacks || (target.delegatedCallbacks = {});
if (!delegatedCallbacks[targetEvent]) {
handlerEntry.increment();
Expand Down Expand Up @@ -3494,10 +3500,13 @@ var delegationStrategy = exports.delegationStrategy = {

var EventManager = exports.EventManager = function () {
function EventManager() {
var escapeShadowRoot = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;



this.elementHandlerLookup = {};
this.eventStrategyLookup = {};
this.escapeShadowRoot = escapeShadowRoot;

this.registerElementConfig({
tagName: 'input',
Expand Down Expand Up @@ -3537,7 +3546,7 @@ var EventManager = exports.EventManager = function () {
}
});

this.defaultEventStrategy = new DefaultEventStrategy();
this.defaultEventStrategy = new DefaultEventStrategy(this);
}

EventManager.prototype.registerElementConfig = function registerElementConfig(config) {
Expand Down
Loading