Skip to content

Commit

Permalink
Setting up code for AmpStoryEmbed viewer (#26276)
Browse files Browse the repository at this point in the history
* skeleton code

* address comments

* address comments

* remove isAMP
  • Loading branch information
Enriqe committed Jan 10, 2020
1 parent f3d4ecf commit abd2089
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 24 deletions.
2 changes: 1 addition & 1 deletion examples/amp-story/embed.html
@@ -1,6 +1,6 @@
<html>
<head>
<title>AMP Story Embed Example</title>
<title>Story Embed (Non-AMP)</title>
<script async src="../../dist/amp-story-embed.js"></script>
<style page>
body {
Expand Down
75 changes: 52 additions & 23 deletions src/amp-story-embed.js
Expand Up @@ -14,34 +14,34 @@
* limitations under the License.
*/

import {setStyle} from '../src/style';
import {setStyle} from './style';
import {toArray} from './types';

/** @enum {string} */
const LoadStateClass = {
LOADING: 'loading',
LOADED: 'loaded',
ERROR: 'error',
LOADING: 'i-amphtml-story-embed-loading',
LOADED: 'i-amphtml-story-embed-loaded',
ERROR: 'i-amphtml-story-embed-error',
};

/** @const {string} */
const CSS = `
:host { all: initial; display: block; border-radius: 0 !important; width: 405px; height: 720px; overflow: auto; }
.story { height: 100%; width: 100%; flex: 0 0 100%; border: 0; opacity: 0; transition: opacity 500ms ease; }
main { display: flex; flex-direction: row; height: 100%; }
.loaded iframe { opacity: 1; }
`;
.i-amphtml-story-embed-loaded iframe { opacity: 1; }`;

/**
* Note that this is a vanilla JavaScript class and should not depend on AMP
* services, as v0.js is not expected to be loaded in this context.
*/
export class AmpStoryEmbed {
/**
* @param {!Document} doc
* @param {!Window} win
* @param {!Element} element
* @constructor
*/
constructor(doc, element) {
constructor(win, element) {
console./*OK*/ assert(
element.childElementCount > 0,
'Missing configuration.'
Expand All @@ -51,20 +51,22 @@ export class AmpStoryEmbed {
this.element_ = element;

/** @private {!Document} */
this.doc_ = doc;
this.doc_ = win.document;

/** @private {!Array<!HTMLAnchorElement>} */
this.stories_ = Array.prototype.slice.call(element.querySelectorAll('a'));
this.stories_ = [];

/** @private {?Element} */
this.rootEl_;
this.rootEl_ = null;

/** @private {?HTMLIframeElement} */
this.iframeEl_;
this.iframeEl_ = null;
}

/** @public */
build() {
buildCallback() {
this.stories_ = toArray(this.element_.querySelectorAll('a'));

this.initializeShadowRoot_();

// TODO: Build all child iframes.
Expand All @@ -73,15 +75,15 @@ export class AmpStoryEmbed {

/** @private */
initializeShadowRoot_() {
this.rootEl_ = this.doc_.createElement('main');

// Create shadow root
const shadowRoot = this.element_.attachShadow({mode: 'open'});

// Inject default styles
const styleEl = this.doc_.createElement('style');
styleEl.textContent = CSS;
shadowRoot.appendChild(styleEl);

this.rootEl_ = this.doc_.createElement('main');
shadowRoot.appendChild(this.rootEl_);
}

Expand All @@ -92,7 +94,6 @@ export class AmpStoryEmbed {
buildIframe_(index) {
const story = this.stories_[index];
this.iframeEl_ = this.doc_.createElement('iframe');
this.iframeEl_.setAttribute('src', story.href);
setStyle(
this.iframeEl_,
'backgroundImage',
Expand All @@ -109,19 +110,47 @@ export class AmpStoryEmbed {

this.iframeEl_.onload = () => {
this.rootEl_.classList.remove(LoadStateClass.LOADING);
this.element_.classList.remove(LoadStateClass.LOADING);
this.rootEl_.classList.add(LoadStateClass.LOADED);
this.element_.classList.add(LoadStateClass.LOADED);
};
this.iframeEl_.onerror = () => {
this.rootEl_.classList.remove(LoadStateClass.LOADING);
this.element_.classList.remove(LoadStateClass.LOADING);
this.rootEl_.classList.add(LoadStateClass.ERROR);
this.element_.classList.add(LoadStateClass.ERROR);
};
}
}

const doc = self.document;
const embeds = doc.getElementsByTagName('amp-story-embed');
for (let i = 0; i < embeds.length; i++) {
const embed = embeds[i];
const embedImpl = new AmpStoryEmbed(doc, embed);
embedImpl.build();
/**
* @return {!Promise}
* @public
*/
layoutCallback() {
// TODO: Layout all child iframes.
return this.layoutIframe_(0);
}

/**
* @param {number} index
* @return {!Promise}
* @private
*/
layoutIframe_(index) {
const story = this.stories_[index];
this.iframeEl_.setAttribute('src', story.href);
return Promise.resolve();
}
}

self.onload = () => {
const doc = self.document;
const embeds = doc.getElementsByTagName('amp-story-embed');
for (let i = 0; i < embeds.length; i++) {
const embed = embeds[i];
const embedImpl = new AmpStoryEmbed(self, embed);
embedImpl.buildCallback();
// TODO(Enriqe): add intersection observer that triggers layoutCallback().
embedImpl.layoutCallback();
}
};

0 comments on commit abd2089

Please sign in to comment.