Skip to content

Commit

Permalink
Render close button for lightbox ads in inabox
Browse files Browse the repository at this point in the history
  • Loading branch information
alanorozco committed Jul 18, 2018
1 parent a0a9c34 commit 61e7b2c
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 27 deletions.
1 change: 1 addition & 0 deletions ads/inabox/frame-overlay-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export class FrameOverlayManager {
this.isExpanded_ = true;
this.viewportChangedSinceExpand_ = false;
this.collapsedRect_ = collapsedRect;

callback(expandedRect);
});
}
Expand Down
69 changes: 60 additions & 9 deletions extensions/amp-lightbox/0.1/amp-lightbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,18 @@ import {Gestures} from '../../../src/gesture';
import {KeyCodes} from '../../../src/utils/key-codes';
import {Services} from '../../../src/services';
import {SwipeXYRecognizer} from '../../../src/gesture-recognizers';
import {computedStyle, setImportantStyles} from '../../../src/style';
import {createCustomEvent} from '../../../src/event-helper';
import {computedStyle, px, setImportantStyles} from '../../../src/style';
import {createCustomEvent, listenOnce} from '../../../src/event-helper';
import {debounce} from '../../../src/utils/rate-limit';
import {dev, user} from '../../../src/log';
import {dict, hasOwn} from '../../../src/utils/object';
import {getMode} from '../../../src/mode';
import {installStylesForDoc} from '../../../src/style-installer';
import {isInFie} from '../../../src/friendly-iframe-embed';
import {cssText as lightboxAdCss} from '../../../build/lightbox-ad.css.js';
import {removeElement, tryFocus} from '../../../src/dom';
import {renderCloseButtonHeader} from '../../../src/full-overlay-frame-helper';
import {toArray} from '../../../src/types';
import {tryFocus} from '../../../src/dom';

