diff --git a/modules/shBidAdapter.js b/modules/shBidAdapter.js index 94d28770548..0f730b57033 100644 --- a/modules/shBidAdapter.js +++ b/modules/shBidAdapter.js @@ -1,5 +1,6 @@ import * as utils from '../src/utils'; import { config } from '../src/config'; +import { Renderer } from '../src/Renderer'; import { registerBidder } from '../src/adapters/bidderFactory'; import { VIDEO, BANNER } from '../src/mediaTypes'; @@ -12,6 +13,13 @@ const STAGE_VL = 'https://video-library.stage.showheroes.com'; const BIDDER_CODE = 'showheroes-bs'; const TTL = 300; +function getEnvURLs(isStage) { + return { + pubTag: isStage ? STAGE_PUBLISHER_TAG : PROD_PUBLISHER_TAG, + vlHost: isStage ? STAGE_VL : PROD_VL + } +} + export const spec = { code: BIDDER_CODE, aliases: ['showheroesBs'], @@ -22,7 +30,12 @@ export const spec = { buildRequests: function(validBidRequests, bidderRequest) { const pageURL = validBidRequests[0].params.contentPageUrl || bidderRequest.refererInfo.referer; const isStage = !!validBidRequests[0].params.stage; - const isBanner = !!validBidRequests[0].mediaTypes.banner; + const isOutstream = utils.deepAccess(validBidRequests[0], 'mediaTypes.video.context') === 'outstream'; + const isCustomRender = utils.deepAccess(validBidRequests[0], 'params.outstreamOptions.customRender'); + const isNodeRender = utils.deepAccess(validBidRequests[0], 'params.outstreamOptions.slot') || utils.deepAccess(validBidRequests[0], 'params.outstreamOptions.iframe'); + const isNativeRender = utils.deepAccess(validBidRequests[0], 'renderer'); + const outstreamOptions = utils.deepAccess(validBidRequests[0], 'params.outstreamOptions'); + const isBanner = !!validBidRequests[0].mediaTypes.banner || (isOutstream && !(isCustomRender || isNativeRender || isNodeRender)); let adUnits = validBidRequests.map((bid) => { const vpaidMode = utils.getBidIdParameter('vpaidMode', bid.params); @@ -30,8 +43,9 @@ export const spec = { let sizes = bid.sizes.length === 1 ? bid.sizes[0] : bid.sizes; if (sizes && !sizes.length) { let mediaSize; - if (!isBanner) { - mediaSize = bid.mediaTypes.video.playerSize; + let mediaVideoSize = utils.deepAccess(bid, 'mediaTypes.video.playerSize'); + if (utils.isArray(mediaVideoSize)) { + mediaSize = mediaVideoSize; } else { mediaSize = bid.mediaTypes.banner.sizes; } @@ -49,7 +63,7 @@ export const spec = { if (vpaidMode && context === 'instream') { streamType = 1; } - if (context === 'outstream' || isBanner) { + if (isBanner || context === 'outstream') { streamType = 5; } @@ -57,6 +71,7 @@ export const spec = { type: streamType, bidId: bid.bidId, mediaType: isBanner ? BANNER : VIDEO, + context: context, playerId: utils.getBidIdParameter('playerId', bid.params), auctionId: bidderRequest.auctionId, bidderCode: BIDDER_CODE, @@ -67,6 +82,7 @@ export const spec = { width: sizes[0], height: sizes[1] }, + params: bid.params, }; }); @@ -78,8 +94,9 @@ export const spec = { 'user': [], 'meta': { 'pageURL': encodeURIComponent(pageURL), - 'vastCacheEnabled': (!!config.getConfig('cache') && !isBanner) || false, + 'vastCacheEnabled': (!!config.getConfig('cache') && !isBanner && !outstreamOptions) || false, 'isDesktop': utils.getWindowTop().document.documentElement.clientWidth > 700, + 'xmlAndTag': !!(isOutstream && isCustomRender) || false, 'stage': isStage || undefined }, 'requests': adUnits, @@ -133,6 +150,7 @@ function createBids(bidRes, reqData) { bidRes.bids.forEach(function (bid) { const reqBid = bidMap[bid.bidId]; + const currentBidParams = reqBid.params; let bidUnit = {}; bidUnit.cpm = bid.cpm; bidUnit.requestId = bid.bidId; @@ -154,6 +172,25 @@ function createBids(bidRes, reqData) { } if (reqBid.mediaType === BANNER) { bidUnit.ad = getBannerHtml(bid, reqBid, reqData); + } else if (reqBid.context === 'outstream') { + const renderer = Renderer.install({ + id: bid.bidId, + url: '//', + config: { + playerId: reqBid.playerId, + width: bid.video.width, + height: bid.video.height, + vastUrl: bid.vastTag, + vastXml: bid.vastXml, + debug: reqData.debug, + isStage: !!reqData.meta.stage, + customRender: utils.getBidIdParameter('customRender', currentBidParams.outstreamOptions), + slot: utils.getBidIdParameter('slot', currentBidParams.outstreamOptions), + iframe: utils.getBidIdParameter('iframe', currentBidParams.outstreamOptions), + } + }); + renderer.setRender(outstreamRender); + bidUnit.renderer = renderer; } bids.push(bidUnit); }); @@ -161,18 +198,69 @@ function createBids(bidRes, reqData) { return bids; } +function outstreamRender(bid) { + const embedCode = createOutstreamEmbedCode(bid); + if (typeof bid.renderer.config.customRender === 'function') { + bid.renderer.config.customRender(bid, embedCode); + } else { + try { + const inIframe = utils.getBidIdParameter('iframe', bid.renderer.config); + if (inIframe && window.document.getElementById(inIframe).nodeName === 'IFRAME') { + const iframe = window.document.getElementById(inIframe); + let framedoc = iframe.contentDocument || (iframe.contentWindow && iframe.contentWindow.document); + framedoc.body.appendChild(embedCode); + return; + } + + const slot = utils.getBidIdParameter('slot', bid.renderer.config); + if (slot && window.document.getElementById(slot)) { + window.document.getElementById(slot).appendChild(embedCode); + } else if (slot) { + utils.logError('[ShowHeroes][renderer] Error: spot not found'); + } + } catch (err) { + utils.logError('[ShowHeroes][renderer] Error:' + err.message) + } + } +} + +function createOutstreamEmbedCode(bid) { + const isStage = utils.getBidIdParameter('isStage', bid.renderer.config); + const urls = getEnvURLs(isStage); + + const fragment = window.document.createDocumentFragment(); + + const script = window.document.createElement('script'); + script.type = 'text/javascript'; + script.src = urls.pubTag; + script.onload = function () { + window.ShowheroesTag = this; + }; + script.setAttribute('data-player-host', urls.vlHost); + + const spot = window.document.createElement('div'); + spot.setAttribute('class', 'showheroes-spot'); + spot.setAttribute('data-player', utils.getBidIdParameter('playerId', bid.renderer.config)); + spot.setAttribute('data-debug', utils.getBidIdParameter('debug', bid.renderer.config)); + spot.setAttribute('data-ad-vast-tag', utils.getBidIdParameter('vastUrl', bid.renderer.config)); + spot.setAttribute('data-stream-type', 'outstream'); + + fragment.appendChild(spot); + fragment.appendChild(script); + return fragment; +} + function getBannerHtml (bid, reqBid, reqData) { const isStage = !!reqData.meta.stage; - const pubTag = isStage ? STAGE_PUBLISHER_TAG : PROD_PUBLISHER_TAG; - const vlHost = isStage ? STAGE_VL : PROD_VL; + const urls = getEnvURLs(isStage); return ` - + data-player-host="${urls.vlHost}">