Skip to content

amp-bind: Support data-amp-bind-* attributes#15408

Merged
dreamofabear merged 2 commits intoampproject:masterfrom
dreamofabear:bind-alternate-syntax
May 19, 2018
Merged

amp-bind: Support data-amp-bind-* attributes#15408
dreamofabear merged 2 commits intoampproject:masterfrom
dreamofabear:bind-alternate-syntax

Conversation

@dreamofabear
Copy link
Copy Markdown

@dreamofabear dreamofabear commented May 17, 2018

Fixes #11115. Also fixes a few lint errors.

  • Support data-amp-bind-foo="bar" as an alternative to [foo]="bar".

Performance impact of additional string operations seems negligible. Time spent scanning examples/bind/performance.amp.html on Mac Pro 2013 with 6x CPU throttling (10 samples each):

Before (median) After (median)
570.15 ms 562.1 ms

/to @aghassemi

@dreamofabear dreamofabear requested a review from aghassemi May 17, 2018 21:11
@dreamofabear dreamofabear force-pushed the bind-alternate-syntax branch from f68f624 to b23bdd3 Compare May 17, 2018 21:14
if (name.length > 2 && name[0] === '[' && name[name.length - 1] === ']') {
const property = name.substr(1, name.length - 2);
if (this.validator_.canBind(tagName, property)) {
const tag = element.tagName;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

per #15204 (comment), isn't the old way better? const {name, tagName } = element?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I wanted to use the shorter tag variable for conciseness.

let property;
if (attr.length > 2 && attr[0] === '[' && attr[attr.length - 1] === ']') {
property = attr.substr(1, attr.length - 2);
} else if (startsWith(attr, 'data-amp-bind-')) {
Copy link
Copy Markdown
Contributor

@aghassemi aghassemi May 18, 2018

Choose a reason for hiding this comment

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

interesting, I initially thought this is allowing any data-amp-bind-* to become bindable via [data-amp-bind-*] ( I actually ran into a case few days ago that I wanted to use a data- attribute in CSS instead of class) but I see that this is an alternative to [foo].

Given we may want to allow arbitrary data- attributes to become bindable in the feature (like how we do with aria-*), I wonder if we should remove data- prefix from this one and make it amp-bind-* and add a general validation/sanitizer rule for it.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Updated the PR description to make this more clear.

It's still safe for binding to data-* attributes since the expected prefix is the more specific data-amp-bind-*. I don't think we'll ever want to support something like [data-amp-bind-foo].

You're right that the validator won't enforce rules for data-amp-bind-*, but I think this is fine for a "workaround" syntax like this one. It'll also avoid yet another source of skew (between validator rules for [foo] vs. data-amp-bind-foo vs. bind-validator.js).

Copy link
Copy Markdown
Author

@dreamofabear dreamofabear left a comment

Choose a reason for hiding this comment

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

Thanks for the fast review.

if (name.length > 2 && name[0] === '[' && name[name.length - 1] === ']') {
const property = name.substr(1, name.length - 2);
if (this.validator_.canBind(tagName, property)) {
const tag = element.tagName;
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I wanted to use the shorter tag variable for conciseness.

let property;
if (attr.length > 2 && attr[0] === '[' && attr[attr.length - 1] === ']') {
property = attr.substr(1, attr.length - 2);
} else if (startsWith(attr, 'data-amp-bind-')) {
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Updated the PR description to make this more clear.

It's still safe for binding to data-* attributes since the expected prefix is the more specific data-amp-bind-*. I don't think we'll ever want to support something like [data-amp-bind-foo].

You're right that the validator won't enforce rules for data-amp-bind-*, but I think this is fine for a "workaround" syntax like this one. It'll also avoid yet another source of skew (between validator rules for [foo] vs. data-amp-bind-foo vs. bind-validator.js).

Copy link
Copy Markdown
Contributor

@aghassemi aghassemi left a comment

Choose a reason for hiding this comment

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

LGTM

for (let i = 0; i < bucketSize && !completed; i++) {
completed = scanNextNode_();
}
const {promise, resolve} = new Deferred();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Did the linter ask you to convert this? It was actually better the other way, because any sync error throws would have been caught.

property = attr.substr(14);
// Ignore `data-amp-bind-foo` if `[foo]` already exists.
if (element.hasAttribute(`[${property}]`)) {
property = null;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: just return here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

amp-bind: XHTML-friendly syntax

4 participants