-
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
Implement bookend component for amp-story #11526
Conversation
|
||
|
||
const LINK_SHARE_TEMPLATE = | ||
`<div class="i-amphtml-story-share-icon"> |
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 don't allow XSS-able inner HTMLs. Please just use the DOM API.
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
`<div class="i-amphtml-story-share-icon"> | ||
${ICONS.link} | ||
</div> | ||
<span class="i-amphtml-story-share-name">Get link</span>`; |
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 to go w/o internationalization for now?
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.
Yeah. Added a TODO
const icon = type == 'email' ? ICONS.mail : ''; | ||
|
||
return ( | ||
`<amp-social-share |
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.
Ditto. DOM API.
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 params = !opt_params ? '' : | ||
Object.keys(opt_params) | ||
.map(field => | ||
`data-param-${escapeHtml(field)}=` + |
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.
DOM API. Then you won't need escapeHtml either.
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
*/ | ||
buildItem_(html) { | ||
const el = this.win_.document.createElement('li'); | ||
el./*OK*/innerHTML = html; |
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.
NOTOK
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.
FAIRENOUGH
extensions/amp-story/0.1/bookend.js
Outdated
* relatedArticles: !Array<!./related-articles.RelatedArticleSet> | ||
* }} | ||
*/ | ||
export let BookendConfig; |
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.
BookendConfigDef
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-story/0.1/bookend.js
Outdated
// TODO(alanorozco): Consider using amp-img and what we need to get it working | ||
const imgHtml = articleData.image ? ( | ||
`<div class="i-amphtml-story-bookend-article-image"> | ||
<img src="${articleData.image}" |
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.
ditto
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
/** | ||
* @typedef {{title: string, url: string, image: (string|undefined)}} | ||
*/ | ||
export let RelatedArticle; |
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.
Def
here and below
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
437966e
to
b94c07a
Compare
}); | ||
|
||
// constant value, no XSS risk | ||
iconEl./*OK*/innerHTML = ICONS.link; |
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.
Let's put a TODO and add this to #11545. Should be possible to create SVGs with pure JS.
Also, let's change icons.js
to use non-string interpolation and add a type declaration.
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.
change icons.js to use non-string interpolation and add a type declaration.
Done.
Should be possible to create SVGs with pure JS.
Should we? Seems like overkill. We could also just use compiled templates.
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.
<template>
? That would work 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.
I made a notes above. But why isn't this in CSS?
|
||
if (type == 'email') { | ||
// constant value, no XSS risk | ||
shareEl./*OK*/innerHTML = ICONS.mail; |
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.
Ditto. Are these icons only used once each? If so, let's just inline them 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.
I feel like that's a little messy :s
Ideally I think we should also move the system layer icons here.
|
||
/** @private */ | ||
loadRequiredExtensions_() { | ||
Services.extensionsFor(this.win_).loadExtension('amp-social-share'); |
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.
installExtensionForDoc
. Are all STAMPs required to have a bookend? When will this be invoked?
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.
All STAMPs are required to have a bookend, but not all bookends will have share buttons that require amp-social-share
, since that is configurable.
It's also not guaranteed that the user will navigate to the bookend, so the extension is only loaded once Bookend
sets share configuration for the share widget. This happens on "bookend preload time", which is executed once the user gets close enough to the widget.
This will be clear in the upcoming PR for the top-level AmpStory
component.
}); | ||
|
||
|
||
function buildLinkShareItem(doc) { |
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.
Please document this function.
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.
} | ||
|
||
|
||
function buildProvider(doc, type, opt_params) { |
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.
Document please.
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.
} | ||
|
||
|
||
export class BookendShareWidget { |
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.
Please document this class.
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-story/0.1/bookend.js
Outdated
const headingEl = createElementWithAttributes(this.win_.document, 'h3', { | ||
'class': 'i-amphtml-story-bookend-heading', | ||
}); | ||
headingEl./*OK*/innerText = escapeHtml(heading); |
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.
textContent
. Also, why do we need to escapeHtml
?
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. We don't need to, fixed.
articles: articleSetsResponse[headingKey].map(buildArticleFromJson_), | ||
}; | ||
|
||
if (!!headingKey.trim().length) { |
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.
!!
unnecessary.
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.
function buildArticleFromJson_(articleJson) { | ||
const article = { | ||
title: user().assert(articleJson.title), | ||
url: user().assert(articleJson.url), |
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.
PE follow-up: we should have useful error messaging and graceful failures. E.g. a missing title in one article shouldn't affect display of other articles.
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.
Yup! Added a TODO, not super important right now.
*/ | ||
// TODO(alanorozco): tighten externs | ||
// TODO(alanorozco): domain name | ||
export function buildFromJson(articleSetsResponse) { |
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.
relatedArticlesFromJson
. Exports should have more context in their names.
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.
<path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/> | ||
<path d="M0 0h24v24H0z" fill="none"/> | ||
</svg>`, | ||
'<svg xmlns="http://www.w3.org/2000/svg" width="32px" height="32px" viewBox="0 0 24 24">' + |
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.
SVGs can definitely be created in JS. But a different question I have here: our approach so far been that we put all icon SVGs in CSS. Why not do it here as well?
From newmuis/amphtml-story#49, newmuis/amphtml-story#54, newmuis/amphtml-story#56, newmuis/amphtml-story#69, newmuis/amphtml-story#183
/cc @newmuis