@68publishers/amp-client
Version:
JS Client for 68publishers/amp
131 lines (114 loc) • 4.45 kB
JavaScript
import { createMainConfig, createExtendedConfig } from './config.mjs';
import { BannerManager } from '../../banner/banner-manager.mjs';
import { DimensionsProvider } from '../../banner/responsive/dimensions-provider.mjs';
import { EventBus } from '../../event/event-bus.mjs';
import { Events } from '../../event/events.mjs';
import { ParentFrameMessenger } from '../../frame/parent-frame-messenger.mjs';
import { BannerInteractionWatcher } from '../../interaction/banner-interaction-watcher.mjs';
import { MetricsSender } from '../../metrics/metrics-sender.mjs';
import { MetricsEventsListener } from '../../metrics/metrics-events-listener.mjs';
import { EventsConfig } from '../../metrics/events-config.mjs';
import { State } from '../../banner/state.mjs';
import { ClosingManager } from '../../banner/closing/closing-manager.mjs';
export class Client {
#version;
#mainConfig;
#extendedConfig;
#eventBus;
#bannerManager;
#frameMessenger;
#bannerInteractionWatcher;
#closingManager;
#metricsSender;
#metricsEventsListener;
#attached;
#parentWindowWidth = null;
/**
* @param {ClientVersion} version
* @param {Object} options
*/
constructor (version, options) {
this.EVENTS = Events;
this.#version = version;
this.#mainConfig = createMainConfig(options);
this.#extendedConfig = createExtendedConfig({});
this.#extendedConfig = null;
this.#eventBus = new EventBus();
this.#bannerManager = new BannerManager(
this.#eventBus,
new DimensionsProvider(() => {
return this.#parentWindowWidth || document.documentElement.clientWidth || document.body.clientWidth;
}),
);
this.#frameMessenger = new ParentFrameMessenger({
clientEventBus: this.#eventBus,
});
this.#closingManager = new ClosingManager({
bannerManager: this.#bannerManager,
eventBus: this.#eventBus,
parentFrameMessenger: this.#frameMessenger,
});
this.#attached = false;
this.#bannerInteractionWatcher = null;
this.#metricsSender = new MetricsSender(
[this.#sendMetricsEvent.bind(this)],
);
this.#metricsEventsListener = new MetricsEventsListener(
this.#metricsSender,
this.#eventBus,
this.#mainConfig.channel,
);
this.#frameMessenger.on('connect', ({ data }) => {
this.#extendedConfig = createExtendedConfig(data.extendedConfig);
this.#parentWindowWidth = data.windowWidth;
this.#bannerInteractionWatcher = new BannerInteractionWatcher(
this.#bannerManager,
this.#eventBus,
this.#extendedConfig.interaction,
);
this.#redrawBanners();
this.#metricsEventsListener.attach(new EventsConfig(this.#extendedConfig.metrics));
this.#bannerInteractionWatcher.start();
});
this.#frameMessenger.on('windowResized', ({ data }) => {
this.#parentWindowWidth = data.windowWidth;
this.#redrawBanners();
});
this.#frameMessenger.listen();
this.#metricsEventsListener.collectBeforeAttach();
this.#closingManager.attachUi();
}
/**
* @returns {ClientVersion}
*/
get version() {
return this.#version;
}
on(event, callback, scope = null) {
return this.#eventBus.subscribe(event, callback, scope);
}
attachBanner() {
if (this.#attached) {
throw new Error('Method attachBanner() should be called only once.');
}
const element = document.querySelector('[data-amp-banner]:not([data-amp-attached])');
if (!element) {
console.warn('No banner found in the embed client.');
return;
}
const banner = this.#bannerManager.addExternalBanner(element);
this.#attached = true;
this.#eventBus.dispatch(this.EVENTS.ON_BANNER_ATTACHED, { banner });
}
#sendMetricsEvent(eventName, eventArgs) {
this.#frameMessenger.sendToParent('metrics', {
eventName,
eventArgs,
});
}
#redrawBanners() {
for (let banner of this.#bannerManager.getBannersByState({ state: State.RENDERED })) {
banner.redrawIfNeeded();
}
}
}