Skip to content

Commit

Permalink
Implement sticky ad bottom type ad
Browse files Browse the repository at this point in the history
  • Loading branch information
powerivq committed Dec 16, 2020
1 parent 37dc08b commit e60e15f
Show file tree
Hide file tree
Showing 12 changed files with 163 additions and 16 deletions.
3 changes: 2 additions & 1 deletion build-system/global-configs/canary-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@
"adsense-ptt-exp": 0.1,
"doubleclick-ptt-exp": 0.1,
"fie-resources": 1,
"amp-cid-backup": 1
"amp-cid-backup": 1,
"sticky-ad-transition": 0.1
}
3 changes: 2 additions & 1 deletion build-system/global-configs/prod-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@
"adsense-ptt-exp": 0.1,
"doubleclick-ptt-exp": 0.1,
"fie-resources": 0.1,
"visibility-trigger-improvements": 1
"visibility-trigger-improvements": 1,
"sticky-ad-transition": 0.1
}
14 changes: 13 additions & 1 deletion examples/sticky.ads.amp.html
Original file line number Diff line number Diff line change
Expand Up @@ -208,14 +208,26 @@
</header>
<main role="main">

<amp-user-notification
layout=nodisplay
id="amp-user-notification6"
data-persist-dismissal="false">
This notification should ALSO ALWAYS show.
<a href="#learn-more">Learn more.</a>
<button on="tap:amp-user-notification6.dismiss" role="button" tabindex="5">Dismiss</button>
</amp-user-notification>


<amp-sticky-ad layout="nodisplay">
<amp-ad width=300 height=50
sticky=bottom
data-consent-notification-id="amp-user-notification6"
type="_ping_"
data-url='https://lh3.googleusercontent.com/pSECrJ82R7-AqeBCOEPGPM9iG9OEIQ_QXcbubWIOdkY=w400-h300-no-n'
data-valid='true'
data-ad-width=300
data-ad-height=50>
</amp-ad>
</amp-sticky-ad>
<article>


