(function() { const makeStub = ()=>{ const TCF_LOCATOR_NAME = '__tcfapiLocator'; const queue = []; const currentWindow = window; let frameLocator = currentWindow; let cmpFrame; let gdprApplies; function addFrame() { const doc = currentWindow.document; const otherCMP = !!currentWindow.frames[TCF_LOCATOR_NAME]; if (!otherCMP) { if (doc.body) { const iframe = doc.createElement('iframe'); iframe.style.cssText = 'display:none'; iframe.name = TCF_LOCATOR_NAME; doc.body.appendChild(iframe); } else setTimeout(addFrame, 5); } return !otherCMP; } function tcfAPIHandler(...args) { if (!args.length) /** * shortcut to get the queue when the full CMP * implementation loads; it can call tcfapiHandler() * with no arguments to get the queued arguments */ return queue; else if (args[0] === 'setGdprApplies') /** * shortcut to set gdprApplies if the publisher * knows that they apply GDPR rules to all * traffic (see the section on "What does the * gdprApplies value mean" for more */ { if (args.length > 3 && parseInt(args[1], 10) === 2 && typeof args[3] === 'boolean') { gdprApplies = args[3]; if (typeof args[2] === 'function') args[2]('set', true); } } else if (args[0] === 'ping') /** * Only supported method; give PingReturn * object as response */ { if (typeof args[2] === 'function') args[2]({ gdprApplies: gdprApplies, cmpLoaded: false, cmpStatus: 'stub' }); } else /** * some other method, just queue it for the * full CMP implementation to deal with */ queue.push(args); } function postMessageEventHandler(event) { const msgIsString = typeof event.data === 'string'; let json = {}; if (msgIsString) try { /** * Try to parse the data from the event. This is important * to have in a try/catch because often messages may come * through that are not JSON */ json = JSON.parse(event.data); } catch (ignore) {} else json = event.data; const payload = typeof json === 'object' && json !== null ? json.__tcfapiCall : null; if (payload) window.__tcfapi(payload.command, payload.version, function(retValue, success) { let returnMsg = { __tcfapiReturn: { returnValue: retValue, success: success, callId: payload.callId } }; if (event && event.source && event.source.postMessage) event.source.postMessage(msgIsString ? JSON.stringify(returnMsg) : returnMsg, '*'); }, payload.parameter); } /** * Iterate up to the top window checking for an already-created * "__tcfapilLocator" frame on every level. If one exists already then we are * not the master CMP and will not queue commands. */ while(frameLocator){ try { if (frameLocator.frames[TCF_LOCATOR_NAME]) { cmpFrame = frameLocator; break; } } catch (ignore) {} // if we're at the top and no cmpFrame if (frameLocator === currentWindow.top) break; // Move up frameLocator = frameLocator.parent; } if (!cmpFrame) { // we have recur'd up the windows and have found no __tcfapiLocator frame addFrame(); currentWindow.__tcfapi = tcfAPIHandler; currentWindow.addEventListener('message', postMessageEventHandler, false); } }; makeStub(); })();