Výdejový script reklamy Source: ssp.js

/**
 * @file SSP reklamní výdejový script
 *
 * @author Seznam Partner <ssp-nasazeni@firma.seznam.cz>
 *
 */

/* IVA Refresher */
import '@iva/refresher';

/* IAB SafeFrame support */
import './safeframe/sf.host';

/* IVA error handler */
import { startErrorHandling } from '@iva/error-reporter';

/* Utility functions */
import { dbg } from './modules/utils/dbg';
import { addToQueue } from './modules/utils/functionStack';
import init from './modules/init';

/* Public APIs */
import { setConfig, getConfig } from './modules/config';
import getAds from './modules/ads/getAds';
import getAdsByTags from './modules/ads/getAdsByTags';
import { setPageViewId, getPageViewId } from './modules/utils/pageView';
import { sessionExists } from './modules/session/sessionDetection';
import { setSessionCookie } from './modules/session/sessionCookies';
import writeAd from './modules/rendering/writeAd';
import served from './modules/impress/served';
import processAdData from './modules/ads/processAdData';
import { cmpInit } from './modules/cmp/cmpLoader';
import { getDot } from './modules/impress/dotLoader';
import { setCustomPath } from './modules/customs';
import { getRenderedAds, updatePositionId, extendVisibilityTracking } from './modules/ads/adRepository';
import { getPawHTML } from './modules/rendering/getPawHTML';
import { appendPawToElement } from './modules/rendering/appendPawToElement';
import sendHit from './modules/utils/sendHit';
import { HIT_MODIFICATION_TITLE } from './constants';
import { doNotInit, isStandAlone } from './modules/config/globalFlags';
import { getVastData } from './modules/utils/vastData';

startErrorHandling({
  endpoint: 'ssp-static',
  scriptName: 'ssp.js',
});

/**
 * @interface sssp
 * @desc Public object <code>sssp</code> exposing API methods for working with Seznam ads.
 */
const sssp = {};

/**
 * Main configuration method. Accepts an object describing
 * website-specific config.
 *
 * @param {Object} config Configuration object
 * @param {Number} config.webId  Used to configure the CMP dialog
 * @param {String} config.site Current site
 * @param {String} config.protocol Set protocol to match your site's configuration. Defaults to "https".
 * @param {Boolean} config.documentWriteOverride Disable replacement of native document.write() method. Required for ads with embedded scripts to work. Defaults to true.
 * @param {String} config.source Set traffic source. Websites receiving traffic from Seznam are required to set this to value according to UTM parameter value in URL.
 * @param {String} config.server Server host to request ads from. Defaults to "ssp.seznam.cz" (development only).
 * @param {String} config.staticServer If the server delivering static files differs from the main adserver, specify it here (development only).
 * @param {String} config.iframeStaticServer If the server for iframe src differs from the main adserver, specify it here (development only).
 * @param {Boolean} config.adblock Flag, that turn on (true) or off (false) antiadblock
 * @param {Object} config.ab
 * @param {Function} config.requestErrorCallback Callback function that SSP calls when an xhr request fails
 * @param {Function} config.preparePositionsCallback Callback function is called If the session started by the user's arrival by clicking from news feed to homepagi is valid Seznam.cz.
 * @param {Boolean} config.premium Premium flag
 * @param {Number} config.rusId Seznam User Id
 * @param {String} config.said Encrypted Seznam User Id
 * @param {Boolean} config.badge If true, then the `premium`, `sid`, `said` can get from badge
 * @param {Boolean} config.test Testing mode for partners
 * @param {Boolean} config.cidsAutoSend  If true, then collect CIDs from response
 * @param {String} config.serviceIdForAllZones assign to all ad zones the serviceId with specified string
 * @param {Boolead} config.callCallbackOnError defaultly set false, if true the callback function in ad position will accept only one parameter
 */
sssp.config = (config) =>
  addToQueue(() => {
    setConfig(config);
    if (!isStandAlone()) {
      cmpInit();
    }
    sssp.conf = getConfig();
  });

/**
 * [deprecated] Object representing current configuration. Read-only.
 */
sssp.conf = getConfig();

/**
 * Main method for calling and displaying ads. Allows requesting and displaying
 * a single zone (single object as the first parameter) or multiple zones by
 * passing an array of zone objects.
 *
 * @param {Object|Object[]} positions Object or array with zones configuration
 * @param {Object} opt Additional request configuration (AMPHTML, etc.)
 */
sssp.getAds = (positions, opt) => addToQueue(getAds, positions, opt);

/**
 * A simpler method for requesting and displaying ads on the page. It doesn't
 * require to pass an array or object with zone configuration, instead it scans
 * the DOM for HTML elements with "data-szn-ssp-ad" attributes and creates the
 * object pased to getAds method.
 */
sssp.getAdsByTags = () => addToQueue(getAdsByTags);

/**
 * Inserts ad to page according to parameters passed.
 *
 * @param {Object} ad Advert object as retrieved from server.
 * @param {Object} data Object representing all configured zones on page.
 */
sssp.writeAd = (ad, data) => writeAd(ad, data);

