Skip to content

Commit

Permalink
Merge 378d398 into ab3e263
Browse files Browse the repository at this point in the history
  • Loading branch information
arelra authored Jul 31, 2024
2 parents ab3e263 + 378d398 commit d12c151
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 29 deletions.
5 changes: 5 additions & 0 deletions .changeset/empty-icons-mate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@guardian/commercial': minor
---

Ogury passback for mobile sticky
9 changes: 1 addition & 8 deletions playwright/lib/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,14 +234,7 @@ const logCommercial = (page: Page) => {
page.on('console', (msg) => {
const label = msg.args()[0]?.toString();
if (label?.includes('commercial')) {
console.log(
msg
.args()
.slice(4)
// eslint-disable-next-line @typescript-eslint/no-base-to-string -- it's just a log
.map((arg) => arg.toString())
.join(' '),
);
console.log(msg.args().slice(4).map(String).join(' '));
}
});
};
Expand Down
109 changes: 88 additions & 21 deletions src/core/messenger/passback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,30 @@ import { breakpoints } from '@guardian/source/foundations';
import { adSizes } from 'core/ad-sizes';
import type { RegisterListener } from 'core/messenger';
import { getCurrentBreakpoint } from 'lib/detect/detect-breakpoint';
import { getAdvertById } from 'lib/dfp/get-advert-by-id';
import fastdom from 'utils/fastdom-promise';
import { adSlotIdPrefix } from '../../lib/dfp/dfp-env-globals';

type PassbackMessagePayload = { source: string };

const adLabelHeight = 24;

/**
* Passback size mappings
* https://developers.google.com/publisher-tag/guides/ad-sizes#responsive_ads
*
* viewport height is set to 0 to denote any size from 0
*
* [
* [
* [ viewport1-width, viewport1-height],
* [ [slot1-width, slot1-height], [slot2-width, slot2-height], ... ]
* ]
* ]
*
*/
const mpu: [number, number] = [adSizes.mpu.width, adSizes.mpu.height];

const outstreamDesktop: [number, number] = [
adSizes.outstreamDesktop.width,
adSizes.outstreamDesktop.height,
Expand All @@ -20,7 +36,54 @@ const outstreamMobile: [number, number] = [
adSizes.outstreamMobile.height,
];

const getValuesForKeys = (
const outstreamSizes = [mpu, outstreamMobile, outstreamDesktop];

const oustreamSizeMappings = [
[
[breakpoints.phablet, 0],
[mpu, outstreamDesktop],
],
[
[breakpoints.mobile, 0],
[mpu, outstreamMobile],
],
] satisfies googletag.SizeMappingArray;

const mobileSticky: [number, number] = [
adSizes.mobilesticky.width,
adSizes.mobilesticky.height,
];

const mobileStickySizes = [mobileSticky];

const mobileStickySizeMappings = [
[[breakpoints.mobile, 0], [mobileSticky]],
] satisfies googletag.SizeMappingArray;

const defaultSizeMappings = [
[[breakpoints.mobile, 0], [mpu]],
] satisfies googletag.SizeMappingArray;

const decideSizes = (source: string) => {
if (source === 'teads') {
return {
sizes: outstreamSizes,
sizeMappings: oustreamSizeMappings,
};
}
if (source === 'ogury') {
return {
sizes: mobileStickySizes,
sizeMappings: mobileStickySizeMappings,
};
}
return {
sizes: [mpu],
sizeMappings: defaultSizeMappings,
};
};

const mapValues = (
keys: string[],
valueFn: (key: string) => string[],
): Array<[string, string[]]> => keys.map((key) => [key, valueFn(key)]);
Expand All @@ -35,6 +98,11 @@ const getPassbackValue = (source: string): string => {
* A listener for 'passback' messages from ad slot iFrames
* Ad providers will postMessage a 'passback' message to tell us they have not filled this slot
* In which case we create a 'passback' slot to fulfil the slot with another ad
*
* More details:
* https://github.com/guardian/frontend/pull/24724
* https://github.com/guardian/frontend/pull/24903
* https://github.com/guardian/frontend/pull/25008
*/
const init = (register: RegisterListener): void => {
register('passback', (messagePayload, ret, iframe) => {
Expand Down Expand Up @@ -98,10 +166,14 @@ const init = (register: RegisterListener): void => {
*/
const updateInitialSlotPromise = fastdom.mutate(() => {
iFrameContainer.style.visibility = 'hidden';
// TODO: this should be promoted to default styles for the initial slot
// Allows passback slot to position absolutely over the parent slot
slotElement.style.position = 'relative';
// Remove any outstream styling for this slot
// Remove any outstream styling for the parent slot
slotElement.classList.remove('ad-slot--outstream');
// Prevent refreshing of the parent slot
slotElement.setAttribute('data-refresh', 'false');
const advert = getAdvertById(slotElement.id);
if (advert) advert.shouldRefresh = false;
});

/**
Expand Down Expand Up @@ -154,11 +226,11 @@ const init = (register: RegisterListener): void => {
/**
* Copy the targeting from the initial slot
*/
const pageTargeting = getValuesForKeys(
const pageTargeting = mapValues(
window.googletag.pubads().getTargetingKeys(),
(key) => window.googletag.pubads().getTargeting(key),
);
const slotTargeting = getValuesForKeys(
const slotTargeting = mapValues(
initialSlot.getTargetingKeys(),
(key) => initialSlot.getTargeting(key),
);
Expand Down Expand Up @@ -217,8 +289,10 @@ const init = (register: RegisterListener): void => {
);
slotElement.style.height = slotHeight;

/*The centre styling is added in here instead of where the element is created
because googletag removes the display style on the passbackElement */
/**
* The centre styling is added in here instead of where the element is created
* because googletag removes the display style on the passbackElement
*/
passbackElement.style.display = 'flex';
passbackElement.style.flexDirection =
'column';
Expand All @@ -228,9 +302,10 @@ const init = (register: RegisterListener): void => {
'center';
passbackElement.style.height = `calc(100% - ${adLabelHeight}px)`;

// Also resize the initial outstream iframe so
// it doesn't block text selection directly under
// the new ad
/**
* Also resize the initial outstream iframe so it doesn't block text selection
* directly under the new ad
*/
iframe.style.height = slotHeight;
iFrameContainer.style.height =
slotHeight;
Expand All @@ -244,24 +319,16 @@ const init = (register: RegisterListener): void => {
* Define and display the new passback slot
*/
window.googletag.cmd.push(() => {
const { sizes, sizeMappings } = decideSizes(source);
// https://developers.google.com/publisher-tag/reference#googletag.defineSlot
const passbackSlot = googletag.defineSlot(
initialSlot.getAdUnitPath(),
[mpu, outstreamMobile, outstreamDesktop],
sizes,
passbackElement.id,
);
if (passbackSlot) {
// https://developers.google.com/publisher-tag/guides/ad-sizes#responsive_ads
passbackSlot.defineSizeMapping([
[
[breakpoints.phablet, 0],
[mpu, outstreamDesktop],
],
[
[breakpoints.mobile, 0],
[mpu, outstreamMobile],
],
]);
passbackSlot.defineSizeMapping(sizeMappings);
passbackSlot.addService(window.googletag.pubads());
passbackTargeting.forEach(([key, value]) => {
passbackSlot.setTargeting(key, value);
Expand Down

0 comments on commit d12c151

Please sign in to comment.