From 838c378058b0855b3d49d6fc46d484ffb6099d2b Mon Sep 17 00:00:00 2001 From: CrystalOnScript Date: Fri, 17 Jan 2020 09:07:16 -0800 Subject: [PATCH 01/10] clarified text node behavior (#26376) * clarified text node behavior * Update amp-timeago.md * codified wrong part --- extensions/amp-timeago/amp-timeago.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/extensions/amp-timeago/amp-timeago.md b/extensions/amp-timeago/amp-timeago.md index c12353d53cc2..c697d955b33a 100644 --- a/extensions/amp-timeago/amp-timeago.md +++ b/extensions/amp-timeago/amp-timeago.md @@ -25,9 +25,11 @@ limitations under the License. # amp-timeago -Provides fuzzy timestamps by formatting dates as `*** time ago` (for example, 3 hours ago). - + + + + @@ -46,10 +48,15 @@ Provides fuzzy timestamps by formatting dates as `*** time ago` (for example, 3 ## Behavior -Provides fuzzy timestamps that you can use on your AMP pages. This component is based on timeago.js. +Use the amp-timago component to count up to, or away from, a specified date and time. + +The component replaces the text node with a fuzzy timestamp, such as `in 30 years` or `3 hours ago`. +If using the `cutoff` attribute, and time has past the cutoff, the text node will display the specified date in the `datetime` attribute. Example: +[example preview="inline" playground="true" imports="amp-timeago"] + ```html ``` +Although it will be overridden, there must be at least one character in the `amp-timeago` text node. + +[/example] + ## Attributes
DescriptionProvides fuzzy timestamps that you can use on your AMP pages, based on timeago.js.
Required Script <script async custom-element="amp-timeago" src="https://cdn.ampproject.org/v0/amp-timeago-0.1.js"></script>
From ce6cd7aa4d91e75e41f0518b452d0c85c3772bed Mon Sep 17 00:00:00 2001 From: Jack Steinberg Date: Fri, 17 Jan 2020 12:08:16 -0500 Subject: [PATCH 02/10] =?UTF-8?q?=E2=9C=A8Add=20support=20for=20AMP=20Stor?= =?UTF-8?q?y=20Quiz=20Reaction=20API=20calls=20(#26242)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build-system/tasks/presubmit-checks.js | 1 + examples/amp-story/quiz.html | 3 +- extensions/amp-story/1.0/amp-story-quiz.js | 251 +++++++++++++++++- .../1.0/amp-story-request-service.js | 13 +- .../amp-story/1.0/test/test-amp-story-quiz.js | 86 +++++- 5 files changed, 332 insertions(+), 22 deletions(-) diff --git a/build-system/tasks/presubmit-checks.js b/build-system/tasks/presubmit-checks.js index ff735fcb1f0e..c7d92faafaaf 100644 --- a/build-system/tasks/presubmit-checks.js +++ b/build-system/tasks/presubmit-checks.js @@ -427,6 +427,7 @@ const forbiddenTerms = { 'extensions/amp-experiment/1.0/variant.js', 'extensions/amp-user-notification/0.1/amp-user-notification.js', 'extensions/amp-consent/0.1/consent-state-manager.js', + 'extensions/amp-story/1.0/amp-story-quiz.js', ], }, 'getBaseCid': { diff --git a/examples/amp-story/quiz.html b/examples/amp-story/quiz.html index d77b695f89ba..303077e441a5 100644 --- a/examples/amp-story/quiz.html +++ b/examples/amp-story/quiz.html @@ -64,7 +64,8 @@

Cat Facts!

+ id='cat-question-appear' + endpoint="http://localhost:3000/reactions">

When did the domestic cat first appear on the scene?

diff --git a/extensions/amp-story/1.0/amp-story-quiz.js b/extensions/amp-story/1.0/amp-story-quiz.js index 1ab2c7fc45ce..6a11fdbc496b 100644 --- a/extensions/amp-story/1.0/amp-story-quiz.js +++ b/extensions/amp-story/1.0/amp-story-quiz.js @@ -21,10 +21,14 @@ import { } from './story-analytics'; import {AnalyticsVariable, getVariableService} from './variable-service'; import {CSS} from '../../../build/amp-story-quiz-1.0.css'; +import {Services} from '../../../src/services'; import {StateProperty, getStoreService} from './amp-story-store-service'; +import {addParamsToUrl, assertAbsoluteHttpOrHttpsUrl} from '../../../src/url'; import {closest} from '../../../src/dom'; import {createShadowRootWithStyle} from './utils'; import {dev} from '../../../src/log'; +import {dict} from '../../../src/utils/object'; +import {getRequestService} from './amp-story-request-service'; import {htmlFor} from '../../../src/static-template'; import {toArray} from '../../../src/types'; @@ -39,6 +43,28 @@ const TAG = 'amp-story-quiz'; /** @const {number} */ const STORY_REACTION_TYPE_QUIZ = 0; +/** @const {string} */ +const ENDPOINT_INVALID_ERROR = + 'The publisher has specified an invalid datastore endpoint'; + +/** + * @typedef {{ + * reactionValue: number, + * totalCount: number, + * selectedByUser: boolean, + * }} + */ +export let ReactionType; + +/** + * @typedef {{ + * totalResponseCount: number, + * hasUserResponded: boolean, + * responses: !Array, + * }} + */ +export let ReactionResponseType; + /** * Generates the template for the quiz. * @@ -80,12 +106,30 @@ export class AmpStoryQuiz extends AMP.BaseElement { /** @private @const {!./story-analytics.StoryAnalyticsService} */ this.analyticsService_ = getAnalyticsService(this.win, element); + /** @private {?Promise} */ + this.clientIdService_ = Services.cidForDoc(this.element); + + /** @private {?Promise} */ + this.clientIdPromise_ = null; + /** @private {boolean} */ - this.hasReceivedResponse_ = false; + this.hasUserSelection_ = false; /** @private {?Element} */ this.quizEl_ = null; + /** @private {?string} */ + this.reactionId_ = null; + + /** @private {!./amp-story-request-service.AmpStoryRequestService} */ + this.requestService_ = getRequestService(this.win, this.element); + + /** @private {?Promise} */ + this.responseDataPromise_ = null; + + /** @private {?ReactionResponseType} */ + this.responseData_ = null; + /** @private @const {!./amp-story-store-service.AmpStoryStoreService} */ this.storeService_ = getStoreService(this.win); @@ -102,6 +146,31 @@ export class AmpStoryQuiz extends AMP.BaseElement { createShadowRootWithStyle(this.element, this.quizEl_, CSS); } + /** @override */ + layoutCallback() { + return (this.responseDataPromise_ = this.element.hasAttribute('endpoint') + ? this.retrieveReactionData_() + : Promise.resolve()); + } + + /** + * Gets a Promise to return the unique AMP clientId + * + * @private + * @return {Promise} + */ + getClientId_() { + if (!this.clientIdPromise_) { + this.clientIdPromise_ = this.clientIdService_.then(data => { + return data.get( + {scope: 'amp-story', createCookieIfNotPresent: true}, + /* consent */ Promise.resolve() + ); + }); + } + return this.clientIdPromise_; + } + /** * Reacts to RTL state updates and triggers the UI for RTL. * @@ -248,7 +317,7 @@ export class AmpStoryQuiz extends AMP.BaseElement { * @private */ handleTap_(e) { - if (this.hasReceivedResponse_) { + if (this.hasUserSelection_) { return; } @@ -292,6 +361,15 @@ export class AmpStoryQuiz extends AMP.BaseElement { ); } + /** + * @param {Element} selectedOption + * @private + */ + updateQuizToPostSelectionState_(selectedOption) { + this.quizEl_.classList.add('i-amphtml-story-quiz-post-selection'); + selectedOption.classList.add('i-amphtml-story-quiz-option-selected'); + } + /** * Triggers changes to quiz state on response interaction. * @@ -299,13 +377,172 @@ export class AmpStoryQuiz extends AMP.BaseElement { * @private */ handleOptionSelection_(optionEl) { - this.triggerAnalytics_(optionEl); + this.responseDataPromise_.then(() => { + if (this.hasUserSelection_) { + return; + } - this.mutateElement(() => { - optionEl.classList.add('i-amphtml-story-quiz-option-selected'); - this.quizEl_.classList.add('i-amphtml-story-quiz-post-selection'); + this.triggerAnalytics_(optionEl); + this.hasUserSelection_ = true; + + this.mutateElement(() => { + this.updateQuizToPostSelectionState_(optionEl); + }); + + if (this.element.hasAttribute('endpoint')) { + this.updateReactionData_(optionEl.optionIndex_); + } + }); + } + + /** + * Get the Reaction data from the datastore + * + * @return {?Promise} + * @private + */ + retrieveReactionData_() { + return this.executeReactionRequest_( + dict({ + 'method': 'GET', + }) + ) + .then(response => { + this.handleSuccessfulDataRetrieval_(response); + }) + .catch(error => { + dev().error(TAG, error); + }); + } + + /** + * Update the Reaction data in the datastore + * + * @param {number} reactionValue + * @private + */ + updateReactionData_(reactionValue) { + this.executeReactionRequest_( + dict({ + 'method': 'POST', + }), + reactionValue + ).catch(error => { + dev().error(TAG, error); + }); + } - this.hasReceivedResponse_ = true; + /** + * Executes a Reactions API call. + * + * @param {Object} requestOptions + * @param {number=} reactionValue + * @return {Promise} + * @private + */ + executeReactionRequest_(requestOptions, reactionValue) { + // TODO(jackbsteinberg): Add a default reactions endpoint. + if (!assertAbsoluteHttpOrHttpsUrl(this.element.getAttribute('endpoint'))) { + return Promise.reject(ENDPOINT_INVALID_ERROR); + } + + if (this.reactionId_ === null) { + const quizPageId = closest(dev().assertElement(this.element), el => { + return el.tagName.toLowerCase() === 'amp-story-page'; + }).getAttribute('id'); + + this.reactionId_ = `CANONICAL_URL#page=${quizPageId}`; + } + + const requestVars = dict({ + 'reactionType': STORY_REACTION_TYPE_QUIZ, + 'reactionId': this.reactionId_, + }); + + let url = this.element.getAttribute('endpoint'); + + if (requestOptions['method'] === 'POST') { + requestVars['reactionValue'] = reactionValue; + requestOptions['body'] = requestVars; + } else if (requestOptions['method'] === 'GET') { + url = addParamsToUrl(url, requestVars); + } + + return this.getClientId_().then(clientId => { + requestVars['clientId'] = clientId; + return this.requestService_.executeRequest(url, requestOptions); + }); + } + + /** + * Handles incoming reaction data response + * + * RESPONSE FORMAT + * { + * totalResponseCount: + * hasUserResponded: + * responses: [ + * { + * reactionValue: + * totalCount: + * selectedByUser: + * }, + * ... + * ] + * } + * @param {ReactionResponseType|undefined} response + * @private + */ + handleSuccessfulDataRetrieval_(response) { + if (!(response && 'data' in response)) { + dev().error( + TAG, + `Invalid reaction response, expected { data: ReactionResponseType, ...} but received ${response}` + ); + return; + } + + this.responseData_ = response.data; + + this.hasUserSelection_ = this.responseData_.hasUserResponded; + if (this.hasUserSelection_) { + this.updateQuizOnDataRetrieval_(); + } + } + + /** + * Updates the quiz to reflect the state of the remote data. + * + * @private + */ + updateQuizOnDataRetrieval_() { + let selectedOptionKey; + this.responseData_.responses.forEach(response => { + if (response.selectedByUser) { + selectedOptionKey = response.reactionValue; + } + }); + + if (selectedOptionKey === undefined) { + dev().error(TAG, `The user-selected reaction could not be found`); + } + + const options = this.quizEl_.querySelectorAll( + '.i-amphtml-story-quiz-option' + ); + + if (selectedOptionKey >= options.length) { + dev().error( + TAG, + `Quiz #${this.element.getAttribute('id')} does not have option ${ + answerChoiceOptions[selectedOptionKey] + }, but user selected option ${answerChoiceOptions[selectedOptionKey]}` + ); + return; + } + + this.mutateElement(() => { + this.updateQuizToPostSelectionState_(options[selectedOptionKey]); }); } } diff --git a/extensions/amp-story/1.0/amp-story-request-service.js b/extensions/amp-story/1.0/amp-story-request-service.js index 226f779b33db..667f6129398e 100644 --- a/extensions/amp-story/1.0/amp-story-request-service.js +++ b/extensions/amp-story/1.0/amp-story-request-service.js @@ -71,7 +71,7 @@ export class AmpStoryRequestService { const credentials = bookendEl.getAttribute( BOOKEND_CREDENTIALS_ATTRIBUTE_NAME ); - return this.loadJsonFromAttribute_(rawUrl, credentials); + return this.executeRequest(rawUrl, credentials ? {credentials} : {}); } // Fallback. Check for an inline json config. @@ -85,22 +85,15 @@ export class AmpStoryRequestService { /** * @param {string} rawUrl - * @param {string|null} credentials + * @param {Object=} opts * @return {(!Promise|!Promise)} - * @private */ - loadJsonFromAttribute_(rawUrl, credentials) { - const opts = {}; - + executeRequest(rawUrl, opts = {}) { if (!isProtocolValid(rawUrl)) { user().error(TAG, 'Invalid config url.'); return Promise.resolve(null); } - if (credentials) { - opts.credentials = credentials; - } - return Services.urlReplacementsForDoc(this.storyElement_) .expandUrlAsync(user().assertString(rawUrl)) .then(url => this.xhr_.fetchJson(url, opts)) diff --git a/extensions/amp-story/1.0/test/test-amp-story-quiz.js b/extensions/amp-story/1.0/test/test-amp-story-quiz.js index 2bbd121e993e..17acc3fb5249 100644 --- a/extensions/amp-story/1.0/test/test-amp-story-quiz.js +++ b/extensions/amp-story/1.0/test/test-amp-story-quiz.js @@ -17,7 +17,9 @@ import {AmpStoryQuiz} from '../amp-story-quiz'; import {AmpStoryStoreService} from '../amp-story-store-service'; import {AnalyticsVariable, getVariableService} from '../variable-service'; +import {Services} from '../../../../src/services'; import {getAnalyticsService} from '../story-analytics'; +import {getRequestService} from '../amp-story-request-service'; import {registerServiceBuilder} from '../../../../src/service'; /** @@ -54,6 +56,43 @@ const populateStandardQuizContent = (win, quizElement) => { populateQuiz(win, quizElement); }; +/** + * Returns mock reaction data + * + * @return {Object} + * @private + */ +const getMockReactionData = () => { + return { + data: { + totalResponseCount: 10, + hasUserResponded: true, + responses: [ + { + reactionValue: 0, + totalCount: 3, + selectedByUser: true, + }, + { + reactionValue: 1, + totalCount: 3, + selectedByUser: false, + }, + { + reactionValue: 2, + totalCount: 3, + selectedByUser: false, + }, + { + reactionValue: 3, + totalCount: 1, + selectedByUser: false, + }, + ], + }, + }; +}; + describes.realWin( 'amp-story-quiz', { @@ -65,14 +104,21 @@ describes.realWin( let storyEl; let analytics; let analyticsVars; + let requestService; beforeEach(() => { win = env.win; + + env.sandbox + .stub(Services, 'cidForDoc') + .resolves({get: () => Promise.resolve('cid')}); + const ampStoryQuizEl = win.document.createElement('amp-story-quiz'); ampStoryQuizEl.getResources = () => win.__AMP_SERVICES.resources.obj; analyticsVars = getVariableService(win); analytics = getAnalyticsService(win, win.document.body); + requestService = getRequestService(win, ampStoryQuizEl); const storeService = new AmpStoryStoreService(win); registerServiceBuilder(win, 'story-store', () => storeService); @@ -90,17 +136,15 @@ describes.realWin( env.sandbox.stub(ampStoryQuiz, 'mutateElement').callsFake(fn => fn()); }); - it('should take the html and reformat it', async () => { + it('should take the html and reformat it', () => { populateStandardQuizContent(win, ampStoryQuiz.element); ampStoryQuiz.buildCallback(); - await ampStoryQuiz.layoutCallback(); expect(ampStoryQuiz.getQuizElement().children.length).to.equal(2); }); - it('should structure the content in the quiz element', async () => { + it('should structure the content in the quiz element', () => { populateStandardQuizContent(win, ampStoryQuiz.element); ampStoryQuiz.buildCallback(); - await ampStoryQuiz.layoutCallback(); const quizContent = ampStoryQuiz.getQuizElement().children; expect(quizContent[0]).to.have.class( @@ -147,6 +191,7 @@ describes.realWin( populateStandardQuizContent(win, ampStoryQuiz.element); ampStoryQuiz.buildCallback(); await ampStoryQuiz.layoutCallback(); + const quizElement = ampStoryQuiz.getQuizElement(); const quizOption = quizElement.querySelector( '.i-amphtml-story-quiz-option' @@ -154,6 +199,9 @@ describes.realWin( quizOption.click(); + // Microtask tick + await Promise.resolve(); + expect(quizElement).to.have.class('i-amphtml-story-quiz-post-selection'); expect(quizOption).to.have.class('i-amphtml-story-quiz-option-selected'); }); @@ -162,6 +210,7 @@ describes.realWin( populateStandardQuizContent(win, ampStoryQuiz.element); ampStoryQuiz.buildCallback(); await ampStoryQuiz.layoutCallback(); + const quizElement = ampStoryQuiz.getQuizElement(); const quizOptions = quizElement.querySelectorAll( '.i-amphtml-story-quiz-option' @@ -170,6 +219,9 @@ describes.realWin( quizOptions[0].click(); quizOptions[1].click(); + // Microtask tick + await Promise.resolve(); + expect(quizOptions[0]).to.have.class( 'i-amphtml-story-quiz-option-selected' ); @@ -190,6 +242,9 @@ describes.realWin( option.click(); + // Microtask tick + await Promise.resolve(); + expect(trigger).to.have.been.calledWith('story-reaction'); const variables = analyticsVars.get(); @@ -199,5 +254,28 @@ describes.realWin( expect(variables[AnalyticsVariable.STORY_REACTION_RESPONSE]).to.equal(0); expect(variables[AnalyticsVariable.STORY_REACTION_TYPE]).to.equal(0); }); + + it('should update the quiz when the user has already reacted', async () => { + // Fill the response to the requestService with mock reaction data + env.sandbox + .stub(requestService, 'executeRequest') + .resolves(getMockReactionData()); + + ampStoryQuiz.element.setAttribute('endpoint', 'http://localhost:8000'); + + populateStandardQuizContent(win, ampStoryQuiz.element); + ampStoryQuiz.buildCallback(); + await ampStoryQuiz.layoutCallback(); + + const quizElement = ampStoryQuiz.getQuizElement(); + const quizOptions = quizElement.querySelectorAll( + '.i-amphtml-story-quiz-option' + ); + + expect(quizElement).to.have.class('i-amphtml-story-quiz-post-selection'); + expect(quizOptions[0]).to.have.class( + 'i-amphtml-story-quiz-option-selected' + ); + }); } ); From afebb3fb2e69892f3564345f33edb083e53f2423 Mon Sep 17 00:00:00 2001 From: Ryan Cebulko Date: Fri, 17 Jan 2020 12:48:23 -0500 Subject: [PATCH 03/10] =?UTF-8?q?=F0=9F=93=96=20Rename=20Dev=20Channel=20t?= =?UTF-8?q?o=20Experimental=20Channel=20in=20docs=20and=20comments=20(#262?= =?UTF-8?q?55)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Rename Dev Channel to Experimental in issue templates * Rename Dev Channel to Experimental in docs * Rename Dev Channel to Experimental in experiments.js * Rename Dev Channel to Experimental in amp-geo docs/examples * /pushed/promoted/s * Explicitly mention experimental and beta channels * /production/Stable/s * Merge sections on Experimental and Beta Channels * Move opt-in channels to "channels" section and freezes to "cadence" * /locahost/localhost/s * /Channel/channel/g * Code review tweaks to release template checkboxes * Remove old release_issue_template.md * Copy edits per rsimha * /stable/stable and LTS/s * Add commas * Lint fixes * Fix italicized Experimental Channel --- .../ISSUE_TEMPLATE/release-tracking-issue.md | 20 ++--- .../ISSUE_TEMPLATE/release_issue_template.md | 37 --------- 3p/README.md | 2 +- contributing/getting-started-e2e.md | 4 +- contributing/getting-started-quick.md | 4 +- contributing/release-schedule.md | 76 ++++++++----------- .../analytics-notification-with-geo.amp.html | 2 +- extensions/amp-geo/amp-geo.md | 2 +- tools/experiments/experiments.js | 12 +-- 9 files changed, 54 insertions(+), 105 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/release_issue_template.md diff --git a/.github/ISSUE_TEMPLATE/release-tracking-issue.md b/.github/ISSUE_TEMPLATE/release-tracking-issue.md index d096fa316657..5d0b36dafbdf 100644 --- a/.github/ISSUE_TEMPLATE/release-tracking-issue.md +++ b/.github/ISSUE_TEMPLATE/release-tracking-issue.md @@ -13,8 +13,8 @@ assignees: '' - [x] Release `[](https://github.com/ampproject/amphtml/releases/tag/)` is cut as a new canary release -- [ ] Release pushed to dev channel () -- [ ] Release pushed to 1% () -- [ ] Release pushed to production () +- [ ] Release promoted to Experimental and Beta (opt-in) channels () +- [ ] Release promoted to Experimental and Beta (1% traffic) channels () +- [ ] Release promoted to Stable channel () -See the [release documentation](https://github.com/ampproject/amphtml/blob/master/contributing/release-schedule.md) for more information on the release process, including how to test changes in the Dev Channel. +See the [release documentation](https://github.com/ampproject/amphtml/blob/master/contributing/release-schedule.md) for more information on the release process, including how to test changes in the Experimental channel. If you find a bug in this build, please file an [issue](https://github.com/ampproject/amphtml/issues/new). If you believe the bug should be fixed in this build, follow the instructions in the [cherry picks documentation](https://go.amp.dev/cherry-picks). diff --git a/.github/ISSUE_TEMPLATE/release_issue_template.md b/.github/ISSUE_TEMPLATE/release_issue_template.md deleted file mode 100644 index a8a6aa383cce..000000000000 --- a/.github/ISSUE_TEMPLATE/release_issue_template.md +++ /dev/null @@ -1,37 +0,0 @@ -# Release tracking issue - - - -- [x] Release `[](https://github.com/ampproject/amphtml/releases/tag/)` is cut as a new canary release -- [ ] Release pushed to dev channel () -- [ ] Release pushed to 1% () -- [ ] Release pushed to production () - - - -See the [release documentation](https://github.com/ampproject/amphtml/blob/master/contributing/release-schedule.md) for more information on the release process, including how to test changes in the Dev Channel. - -If you find a bug in this build, please file an [issue](https://github.com/ampproject/amphtml/issues/new). If you believe the bug should be fixed in this build, follow the instructions in the [cherry picks documentation](https://go.amp.dev/cherry-picks). diff --git a/3p/README.md b/3p/README.md index 145340275765..49b5af83fbe9 100644 --- a/3p/README.md +++ b/3p/README.md @@ -66,5 +66,5 @@ Review the [ads/README](../ads/README.md) for further details on ad integration. You should ensure there are integration tests for your extension. These should be added to the AMP repo where it makes sense. In some cases this won't be possible because it relies on bringing up third-party infrastructure. In these cases you should maintain testing for the extension on your -infrastructure against both production AMP and [canary](https://github.com/ampproject/amphtml/blob/master/contributing/release-schedule.md#amp-dev-channel). +infrastructure against both production AMP and [canary](https://github.com/ampproject/amphtml/blob/master/contributing/release-schedule.md#amp-experimental-and-beta-channels). Upon any monitored failures, an escalation can be raised in [regular AMP communication channel](https://github.com/ampproject/amphtml/blob/master/CONTRIBUTING.md#discussion-channels). diff --git a/contributing/getting-started-e2e.md b/contributing/getting-started-e2e.md index 3c760e98578b..b10e92b87bea 100644 --- a/contributing/getting-started-e2e.md +++ b/contributing/getting-started-e2e.md @@ -582,9 +582,9 @@ AMP is pushed to production after undergoing testing. Generally, it takes about **Once the push of the build that includes your change is complete all users of AMP will be using the code you contributed!** -You can see whether your change made it into a given build on the [amphtml Releases page](https://github.com/ampproject/amphtml/releases). The build marked `Pre-release` is the version on the Dev Channel and the build marked `Latest Release` is what is running in production. Your Pull Request will be listed in the first build that includes it; if you don't see your Pull Request listed it will likely be in the next build. +You can see whether your change made it into a given build on the [amphtml Releases page](https://github.com/ampproject/amphtml/releases). The build marked `Pre-release` is the version on the Experimental Channel and the build marked `Latest Release` is what is running in production. Your Pull Request will be listed in the first build that includes it; if you don't see your Pull Request listed it will likely be in the next build. -You can set your browser to use the Dev Channel build by enabling `dev-channel` on the [AMP Experiments](https://cdn.ampproject.org/experiments.html) page. This will let you see how your changes will affect any AMP page before your changes are rolled out to all AMP pages. Note that this only affects the browser in which you enable the experiment. +You can set your browser to use the Experimental Channel build by enabling `experimental-channel` on the [AMP Experiments](https://cdn.ampproject.org/experiments.html) page. This will let you see how your changes will affect any AMP page before your changes are rolled out to all AMP pages. Note that this only affects the browser in which you enable the experiment. You can verify the AMP version your browser is using for a given page by looking at your browser's developer console. After loading an AMP page (e.g. [https://amp.dev](https://amp.dev)) the console will have a message like `Powered by AMP ⚡ HTML – Version `). The `` will match one of the build numbers on the [amphtml Releases page](https://github.com/ampproject/amphtml/releases). diff --git a/contributing/getting-started-quick.md b/contributing/getting-started-quick.md index 0d9713cf6ccb..b071903f6514 100644 --- a/contributing/getting-started-quick.md +++ b/contributing/getting-started-quick.md @@ -155,6 +155,6 @@ git checkout -b master - If your change affected internal documentation, tests, the build process, etc. you can generally see your changes right after they're merged. - If your change was to the code that runs on AMP pages across the web, you'll have to wait for the change to be included in a production release. Generally, it takes about 1-2 weeks for a change to be live for all users. See the [release schedule](release-schedule.md) for more specific details. -- The [amphtml Releases page](https://github.com/ampproject/amphtml/releases) will list your PR in the first build that contains it. `Pre-release` is the build on the Dev Channel, `Latest Release` is the build in production. -- Opt in to using the Dev Channel in a browser by enabling `dev-channel` on the [AMP Experiments](https://cdn.ampproject.org/experiments.html) page. +- The [amphtml Releases page](https://github.com/ampproject/amphtml/releases) will list your PR in the first build that contains it. `Pre-release` is the build on the Experimental Channel, `Latest Release` is the build in production. +- Opt in to using the Experimental Channel in a browser by enabling `experimental-channel` on the [AMP Experiments](https://cdn.ampproject.org/experiments.html) page. - Find the AMP version being used on a page in the developer console, i.e. `Powered by AMP ⚡ HTML – Version `. diff --git a/contributing/release-schedule.md b/contributing/release-schedule.md index 49419337ba65..4afbd93026b9 100644 --- a/contributing/release-schedule.md +++ b/contributing/release-schedule.md @@ -3,12 +3,11 @@ - [Release Channels](#release-channels) - [Weekly](#weekly) - [Long-Term Stable (lts)](#long-term-stable-lts) + - [AMP Experimental and Beta Channels](#amp-experimental-and-beta-channels) - [Determining if your change is in a release](#determining-if-your-change-is-in-a-release) - [Release Cadence](#release-cadence) - [Detailed schedule](#detailed-schedule) - - [AMP Dev Channel (Experimental)](#amp-dev-channel-experimental) - - [AMP Beta Channel (Beta)](#amp-beta-channel-beta) -- [Release Freezes](#release-freezes) + - [Release Freezes](#release-freezes) A new release of AMP is pushed to all AMP pages every week on Tuesday. **Once a change in AMP is merged into the master branch of the amphtml repository, it will typically take 1-2 weeks for the change be live for all users.** @@ -43,70 +42,57 @@ You can determine what changes are in a given build using one of the following: > Note: These labels still use legacy release names. They will be renamed soon to reflect the new release channel names (**beta** and **stable**). -## Release Cadence - -We are intentionally cautious with our release cadence. - -In determining how often we should push new versions of AMP to everyone, we have to weigh many factors including: - -- stability for the millions of sites/billions of pages built using AMP -- cache busting that might happen when we push a new version -- the desire to get new features out quickly +### AMP Experimental and Beta Channels -After considering all of these factors we have arrived at the 1-2 week push cycle. Thus far we have found this to be a reasonable compromise, but we will continue to evaluate all of these factors and may make changes in the future. +The _AMP Experimental Channel_ is a way to opt a browser into using the **experimental** release build of the AMP JS libraries. The _Experimental Channel_ **may be less stable** and it may contain features not yet available to all users. -### Detailed schedule - -We try to stick to this schedule as closely as possible, though complications may cause delays. You can track the latest status about any release in the [_Type: Release_ GitHub issues](https://github.com/ampproject/amphtml/labels/Type%3A%20Release) and the [AMP Slack #release channel](https://amphtml.slack.com/messages/C4NVAR0H3/) ([sign up for Slack](https://bit.ly/amp-slack-signup)). +Opting into the _Experimental Channel_ is intended for: -- Tuesday @ [11am Pacific](https://www.google.com/search?q=11am+pacific+in+current+time+zone): new **experimental** and **beta** release builds are created from the [latest master build that passes all of our tests](https://travis-ci.org/ampproject/amphtml/branches) and are pushed to users of AMP who opted into the [AMP Dev Channel](#amp-dev-channel) or [AMP Beta Channel](#amp-beta-channel), respectively. -- Wednesday: we check bug reports for _Dev Channel_ and _Beta Channel_ users and if everything looks fine, we push the **beta** to 1% of AMP pages -- Thursday-Monday: we continue to monitor error rates and bug reports for _Dev Channel_ and _Beta Channel_ users and the 1% of pages with the **experimental**/**beta** builds -- Tuesday the following week: the **beta** build is fully promoted to **stable** (i.e. all AMP pages will now use this build) +- testing and playing with new features not yet available to all users +- using in Quality Assurance (QA) to ensure that your site is compatible with upcoming features of AMP that are still under development -### AMP Dev Channel (Experimental) +To opt your browser into the _AMP Experimental Channel_, go to [the AMP experiments page](https://cdn.ampproject.org/experiments.html) and activate the "AMP Experimental Channel" experiment. Please subscribe to our [low-volume announcements](https://groups.google.com/forum/#!forum/amphtml-announce) mailing list to get notified about important/breaking changes about AMP. -The _AMP Dev Channel_ is a way to opt a browser into using the **experimental** release build of the AMP JS libraries. The _Dev Channel_ **may be less stable** and it may contain features not yet available to all users. +The _AMP Beta Channel_ is a way to opt a browser into using the **beta** release build of the AMP JS libraries that will be promoted to **stable** during the subsequent release cycle (typically, a week later). It is similar to the _Experimental Channel_ described above, but it will not contain the experimental features that are still under development. -Opting into the _Dev Channel_ is intended for: +Opting into the _Beta Channel_ is intended for: -- testing and playing with new features not yet available to all users -- using in Quality Assurance (QA) to ensure that your site is compatible with upcoming features of AMP that are still under development +- testing and playing with the version of the AMP runtime that will be released soon +- using in Quality Assurance (QA) to ensure that your site is compatible with the next version of AMP -When you opt into the _AMP Dev Channel_ you are only affecting the AMP JS libraries in your browser; there is no way to force visitors to your site to use the _AMP Dev Channel_ version of AMP. +When you opt into the _Experimental_ or _Beta_ channel, you are only affecting the AMP JS libraries in your browser; there is no way to force visitors to your site to use the _AMP Experimental/Beta Channel_ version of AMP. -To opt your browser into the _AMP Dev Channel_, go to [the AMP experiments page](https://cdn.ampproject.org/experiments.html) and activate the "AMP Dev Channel" experiment. Please subscribe to our [low-volume announcements](https://groups.google.com/forum/#!forum/amphtml-announce) mailing list to get notified about important/breaking changes about AMP. +To opt your browser into one of these channels, go to [the AMP experiments page](https://cdn.ampproject.org/experiments.html) and activate the "AMP Experimental Channel" or "AMP Beta Channel" experiment. Please subscribe to our [low-volume announcements](https://groups.google.com/forum/#!forum/amphtml-announce) mailing list to get notified about important/breaking changes about AMP. -**If you find an issue that appears to only occur in the Dev Channel version of AMP**: +**If you find an issue that appears to only occur in the _Experimental/Beta Channel_ version of AMP**: - please [file an issue](https://github.com/ampproject/amphtml/issues/new) with a description of the problem - - include a note that the problem is new to the Dev Channel build so that it can be properly prioritized + - include a note that the problem is new to the _Experimental/Beta Channel_ build so that it can be properly prioritized - include a URL to a page that reproduces the problem -- ping the [AMP Slack #release channel](https://amphtml.slack.com/messages/C4NVAR0H3/) ([sign up for Slack](https://bit.ly/amp-slack-signup)) with the issue you filed so we can delay the push of the Dev Channel version to production if needed - -### AMP Beta Channel (Beta) +- ping the [AMP Slack #release channel](https://amphtml.slack.com/messages/C4NVAR0H3/) ([sign up for Slack](https://bit.ly/amp-slack-signup)) with the issue you filed so we can delay the push of the _Experimental/Beta Channel_ version to production if needed -The _AMP Beta Channel_ is a way to opt a browser into using the **beta** release build of the AMP JS libraries that will be promoted to **stable** during the subsequent release cycle (typically, a week later). It is similar to the _Dev Channel_ described above, but it will not contain the experimental features that are still under development. +## Release Cadence -Opting into the _Beta Channel_ is intended for: +We are intentionally cautious with our release cadence. -- testing and playing with the version of the AMP runtime that will be released soon -- using in Quality Assurance (QA) to ensure that your site is compatible with the next version of AMP +In determining how often we should push new versions of AMP to everyone, we have to weigh many factors including: -Similar to the _Dev Channel_, when you opt into the _AMP Beta Channel_ you are only affecting the AMP JS libraries in your browser; there is no way to force visitors to your site to use the _AMP Beta Channel_ version of AMP. +- stability for the millions of sites/billions of pages built using AMP +- cache busting that might happen when we push a new version +- the desire to get new features out quickly -To opt your browser into the _AMP Beta Channel_, go to [the AMP experiments page](https://cdn.ampproject.org/experiments.html) and activate the "AMP RC Channel" experiment. Please subscribe to our [low-volume announcements](https://groups.google.com/forum/#!forum/amphtml-announce) mailing list to get notified about important/breaking changes about AMP. +After considering all of these factors, we have arrived at the 1-2 week push cycle. Thus far, we have found this to be a reasonable compromise, but we will continue to evaluate all of these factors and may make changes in the future. -> Note: "RC" refers to the term "Release Candidate", which was the previous name for the **beta** release channel. +### Detailed schedule -**If you find an issue that appears to only occur in the _Beta Channel_ version of AMP**: +We try to stick to this schedule as closely as possible, though complications may cause delays. You can track the latest status about any release in the [_Type: Release_ GitHub issues](https://github.com/ampproject/amphtml/labels/Type%3A%20Release) and the [AMP Slack #release channel](https://amphtml.slack.com/messages/C4NVAR0H3/) ([sign up for Slack](https://bit.ly/amp-slack-signup)). -- please [file an issue](https://github.com/ampproject/amphtml/issues/new) with a description of the problem - - include a note that the problem is new to the _Beta Channel_ build so that it can be properly prioritized - - include a URL to a page that reproduces the problem -- ping the [AMP Slack #release channel](https://amphtml.slack.com/messages/C4NVAR0H3/) ([sign up for Slack](https://bit.ly/amp-slack-signup)) with the issue you filed so we can delay the push of the _Beta Channel_ version to production if needed +- Tuesday @ [11am Pacific](https://www.google.com/search?q=11am+pacific+in+current+time+zone): new **experimental** and **beta** release builds are created from the [latest master build that passes all of our tests](https://travis-ci.org/ampproject/amphtml/branches) and are pushed to users of AMP who opted into the [AMP Experimental Channel](#amp-experimental-and-beta-channels) or [AMP Beta Channel](#amp-experimental-and-beta-channels), respectively. +- Wednesday: we check bug reports for _Experimental Channel_ and _Beta Channel_ users and if everything looks fine, we push the **beta** to 1% of AMP pages +- Thursday-Monday: we continue to monitor error rates and bug reports for _Experimental Channel_ and _Beta Channel_ users and the 1% of pages with the **experimental**/**beta** builds +- Tuesday the following week: the **beta** build is fully promoted to **stable** (i.e. all AMP pages will now use this build) -## Release Freezes +### Release Freezes There are occasions when we will skip a release of AMP to production, known as a release freeze. diff --git a/examples/analytics-notification-with-geo.amp.html b/examples/analytics-notification-with-geo.amp.html index c92a1004db86..06757f5e71aa 100644 --- a/examples/analytics-notification-with-geo.amp.html +++ b/examples/analytics-notification-with-geo.amp.html @@ -129,6 +129,6 @@

Notification with amp-geo demo

This page has three "amp-user-notification" elements. They are configured to trigger in different countries. One for NAFTA (CA, MX, US). One for multiple country groups and one for the negative matched country groups.

-

If you are using locahost or in the dev channel you can set your country using #amp-geo= with the two letter ISO country code. For example #amp-geo=us.

+

If you are using localhost or in the experimental channel you can set your country using #amp-geo= with the two letter ISO country code. For example #amp-geo=us.

diff --git a/extensions/amp-geo/amp-geo.md b/extensions/amp-geo/amp-geo.md index 5407d4f1e267..418dd3738677 100644 --- a/extensions/amp-geo/amp-geo.md +++ b/extensions/amp-geo/amp-geo.md @@ -249,7 +249,7 @@ The string `{{AMP_ISO_COUNTRY_HOTPATCH}}` must be replaced at serving time with ### Debugging -Adding `#amp-geo=XX` to the document url forces the country to appear as the country `XX`. This allows you to test without having to VPN to a country. For security reasons, to prevent sharing of geo-spoofing urls, this feature is only available to users who have enabled the [Dev Channel](https://amp.dev/documentation/guides-and-tutorials/learn/experimental) or who are testing locally (i.e., `amp-geo.js` is served in development mode via [`gulp serve`](https://github.com/ampproject/amphtml/blob/master/contributing/DEVELOPING.md)). +Adding `#amp-geo=XX` to the document url forces the country to appear as the country `XX`. This allows you to test without having to VPN to a country. For security reasons, to prevent sharing of geo-spoofing urls, this feature is only available to users who have enabled the [Experimental Channel](https://amp.dev/documentation/guides-and-tutorials/learn/experimental) or who are testing locally (i.e., `amp-geo.js` is served in development mode via [`gulp serve`](https://github.com/ampproject/amphtml/blob/master/contributing/DEVELOPING.md)). **Note:** Debugging in DevChannel may not work in Safari due to [ITP](https://webkit.org/blog/8311/intelligent-tracking-prevention-2-0/). diff --git a/tools/experiments/experiments.js b/tools/experiments/experiments.js index 761789b2f3f9..c4b0404a2f1d 100644 --- a/tools/experiments/experiments.js +++ b/tools/experiments/experiments.js @@ -63,21 +63,21 @@ const AMP_CANARY_COOKIE = { /** @const {!Array} */ const CHANNELS = [ - // Canary (Dev Channel) + // Experimental Channel { id: CANARY_EXPERIMENT_ID, - name: 'AMP Dev Channel (more info)', + name: 'AMP Experimental Channel (more info)', spec: 'https://github.com/ampproject/amphtml/blob/master/' + - 'contributing/release-schedule.md#amp-dev-channel', + 'contributing/release-schedule.md#amp-experimental-and-beta-channels', }, - // Release Candidate (RC Channel) + // Beta Channel { id: RC_EXPERIMENT_ID, - name: 'AMP RC Channel (more info)', + name: 'AMP Beta Channel (more info)', spec: 'https://github.com/ampproject/amphtml/blob/master/' + - 'contributing/release-schedule.md#amp-release-candidate-rc-channel', + 'contributing/release-schedule.md#amp-experimental-and-beta-channels', }, ]; From 6d8d4199e0c74b8e861e48da600e2414e2662103 Mon Sep 17 00:00:00 2001 From: Daniel Rozenberg Date: Fri, 17 Jan 2020 14:51:10 -0500 Subject: [PATCH 04/10] =?UTF-8?q?=E2=9C=A8=20Add=20support=20for=20`"intri?= =?UTF-8?q?sic"`=20layout=20for=20``=20(#26369)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add support for "intrisic" layout for * Add supported layouts to .md file --- extensions/amp-script/amp-script.md | 4 ++++ extensions/amp-script/validator-amp-script.protoascii | 1 + 2 files changed, 5 insertions(+) diff --git a/extensions/amp-script/amp-script.md b/extensions/amp-script/amp-script.md index b25de7c44ea0..8d6df31586af 100644 --- a/extensions/amp-script/amp-script.md +++ b/extensions/amp-script/amp-script.md @@ -46,6 +46,10 @@ limitations under the License. +
+ + +
Supported Layoutscontainer, fill, fixed, fixed-height, flex-item, intrinsic, responsive
Tutorials diff --git a/extensions/amp-script/validator-amp-script.protoascii b/extensions/amp-script/validator-amp-script.protoascii index c0f6d5c693f5..7e7d1211b48d 100644 --- a/extensions/amp-script/validator-amp-script.protoascii +++ b/extensions/amp-script/validator-amp-script.protoascii @@ -211,6 +211,7 @@ tags: { # supported_layouts: FIXED supported_layouts: FIXED_HEIGHT supported_layouts: FLEX_ITEM + supported_layouts: INTRINSIC supported_layouts: NODISPLAY supported_layouts: RESPONSIVE } From d46416bb1c520bae1c9d09521d1e2e93cef51405 Mon Sep 17 00:00:00 2001 From: Naina Raisinghani Date: Fri, 17 Jan 2020 12:05:30 -0800 Subject: [PATCH 05/10] Update I2I & I2S to reflect new Open Source process (#25530) * Update I2I & I2S to reflect new Open Source process See here for context: https://docs.google.com/document/d/1bF5tHbm-ObyjKLfoiIEAI5V-YvMsA3Bchsux5u4cKZM/edit# * Add I2S as well. * Change order in I2I * Change status to be explicitly stated * Suggested changes (rudygalfi) to I2I.md * Suggested changes (rudygalfi) to I2S. * Suggested changes (paularmstrong) to I2I * Suggested changes (cramforce) to I2I * Suggested changes (cramforce) to I2S * Fix invalid links * Force an update to Percy --- .../intent-to-implement--i2i-.md | 21 ++++++- .../ISSUE_TEMPLATE/intent-to-ship--i2s-.md | 60 ++++++++++++++++++- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/intent-to-implement--i2i-.md b/.github/ISSUE_TEMPLATE/intent-to-implement--i2i-.md index 556581676751..56be63649fc3 100644 --- a/.github/ISSUE_TEMPLATE/intent-to-implement--i2i-.md +++ b/.github/ISSUE_TEMPLATE/intent-to-implement--i2i-.md @@ -15,6 +15,13 @@ See https://github.com/ampproject/amphtml/blob/master/contributing/contributing- If you haven't already done so, sign the Contributor License Agreement (CLA) as soon as possible to avoid delays merging your code. A signed CLA is not necessary to submit this I2I or to send a pull request, but it will be needed before your code can be merged. See https://github.com/ampproject/amphtml/blob/master/contributing/contributing-code.md#contributor-license-agreement for more information on CLAs. --> +## Status +- [ ] Draft +- [ ] Ready for review + + ## Summary +## Consideration checklist +### Software Design +- [ ] Design shows understanding of problem statement/priority +- [ ] Acceptance/success criteria for problem being solved is clear +- [ ] Brought to design review + + /cc @ampproject/wg-approvers diff --git a/.github/ISSUE_TEMPLATE/intent-to-ship--i2s-.md b/.github/ISSUE_TEMPLATE/intent-to-ship--i2s-.md index 14f8b0fcdf57..794c771f664e 100644 --- a/.github/ISSUE_TEMPLATE/intent-to-ship--i2s-.md +++ b/.github/ISSUE_TEMPLATE/intent-to-ship--i2s-.md @@ -51,8 +51,66 @@ Provide instructions for how to demo your feature such as a link to a demo page. Add any other information that may be relevant in determining if your feature can ship. --> +## Build checklist + +This section describes considerations the implementor should keep in mind while building this technical solution. + +- [ ] Tests written + +- [ ] Documentation present + +- [ ] Cross platform testing + + +### Considerations checklist + +This section describes different cross cutting considerations that the implementor should keep in mind while building this technical solution. + + + +- #### Accessibility Considerations + +- #### Performance Considerations + +- #### Privacy Considerations + +- #### Security Considerations + +- #### Analytics Considerations + + +### Launch checklist + +This section describes the final approvals needed before this feature can launch. + +- [ ] TSC/Approvers WG approved + /cc @ampproject/wg-approvers From b7188b9266094a8b58a8eb2c759bf59e82b11dc2 Mon Sep 17 00:00:00 2001 From: Esther Kim <44627152+estherkim@users.noreply.github.com> Date: Fri, 17 Jan 2020 15:49:27 -0500 Subject: [PATCH 06/10] Skip amp story affiliate link test (#26386) --- .../1.0/test/integration/test-amp-story-affiliate-link.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/amp-story/1.0/test/integration/test-amp-story-affiliate-link.js b/extensions/amp-story/1.0/test/integration/test-amp-story-affiliate-link.js index 8a9f8e7a0857..a0043e1397db 100644 --- a/extensions/amp-story/1.0/test/integration/test-amp-story-affiliate-link.js +++ b/extensions/amp-story/1.0/test/integration/test-amp-story-affiliate-link.js @@ -77,7 +77,7 @@ t.run('amp-story-affiliate link', () => { expect(RequestBank.withdraw()).to.throw; }); - it('should send analytics event on external click', async () => { + it.skip('should send analytics event on external click', async () => { browser.click('#blink-1'); browser.click('#blink-1'); const req = await RequestBank.withdraw(); From 9b1106300692c362e8690eaa9bcc35e540d4ffd5 Mon Sep 17 00:00:00 2001 From: Naina Raisinghani Date: Fri, 17 Jan 2020 13:31:33 -0800 Subject: [PATCH 07/10] Revert "Update I2I & I2S to reflect new Open Source process (#25530)" (#26392) This reverts commit d46416bb1c520bae1c9d09521d1e2e93cef51405. --- .../intent-to-implement--i2i-.md | 21 +------ .../ISSUE_TEMPLATE/intent-to-ship--i2s-.md | 60 +------------------ 2 files changed, 2 insertions(+), 79 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/intent-to-implement--i2i-.md b/.github/ISSUE_TEMPLATE/intent-to-implement--i2i-.md index 56be63649fc3..556581676751 100644 --- a/.github/ISSUE_TEMPLATE/intent-to-implement--i2i-.md +++ b/.github/ISSUE_TEMPLATE/intent-to-implement--i2i-.md @@ -15,13 +15,6 @@ See https://github.com/ampproject/amphtml/blob/master/contributing/contributing- If you haven't already done so, sign the Contributor License Agreement (CLA) as soon as possible to avoid delays merging your code. A signed CLA is not necessary to submit this I2I or to send a pull request, but it will be needed before your code can be merged. See https://github.com/ampproject/amphtml/blob/master/contributing/contributing-code.md#contributor-license-agreement for more information on CLAs. --> -## Status -- [ ] Draft -- [ ] Ready for review - - ## Summary -## Consideration checklist -### Software Design -- [ ] Design shows understanding of problem statement/priority -- [ ] Acceptance/success criteria for problem being solved is clear -- [ ] Brought to design review - - /cc @ampproject/wg-approvers diff --git a/.github/ISSUE_TEMPLATE/intent-to-ship--i2s-.md b/.github/ISSUE_TEMPLATE/intent-to-ship--i2s-.md index 794c771f664e..14f8b0fcdf57 100644 --- a/.github/ISSUE_TEMPLATE/intent-to-ship--i2s-.md +++ b/.github/ISSUE_TEMPLATE/intent-to-ship--i2s-.md @@ -51,66 +51,8 @@ Provide instructions for how to demo your feature such as a link to a demo page. Add any other information that may be relevant in determining if your feature can ship. --> -## Build checklist - -This section describes considerations the implementor should keep in mind while building this technical solution. - -- [ ] Tests written - -- [ ] Documentation present - -- [ ] Cross platform testing - - -### Considerations checklist - -This section describes different cross cutting considerations that the implementor should keep in mind while building this technical solution. - - - -- #### Accessibility Considerations - -- #### Performance Considerations - -- #### Privacy Considerations - -- #### Security Considerations - -- #### Analytics Considerations - - -### Launch checklist - -This section describes the final approvals needed before this feature can launch. - -- [ ] TSC/Approvers WG approved - /cc @ampproject/wg-approvers From 89c378bab479f9f3ed40abde3206d92bc317e778 Mon Sep 17 00:00:00 2001 From: Gabriel Majoulet Date: Fri, 17 Jan 2020 16:36:23 -0500 Subject: [PATCH 08/10] Render video alt and title attributes in vertical rendering mdoe. (#26370) --- extensions/amp-story/1.0/amp-story-page.js | 60 ++++++++++++++-------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/extensions/amp-story/1.0/amp-story-page.js b/extensions/amp-story/1.0/amp-story-page.js index cf2843d2f002..837a2d095d72 100644 --- a/extensions/amp-story/1.0/amp-story-page.js +++ b/extensions/amp-story/1.0/amp-story-page.js @@ -295,9 +295,6 @@ export class AmpStoryPage extends AMP.BaseElement { /** @private {?number} Time at which an audio element failed playing. */ this.playAudioElementFromTimestamp_ = null; - - /** @private {?string} A textual description of the content of the page. */ - this.description_ = null; } /** @@ -1643,52 +1640,73 @@ export class AmpStoryPage extends AMP.BaseElement { } /** - * Sets the description of the page. + * Sets the description of the page, from its title and its videos + * alt/title attributes. * @private */ setPageDescription_() { - this.description_ = this.element.getAttribute('title'); - if (this.isBotUserAgent_) { this.renderPageDescription_(); - } else { + } + + if (!this.isBotUserAgent_ && this.element.hasAttribute('title')) { // Strip the title attribute from the page on non-bot user agents, to // prevent the browser tooltip. if (!this.element.getAttribute('aria-label')) { - this.element.setAttribute('aria-label', this.description_); + this.element.setAttribute( + 'aria-label', + this.element.getAttribute('title') + ); } this.element.removeAttribute('title'); } } /** - * Renders the page description in the page. + * Renders the page description, and videos title/alt attributes in the page. * @private */ renderPageDescription_() { - if (!this.description_) { - return; - } - const descriptionElId = `i-amphtml-story-${this.element.id}-description`; const descriptionEl = createElementWithAttributes( this.win.document, - 'h2', + 'div', dict({ 'class': 'i-amphtml-story-page-description', 'id': descriptionElId, }) ); - descriptionEl./* OK */ textContent = this.description_; - this.element.parentElement.insertBefore( - descriptionEl, - this.element.nextElementSibling - ); + const addTagToDescriptionEl = (tagName, text) => { + if (!text) { + return; + } + const el = this.win.document.createElement(tagName); + el./* OK */ textContent = text; + descriptionEl.appendChild(el); + }; + + addTagToDescriptionEl('h2', this.element.getAttribute('title')); + + this.getMediaBySelector_(Selectors.ALL_AMP_VIDEO, true).forEach(videoEl => { + addTagToDescriptionEl('p', videoEl.getAttribute('alt')); + addTagToDescriptionEl('p', videoEl.getAttribute('title')); + }); - if (!this.element.getAttribute('aria-labelledby')) { - this.element.setAttribute('aria-labelledby', descriptionElId); + if (descriptionEl.childElementCount === 0) { + return; } + + this.mutateElement(() => { + this.element.parentElement.insertBefore( + descriptionEl, + this.element.nextElementSibling + ); + + if (!this.element.getAttribute('aria-labelledby')) { + this.element.setAttribute('aria-labelledby', descriptionElId); + } + }); } /** From b0e732abf7c11b40161598b90528c5ed5bb26777 Mon Sep 17 00:00:00 2001 From: CrystalOnScript Date: Fri, 17 Jan 2020 16:38:08 -0800 Subject: [PATCH 09/10] rephrased reasoning for text node (#26393) * rephrased * is pretty --- extensions/amp-timeago/amp-timeago.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/amp-timeago/amp-timeago.md b/extensions/amp-timeago/amp-timeago.md index c697d955b33a..481b1678aca2 100644 --- a/extensions/amp-timeago/amp-timeago.md +++ b/extensions/amp-timeago/amp-timeago.md @@ -68,7 +68,7 @@ Example: > ``` -Although it will be overridden, there must be at least one character in the `amp-timeago` text node. +The `amp-timeago` component requires a placeholder in the text node. The calculated timestamp replaces the placeholder once ready. Use the placeholder as a fallback to display to users if `amp-timeago` is unable to process the fuzzy timestamp. [/example] From 6f79c3630aa033730269a05da46346bc6d56918e Mon Sep 17 00:00:00 2001 From: Kieran Boyle Date: Sun, 19 Jan 2020 21:08:40 -0800 Subject: [PATCH 10/10] [yahoonativeads-amp] code cleanup and bug fix (#26325) --- ads/yahoonativeads.js | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/ads/yahoonativeads.js b/ads/yahoonativeads.js index 0ea90a7f0e7d..4d2c284d9ec0 100644 --- a/ads/yahoonativeads.js +++ b/ads/yahoonativeads.js @@ -29,21 +29,6 @@ export function yahoonativeads(global, data) { global.publisherUrl = data.url; global.amp = true; - global.context.observeIntersection( - entries => { - entries.forEach(entry => { - if (global.Native) { - global.Native.onViewChange({ - intersectionRatio: entry.intersectionRatio, - }); - } - }); - }, - { - threshold: [0, 0.5, 1], - } - ); - loadScript(global, 'https://s.yimg.com/dy/ads/native.js', () => global.context.renderStart() );