/**
 * Attempts to hit each provided URL in array in order to count metrics (miss,
 * impress, visible)
 *
 * @param {Array} servedUrls Array of URLs as strings
 */
sssp.served = (servedUrls) => served(servedUrls);

/**
 * Retrieve page view ID from config (web is Single-Page Application (SPA))
 */
sssp.getPageViewId = () => getPageViewId();

/**
 * Set page view ID. If provided, pageview ID will be set to the value of
 * the argument. If not, the script will generate one (usually the desired
 * behavior).
 *
 * @param {String} pageViewId Optional pageView ID
 * @param {Boolean} resetVisibilityElements Optional flag to reset visibility elements
 */
sssp.setPageViewId = (pageViewId, resetVisibilityElements) =>
  addToQueue(setPageViewId, pageViewId, resetVisibilityElements);

/**
 * Detects an active Seznam partner session. Intended for partner websites
 * to check for traffic generated by Seznam and display ads according to the
 * traffic source.
 *
 * @returns {Boolean}
 */
sssp.displaySeznamAds = sessionExists;

/**
 * Detects if a session cookie was set for a Seznam partner website
 *
 * @returns {Boolean}
 */
sssp.existSessionCookie = sessionExists;

/**
 * Set session cookie to mark valid session to continue serving Seznam ads
 *
 * @param {String} media utm media name
 */
sssp.setSessionCookie = (media) => setSessionCookie({ media });

/**
 * Renders an ad or invokes a callback.
 * @param ad {Object} - single ad returned by ssp server
 * @param data {Object} - position definition
 */
sssp.processAdData = (ad, data) => addToQueue(processAdData, ad, data);

/**
 * Gets info about rendered positions/ads (= content of positionsStore). Watcher for future updates can be registered.
 * @param {Function} watcher - callback to be called inside done() function (optional)
 * @returns {Object} object
 * @returns {Array} object.data - array of positions (basic info)
 * @returns {Function} object.removeWatcher - funtion to be called for watcher removal (optional)
 */
sssp.getRenderedAds = (watcher) => getRenderedAds(watcher);

/**
 * Manually initialize SSP. Use only when `window._sspDoNotInit` has been set to
 * a truthy value before running ssp.js.
 */
sssp.init = init;

/**
 * Private method for debugging and testing purposes only
 * returns SSP's current DOT instance
 */
sssp._getDotInstance = getDot;

/**
 * Updating element / container ID according to zoneId (if adRepository[item].ad.id = falsy) in adRepository (affects all positions satisfying condition)
 * @returns {Object} object
 */
sssp.updateAdContainerId = (adObject) => updatePositionId(adObject);

/**
 * Sets custom resources paths for debugging and testing purposes only
 */
sssp._setCustomPath = setCustomPath;

/**
 * Returns pawHTML for all DSP types except Sklik, OGAR & ONEGAR
 * @param {Object} ad - reklama z sssp
 * @returns {String | null} pawHTML
 */
sssp.getPawHTML = getPawHTML;

/**
 * Appends pawHTML to an element
 * @param {Object} ad - reklama z sssp
 * @param {HTMLElement} element - HTML DOM element, where the paw should be inserted
 */
sssp.appendPawToElement = appendPawToElement;

/**
 * Add positions from callback ad into positionsStore for visibility measurement
 * @param {Array} callbackAdData - Array of positions with id and visibility URL.
 */
sssp.extendVisibilityTracking = (callbackAdData) => extendVisibilityTracking(callbackAdData);

/**
 * Clear sklikData from window object
 */
sssp.clearData = function () {
  try {
    if (!delete window.sklikData) {
      window.sklikData = null;
    }
  } catch (e) {
    window.sklikData = null;
  }
};

/**
 * Geet VAST related data (tags, ...) from "anywhere".
 * Returns Promise (syncing from top) -> works in top level and also embeds.
 * @param {String} targetOrigin - origin of the top window (defaults to "*")
 * @param {String} timeoutMs - timeout for promise in ms (defaults to 500)
 * @returns {Object | null} data
 */
sssp.getVastData = getVastData;

if ('sssp' in window && window.sssp.isStub) {
  delete window.sssp;
}

/* Attempt to initialize SSP */
if (!window.sssp) {
  dbg('info', '### exporting sssp object to window');

  if ('Proxy' in window) {
    const proxyHandler = {
      set(obj, prop, value) {
        obj[prop] = value;

        // log modification of module properties
        sendHit({ t: HIT_MODIFICATION_TITLE, i: '1', r: top.location.origin, z: '1' });

        return true;
      },
    };

    Object.defineProperty(window, 'sssp', {
      configurable: true,
      get() {
        return new Proxy(sssp, proxyHandler);
      },
      set(value) {
        // log modification of the whole module
        sendHit({ t: HIT_MODIFICATION_TITLE, i: '1', r: top.location.origin, z: '1' });
        Object.defineProperty(window, 'sssp', { value });
      },
    });
  } else {
    window.sssp = sssp;
  }

  if (!doNotInit()) {
    dbg('info', '### initializing sssp');
    init();
  } else {
    dbg('info', '### variable window._sspDoNotInit is set, skipping ssp initialization');
  }
} else {
  dbg('info', '### sssp already exists - exiting');
}

export { sssp };