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

feat(engine-core): data-passing heuristic for external components #3150

Merged
merged 11 commits into from
Nov 14, 2022

Conversation

ekashida
Copy link
Member

@ekashida ekashida commented Nov 9, 2022

Details

https://rfcs.lwc.dev/rfcs/lwc/0118-native-web-components-support#passing-data

This was originally implemented using a new type of vnode for external custom elements but the amount of required changes to existing code didn't seem worth it, especially since the engine only needs to know whether an element is external when patching attributes/properties. I think we can consider defining a new vnode type if we end up having to do more than this in the future.

Does this pull request introduce a breaking change?

No

Does this pull request introduce an observable change?

No

GUS work item

W-11610752

const old = oldAttrs[name];

const propName = htmlAttributeToProperty(name);
if (propName in elm) {
Copy link
Contributor

Choose a reason for hiding this comment

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

why not move this one check to attrs.ts and do the prop assignment there?

// attrs.ts
if(vnode.data.external && htmlAttributeToProperty(name) in elm) {
  (elm as any)[propName] = cur;
}

this will prevent duplication of the attribute assignment logic below.

Copy link
Contributor

@caridy caridy Nov 10, 2022

Choose a reason for hiding this comment

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

I don't think we want to slow down the regular cases with more conditions @abdulsattar, I think it is fine to have this small duplication. Another alternative is to move the logic below into an abstraction layer that both modules can rely on.

Copy link
Contributor

Choose a reason for hiding this comment

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

@caridy I did think of that but I realized that we're doing the check anyway: https://github.com/salesforce/lwc/pull/3150/files#diff-8622743d79e146365dd8c59fb85057a09b0f9577d99f065628abdd95d0d7a754R549

So, the first conditional in the above if(vnode.data.external && ...) is equivalent to what we have here.

Copy link
Collaborator

Choose a reason for hiding this comment

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

if (propName in elm) {

Will this be an issue if propName is constructor? Or __proto__? Should this be a hasOwnProperty check instead?

Copy link
Contributor

@caridy caridy Nov 11, 2022

Choose a reason for hiding this comment

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

It can't be hasOwnProperty because inheritance on web components. but since our compiler is responsible for constructing the attrs dictionary per vnode, we can ban those names when parsing the element. It is probably already a problem with spread directive, so we better do that soon here. Although I don't know how to solve it with spread directive, since that's runtime. I believe class declarations will prevent the modification of some of that though, making them non-configurable, non-writable.

Copy link
Member Author

Choose a reason for hiding this comment

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

@abdulsattar The check that you pointed out is done once per element, whereas the check required in attrs.ts would be once per attribute.

Copy link
Member

Choose a reason for hiding this comment

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

For what it's worth Vue and Svelte uses the same in check to differentiate between props and attributes.

Copy link
Contributor

@caridy caridy left a comment

Choose a reason for hiding this comment

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

adjusts needed

@ekashida ekashida force-pushed the ekashida/attr-unless-prop branch from a5d4145 to 5f5ee16 Compare November 12, 2022 08:03
@ekashida
Copy link
Member Author

@caridy ready for another pass

Copy link
Contributor

@caridy caridy left a comment

Choose a reason for hiding this comment

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

LGTM

@ekashida ekashida merged commit 343a078 into master Nov 14, 2022
@ekashida ekashida deleted the ekashida/attr-unless-prop branch November 14, 2022 20:12
if (old !== cur) {
const propName = htmlAttributeToProperty(name);
if (propName in elm!) {
(elm as any)[propName] = cur;
Copy link
Contributor

Choose a reason for hiding this comment

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

use setProperty instead

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.

6 participants