diff --git a/3p/vendors/neuwo.js b/3p/vendors/neuwo.js new file mode 100644 index 000000000000..6b845c0fe225 --- /dev/null +++ b/3p/vendors/neuwo.js @@ -0,0 +1,12 @@ +// src/polyfills.js must be the first import. +import '#3p/polyfills'; + +import {register} from '#3p/3p'; +import {draw3p, init} from '#3p/integration-lib'; + +import {neuwo} from '#ads/vendors/neuwo'; + +init(window); +register('neuwo', neuwo); + +window.draw3p = draw3p; diff --git a/ads/_config.js b/ads/_config.js index 1070c19e7c8f..d38e102a83dd 100755 --- a/ads/_config.js +++ b/ads/_config.js @@ -976,6 +976,10 @@ const adConfig = jsonConfiguration({ renderStartImplemented: true, }, + 'neuwo': { + renderStartImplemented: true, + }, + 'noddus': { prefetch: 'https://noddus.com/amp_loader.js', renderStartImplemented: true, diff --git a/ads/vendors/neuwo.js b/ads/vendors/neuwo.js new file mode 100644 index 000000000000..f69aad421908 --- /dev/null +++ b/ads/vendors/neuwo.js @@ -0,0 +1,23 @@ +import {validateData, writeScript} from '#3p/3p'; + +/** + * Neuwo Monetisation Platform. + * @param {!Window} global + * @param {!Object} data + */ +export function neuwo(global, data) { + validateData(data, ['scriptid'], []); + + // The Neuwo SDK dispatches these custom events on the 3p-iframe window when a + // placement renders (fill) or has no fill. Bridge them to the AMP ad + // lifecycle so AMP can start rendering / fall back to the next slot. + global.addEventListener('neuwoAdRender', () => global.context.renderStart()); + global.addEventListener('neuwoAdNoFill', () => + global.context.noContentAvailable() + ); + + writeScript( + global, + 'https://ads.neuwo.ai/loader/neuwo-ad.js?staticTagId=' + data['scriptid'] + ); +} diff --git a/ads/vendors/neuwo.md b/ads/vendors/neuwo.md new file mode 100644 index 000000000000..5e1d10b82c08 --- /dev/null +++ b/ads/vendors/neuwo.md @@ -0,0 +1,19 @@ +# Neuwo + +Neuwo Monetisation Platform. + +## Example + +```html + +``` + +## Configuration + +You need to get a `scriptid` (static tag ID) from your Neuwo account manager. + +For testing purposes you can use `data-scriptid="91"`. + +### Required parameters + +- `data-scriptid` diff --git a/examples/amp-ad/ads.amp.esm.html b/examples/amp-ad/ads.amp.esm.html index 9a2965878b84..b8c3bd322912 100644 --- a/examples/amp-ad/ads.amp.esm.html +++ b/examples/amp-ad/ads.amp.esm.html @@ -206,6 +206,7 @@ + @@ -1642,6 +1643,10 @@

NETLETIX

data-nxheight='250'> +

Neuwo

+ + +

Noddus

navegg + @@ -1486,6 +1487,10 @@

NETLETIX

data-nxunit='/60343726/netzathleten_.de' data-nxwidth='300' data-nxheight='250'>
+

Neuwo

+ + +

Noddus

{ + let sandbox; + let win; + + beforeEach(() => { + sandbox = env.sandbox; + + return createIframePromise(true).then((iframe) => { + // Simulate the iframe that neuwo will be called inside. + win = iframe.win; + win.context = { + renderStart: sandbox.spy(), + noContentAvailable: sandbox.spy(), + referrer: null, + }; + }); + }); + + it('should require the scriptid parameter', () => { + allowConsoleError(() => { + expect(() => neuwo(win, {})).to.throw(/scriptid/); + }); + }); + + it('should load the Neuwo static loader with the given scriptid', () => { + const writeScript = sandbox.stub(_3p, 'writeScript'); + neuwo(win, {'scriptid': '91'}); + expect(writeScript).to.be.calledOnce; + expect(writeScript.firstCall.args[1]).to.contain( + 'ads.neuwo.ai/loader/neuwo-ad.js?staticTagId=91' + ); + }); + + it('should bridge neuwoAdRender to renderStart()', () => { + sandbox.stub(_3p, 'writeScript'); + neuwo(win, {'scriptid': '91'}); + win.dispatchEvent(new win.Event('neuwoAdRender')); + expect(win.context.renderStart).to.be.calledOnce; + }); + + it('should bridge neuwoAdNoFill to noContentAvailable()', () => { + sandbox.stub(_3p, 'writeScript'); + neuwo(win, {'scriptid': '91'}); + win.dispatchEvent(new win.Event('neuwoAdNoFill')); + expect(win.context.noContentAvailable).to.be.calledOnce; + }); +});