-
Notifications
You must be signed in to change notification settings - Fork 24
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
Feature Capture Event #91
Conversation
src/updateAttribute.js
Outdated
node.addEventListener(eventName, patchedHandler); | ||
let isCaptureEvent = eventName.endWith('Capture'); | ||
if(isCaptureEvent) { | ||
let cleanedEventName = eventName.replace('Capture', ''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we are passing attrName for mapping patched handler. We can do this logic inside getEventName
only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, making the update
src/updateAttribute.js
Outdated
if(isCaptureEvent) { | ||
let cleanedEventName = eventName.replace('Capture', ''); | ||
node.addEventListener(cleanedEventName, patchedHandler); | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to have if/else, we can just do.
node.addEventListener(cleanedEventName, patchedHandler, isCaptureEvent);
If it is false it will assign it in bubble phase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that indeed is cleaner 👍
Will update this
src/utils.js
Outdated
@@ -21,7 +21,9 @@ export function getNodeName(node) { | |||
} | |||
|
|||
export function getEventName(attrName) { | |||
return attrName.replace('on', '').toLowerCase(); | |||
let eventName = attrName.replace('on', '').toLowerCase(); | |||
if(eventName.endsWith('capture')) return eventName.replace('capture', ''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could add the capture replace in the same code itself, but it would be better if we only remove it my removing capture from the end via substring
Just not sure, if thats reasonable for some event to have capture in its name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually there are two, gotpointercapture and lostpointercapture.
https://developer.mozilla.org/en-US/docs/Web/Events
I don't see preact handling it. https://github.com/preactjs/preact/blob/master/src/diff/props.js#L92
Have to check react if they handle it differently
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also you can replace on and capture together using regex.
.replace(/^on(.*?)(Capture$|$)/, '$1')
src/updateAttribute.js
Outdated
@@ -56,7 +56,8 @@ function setAttribute(node, attrName, attrValue, oldAttrValue, isSvgAttribute) { | |||
|
|||
// if the event is getting added first time add a listener | |||
} else if (!oldAttrValue && attrValue) { | |||
node.addEventListener(eventName, patchedHandler); | |||
let isCaptureEvent = attrName.endWith('Capture'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Define it outside, so you can use it to remove the event listener as well.
src/utils.js
Outdated
@@ -21,7 +21,9 @@ export function getNodeName(node) { | |||
} | |||
|
|||
export function getEventName(attrName) { | |||
return attrName.replace('on', '').toLowerCase(); | |||
let eventName = attrName.replace('on', '').toLowerCase(); | |||
if(eventName.endsWith('capture')) return eventName.replace('capture', ''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually there are two, gotpointercapture and lostpointercapture.
https://developer.mozilla.org/en-US/docs/Web/Events
I don't see preact handling it. https://github.com/preactjs/preact/blob/master/src/diff/props.js#L92
Have to check react if they handle it differently
src/utils.js
Outdated
@@ -21,7 +21,9 @@ export function getNodeName(node) { | |||
} | |||
|
|||
export function getEventName(attrName) { | |||
return attrName.replace('on', '').toLowerCase(); | |||
let eventName = attrName.replace('on', '').toLowerCase(); | |||
if(eventName.endsWith('capture')) return eventName.replace('capture', ''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also you can replace on and capture together using regex.
.replace(/^on(.*?)(Capture$|$)/, '$1')
src/updateAttribute.js
Outdated
@@ -49,14 +49,15 @@ function setAttribute(node, attrName, attrValue, oldAttrValue, isSvgAttribute) { | |||
|
|||
// get patched event handler | |||
const patchedHandler = getPatchedEventHandler(node, attrName, attrValue); | |||
|
|||
const isCaptureEvent = attrName.endWith('Capture'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const isCaptureEvent = attrName.endWith('Capture'); | |
const isCaptureEvent = attrName.endsWith('Capture'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will also need to add support for onGotPointerCapture, and onLostPointerCapture as well. React does handle it.
Also, we can have a capture phase on these events, so this becomes more tricky. You can try the below logic in browser.
const para = document.querySelector('p');
para.addEventListener('gotpointercapture', () => {
console.log('I\'ve been captured!')
}, false);
para.addEventListener('pointerdown', (event) => {
para.setPointerCapture(event.pointerId);
});
document.body.addEventListener('gotpointercapture', () => {
console.log('budy I\'ve been captured!')
}, false);
document.body.addEventListener('pointerdown', (event) => {
para.setPointerCapture(event.pointerId);
});
So ideally even this onGotPointerCaptureCapture
and onLostPointerCaptureCapture
is valid event.
We will have to add Edge case for this two events.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this recently got fixed in React as well.
https://github.com/facebook/react/blob/master/packages/react-dom/src/events/DOMPluginEventSystem.js#L498
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we handle it the way react does ?
We can also check for these specific events and then do the special logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can handle it in the same way.
https://www.measurethat.net/Benchmarks/Show/9484/0/substr-vs-endswith
We will also have to take care of getEventName method for this
src/utils.js
Outdated
@@ -21,6 +21,11 @@ export function getNodeName(node) { | |||
} | |||
|
|||
export function getEventName(attrName) { | |||
const isSpecialCaptureEvent = attrName.substr(-7) === 'Capture' && attrName.substr(-14, 7) !== 'Pointer'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic we should put on updateAttribute method to find isCaptureEvent
event. This case handles both the normal capture case and special case. So it's not just the isSpecialCaptureEvent
And we can pass isCaptureEvent as param in this function.
src/updateAttribute.js
Outdated
@@ -50,7 +50,7 @@ function setAttribute(node, attrName, attrValue, oldAttrValue, isSvgAttribute) { | |||
// get patched event handler | |||
const patchedHandler = getPatchedEventHandler(node, attrName, attrValue); | |||
|
|||
const isCaptureEvent = attrName.endWith('Capture'); | |||
const isCaptureEvent = attrName.substr(-7) === "Capture"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will break for the special case. We can use the logic below here and pass isCaptureEvent as param to getEventName, just check if getEventName is getting called from anywhere else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why will this break ?
src/utils.js
Outdated
if(isSpecialCaptureEvent) { | ||
// Capture -> 7 , on -> 2 ; 7 + 2 = 9; | ||
return attrName.replace('on', '').substr(0, (attrName.length - 9)).toLowerCase(); | ||
} | ||
return attrName.replace(/^on(.*?)(Capture$|$)/, '$1').toLowerCase(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (isCapture) attrName = attrName.replace(/Capture$/, '');
return attrName.replace('on', '').toLowerCase();
added suggested improvements capture added to removeEventListener and getEventName Made the appropriate changes Review Changes done
First draft implementation for #33