-
Notifications
You must be signed in to change notification settings - Fork 4k
Minimal (experimental) document-level infinite-scroll extension #13184
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
Minimal (experimental) document-level infinite-scroll extension #13184
Conversation
|
We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for the commit author(s). If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google. |
26b1b67 to
ed4aee0
Compare
|
CLAs look good, thanks! |
| * limitations under the License. | ||
| */ | ||
|
|
||
| i-amp-document-recommendations {} |
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.
There is no tag called i-amp-document-recommendations right? I think this can be removed.
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.
|
|
||
| i-amp-document-recommendations {} | ||
|
|
||
| .i-amp-document-recommendations { |
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.
naming convention is i-amphtml-component-name for private CSS classes.
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.
| i-amp-document-recommendations {} | ||
|
|
||
| .i-amp-document-recommendations { | ||
| background: white; |
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: use hex
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.
| */ | ||
|
|
||
| /** @const */ | ||
| const MAX_ARTICLES = 2; |
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: varibales after imports
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.
| constructor(element) { | ||
| super(element); | ||
|
|
||
| this.element.classList.add('i-amp-document-recommendations'); |
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.
move to buildCallback
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.
| this.element.classList.add('i-amp-document-recommendations'); | ||
|
|
||
| // TODO(emarchiori): Consider using a service instead of singleton. | ||
| if (this.win.CONTENT_DISCOVERY) { |
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 assume this is simply a flag so that the component is only rendered once? If so, just having it be a variable outside of class (e.g. at extension level) would be better for now until this becomes a window level service.
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.
Correct. Done.
| return true; | ||
| } | ||
|
|
||
| appendDivision_() { |
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.
jsdocs for all methods.
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.
| this.nextArticle_++; | ||
|
|
||
| Services.xhrFor(this.win) | ||
| .fetchDocument(next.ampUrl, {}) |
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.
No need to pass {} since it is optional.
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.
| appendArticleLinks_(from) { | ||
| const doc = this.win.document; | ||
| let article = from; | ||
| const viewer = Services.viewerForDoc(this.getAmpDoc()); |
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.
do in constructor and keep this.viewer_
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.
| const next = this.config_.recommendations[article]; | ||
| article++; | ||
|
|
||
| const articleHolder = doc.createElement('div'); |
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.
use button for A11Y, otherwise need to handle taxIndex and enter/space activation manually.
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.
|
|
||
| this.config_ = assertConfig(configJson); | ||
|
|
||
| return this.mutateElement(() => { |
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.
Other components (amp-list, amp-date-picker) make XHR requests for their content from the layoutCallback - probably makes sense for this too?
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.
|
@emarchiori @peterjosling Please ping me on this PR when ready for the final look. Thanks! |
| * @const | ||
| * TODO(emarchiori): Make this a configurable parameter. | ||
| */ | ||
| const SEPARATPOR_RECOS = 3; |
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.
typo: SEPARATOR
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.
| } | ||
|
|
||
| .i-amphtml-reco-holder-article { | ||
| padding-top:10px; |
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: space between colon and value (for each line in this block)
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.
|
|
||
| /** @override */ | ||
| isLayoutSupported(layout) { | ||
| return layout == Layout.CONTAINER; |
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: ===
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.
Keeping == for consistency with other extensions and rest of the code.
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 had a long discussions about this in the team :) although style guides says ===, we are sticking with ==
| { | ||
| "recommendations": [ | ||
| { | ||
| "image": "http://localhost:8000/examples/img/hero@1x.jpg", |
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.
Remove http://localhost:8000 and just have these as absolute paths ("image": "/examples/img/hero@1x.jpg", etc.) The host/port can be overridden.
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.
This does not handle any edge cases or error cases, and does all the loading ahead.
Having trouble running check-types locally becase of ampproject#11574.
634e553 to
b4c2f57
Compare
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.
few nits and one request for checking that experiment is enabled in buildCallback.
| } | ||
|
|
||
| /** @override */ | ||
| buildCallback() { |
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.
needs a
if (!isExperimentOn(this.getWin(), TAG)) {
user.warn('Experiment %s is not turned on.', TAG);
return;
}
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.
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.
Used an assert, for consistency with other experiments.
| background: #FFFFFF; | ||
| } | ||
|
|
||
| .amp-document-recommendations-division { |
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: keep public css class on top of the CSS file
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.
|
|
||
| /** @override */ | ||
| isLayoutSupported(layout) { | ||
| return layout == Layout.CONTAINER; |
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 had a long discussions about this in the team :) although style guides says ===, we are sticking with ==
|
@emarchiori @peterjosling merged. |
| tags: { # <amp-document-recommendations> | ||
| html_format: AMP | ||
| tag_name: "AMP-DOCUMENT-RECOMMENDATIONS" | ||
| mandatory_parent: "BODY" |
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.
Is there a reason this needs to have parent of body and why it must be the last child of body?
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.
This is a restriction that we might want to remove or relax it in the future, but forcing those two conditions reduces potentially unexpected behaviors (e.g. no footer on the first article as there are others in between, but the following article having a footer in the middle as it does not load other articles recursively).
Adding support to hide things like footer in all but the last article and headers in all but the first can probably led to the relaxation of this in followup changes.
Any particular concerns with this restrictions?
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.
Yes, it means no other component can also be last in the body. It makes this component have some significance among all components. @aghassemi thoughts?
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.
Spoke with @aghassemi to clarify intent. Thank you.
* Revision bump for #13184 * Revision bump for #13480, #13665 * Revision bump for #13752 * Revision bump for #13773 * Removing AMP-YOUTUBE tag from AMP4EMAIL validator spec. * A unit test that ensures no extensions are accidentally added to EXPERIMENTAL amp html format. * Implement amp-story-auto-ads validation rules. * Revision bump for #13846 and #13816 * Revision bump for #13883
* Revision bump for ampproject#13184 * Revision bump for ampproject#13480, ampproject#13665 * Revision bump for ampproject#13752 * Revision bump for ampproject#13773 * Removing AMP-YOUTUBE tag from AMP4EMAIL validator spec. * A unit test that ensures no extensions are accidentally added to EXPERIMENTAL amp html format. * Implement amp-story-auto-ads validation rules. * Revision bump for ampproject#13846 and ampproject#13816 * Revision bump for ampproject#13883
amp-document-recommendations
Initial minimal extension for feedback and for incremental implementation. Settled on temporary name, avoiding infinite-scroll as UX currently has recommendations in between to create separation.
This PL does:
This PL does not:
Related-to #12945
cc/ @aghassemi @peterjosling