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(engine): relatedTarget might not be present #857

Merged
merged 1 commit into from
Nov 22, 2018
Merged

Conversation

caridy
Copy link
Contributor

@caridy caridy commented Nov 21, 2018

Details

Fixes #854

During the retargeting process for relatedTarget, we were assuming that all events will have that accessor, which is incorrect, and triggers an "Invalid Invocation" when attempting to extract the relatedTarget of an event that doesn't have that getter.

Does this PR introduce a breaking change?

  • No

@@ -146,6 +146,89 @@ describe('events', () => {
expect(dispatched).toHaveLength(0);
});
});
describe('relatedTarget', () => {
it('should report correct the retargeted value', () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sanity unit for relatedTarget, but we do have a bunch of integrations, not sure why not having units. that's a question for @davidturissini, in any case, it is fine.

const e = new CustomEvent('focus');
elm.shadowRoot.querySelector('input').dispatchEvent(e);
return Promise.resolve().then(() => {
expect(relatedTarget).toBe(undefined);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

testing that a custom event named focus should not have a relatedTarget accessor (returning undefined)

@@ -209,9 +292,6 @@ describe('events', () => {
handleClick(evt) {
// event handler is here to trigger patching of the event
}
render() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duplicated render method

@@ -251,9 +331,6 @@ describe('events', () => {
handleClick(evt) {
// event handler is here to trigger patching of the event
}
render() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duplicated render method

@@ -47,52 +47,57 @@ type ComposableEvent = (Event & {
composed: boolean
});

const EventPatchDescriptors: PropertyDescriptorMap = {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of having this as static, we have to define it per event that is being patched, so we can inspect the original event, and provide relatedTarget if needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

basically, this entire block was moved down into the patchEvent() method.

}
// not all events implement the relatedTarget getter, that's why we need to extract it from the instance
// Note: we can't really use the super here because of issues with the typescript transpilation for accessors
const originalRelatedTargetDescriptor = getPropertyDescriptor(event, 'relatedTarget');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extracting the original descriptor from the proto chain (notice that it is our utility getPropertyDescriptor).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the rest is pretty much the same, just moving things to the patch method.

@caridy
Copy link
Contributor Author

caridy commented Nov 21, 2018

@davidturissini I'm not sure if the same issue affects our delegateFocus madness because those events we add them a the lower level, but they might be triggered by the user somehow. Maybe just ignoring those that are not trusted (isTrusted), or something to make sure that we only listen for those keyboard or mouse interactions.

@salesforce-best-lwc-internal
Copy link

Benchmark results

Base commit: 058e40c | Target commit: 9f1548f

lwc-engine-benchmark

table-append-1k metric base(058e40c) target(9f1548f) trend
benchmark-table/append/1k duration 147.05 (±3.15 ms) 148.40 (±3.95 ms) +1.3ms (0.9%) 👌
table-clear-1k metric base(058e40c) target(9f1548f) trend
benchmark-table/clear/1k duration 5.90 (±0.20 ms) 5.90 (±0.40 ms) 0.0ms (0.0%) 👌
table-create-10k metric base(058e40c) target(9f1548f) trend
benchmark-table/create/10k duration 883.15 (±7.05 ms) 869.80 (±7.10 ms) -13.4ms (1.5%) 👍
table-create-1k metric base(058e40c) target(9f1548f) trend
benchmark-table/create/1k duration 117.30 (±2.15 ms) 118.15 (±3.50 ms) +0.8ms (0.7%) 👌
table-update-10th-1k metric base(058e40c) target(9f1548f) trend
benchmark-table/update-10th/1k duration 76.95 (±2.45 ms) 75.95 (±2.20 ms) -1.0ms (1.3%) 👌
tablecmp-append-1k metric base(058e40c) target(9f1548f) trend
benchmark-table-component/append/1k duration 253.00 (±6.40 ms) 250.65 (±6.95 ms) -2.4ms (0.9%) 👌
tablecmp-clear-1k metric base(058e40c) target(9f1548f) trend
benchmark-table-component/clear/1k duration 11.60 (±1.70 ms) 12.05 (±1.60 ms) +0.5ms (3.9%) 👌
tablecmp-create-10k metric base(058e40c) target(9f1548f) trend
benchmark-table-component/create/10k duration 1743.30 (±11.50 ms) 1727.40 (±12.15 ms) -15.9ms (0.9%) 👍
tablecmp-create-1k metric base(058e40c) target(9f1548f) trend
benchmark-table-component/create/1k duration 210.85 (±5.25 ms) 207.90 (±7.30 ms) -3.0ms (1.4%) 👌
tablecmp-update-10th-1k metric base(058e40c) target(9f1548f) trend
benchmark-table-component/update-10th/1k duration 69.90 (±4.40 ms) 70.85 (±4.35 ms) +0.9ms (1.4%) 👌
wc-append-1k metric base(058e40c) target(9f1548f) trend
benchmark-table-wc/append/1k duration 255.75 (±7.10 ms) 255.05 (±8.60 ms) -0.7ms (0.3%) 👌
wc-clear-1k metric base(058e40c) target(9f1548f) trend
benchmark-table-wc/clear/1k duration 21.05 (±2.70 ms) 22.20 (±2.65 ms) +1.2ms (5.5%) 👎
wc-create-10k metric base(058e40c) target(9f1548f) trend
benchmark-table-wc/create/10k duration 1823.90 (±34.60 ms) 1845.30 (±30.25 ms) +21.4ms (1.2%) 👎
wc-create-1k metric base(058e40c) target(9f1548f) trend
benchmark-table-wc/create/1k duration 220.65 (±3.10 ms) 223.85 (±5.70 ms) +3.2ms (1.5%) 👌
wc-update-10th-1k metric base(058e40c) target(9f1548f) trend
benchmark-table-wc/update-10th/1k duration 69.65 (±4.85 ms) 73.60 (±4.40 ms) +3.9ms (5.7%) 👌

Copy link
Contributor

@gonzalocordero gonzalocordero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will probably work for us right now, at least it will not throw, I did a quick code search and so far we only are using that Aura blur event for tests, but ideally we should try to figure out why $A.fireDomEvent('blur') is posing as a focusout event instead.

Copy link
Member

@ekashida ekashida left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

const originalRelatedTargetDescriptor = getPropertyDescriptor(event, 'relatedTarget');
defineProperties(event, {
relatedTarget: {
get(this: ComposableEvent): EventTarget | null | undefined {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice

@ekashida
Copy link
Member

I'm not sure if the same issue affects our delegateFocus madness because those events we add them a the lower level, but they might be triggered by the user somehow. Maybe just ignoring those that are not trusted (isTrusted), or something to make sure that we only listen for those keyboard or mouse interactions.

Yeah, I was worried about this in the beginning as well. isTrusted might not be good enough since .focus() and .blur() result in false values. I was thinking that a managed event queue might be the only solution to avoid conflicts, but that makes things very complicated...

@diervo diervo merged commit 16528a5 into master Nov 22, 2018
@diervo diervo deleted the caridy/issue-854 branch November 22, 2018 00:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants