Skip to content

Props with dashes in their names are handled as public attributes #202

Description

@jsahlen

I'm working on a project where I utilize the ability to pass on a lot of attributes to my WebC components, but at the same time using props to control rendering and behavior of those components.

I ran into an issue when trying to use @attributes to automatically render passed attributes, where supposedly private props would be included in the final HTML output. I think that props that have dashes in them (and camelCased when using in the component) aren't marked as private correctly by WebC.

Here's a small test case:

page.webc:

<test-component
  mylowercaseattr="foo"
  my-public-attr="bar"
  @mylowercaseprop="baz"
  @my-dashed-prop="qux"
></test-component>

test-component.webc:

<script webc:type="js">
  console.log(webc.attributes);
  console.log(webc.filterPublicAttributes(webc.attributes));
  ('');
</script>
<div @attributes></div>

Result:

// console.log(webc.attributes)
{
  "myDashedProp": "qux",
  "mylowercaseattr": "foo",
  "mylowercaseprop": "baz",
  "myPublicAttr": "bar",
  "uid": "webc-Ht-95",
  "my-dashed-prop___webc_privacy": "private",
  "my-public-attr___webc_privacy": "public",
  "mylowercaseattr___webc_privacy": "public",
  "mylowercaseprop___webc_privacy": "private",
  "uid___webc_privacy": "private",
}

// console.log(webc.filterPublicAttributes(webc.attributes));
{
  "myDashedProp": "qux",
  "mylowercaseattr": "foo",
  "myPublicAttr": "bar",
}
<div mylowercaseattr="foo" myPublicAttr="bar" myDashedProp="qux"></div>

As you can see, myDashedProp is included in the output, because the property marking it as private within the attributes object is named my-dashed-prop___webc_privacy instead of myDashedProp___webc_privacy.

I'm guessing that these lines in attributeSerializer.js is where it goes wrong, but I don't feel I understand the internals of WebC enough to make a PR at this time.

static async normalizeAttributesForData(attrs) {
let newData = {};
for(let name in attrs) {
let value = attrs[name];
// prop does nothing
// prop-name becomes propName
// @prop-name and :prop-name prefixes should already be removed
newData[AttributeSerializer.camelCaseAttributeName(name)] = value;
// Maintain privacy in new object
let privacy = attrs[`${name}___webc_privacy`];
if(privacy) {
AttributeSerializer.setKeyPrivacy(newData, name, privacy);
}
}
return newData;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No fields configured for Bug.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions