lwc
lwc copied to clipboard
event.composedPath() throws
Description
Trying to read composedPath on event throws exception
Steps to Reproduce
- create LWC app like in this playground: https://developer.salesforce.com/docs/component-library/tools/playground/9Xurl1YY9/1/edit
- click on Click me div
Expected Results
div
(9) ["DIV", "DIV", undefined, "C-APP", "MAIN", "BODY", "HTML", undefined, undefined]
root
(9) ["DIV", "DIV", undefined, "C-APP", "MAIN", "BODY", "HTML", undefined, undefined]
document
(9) ["DIV", "DIV", undefined, "C-APP", "MAIN", "BODY", "HTML", undefined, undefined]
Actual Results
div
TypeError: Illegal invocation
at Object.composedPathValue (aura_proddebug.js:473)
at Object.SecureFunction (aura_proddebug.js:18838)
at Proxy.eval (active_element_test.js:61)
at HTMLDivElement.handleEvent (aura_proddebug.js:16832)
at HTMLDivElement.fnOrObj.$$lwcEventWrapper$$ (aura_proddebug.js:2471)
root
TypeError: Illegal invocation
at Object.composedPathValue (aura_proddebug.js:473)
at Object.SecureFunction (aura_proddebug.js:18838)
at Object.eval (active_element_test.js:52)
at DocumentFragment.handleEvent (aura_proddebug.js:16832)
at shadowRootWrappedListener (aura_proddebug.js:567)
at aura_proddebug.js:650
at Array.forEach (<anonymous>)
at invokeListenersByPlacement (aura_proddebug.js:647)
at HTMLElement.domListener (aura_proddebug.js:657)
document
TypeError: Illegal invocation
at Object.composedPathValue (aura_proddebug.js:473)
at Object.SecureFunction (aura_proddebug.js:18838)
at Object.eval (active_element_test.js:43)
at HTMLDocument.handleEvent (aura_proddebug.js:16832)
at HTMLDocument.fnOrObj.$$lwcEventWrapper$$ (aura_proddebug.js:2471)
Browsers Affected
Tested in Chrome
Version
- "lwc-engine": "1.1.13-224.4"
Additional context/Screenshots
I found a PR which add event.path
property: https://github.com/salesforce/lwc/pull/859
event.path
works like composedPath
is supposed to, but since it is not in the spec I am not sure if it is safe to use it. I assume it can be removed without a notice? event.composedPath
is part of spec though and it would be great to use it, if it wouldn't throw.
This is related to locker service, not LWC. As you can see in the playground, LWC works fine, but when inside locker in platform (and we can see some SecureFunction in the error stack), locker prevents access to such feature afaik. /cc @seksenov @manuel-jasso
Can I use event.path
though? I can see it was deliberately added as part of mentioned PR. Do you intend to support it in future?
No, event.path
is non-standard. Yes, there are plans to support composedPath
, @seksenov owns that timeline :)
Apologies for thread necromancy but do you have any news on the composedPath()
?
I am trying to use https://visjs.org/ Timeline which internally uses https://github.com/naver/hammer.js (for easy use of touch gestures etc across multiple browsers). They have support for shadow DOM but (as far as I can tell) it sometimes dies on Lightning Locker. It's really weird, simple clicks on the timeline or mousewheel (triggers zoom in-out on the timeline) work fine but panning / dragging sideways doesn't call right handlers.
They have piece of code going like that
if (srcEvent.composedPath) {
srcEventTarget = srcEvent.composedPath()[0];
} else if (srcEvent.path) {
srcEventTarget = srcEvent.path[0];
} else {
srcEventTarget = srcEvent.target;
}
In LWC input.srcEvent.composedPath
exists but attempts to call it end up with SecureFunction's "Illegal Invocation" exception. As a temp hack I can experiment with commenting it out and using path
.
Any idea what do you mean by it being non-standard? https://caniuse.com/?search=event%20path looks pretty good?
@tomekduda I can't find any mention of event.path
on MDN, but based on this SO answer and this quick test I wrote, it seems like it's supported in Chrome but not Firefox or Safari, and it doesn't seem to be on the standards track.
The issue you're running into with composedPath
being blocked by Locker sounds like the same issue as the original poster.
that's correct, web components first iteration had 2 APIs that are now deprecated, path
and composePath
accessor, which became a method in the next iteration. The code above is trying to guess the best possible target, trying with composedPath first, the first element there is usually the original target in open shadows. The second branch is similar, but since that's not accessible in locker (doesn't support legacy path
), then it is going to go with the target, and the target is probably not what you want for some cases since it was already retargeted.
As for the invalid invocation exception, that sounds more like a bug.
Are there any news on the matter? Recently we noticed that every mouse event that we listen and try to read composedPath
from - throws Illegal invocation
error. Has smth changed recently with Locker Service that composedPath
became inaccessible?
Can we use event.path
?
My events started to work when I ditched Lightning Locker and switched the org over to Lightning Web Security. But it's "all or nothing" global switch, it's not like Locker where you (in aura at least) choose API version and it turns it on/off.
...switched the org over to Lightning Web Security.
That's the way to go here, we will probably not be opening up any new DOM API in legacy locker at this point.
@tomekduda unfortunately I cannot switch to Lightning Web Security just yet because library I'm working on does not yet support it. So I just started using a try-catch for event.composedPath falling back to event.path. I suppose path should work for Locker Service and composedPath should be working when we eventually switch to LWS.
@bmblb
@tomekduda unfortunately I cannot switch to Lightning Web Security just yet because library I'm working on does not yet support it.
I want to learn more. If it works in legacy locker, it will work in LWS for sure. cc @manuel-jasso
So I just started using a try-catch for event.composedPath falling back to event.path. I suppose path should work for Locker Service and composedPath should be working when we eventually switch to LWS.
event.path
is not standard, and will be missing in some browsers, e.g.: Safari and FF.
@caridy I've just checked firefox, event.path
works. Don't know about safari though
Object.getOwnPropertyDescriptor(Event.prototype, 'path')
Chrome has a descriptor there, Safari-15.4 and FF-98 doesn't.
This exception is thrown by the patchedComposedPathValue
method while reading the target
property of the event.
Here is a snippet from aura_proddebug.js
:
function patchedComposedPathValue() {
const originalTarget = eventTargetGetter.call(this); // <--<< throws "Illegal Invocation" error
//...
}
The this
reference here is a "fake" event object, not an instance of the Event
class. It does however have own target
property, which can be read via this.target
and it returns a Proxy
wrapped SecureElement
.
I got this error in LWC, not using any third-party code. Is this expected behaviour?
@caridy
...switched the org over to Lightning Web Security.
That's the way to go here, we will probably not be opening up any new DOM API in legacy locker at this point.
Myself and @amurashinffdc are using the library that @bmblb is mentioning in this git issue. This, unfortunately, is not a feasible outcome for us.
We have a number of other LWS cases open which are not related to this library which are blocking us from recommending that our customers enable Lightning Web Security at this time.
Further, as an ISV, we cannot guarantee that our customers will enable LWS. We have heard from multiple customers that they will NOT be able to upgrade to LWS because of incompatibility with other existing functionality from other packages that we do not own. We cannot force them to upgrade.
Unfortunately, the upgrade path to LWS has not been as simple or transparent as advertised. For that reason desperately need support for this API within Locker Service
cc @manuel-jasso @seksenov can you track this somewhere else? this is definitely not LWC related, but Locker.
@pallenffdc you should engage in a conversation with locker PM @seksenov to see what they can do. Keep in mind that enabling this in current locker might NOT be possible for other reasons that I don't know ATM.
Thanks @caridy, I've reached out to @seksenov directly.
Thanks @caridy and @amurashinffdc, I will sync with @seksenov for tracking this.