-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8 from jwplayer/feat/AD-1583
[AD-1583] Allow publisher to specify tracking urls
- Loading branch information
Showing
6 changed files
with
625 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
|
||
export function buildVastWrapper(adId, adTagUrl, impressionUrl, impressionId, errorUrl) { | ||
let wrapperBody = getAdSystemNode('Prebid org', $$PREBID_GLOBAL$$.version); | ||
|
||
if (adTagUrl) { | ||
wrapperBody += getAdTagUriNode(adTagUrl); | ||
} | ||
|
||
if (impressionUrl) { | ||
wrapperBody += getImpressionNode(impressionUrl, impressionId); | ||
} | ||
|
||
if (errorUrl) { | ||
wrapperBody += getErrorNode(errorUrl); | ||
} | ||
|
||
return getVastNode(getAdNode(getWrapperNode(wrapperBody), adId), '4.2'); | ||
} | ||
|
||
export function getVastNode(body, vastVersion) { | ||
return getNode('VAST', body, { version: vastVersion }); | ||
} | ||
|
||
export function getAdNode(body, adId) { | ||
return getNode('Ad', body, { id: adId }); | ||
} | ||
|
||
export function getWrapperNode(body) { | ||
return getNode('Wrapper', body); | ||
} | ||
|
||
export function getAdSystemNode(system, version) { | ||
return getNode('AdSystem', system, { version }); | ||
} | ||
|
||
export function getAdTagUriNode(adTagUrl) { | ||
return getUrlNode('VASTAdTagURI', adTagUrl); | ||
} | ||
|
||
export function getImpressionNode(pingUrl, id) { | ||
return getUrlNode('Impression', pingUrl, { id }); | ||
} | ||
|
||
export function getErrorNode(pingUrl) { | ||
return getUrlNode('Error', pingUrl); | ||
} | ||
|
||
// Helpers | ||
|
||
function getUrlNode(labelName, url, attributes) { | ||
const body = `<![CDATA[${url}]]>`; | ||
return getNode(labelName, body, attributes); | ||
} | ||
|
||
function getNode(labelName, body, attributes) { | ||
const openingLabel = getOpeningLabel(labelName, attributes); | ||
return `<${openingLabel}>${body}</${labelName}>`; | ||
} | ||
|
||
/* | ||
attributes is a KVP Object. | ||
*/ | ||
function getOpeningLabel(name, attributes) { | ||
if (!attributes) { | ||
return name; | ||
} | ||
|
||
return Object.keys(attributes).reduce((label, key) => { | ||
const value = attributes[key]; | ||
if (!value) { | ||
return label; | ||
} | ||
|
||
return label + ` ${key}="${value}"`; | ||
}, name); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import { getErrorNode, getImpressionNode, buildVastWrapper } from './vastXmlBuilder.js'; | ||
|
||
export const XML_MIME_TYPE = 'application/xml'; | ||
|
||
export function VastXmlEditor(xmlUtil_) { | ||
const xmlUtil = xmlUtil_; | ||
|
||
function getVastXmlWithTrackingNodes(vastXml, impressionUrl, impressionId, errorUrl) { | ||
const impressionDoc = getImpressionDoc(impressionUrl, impressionId); | ||
const errorDoc = getErrorDoc(errorUrl); | ||
if (!impressionDoc && !errorDoc) { | ||
return vastXml; | ||
} | ||
|
||
const vastXmlDoc = xmlUtil.parse(vastXml); | ||
const nodes = vastXmlDoc.querySelectorAll('InLine,Wrapper'); | ||
const nodeCount = nodes.length; | ||
for (let i = 0; i < nodeCount; i++) { | ||
const node = nodes[i]; | ||
// A copy of the child is required until we reach the last node. | ||
const requiresCopy = i < nodeCount - 1; | ||
appendChild(node, impressionDoc, requiresCopy); | ||
appendChild(node, errorDoc, requiresCopy); | ||
} | ||
|
||
return xmlUtil.serialize(vastXmlDoc); | ||
} | ||
|
||
return { | ||
getVastXmlWithTrackingNodes, | ||
buildVastWrapper | ||
} | ||
|
||
function getImpressionDoc(impressionUrl, impressionId) { | ||
if (!impressionUrl) { | ||
return; | ||
} | ||
|
||
const impressionNode = getImpressionNode(impressionUrl, impressionId); | ||
return xmlUtil.parse(impressionNode); | ||
} | ||
|
||
function getErrorDoc(errorUrl) { | ||
if (!errorUrl) { | ||
return; | ||
} | ||
|
||
const errorNode = getErrorNode(errorUrl); | ||
return xmlUtil.parse(errorNode); | ||
} | ||
|
||
function appendChild(node, child, copy) { | ||
if (!child) { | ||
return; | ||
} | ||
|
||
const doc = copy ? child.cloneNode(true) : child; | ||
node.appendChild(doc.documentElement); | ||
} | ||
} | ||
|
||
function XMLUtil() { | ||
let parser; | ||
let serializer; | ||
|
||
function getParser() { | ||
if (!parser) { | ||
// DOMParser instantiation is costly; instantiate only once throughout Prebid lifecycle. | ||
parser = new DOMParser(); | ||
} | ||
return parser; | ||
} | ||
|
||
function getSerializer() { | ||
if (!serializer) { | ||
// XMLSerializer instantiation is costly; instantiate only once throughout Prebid lifecycle. | ||
serializer = new XMLSerializer(); | ||
} | ||
return serializer; | ||
} | ||
|
||
function parse(xmlString) { | ||
return getParser().parseFromString(xmlString, XML_MIME_TYPE); | ||
} | ||
|
||
function serialize(xmlDoc) { | ||
return getSerializer().serializeToString(xmlDoc); | ||
} | ||
|
||
return { | ||
parse, | ||
serialize | ||
}; | ||
} | ||
|
||
export function vastXmlEditorFactory() { | ||
return VastXmlEditor(XMLUtil()); | ||
} |
Oops, something went wrong.