Expand Down
14 changes: 12 additions & 2 deletions extensions/amp-a4a/0.1/amp-a4a.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ import {CONSENT_POLICY_STATE} from '../../../src/consent-state';
import {DetachedDomStream} from '../../../src/utils/detached-dom-stream';
import {DomTransformStream} from '../../../src/utils/dom-tranform-stream';
import {Layout, LayoutPriority, isLayoutSizeDefined} from '../../../src/layout';
import {
STICKY_AD_TRANSITION_EXP,
divertStickyAdTransition,
} from '../../../src/experiments/sticky-ad-transition-exp';
import {Services} from '../../../src/services';
import {SignatureVerifier, VerificationStatus} from './signature-verifier';
import {
Expand Down Expand Up @@ -48,6 +52,7 @@ import {
getConsentPolicyState,
} from '../../../src/consent';
import {getContextMetadata} from '../../../src/iframe-attributes';
import {getExperimentBranch} from '../../../src/experiments';
import {getMode} from '../../../src/mode';
import {insertAnalyticsElement} from '../../../src/extension-analytics';
import {
Expand Down Expand Up @@ -1714,7 +1719,6 @@ export class AmpA4A extends AMP.BaseElement {
height,
width
);
this.applyFillContent(this.iframe);

let body = '';
// If srcdoc is not supported, streaming is also not supported so we
Expand Down Expand Up @@ -1789,7 +1793,13 @@ export class AmpA4A extends AMP.BaseElement {
'title': this.getIframeTitle(),
})
));
this.applyFillContent(this.iframe);
divertStickyAdTransition(this.win);
if (
getExperimentBranch(this.win, STICKY_AD_TRANSITION_EXP.id) !==
STICKY_AD_TRANSITION_EXP.experiment
) {
this.applyFillContent(this.iframe);
}
const fontsArray = [];
if (creativeMetaData.customStylesheets) {
creativeMetaData.customStylesheets.forEach((s) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
maybeAppendErrorParameter,
} from '../../../ads/google/a4a/utils';
import {ResponsiveState} from './responsive-state';
import {STICKY_AD_TRANSITION_EXP} from '../../../src/experiments/sticky-ad-transition-exp';
import {Services} from '../../../src/services';
import {
addAmpExperimentIdToElement,
Expand Down Expand Up @@ -240,6 +241,14 @@ export class AmpAdNetworkAdsenseImpl extends AmpA4A {
isTrafficEligible: () => true,
branches: Object.values(PTT_EXP_BRANCHES),
},
{
experimentId: STICKY_AD_TRANSITION_EXP.id,
isTrafficEligible: () => true,
branches: [
STICKY_AD_TRANSITION_EXP.control,
STICKY_AD_TRANSITION_EXP.experiment,
],
},
]);
const setExps = randomlySelectUnsetExperiments(
this.win,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import {
RefreshManager, // eslint-disable-line no-unused-vars
getRefreshManager,
} from '../../amp-a4a/0.1/refresh-manager';
import {STICKY_AD_TRANSITION_EXP} from '../../../src/experiments/sticky-ad-transition-exp';
import {SafeframeHostApi} from './safeframe-host';
import {Services} from '../../../src/services';
import {
Expand Down Expand Up @@ -105,6 +106,7 @@ import {
} from '../../../src/experiments';
import {getMode} from '../../../src/mode';
import {getMultiSizeDimensions} from '../../../ads/google/utils';

import {getOrCreateAdCid} from '../../../src/ad-cid';

import {insertAnalyticsElement} from '../../../src/extension-analytics';
Expand Down Expand Up @@ -447,6 +449,14 @@ export class AmpAdNetworkDoubleclickImpl extends AmpA4A {
isTrafficEligible: () => true,
branches: Object.values(PTT_EXP_BRANCHES),
},
{
experimentId: STICKY_AD_TRANSITION_EXP.id,
isTrafficEligible: () => true,
branches: [
STICKY_AD_TRANSITION_EXP.control,
STICKY_AD_TRANSITION_EXP.experiment,
],
},
]);
const setExps = this.randomlySelectUnsetExperiments_(experimentInfoList);
Object.keys(setExps).forEach(
Expand Down
45 changes: 42 additions & 3 deletions extensions/amp-ad/0.1/amp-ad-ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,19 @@
* limitations under the License.
*/

import {
STICKY_AD_TRANSITION_EXP,
divertStickyAdTransition,
} from '../../../src/experiments/sticky-ad-transition-exp';
import {Services} from '../../../src/services';
import {
ancestorElementsByTag,
createElementWithAttributes,
removeElement,
} from '../../../src/dom';
import {devAssert} from '../../../src/log';
import {dict} from '../../../src/utils/object';
import {getExperimentBranch} from '../../../src/experiments';

import {getAdContainer} from '../../../src/ad-helper';
import {listen} from '../../../src/event-helper';
Expand Down Expand Up @@ -207,6 +213,17 @@ export class AmpAdUIHandler {
maybeInitStickyAd() {
if (this.isStickyAd()) {
setStyle(this.element_, 'visibility', 'visible');

if (this.stickyAdPosition_ == StickyAdPositions.BOTTOM) {
const paddingBar = this.doc_.createElement('amp-ad-sticky-padding');
this.element_.insertBefore(
paddingBar,
devAssert(
this.element_.firstChild,
'amp-ad should have been expanded.'
)
);
}
}
}

Expand Down Expand Up @@ -312,10 +329,10 @@ export class AmpAdUIHandler {
}

// Special case: for sticky ads, we enforce 20% size limit and 50% height limit
if (this.element_.hasAttribute('sticky')) {
if (this.isStickyAd()) {
const viewport = this.baseInstance_.getViewport();
if (
newHeight * newWidth >
height * width >
STICKY_AD_MAX_SIZE_LIMIT *
viewport.getHeight() *
viewport.getWidth() ||
Expand All @@ -328,14 +345,36 @@ export class AmpAdUIHandler {
return this.baseInstance_
.attemptChangeSize(newHeight, newWidth, event)
.then(
() => resizeInfo,
() => {
divertStickyAdTransition(this.baseInstance_.win);
if (
getExperimentBranch(
this.baseInstance_.win,
STICKY_AD_TRANSITION_EXP.id
) === STICKY_AD_TRANSITION_EXP.experiment
) {
this.setSize_(this.element_.querySelector('iframe'), height, width);
}
return resizeInfo;
},
() => {
resizeInfo.success = false;
return resizeInfo;
}
);
}

/**
* Force set the dimensions for an element
* @param {Any} element
* @param {number} newHeight
* @param {number} newWidth
*/
setSize_(element, newHeight, newWidth) {
setStyle(element, 'height', newHeight, 'px');
setStyle(element, 'width', newWidth, 'px');
}

/**
* Clean up the listeners
*/
Expand Down
1 change: 0 additions & 1 deletion extensions/amp-ad/0.1/amp-ad-xorigin-iframe-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ export class AmpAdXOriginIframeHandler {
devAssert(!this.iframe, 'multiple invocations of init without destroy!');
this.iframe = iframe;
this.iframe.setAttribute('scrolling', 'no');
this.baseInstance_.applyFillContent(this.iframe);
const timer = Services.timerFor(this.baseInstance_.win);

// Init the legacy observeInterection API service.
Expand Down
20 changes: 20 additions & 0 deletions extensions/amp-ad/0.1/amp-ad.css
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ amp-embed iframe {

amp-ad[sticky] {
visibility: hidden;
align-items: center;
}

amp-ad[amp-story] iframe {
width: 100%;
height: 100%;
}

amp-ad[type='adsense'],
Expand Down Expand Up @@ -116,12 +122,26 @@ amp-ad .amp-ad-close-button:before {
left: 0;
}

amp-ad-sticky-padding {
display: block;
width: 100% !important;
background: #fff;
height: 4px;
max-height: 5px !important;
overflow-x: hidden;
overflow-y: hidden;
/** Must be above the dismiss button to cover bottom shadow */
z-index: 12;
}

amp-ad[sticky] {
z-index: 11;
position: fixed;
overflow: visible !important;
padding-bottom: env(safe-area-inset-bottom, 0px);
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.2) !important;
display: flex;
flex-direction: column;
}

amp-ad[sticky='top'] {
Expand Down
2 changes: 2 additions & 0 deletions extensions/amp-ad/0.1/test/test-amp-ad-ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ describes.realWin(
height: '50px',
});
env.win.document.body.appendChild(adElement);
env.sandbox.stub(uiHandler, 'setSize_');
env.sandbox
.stub(adImpl, 'attemptChangeSize')
.callsFake((height, width) => {
Expand All @@ -262,6 +263,7 @@ describes.realWin(
});

it('should tolerate string input', () => {
env.sandbox.stub(uiHandler, 'setSize_');
env.sandbox
.stub(adImpl, 'attemptChangeSize')
.callsFake((height, width) => {
Expand Down
16 changes: 9 additions & 7 deletions extensions/amp-story-auto-ads/0.1/amp-story-auto-ads.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
* limitations under the License.
*/

.i-amphtml-story-desktop-panels amp-story-page[i-amphtml-loading][ad] {
.i-amphtml-story-desktop-panels amp-story-page[i-amphtml-loading][ad] {
/* Move below viewport so that ad preloads */
transform: scale(1.0) translateX(-100%) translateY(200%) !important;
transform: scale(1) translateX(-100%) translateY(200%) !important;
}

.i-amphtml-cta-container {
Expand All @@ -43,21 +43,23 @@ amp-story-page[xdomain-ad] .i-amphtml-glass-pane {
}

/* TODO(ccordry): refactor centering logic in amp-ad.css and remove this hack. */
amp-story-page amp-ad[data-a4a-upgrade-type="amp-ad-network-doubleclick-impl"] > iframe,
amp-story-page amp-ad[type="adsense"] > iframe {
amp-story-page amp-ad[data-a4a-upgrade-type='amp-ad-network-doubleclick-impl'],
amp-story-page amp-ad[type='adsense'] {
top: 0 !important;
left: 0 !important;
transform: translate(0) !important;
}

/* TODO(ccordry) allow advertisers to opt-in to fullscreen ads. */
.i-amphtml-story-desktop-fullbleed .i-amphtml-story-grid-template-fill > amp-ad > iframe {
.i-amphtml-story-desktop-fullbleed
.i-amphtml-story-grid-template-fill
> amp-ad {
left: 50% !important;
right: auto !important;
margin: auto !important;
min-height: 75vh !important;
max-height: 75vh !important;
min-width: calc(3/5 * 75vh) !important;
max-width: calc(3/5 * 75vh) !important;
min-width: calc(3 / 5 * 75vh) !important;
max-width: calc(3 / 5 * 75vh) !important;
transform: translateX(-50%) !important;
}
42 changes: 42 additions & 0 deletions src/experiments/sticky-ad-transition-exp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Copyright 2020 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 {randomlySelectUnsetExperiments} from '../experiments';

/** @const @enum{string} */
export const STICKY_AD_TRANSITION_EXP = {
id: 'sticky-ad-transition',
control: '21069722',
experiment: '21069723',
};

/**
* Select exp vs control for sticky-ad-transition.
* @param {!Window} win
*/
export function divertStickyAdTransition(win) {
const expInfoList = /** @type {!Array<!../experiments.ExperimentInfo>} */ ([
{
experimentId: STICKY_AD_TRANSITION_EXP.id,
isTrafficEligible: () => true,
branches: [
STICKY_AD_TRANSITION_EXP.control,
STICKY_AD_TRANSITION_EXP.experiment,
],
},
]);
randomlySelectUnsetExperiments(win, expInfoList);
}

0 comments on commit e60e15f

Please sign in to comment.