diff --git a/build-system/tasks/check-links.js b/build-system/tasks/check-links.js index f15e55d42c88a..6052e3b9e9e2f 100644 --- a/build-system/tasks/check-links.js +++ b/build-system/tasks/check-links.js @@ -111,6 +111,10 @@ function filterWhitelistedLinks(markdown) { filteredMarkdown = filteredMarkdown.replace(/https:\/\/cdn.ampproject.org(?!\/)/g, ''); + // TODO(honeybadgerdontcare): Remove after PR #9434 is merged + filteredMarkdown = + filteredMarkdown.replace(/https:\/\/github.com\/ampproject\/amphtml\/blob\/master\/extensions\/amp-imgur\/0.1\/validator-amp-imgur.protoascii/g, ''); + return filteredMarkdown; } diff --git a/examples/amp-imgur.amp.html b/examples/amp-imgur.amp.html new file mode 100644 index 0000000000000..f39061dcdf17a --- /dev/null +++ b/examples/amp-imgur.amp.html @@ -0,0 +1,15 @@ + + + + + amp-imgur example + + + + + + + + + + diff --git a/extensions/amp-imgur/0.1/amp-imgur.js b/extensions/amp-imgur/0.1/amp-imgur.js new file mode 100644 index 0000000000000..a9256a79ceb30 --- /dev/null +++ b/extensions/amp-imgur/0.1/amp-imgur.js @@ -0,0 +1,119 @@ +/** + * Copyright 2017 The AMP HTML Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS-IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + /** + * @fileoverview Embeds a imgur + * Example: + * + * + * + * + */ + +import {user} from '../../../src/log'; +import {isLayoutSizeDefined} from '../../../src/layout'; +import {removeElement} from '../../../src/dom'; +import {tryParseJson} from '../../../src/json'; +import {isObject} from '../../../src/types'; +import {listen} from '../../../src/event-helper'; +import {startsWith} from '../../../src/string'; + +export class AmpImgur extends AMP.BaseElement { + + /** @param {!AmpElement} element */ + constructor(element) { + super(element); + + /** @private {?Element} */ + this.iframe_ = null; + + /** @private {?Function} */ + this.unlistenMessage_ = null; + + /** @private {?string} */ + this.imgurid_ = ''; + } + + /** @override */ + isLayoutSupported(layout) { + return isLayoutSizeDefined(layout); + } + + /** @override */ + buildCallback() { + this.imgurid_ = user().assert( + this.element.getAttribute('data-imgur-id'), + 'The data-imgur-id attribute is required for %s', + this.element); + } + + /** @override */ + layoutCallback() { + const iframe = this.element.ownerDocument.createElement('iframe'); + this.iframe_ = iframe; + + this.unlistenMessage_ = listen( + this.win, + 'message', + this.hadleImgurMessages_.bind(this) + ); + + iframe.setAttribute('scrolling', 'no'); + iframe.setAttribute('frameborder', '0'); + iframe.setAttribute('allowfullscreen', 'true'); + + iframe.src = 'https://imgur.com/a/' + + encodeURIComponent(this.imgurid_) + '/embed?pub=true'; + this.applyFillContent(iframe); + this.element.appendChild(iframe); + return this.loadPromise(iframe); + } + + /** @private */ + hadleImgurMessages_(event) { + if (event.origin != 'https://imgur.com' || + event.source != this.iframe_.contentWindow) { + return; + } + if (!event.data || !(isObject(event.data)) || startsWith(event.data, '{')) { + return; + } + const data = isObject(event.data) ? event.data : tryParseJson(event.data); + if (data.message == 'resize_imgur') { + const height = data.height; + this.attemptChangeHeight(height).catch(() => {}); + } + } + + /** @override */ + unlayoutCallback() { + if (this.iframe_) { + removeElement(this.iframe_); + this.iframe_ = null; + } + if (this.unlistenMessage_) { + this.unlistenMessage_(); + } + return true; // Call layoutCallback again. + } + +} + +AMP.registerElement('amp-imgur', AmpImgur); diff --git a/extensions/amp-imgur/0.1/test/test-amp-imgur.js b/extensions/amp-imgur/0.1/test/test-amp-imgur.js new file mode 100644 index 0000000000000..9fa5fbf2885c0 --- /dev/null +++ b/extensions/amp-imgur/0.1/test/test-amp-imgur.js @@ -0,0 +1,47 @@ +/** + * Copyright 2017 The AMP HTML Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS-IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + createIframePromise, + doNotLoadExternalResourcesInTest, +} from '../../../../testing/iframe'; +import '../amp-imgur'; + +describe('amp-imgur', () => { + + function getIns(imgurId) { + return createIframePromise().then(iframe => { + doNotLoadExternalResourcesInTest(iframe.win); + const ins = iframe.doc.createElement('amp-imgur'); + ins.setAttribute('data-imgur-id', imgurId); + ins.setAttribute('width', '1'); + ins.setAttribute('height', '1'); + ins.setAttribute('layout', 'responsive'); + return iframe.addElement(ins); + }); + } + + function testIframe(iframe) { + expect(iframe).to.not.be.null; + expect(iframe.src).to.equal('https://imgur.com/a/2CnX7/embed?pub=true'); + expect(iframe.className).to.match(/i-amphtml-fill-content/); + } + + it('renders', () => { + return getIns('2CnX7').then(ins => { + testIframe(ins.querySelector('iframe')); + }); + }); +}); diff --git a/extensions/amp-imgur/0.1/validator-amp-imgur.protoascii b/extensions/amp-imgur/0.1/validator-amp-imgur.protoascii new file mode 100644 index 0000000000000..4bf4dc0e47c72 --- /dev/null +++ b/extensions/amp-imgur/0.1/validator-amp-imgur.protoascii @@ -0,0 +1,48 @@ +# +# Copyright 2017 The AMP HTML Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS-IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the license. +# + +tags: { # amp-imgur + html_format: AMP + tag_name: "SCRIPT" + satisfies: "amp-imgur extension .js script" + requires: "amp-imgur" + extension_spec: { + name: "amp-imgur" + allowed_versions: "0.1" + allowed_versions: "latest" + } + attr_lists: "common-extension-attrs" +} +tags: { # + html_format: AMP + tag_name: "AMP-IMGUR" + satisfies: "amp-imgur" + requires: "amp-imgur extension .js script" + attrs: { + name: "data-imgur-id" + mandatory: true + } + attr_lists: "extended-amp-global" + spec_url: "https://www.ampproject.org/docs/reference/components/amp-imgur" + amp_layout: { + supported_layouts: FILL + supported_layouts: FIXED + supported_layouts: FIXED_HEIGHT + supported_layouts: FLEX_ITEM + supported_layouts: NODISPLAY + supported_layouts: RESPONSIVE + } +} diff --git a/extensions/amp-imgur/OWNERS.yaml b/extensions/amp-imgur/OWNERS.yaml new file mode 100644 index 0000000000000..ea418eb50f24a --- /dev/null +++ b/extensions/amp-imgur/OWNERS.yaml @@ -0,0 +1 @@ +- techhtml \ No newline at end of file diff --git a/extensions/amp-imgur/amp-imgur.md b/extensions/amp-imgur/amp-imgur.md new file mode 100644 index 0000000000000..a67dbdac0e6db --- /dev/null +++ b/extensions/amp-imgur/amp-imgur.md @@ -0,0 +1,61 @@ + + +# `amp-imgur` + + + + + + + + + + + + + + + + + + + + + + +
DescriptionDisplays a imgur.
Availabilityin development
Required Script<script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-imgur-0.1.js"></script>
Supported Layoutsfill, fixed, fixed-height, flex-item, nodisplay, responsive
ExamplesNone
+ +## Behavior + +This extension creates an iframe and displays the imgur post. + +## Attributes + +**data-imgur-id** (required) +The ID of the imgur to embed. + +**layout** (required) +Currently only supports `responsive`. + +**width** (required) +The width of the imgur. + +**height** (required) +The width of the imgur. + +## Validation +See [amp-imgur rules](https://github.com/ampproject/amphtml/blob/master/extensions/amp-imgur/0.1/validator-amp-imgur.protoascii) in the AMP validator specification. diff --git a/gulpfile.js b/gulpfile.js index 9b0c4b135e5f9..7fdd74ed3eb2e 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -90,6 +90,7 @@ declareExtension('amp-hulu', '0.1', false); declareExtension('amp-iframe', '0.1', false, 'NO_TYPE_CHECK'); declareExtension('amp-ima-video', '0.1', false); declareExtension('amp-image-lightbox', '0.1', true); +declareExtension('amp-imgur', '0.1', false); declareExtension('amp-instagram', '0.1', true); declareExtension('amp-install-serviceworker', '0.1', false); declareExtension('amp-izlesene', '0.1', false);