-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
amp-bind: Don't depend on template location to locate dynamic elements #8367
Conversation
extensions/amp-bind/0.1/bind-impl.js
Outdated
if (typeof element.getDynamicElements === 'function') { | ||
dynamicElements = element.getDynamicElements(); | ||
} else if (element.tagName === 'FORM') { | ||
// FORM is not an amp element, so it doesn't have the getter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could add a static method to AmpForm that returns the related instance for a given form element. Similar to what we do with Resource#forElement
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
When I tried to add the type annotation
@return {?../extensions/amp-form/0.1/amp-form.AmpForm}
on the functions in src/form.js
I got the following error:
WARNING - Failed to load module "../extensions/amp-form/0.1/amp-form.js"
Any idea what's happening here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably need to add it to the sources list for Closure type checker in build-system/tasks/compile.js
.
/to @choumx @jridgewell |
src/base-element.js
Outdated
* element owns that could have children added or removed dynamically. | ||
* The array should not contain any ancestors of this element, but could | ||
* contain this element itself. | ||
* @return {Array<!Element>} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
!Array<!Element>
. Classes are nullable by default in Closure typing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/base-element.js
Outdated
* @return {Array<!Element>} | ||
* @public | ||
*/ | ||
getDynamicElements() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe getDynamicElementContainers
is a bit more precise? We don't actually return every dynamic element.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds good
extensions/amp-bind/0.1/bind-impl.js
Outdated
if (typeof element.getDynamicElements === 'function') { | ||
dynamicElements = element.getDynamicElements(); | ||
} else if (element.tagName === 'FORM') { | ||
// FORM is not an amp element, so it doesn't have the getter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably need to add it to the sources list for Closure type checker in build-system/tasks/compile.js
.
extensions/amp-form/0.1/amp-form.js
Outdated
const errorDiv = | ||
this.form_./*OK*/querySelector(`[${FormState_.SUBMIT_ERROR}]`); | ||
successDiv && dynamicElements.push(successDiv); | ||
errorDiv && dynamicElements.push(errorDiv); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO it's more readable to use conditionals when your statements have side effects. ||
or the ternary operator are typically used for returning values without side effects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
src/service/resource.js
Outdated
@@ -89,7 +89,7 @@ export class Resource { | |||
* @return {?Resource} | |||
*/ | |||
static forElementOptional(element) { | |||
return /** @type {!Resource} */ (element[RESOURCE_PROP_]); | |||
return /** @type {?Resource} */ (element[RESOURCE_PROP_]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: ?
unnecessary. Objects are nullable by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
extensions/amp-bind/0.1/bind-impl.js
Outdated
} else if (element.tagName === 'FORM') { | ||
// FORM is not an amp element, so it doesn't have the getter directly. | ||
const form = formOrNullForElement(element); | ||
if (form) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure we'd ever expect this to be null. May want to assert here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
acdc68d
to
d3a0f42
Compare
d3a0f42
to
f415c30
Compare
*/ | ||
|
||
/** @const {string} */ | ||
const FORM_PROP_ = '__AMP_FORM'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if it's beneficial to extend this beyond just Forms. As in, do we expect there'll be another element that has an AMP class equivalent, but doesn't use it directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's definitely a useful pattern. My understanding is that bind doesn't support any other elements that behave this way but might in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems unlikely since IIRC Dima somewhat regrets not having forms follow the same custom element pattern.
@jridgewell good to go? |
Added a method to base-element for an element to report any elements it "owns" that are containers for dynamic contents. For instance,
<div items>
on an amp-live-list can have elements added/removed from its child list and so amp-live-list should return that div. The returned elements will be observed for mutations by bind. I'm not thrilled with the method name,getDynamicElements
so I'm open to renaming.I've also changed
bind-impl
to depend on this new method instead of the locations of templates. One caveat is forms;amp-form
isn't an element, and so I've implemented custom behavior for the success/failure divs.Fixes #8341
/to @choumx @jridgewell