/** @const {string} */
const TAG = 'amp-lightbox';
Expand Down Expand Up @@ -255,6 +258,8 @@ class AmpLightbox extends AMP.BaseElement {
const transition =
props.map(p => `${p} ${durationSeconds}s ease-in`).join(',');

element.classList.add('amp-open');

this.eventCounter_++;

if (this.isScrollable_) {
Expand All @@ -277,6 +282,7 @@ class AmpLightbox extends AMP.BaseElement {
});

this.handleAutofocus_();
this.maybeRenderCloseButtonHeader_();

// TODO (jridgewell): expose an API accomodating this per PR #14676
this.mutateElement(() => {
Expand Down Expand Up @@ -305,6 +311,38 @@ class AmpLightbox extends AMP.BaseElement {
this.active_ = true;
}

/** @private */
maybeRenderCloseButtonHeader_() {
if (!this.isInabox_()) {
return;
}

const header = renderCloseButtonHeader(this.element);

listenOnce(header, 'click', () => {
removeElement(header);
this.close();
});

installStylesForDoc(this.getAmpDoc(), lightboxAdCss, () => {
this.element.insertBefore(header, this.container_);

// Done in callback in order to apply transition.
header.classList.add('amp-ad-close-header');

let headerHeight;

this.measureMutateElement(() => {
headerHeight = header./*OK*/getBoundingClientRect().height;
}, () => {
setImportantStyles(this.container_, {
'margin-top': px(headerHeight),
'min-height': `calc(100vh - ${px(headerHeight)})`,
});
});
});
}

/**
* @private
* @return {!AnimationPresetDef}
Expand Down Expand Up @@ -343,22 +381,27 @@ class AmpLightbox extends AMP.BaseElement {
*/
finalizeClose_() {
const {element} = this;

st.setStyles(element, this.getAnimationPresetDef_().closedStyle);

const event = ++this.eventCounter_;

const collapseAndReschedule = () => {
// Don't collapse on transitionend if there was a previous event.
// Don't collapse on transitionend if there was a subsequent event.
if (event != this.eventCounter_) {
return;
}
this./*OK*/collapse();
this.boundReschedule_();
};

element.addEventListener('transitionend', collapseAndReschedule);
element.addEventListener('animationend', collapseAndReschedule);
// Disable transition for inabox since the frame gets immediately collapsed.
if (this.isInabox_()) {
st.resetStyles(element, ['transition']);
collapseAndReschedule();
} else {
element.addEventListener('transitionend', collapseAndReschedule);
element.addEventListener('animationend', collapseAndReschedule);
}

st.setStyles(element, this.getAnimationPresetDef_().closedStyle);

if (this.historyId_ != -1) {
this.getHistory_().pop(this.historyId_);
Expand All @@ -371,6 +414,14 @@ class AmpLightbox extends AMP.BaseElement {
this.triggerEvent_(LightboxEvents.CLOSE);
}

/**
* @return {boolean}
* @private
*/
isInabox_() {
return getMode(this.win).runtime == 'inabox';
}

/**
* Handles scroll on the amp-lightbox.
* The scroll throttling and visibility calculation is similar to
Expand Down
6 changes: 6 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,12 @@ function compileCss(watch, opt_compileAll) {
.then(() => {
endBuildStep('Recompiled CSS in', 'amp.css', startTime);
})
.then(() => jsifyCssAsync('css/lightbox-ad.css'))
.then(css => writeCss(css,
'lightbox-ad.css', 'lightbox-ad.css.js', 'lightbox-ad.css'))
.then(() => {
endBuildStep('Recompiled CSS in', 'lightbox-ad.css', startTime);
})
.then(() => jsifyCssAsync('css/video-docking.css'))
.then(css => writeCss(css,
'video-docking.css', 'video-docking.css.js', 'video-docking.css'))
Expand Down
16 changes: 7 additions & 9 deletions src/friendly-iframe-embed.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {closestBySelector, escapeHtml, removeElement} from './dom';
import {createCustomEvent, listenOnce, loadPromise} from './event-helper';
import {dev, rethrowAsync, user} from './log';
import {disposeServicesForEmbed, getTopWindow} from './service';
import {htmlFor} from './static-template';
import {isDocumentReady} from './document-ready';
import {layoutRectLtwh} from './layout-rect';
import {
Expand All @@ -33,6 +32,7 @@ import {
setStyle,
setStyles,
} from './style';
import {renderCloseButtonHeader} from './full-overlay-frame-helper';
import {toWin} from './types';


Expand Down Expand Up @@ -523,7 +523,8 @@ export class FriendlyIframeEmbed {
'Only <amp-ad> is allowed to enter lightbox mode.');

const header =
renderCloseButtonHeader(this.win, ampAdParent, requestingElement);
renderClickableCloseButtonHeader(
this.win, ampAdParent, requestingElement);

ampAdParent.appendChild(header);

Expand Down Expand Up @@ -635,13 +636,10 @@ export class FriendlyIframeEmbed {
* @param {!Element} ampLightbox
* @visibleForTesting
*/
export function renderCloseButtonHeader(win, ampAdParent, ampLightbox) {
const el = htmlFor(ampAdParent)`
<i-amphtml-ad-close-header role=button tabindex=0 aria-label="Close Ad">
<div>Ad</div>
<i-amphtml-ad-close-button class="amp-ad-close-button">
</i-amphtml-ad-close-button>
</i-amphtml-ad-close-header>`;
export function renderClickableCloseButtonHeader(
win, ampAdParent, ampLightbox) {

const el = renderCloseButtonHeader(/* ctx */ ampAdParent);

listenOnce(el, 'click', () => {
triggerLightboxClose(win, ampLightbox, /* caller */ ampAdParent);
Expand Down
24 changes: 20 additions & 4 deletions src/full-overlay-frame-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {htmlFor} from './static-template';
import {px, resetStyles, setStyles, translate} from './style';


Expand All @@ -27,11 +28,12 @@ import {px, resetStyles, setStyles, translate} from './style';
*/
export function centerFrameUnderVsyncMutate(
iframe, iframeRect, viewportSize, transitionTimeMs) {

const translateX = px(
(viewportSize.width / 2 - iframeRect.width / 2) - iframeRect.left);
(viewportSize.width / 2) - (iframeRect.width / 2) - iframeRect.left);

const translateY = px(
(viewportSize.height / 2 - iframeRect.height / 2) - iframeRect.top);
(viewportSize.height / 2) - (iframeRect.height / 2) - iframeRect.top);

setStyles(iframe, {
'position': 'fixed',
Expand All @@ -41,8 +43,7 @@ export function centerFrameUnderVsyncMutate(
'bottom': px(viewportSize.height - (iframeRect.top + iframeRect.height)),
'height': px(iframeRect.height),
'width': px(iframeRect.width),
'transition':
`transform ${(transitionTimeMs / 1000)}s ease`,
'transition': `transform ${transitionTimeMs}ms ease`,
'transform': translate(translateX, translateY),
});
}
Expand Down Expand Up @@ -92,3 +93,18 @@ export function collapseFrameUnderVsyncMutate(iframe) {
'border',
]);
}


/**
* @param {!Element} ctx
* @return {!Element}
* @visibleForTesting
*/
export function renderCloseButtonHeader(ctx) {
return htmlFor(ctx)`
<i-amphtml-ad-close-header role=button tabindex=0 aria-label="Close Ad">
<div>Ad</div>
<i-amphtml-ad-close-button class="amp-ad-close-button">
</i-amphtml-ad-close-button>
</i-amphtml-ad-close-header>`;
}
9 changes: 8 additions & 1 deletion src/inabox/inabox-viewport.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ export class ViewportBindingInabox {
* @private
*/
leaveOverlayMode_() {
return this.requestCancelFullOverlayFrame_()
return this.requestCancelFullOverlayFrame_();
.then(() => this.resetBodyForOverlay_());
}

Expand Down Expand Up @@ -352,6 +352,13 @@ export class ViewportBindingInabox {
MessageType.CANCEL_FULL_OVERLAY_FRAME,
MessageType.CANCEL_FULL_OVERLAY_FRAME_RESPONSE,
response => {
const openLightbox =
this.win.document.querySelector('amp-lightbox.amp-open');

if (openLightbox) {
openLightbox.getImpl().then(impl => impl.close());
}

unlisten();
this.updateBoxRect_(response.boxRect);
resolve();
Expand Down
8 changes: 4 additions & 4 deletions test/functional/test-friendly-iframe-embed.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
getFriendlyIframeEmbedOptional,
installFriendlyIframeEmbed,
mergeHtmlForTesting,
renderCloseButtonHeader,
renderClickableCloseButtonHeader,
setFriendlyIframeEmbedVisible,
setSrcdocSupportedForTesting,
whenContentIniLoad,
Expand Down Expand Up @@ -824,15 +824,15 @@ describe('friendly-iframe-embed', () => {
});
});

describe('#renderCloseButtonHeader', () => {
describe('#renderClickableCloseButtonHeader', () => {

const win = document.defaultView;

it('renders', () => {
const ampAdParentMock = document.createElement('div');
const ampLightboxMock = document.createElement('div');

const el = renderCloseButtonHeader(win, ampAdParentMock, ampLightboxMock);
const el = renderClickableCloseButtonHeader(win, ampAdParentMock, ampLightboxMock);

expect(el.tagName.toLowerCase()).to.equal('i-amphtml-ad-close-header');
expect(el.getAttribute('role')).to.equal('button');
Expand All @@ -853,7 +853,7 @@ describe('friendly-iframe-embed', () => {
const ampAdParentMock = document.createElement('div');
const ampLightboxMock = document.createElement('div');

const el = renderCloseButtonHeader(win, ampAdParentMock, ampLightboxMock);
const el = renderClickableCloseButtonHeader(win, ampAdParentMock, ampLightboxMock);

const execute = sandbox.spy();
const actionServiceMock = {execute};
Expand Down

0 comments on commit 61e7b2c

Please sign in to comment.