Skip to content

Commit

Permalink
amp-instagram: Resizing in response to messages posted by iframe (#7705)
Browse files Browse the repository at this point in the history
* Resizing in response to messages posted by Instagram iframe

* Fixing lint errors

* Adding listen/unlisten and use of getVsync

* Fixing type check
  • Loading branch information
src-code authored and adelinamart committed Mar 1, 2017
1 parent 724b99b commit ffc75d1
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 4 deletions.
54 changes: 50 additions & 4 deletions extensions/amp-instagram/0.1/amp-instagram.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,14 @@ import {isLayoutSizeDefined} from '../../../src/layout';
import {setStyles} from '../../../src/style';
import {removeElement} from '../../../src/dom';
import {user} from '../../../src/log';
import {tryParseJson} from '../../../src/json';
import {isObject} from '../../../src/types';
import {listen} from '../../../src/event-helper';

const PADDING_LEFT = 8;
const PADDING_RIGHT = 8;
const PADDING_BOTTOM = 48;
const PADDING_TOP = 48;

class AmpInstagram extends AMP.BaseElement {

Expand All @@ -55,6 +62,9 @@ class AmpInstagram extends AMP.BaseElement {

/** @private {?string} */
this.shortcode_ = '';

/** @private {?Function} */
this.unlistenMessage_ = null;
}
/**
* @param {boolean=} opt_onLayout
Expand Down Expand Up @@ -102,10 +112,10 @@ class AmpInstagram extends AMP.BaseElement {
// This makes the non-iframe image appear in the exact same spot
// where it will be inside of the iframe.
setStyles(image, {
'top': '48px',
'bottom': '48px',
'left': '8px',
'right': '8px',
'top': PADDING_TOP + 'px',
'bottom': PADDING_BOTTOM + 'px',
'left': PADDING_LEFT + 'px',
'right': PADDING_RIGHT + 'px',
});
placeholder.appendChild(image);
return placeholder;
Expand All @@ -120,6 +130,13 @@ class AmpInstagram extends AMP.BaseElement {
layoutCallback() {
const iframe = this.element.ownerDocument.createElement('iframe');
this.iframe_ = iframe;

this.unlistenMessage_ = listen(
this.win,
'message',
this.handleInstagramMessages_.bind(this)
);

iframe.setAttribute('frameborder', '0');
iframe.setAttribute('allowtransparency', 'true');
//Add title to the iframe for better accessibility.
Expand All @@ -141,6 +158,32 @@ class AmpInstagram extends AMP.BaseElement {
});
}

/** @private */
handleInstagramMessages_(event) {
if (event.origin != 'https://www.instagram.com' ||
event.source != this.iframe_.contentWindow) {
return;
}
if (!event.data ||
!(isObject(event.data) || event.data.indexOf('{') == 0)) {
return; // Doesn't look like JSON.
}
const data = isObject(event.data) ? event.data : tryParseJson(event.data);
if (data === undefined) {
return; // We only process valid JSON.
}
if (data.type == 'MEASURE' && data.details) {
const height = data.details.height;
this.getVsync().measure(() => {
if (this.iframe_./*OK*/offsetHeight !== height) {
// Height returned by Instagram includes header, so
// subtract 48px top padding
this.attemptChangeHeight(height - PADDING_TOP).catch(() => {});
}
});
}
}

/** @override */
unlayoutOnPause() {
return true;
Expand All @@ -153,6 +196,9 @@ class AmpInstagram extends AMP.BaseElement {
this.iframe_ = null;
this.iframePromise_ = null;
}
if (this.unlistenMessage_) {
this.unlistenMessage_();
}
return true; // Call layoutCallback again.
}
};
Expand Down
56 changes: 56 additions & 0 deletions extensions/amp-instagram/0.1/test/test-amp-instagram.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,22 @@ import {
} from '../../../../testing/iframe';
import '../amp-instagram';
import {adopt} from '../../../../src/runtime';
import * as sinon from 'sinon';

adopt(window);

describe('amp-instagram', () => {

let sandbox;

beforeEach(() => {
sandbox = sinon.sandbox.create();
});

afterEach(() => {
sandbox.restore();
});

function getIns(shortcode, opt_responsive, opt_beforeLayoutCallback) {
return createIframePromise(true, opt_beforeLayoutCallback).then(iframe => {
doNotLoadExternalResourcesInTest(iframe.win);
Expand All @@ -36,6 +47,21 @@ describe('amp-instagram', () => {
if (opt_responsive) {
ins.setAttribute('layout', 'responsive');
}
ins.implementation_.getVsync = () => {
return {
mutate(cb) { cb(); },
measure(cb) { cb(); },
runPromise(task, state = {}) {
if (task.measure) {
task.measure(state);
}
if (task.mutate) {
task.mutate(state);
}
return Promise.resolve();
},
};
};
return iframe.addElement(ins);
});
}
Expand Down Expand Up @@ -116,4 +142,34 @@ describe('amp-instagram', () => {
expect(getIns('')).to.be.rejectedWith(
/The data-shortcode attribute is required for/);
});

it('resizes in response to messages from Instagram iframe', () => {
return getIns('fBwFP', true).then(ins => {
const impl = ins.implementation_;
const iframe = ins.querySelector('iframe');
const attemptChangeHeight = sandbox.spy(impl, 'attemptChangeHeight');
const newHeight = 977;

expect(iframe).to.not.be.null;

sendFakeMessage(ins, iframe, 'MEASURE', {
height: newHeight,
});

expect(attemptChangeHeight).to.be.calledOnce;
// Height minus padding
expect(attemptChangeHeight.firstCall.args[0]).to.equal(newHeight - 48);
});
});

function sendFakeMessage(ins, iframe, type, details) {
ins.implementation_.handleInstagramMessages_({
origin: 'https://www.instagram.com',
source: iframe.contentWindow,
data: JSON.stringify({
type,
details,
}),
});
}
});

0 comments on commit ffc75d1

Please sign in to comment.