Skip to content

Commit e0a3044

Browse files
authored
Merge c3a4123 into b5ee339
2 parents b5ee339 + c3a4123 commit e0a3044

6 files changed

Lines changed: 445 additions & 158 deletions

File tree

.changeset/young-mangos-thank.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@guardian/commercial-core': minor
3+
---
4+
5+
Introduces a globalAdEvents public API, enabling consumers to add listeners for ad lifecycle events with filtering by status and slot name.

bundle/src/define/Advert.spec.ts

Lines changed: 0 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { globalAdEvents } from '@guardian/commercial-core';
21
import type * as AdSizesType from '@guardian/commercial-core/ad-sizes';
32
import { slotSizeMappings as slotSizeMappings_ } from '@guardian/commercial-core/ad-sizes';
43
import { _, Advert, findSmallestAdHeightForSlot } from './Advert';
@@ -181,127 +180,6 @@ describe('Advert', () => {
181180
});
182181
});
183182

184-
describe('globalAdEvents', () => {
185-
it('should dispatch adStatusChange on globalAdEvents when status changes', () => {
186-
const slot = document.createElement('div');
187-
slot.setAttribute('data-name', 'top-above-nav');
188-
const ad = new Advert(slot);
189-
190-
const listener = jest.fn();
191-
globalAdEvents.addEventListener('adStatusChange', listener);
192-
193-
ad.setStatus('loading', true);
194-
195-
expect(listener).toHaveBeenCalledTimes(1);
196-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- test
197-
expect((listener.mock.calls[0][0] as CustomEvent).detail).toEqual(
198-
expect.objectContaining({
199-
name: 'loading',
200-
status: true,
201-
}),
202-
);
203-
204-
globalAdEvents.removeEventListener('adStatusChange', listener);
205-
});
206-
it('should dispatch adStatusChange on globalAdEvents when status changes on multiple adverts', () => {
207-
const slot = document.createElement('div');
208-
slot.setAttribute('data-name', 'top-above-nav');
209-
const ad1 = new Advert(slot);
210-
const ad2 = new Advert(slot);
211-
212-
const listener = jest.fn();
213-
214-
globalAdEvents.addEventListener('adStatusChange', listener);
215-
216-
ad1.setStatus('loading', true);
217-
ad2.setStatus('loaded', true);
218-
219-
expect(listener).toHaveBeenCalledTimes(2);
220-
221-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- test
222-
expect((listener.mock.calls[0][0] as CustomEvent).detail).toEqual(
223-
expect.objectContaining({
224-
name: 'loading',
225-
status: true,
226-
}),
227-
);
228-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- test
229-
expect((listener.mock.calls[1][0] as CustomEvent).detail).toEqual(
230-
expect.objectContaining({
231-
name: 'loaded',
232-
status: true,
233-
}),
234-
);
235-
236-
globalAdEvents.removeEventListener('adStatusChange', listener);
237-
});
238-
it('should dispatch adStatusChange on globalAdEvents when multiple status changes on the same advert', () => {
239-
const slot = document.createElement('div');
240-
slot.setAttribute('data-name', 'top-above-nav');
241-
const ad1 = new Advert(slot);
242-
243-
const listener = jest.fn();
244-
245-
globalAdEvents.addEventListener('adStatusChange', listener);
246-
247-
ad1.setStatus('loading', true);
248-
ad1.setStatus('rendered', true);
249-
250-
expect(listener).toHaveBeenCalledTimes(2);
251-
252-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- test
253-
expect((listener.mock.calls[0][0] as CustomEvent).detail).toEqual(
254-
expect.objectContaining({
255-
name: 'loading',
256-
status: true,
257-
}),
258-
);
259-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- test
260-
expect((listener.mock.calls[1][0] as CustomEvent).detail).toEqual(
261-
expect.objectContaining({
262-
name: 'rendered',
263-
status: true,
264-
}),
265-
);
266-
267-
globalAdEvents.removeEventListener('adStatusChange', listener);
268-
});
269-
it('should dispatch adStatusChange on globalAdEvents when listener is removed', () => {
270-
const slot = document.createElement('div');
271-
slot.setAttribute('data-name', 'top-above-nav');
272-
const ad = new Advert(slot);
273-
274-
const listener = jest.fn();
275-
276-
globalAdEvents.addEventListener('adStatusChange', listener);
277-
278-
ad.setStatus('loading', true);
279-
280-
globalAdEvents.removeEventListener('adStatusChange', listener);
281-
ad.setStatus('rendered', true);
282-
283-
expect(listener).toHaveBeenCalledTimes(1);
284-
});
285-
it('should allow for multiple independent listeners, and both should hear the same event', () => {
286-
const slot = document.createElement('div');
287-
slot.setAttribute('data-name', 'top-above-nav');
288-
const ad = new Advert(slot);
289-
290-
const listener1 = jest.fn();
291-
const listener2 = jest.fn();
292-
293-
globalAdEvents.addEventListener('adStatusChange', listener1);
294-
globalAdEvents.addEventListener('adStatusChange', listener2);
295-
296-
ad.setStatus('loading', true);
297-
298-
expect(listener1).toHaveBeenCalledTimes(1);
299-
expect(listener2).toHaveBeenCalledTimes(1);
300-
globalAdEvents.removeEventListener('adStatusChange', listener1);
301-
globalAdEvents.removeEventListener('adStatusChange', listener2);
302-
});
303-
});
304-
305183
describe('on() method', () => {
306184
it('should call callback immediately if advert is already at the specified status', () => {
307185
const slot = document.createElement('div');

bundle/src/define/Advert.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import type {
1010
SlotName,
1111
} from '@guardian/commercial-core/ad-sizes';
1212
import type { Breakpoint } from '@guardian/commercial-core/breakpoint';
13-
import { globalAdEvents } from '@guardian/commercial-core/global-ad-events';
1413
import { log } from '@guardian/libs';
1514
import { breakpoints as sourceBreakpoints } from '@guardian/source/foundations';
1615
import type { Size } from 'prebid.js/dist/src/types/common';
@@ -270,9 +269,9 @@ class Advert extends EventTarget {
270269
this.dispatchEvent(
271270
new CustomEvent('statusChange', { detail: { name, status } }),
272271
);
273-
globalAdEvents.dispatchEvent(
274-
new CustomEvent('adStatusChange', {
275-
detail: { advert: this, name, status },
272+
document.dispatchEvent(
273+
new CustomEvent('commercial:adStatusChange', {
274+
detail: { slotName: this.name, name, status },
276275
}),
277276
);
278277
}

0 commit comments

Comments
 (0)