/** * copyright 2014 KnowledgeVision Systems */ ///////////////////////////// // Global variables // ///////////////////////////// // arrays loaded from video.xml var KVPlr_cueTime = []; var KVPlr_type = []; var KVPlr_key = []; var KVPlr_zoom = []; var KVPlr_title = []; var KVPlr_footnote = []; var KVPlr_attachment = []; var KVPlr_attachmentN = []; var KVPlr_imgSrc = []; // state variables var KVPlr_curArray = -1; var KVPlr_maxArray = -1; var KVPlr_chapterHt = 170; var KVPlr_zoomOverride= false; var KVPlr_chapterIdx = -1; var KVPlr_footnoteIdx = -1; var KVPlr_gotoCurrentTime = -10.0; var KVPlr_visibleIndex = 0; // holds the index of the slide currently displayed // tracking constants var KVTRACK_ATTACHMENT = "Attachment"; var KVTRACK_CHAPTER = "Chapter"; var KVTRACK_CUEPOINT = "CuePoint"; var KVTRACK_FOOTNOTE = "FootnoteLink"; var KVTRACK_PLAYBACK = "Playback"; // device constants var KVDEVICE_IPAD = "iPad"; var KVDEVICE_IPHONE = "iPhone"; var KVDEVICE_PHONE = "phone"; var KVDEVICE_ANDROID = "android"; var PRESENTATION_NOT_AVAILABLE_FOR_MOBILE = '

This presentation is not available for mobile devices.

KnowledgeVision Systems Incorporated

'; // domain constants var VIEW_KNOWLEDGEVISION_COM = 'view.knowledgevision.com'; var DEV_VIEW_KNOWLEDGEVISION_COM = 'dev-view.knowledgevision.com'; var STAGE_VIEW_KNOWLEDGEVISION_COM = 'stage-view.knowledgevision.com'; // keys var SERVICE_NAME = 'kv-player'; var SERVICE_KEY = 'f2c8933d-621d-45a2-9dc5-a81aeed6e25a'; var DEV_SERVICE_NAME = 'kv-player'; var DEV_SERVICE_KEY = '4b991d50-33f4-4b4f-ae7f-87bddf7bc808'; var STAGE_SERVICE_NAME = 'kv-player'; var STAGE_SERVICE_KEY = '223f04c1-7f3b-46be-b924-5463bff1cd24'; var X_SERVICE_AUTHENTICATION = 'X-Service-Authentication'; var KVPlr_playbackInterval = 5; // Interval for %percent playback track reporting var KVPlr_lastPlaybackReported = 0; // start at zero var KVPlr_nextPlaybackToReport = 5; var KVPlr_maxPlaybackToReport = 100; // component to load var KVPLr_component = 'footnote'; //default to footnote // url of video var KVPlr_videoURL; var KVPlr_videoType; var KVPlr_Playback_Time = 0; var KVPlr_BC_VideoID; var KVPlr_BC_PlayerID; var KVPlr_BC_PublisherID; var KVPLR_BC_CdnURL = "default"; // bc vars var modExp; var modCon; var modVP; var KVPlr_videoDuration; var KVPlr_comboVideo; var KVPlr_comboVideoStream; var KVPlr_DefaultVideo = "http://present.knowledgevision.com/player/mobile/assets/videos/defaultVideo.mp4"; var KVPlr_device; // variables to support iScroll scrolling var KVPlr_myScroll; var KVPlr_myScroll2; var KVPlr_myScroll3; // tracking var trackerObj = null; var KVPlr_embedId = null; var defaultPlayerTemplate = ""; //var BCPlayerTemplate = "
"; var BCPlayerTemplate = "
"; var KVPLr_loadedVideo = false; // for testing var TEST_DATA__BC_IPAD_SAMPLE = 'testData/BC_IPad_Sample.xml'; ///////////////////////////// // End of Global variables // ///////////////////////////// document.addEventListener('DOMContentLoaded', KVPlr_loadConfigXML, false); /** * Inserts values into BC player template - only used if video type is 'brightcove' * @param html * @param data - options Object * @returns {string} * @private */ function KVPlr_buildPlayer(html, data) { var m; var i = 0; var match = html.match(data instanceof Array ? /{{\d+}}/g : /{{\w+}}/g) || []; while (m = match[i++]) { html = html.replace(m, data[m.substr(2, m.length-4)]); } return html; } /** * Looks for brightcove object in global scope and if found, it continues the load. * If not, wait and try again * @private */ function isBCAvailable(){ //alert("in isFunctionAvailable"); if (typeof(brightcove) === 'object'){ KVPlr_continueBCLoad(); } else { setTimeout(function(){ isBCAvailable(); },20); } } /** * Creates and loads a Brightcove SmartPlayer in place of the generic HTML5 video element * @private */ function KVPlr_continueBCLoad(){ var playerData = { "playerID" : KVPlr_BC_PlayerID, "width" : "100%", "height" : "100%", "videoID" : KVPlr_BC_VideoID }; var playerHTML; // populate the player object template playerHTML = KVPlr_buildPlayer(BCPlayerTemplate, playerData); // inject the player code into the DOM document.getElementById("videoBlock").innerHTML = playerHTML; // instantiate the player brightcove.createExperiences(); } /** * Determines which BC player environment to load. Currently we have US and Japan. * After dynamically loading the correct js file, if calls a fn to start watching for the existance * of the brightcove object in global scope * @private */ function KVPlr_loadBCPlayer(){ var scriptElmt = document.createElement('script'); scriptElmt.type = 'text/javascript'; //if(KVPLR_BC_CdnURL === 'admin.brightcove.co.jp'){ if(KVPLR_BC_CdnURL == 'default'){ scriptElmt.src="http://admin.brightcove.com/js/BrightcoveExperiences.js"; } else { scriptElmt.src="http://" + KVPLR_BC_CdnURL + "/js/BrightcoveExperiences.js"; } //append the script $("body").append(scriptElmt); // make sure script loads before doing anything else isBCAvailable(); } function KVPlr_Resize_BC_Player(newWidth, newHeight) { if(modExp){ modExp.setSize(newWidth,newHeight); } } /*function myTemplateLoaded(experienceID) { var player = brightcove.api.getExperience(experienceID); modVP = player.getModule(brightcove.api.modules.APIModules.VIDEO_PLAYER); modExp = player.getModule(brightcove.api.modules.APIModules.EXPERIENCE); modCon = player.getModule(brightcove.api.modules.APIModules.CONTENT); modExp.addEventListener(brightcove.api.events.ExperienceEvent.TEMPLATE_READY, onTemplateReady); }*/ /*function onTemplateReady(evt) { modExp.removeEventListener(brightcove.api.events.ExperienceEvent.TEMPLATE_READY, onTemplateReady); modVP.addEventListener(brightcove.api.events.MediaEvent.BEGIN, onMediaEventFired); modVP.addEventListener(brightcove.api.events.MediaEvent.CHANGE, onMediaEventFired); modVP.addEventListener(brightcove.api.events.MediaEvent.COMPLETE, onMediaEventFired); modVP.addEventListener(brightcove.api.events.MediaEvent.ERROR, onMediaEventFired); modVP.addEventListener(brightcove.api.events.MediaEvent.PLAY, onMediaEventFired); modVP.addEventListener(brightcove.api.events.MediaEvent.PROGRESS, onMediaProgressFired); modVP.addEventListener(brightcove.api.events.MediaEvent.STOP, onMediaEventFired); modCon.addEventListener(brightcove.api.events.ContentEvent.MEDIA_NOT_FOUND, onContentEventFired); // resize video if it is an iPhone/iPod if(KVPlr_device === KVDEVICE_IPHONE){ //alert('resize for iPhone'); var videoBlk = $('#videoBlock'); videoBlk.css('width','200px'); KVPlr_Resize_BC_Player(289,155); } }*/ /*function onMediaEventFired(evt) { //console.log("MEDIA EVENT: " + evt.type + " fired at position:" + evt.position) ; }*/ /*function onMediaProgressFired(evt) { //console.log("CURRENT POSITION: " + evt.position) ; KVPlr_Playback_Time = evt.position; KVPlr_processTimeChange(); }*/ /*function onContentEventFired(evt) { alert("Content Error "+ evt.media) }*/ /** * Parses parameters from URL to load mobile presentation * @private */ function KVPlr_getQueryParams(){ var vars = [], hash, hash1, kvID; var customParams; var embed = {}; var track = {}; var q = decodeURI(document.URL).split('?')[1]; if(q != undefined){ q = q.split('&'); for(var i = 0; i < q.length; i++){ hash = q[i].split('='); var val0 = hash[0]; var val1 = hash[1]; // now check for required vars if(val0 == "kv_id"){ embed.id = val1; KVPlr_embedId = embed.id; //alert("set embed.id to "+ val1); } else if(val0 == "kv_presentationId"){ track.presentationId = val1; }else if(val0 == "kv_presentationVersion"){ track.presentationVersion = decodeURIComponent(val1); }else if(val0 == "kv_duration"){ track.duration = decodeURIComponent(val1); }else if(val0 == "kv_slideCount"){ track.slideCount = decodeURIComponent(val1); }else if(val0 == "kv_licenseId"){ track.licenseId = decodeURIComponent(val1); }else if(val0 == "kv_subAccountId"){ track.subAccountId = decodeURIComponent(val1); }else if(val0 == "kv_trackUrl"){ track.trackUrl = decodeURIComponent(val1); } else if(val0 == "config"){ // skip it } else if(val0 == "kv_params"){ // decode it and then loop customParams = decodeURIComponent(val1); } else { // if here what could it be? // just do nothing } } embed.track = track; if(customParams){ // first look for a trailing #value (wufoo does this) var hashTagValue = customParams.split('#')[1]; var mainQueryParams = customParams.split('#')[0]; var q1; if(hashTagValue){ var hashObj = {name:"#",value:hashTagValue}; vars.push(hashObj); q1 = mainQueryParams.split("&"); } else { q1 = customParams.split("&"); } // now parse and stuff in the query parameters (vars) for(var j = 0; j < q1.length; j++){ hash1 = q1[j].split('='); var val1a = hash1[0]; var val1b = decodeURIComponent(hash1[1]); // check if it's kvID var regExp1 = /^kvid$/i; var match1 = (regExp1).test(val1a); if(match1){ kvID = val1b; } else { var tmpObj = {name:val1a,value:val1b}; vars.push(tmpObj); } } } } knowledgevisionLoader.loadMobilePresentation(embed, vars, kvID); } /** * Function to resize video and slides * note: we also have to resize when the orientation is changed (between portrait and landscape) * @param sliderVal * @param resizeReason */ function KVPlr_resize(sliderVal, resizeReason){ var sliderInt = parseInt(sliderVal)+50; // 50 to 150 var newHeight; var newVideoHeight; var newVideoWidth; var newSlideHeight; var newSlideWidth; var newVideoBlockWidth; var newSlideBlockWidth; var newSliderPosition; if (resizeReason == 'user') KVPlr_zoomOverride = true; // if the user zooms, go to override mode if (resizeReason == 'auto') { if (KVPlr_zoomOverride && (sliderInt == 100)) { return; // for auto resize, if auto-resizing to default size, don't turn off user size override } KVPlr_zoomOverride = false; // if user override is on, turn it off // these changes are made immediately (i.e. not animated) $('a[role*="slider"]').attr("aria-valuenow", sliderVal).attr("aria-valuetext", sliderVal).attr("title", sliderVal).css('left', sliderVal + "%"); } // compute the new sizes if (Math.abs(window.orientation) == 90) { // landscape newVideoHeight = (360*(200-sliderInt)/100); newVideoWidth = (480*(200-sliderInt)/100); newSlideHeight = (360*sliderInt/100); newSlideWidth =(480*sliderInt/100); newHeight = 544 - Math.max(newVideoHeight, newSlideHeight); newSliderPosition = "-240px"; } else { // portrait newVideoHeight = (270*(200-sliderInt)/100); newVideoWidth = (356*(200-sliderInt)/100); newSlideHeight = (270*sliderInt/100); newSlideWidth = (356*sliderInt/100); newHeight = 800 - Math.max(newVideoHeight, newSlideHeight); newSliderPosition = "-120px"; } newVideoBlockWidth = (100-(sliderInt/2)); newSlideBlockWidth = (sliderInt/2); $('#slideBlock').css('width',newSlideBlockWidth+'%'); $('#KVPlr_slideImage').css('width',newSlideWidth+'px').css('height',newSlideHeight+'px'); var $videoBlock = $('#videoBlock'); $videoBlock.css('width',newVideoBlockWidth+'%'); // alert("videoBlock width: "+newVideoBlockWidth + "% slideBlock width: "+newSlideBlockWidth+"%"); if(KVPlr_videoType != "brightcove"){ $('#KVPlr_video').css('width',newVideoWidth+'px').css('height',newVideoHeight+'px'); } else { var videoBlk = $videoBlock; videoBlk.css('width',newVideoWidth+'px'); videoBlk.css('height',newVideoHeight+'px'); KVPlr_Resize_BC_Player(newVideoWidth,newVideoHeight); } $('#sliderdiv').css('right', newSliderPosition); if (newHeight != KVPlr_chapterHt) { // if we change the height of the upper two elements, then we need to change height of chapters and footnotes $('#swrapper').css('height',newHeight+'px'); $('#swrapper2').css('height',newHeight+'px'); $('#swrapper3').css('height',newHeight+'px'); if (resizeReason != 'initialize') { setTimeout("KVPlr_myScroll.refresh()",2100); // after the 2-second animation completes, iScroll needs to be refreshed setTimeout("KVPlr_myScroll2.refresh()",2100); setTimeout("KVPlr_myScroll3.refresh()",2100); // ditto } KVPlr_chapterHt = newHeight; } } /** * Function to shred video.xml and load into global arrays * since this is called asynchronously, populating the other * sections of the page need to wait for it to complete. * For that reason, it calls the functions to load the sections. * @param xml */ function KVPlr_parseVideoXML (xml) { $(xml).find("tracks > track").first().find("cuePoints > cuePoint").each(function(index, cue){ KVPlr_cueTime[index] = parseFloat($(cue).find('time').text()); KVPlr_type[index] = $(cue).find('type').text(); KVPlr_key[index] = $(cue).find('settings > key').text(); KVPlr_zoom[index] = $(cue).find('settings > zoom').text(); KVPlr_title[index] = $(cue).find('metadata > title').text(); KVPlr_imgSrc[index] = $(cue).find('source > image').text(); KVPlr_footnote[index] = KVPlr_stripFont($(cue).find('metadata > footnote').text()); }); KVPlr_maxArray = KVPlr_cueTime.length; KVPlr_curArray = 0; KVPlr_launchSlides(0); KVPlr_launchVideo(); KVPlr_launchChapters(); KVPlr_launchFootnotes(); KVPlr_launchAttachments(); //show the selected component or leave footnotes if ($.trim(KVPLr_component) === 'attachment') { $('.component2').hide(); $('#KVPlr_attachmentsId').show(); } if (Math.abs(window.orientation) != 90) KVPlr_resize('50', 'initialize'); // add shadow to slider (which isn't assigned id by JqueryMobile) var $divRoleApplication = $('div[role*="application"]'); $divRoleApplication.css("-webkit-box-shadow", "5px 5px 5px #242424"); // set up event listeners $('a[role*="slider"]').mouseup(function(event, ui) { KVPlr_resize($(this).attr("aria-valuenow"), 'user'); }); $divRoleApplication.touchend(function(event, ui) { KVPlr_resize($('a[role*="slider"]').attr("aria-valuenow"), 'user'); }); $(window).bind('orientationchange', function(){ KVPlr_resize($('a[role*="slider"]').attr("aria-valuenow"), 'orientation'); }); // initialize iScroll //document.addEventListener('touchmove', function(e){ e.preventDefault(); }, false); KVPlr_myScroll = new iScroll('KVPlr_chapterDiv', { checkDOMChanges: false }); KVPlr_myScroll2 = new iScroll('KVPlr_footnoteDiv', { checkDOMChanges: false }); KVPlr_myScroll3 = new iScroll('KVPlr_attachmentsId', { checkDOMChanges: false }); KVPlr_myScroll.scrollToElement("#KVPlr_chapterA_0", '100ms'); // move scroll focus to initial chapter setTimeout(function() { $(".ui-grid-a").scrollLeft(0); $('.ui-grid-a').css('overflow', 'hidden'); if((KVPlr_device === KVDEVICE_IPHONE) || (KVPlr_device === KVDEVICE_ANDROID)) { $("#KVPlr_video").width("100%"); } } ,2100); } /** * Parses Attachments XML * @param xml */ function KVPlr_parseAttachXML (xml){ $(xml).find('attachments > attachment').each(function(index, attachment){ KVPlr_attachment[index] = $(attachment).find('url').text(); KVPlr_attachmentN[index] = $(attachment).find('displayName').text(); }); } /** * Returns X-Service-Authentication header * @param url {string} * @returns {object} */ function getXServiceAuthenticationHeader(url){ var serviceName; var serviceKey; var urlSplitter; if(url.indexOf(DEV_VIEW_KNOWLEDGEVISION_COM) != -1) { serviceName = DEV_SERVICE_NAME; serviceKey = DEV_SERVICE_KEY; urlSplitter = DEV_VIEW_KNOWLEDGEVISION_COM; } else if(url.indexOf(STAGE_VIEW_KNOWLEDGEVISION_COM) != -1){ serviceName = STAGE_SERVICE_NAME; serviceKey = STAGE_SERVICE_KEY; urlSplitter = STAGE_VIEW_KNOWLEDGEVISION_COM; } else if(url.indexOf(VIEW_KNOWLEDGEVISION_COM) != -1){ serviceName = SERVICE_NAME; serviceKey = SERVICE_KEY; urlSplitter = VIEW_KNOWLEDGEVISION_COM; } else { return {}; } var timestamp = Date.now(); var requestUrlWithoutDomain; var requestBody = ''; if(url.split(urlSplitter)[1]){ requestUrlWithoutDomain = url.split(urlSplitter)[1]; } var sha256part = CryptoJS.SHA256(serviceName + ':' + serviceKey + ':' + timestamp + ':' + requestUrlWithoutDomain + ':' + requestBody); return { 'X-Service-Authentication': 'Service-Request-Token ' + CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(serviceName + ':' + timestamp + ':' + sha256part.toString(CryptoJS.enc.Hex))) }; } /** * Function to asynchronously get config.xml from server. * It also sets X-Service-Authentication header */ function KVPlr_loadConfigXML() { // For testing only // var url = TEST_DATA__BC_IPAD_SAMPLE; // get the embed and query parameters KVPlr_getQueryParams(); var url = decodeURIComponent($.urlParam("config")); var embedInfo = KVPlr_embedId.split('KnowledgeVisionEmbeddedContent'); var embedId = embedInfo[1] || embedInfo[0]; url = url + (url.indexOf('?') != -1 ? '&' : '?') + "embedId=" + embedId; var headers = getXServiceAuthenticationHeader(url); setGoogleAnalytics(url, KVPlr_embedId); if(headers[X_SERVICE_AUTHENTICATION]) { // IE fix for window.location.origin if (!window.location.origin) { window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: ''); } if(window.location.origin.indexOf('http://') != -1 && url.indexOf('https://') != -1) { url = url.replace(/https/, 'http'); } else if(window.location.origin.indexOf('https://') != -1 && url.indexOf('http://') != -1) { url = url.replace(/http/, 'https'); } var authParamPrefix = url.indexOf('?') != -1 ? '&' : '?'; url = url + authParamPrefix + X_SERVICE_AUTHENTICATION + '=' + headers[X_SERVICE_AUTHENTICATION]; } // we need this to support IE8&9 $.support.cors = true; $.ajax({ type: "GET", url: url, dataType: "xml", async: "true", context: document, success: function(xml) { //alert("KVPlr_loadConfigXML :: config.xml fetched"); KVPlr_parseConfigXML(xml); }, error: function(xhr, ajaxOptions, thrownError){ alert(xhr.responseText); alert("thrownError"+ thrownError); } }); } function KVPlr_ConfigureVideoPlayer(xml){ KVPlr_videoType = $(xml).find("type").first().text(); KVPlr_videoURL = $(xml).find('sources > source').first().find('fileURL').text(); //alert("url is " + KVPlr_videoURL); if(KVPlr_videoURL !== ""){ KVPLr_loadedVideo = true; } if((KVPlr_videoType == "brightcove") && (navigator.userAgent.match(/(iPad)/i))){ // get the properties $(xml).find('sources > source > properties').find("property").each(function() { var videoPropertyName = $(this).attr("name"); var videoPropertyValue = $(this).attr("value"); switch(videoPropertyName) { case "videoID": KVPlr_BC_VideoID = videoPropertyValue; break; case "publisherID": KVPlr_BC_PublisherID = videoPropertyValue; break; case "playerID": KVPlr_BC_PlayerID = videoPropertyValue; break; case "cdnURL": KVPLR_BC_CdnURL = videoPropertyValue; break; } }); KVPlr_loadBCPlayer(); } } /** * Function to parse config.xml * @param xml */ function KVPlr_parseConfigXML(xml) { // get displayName from configXML, if not there use organization //var loadedVideo = false; var displayName = $(xml).find("project > metadata > displayName").text(); var title = $(xml).find("project > metadata > title").text(); var organization = $(xml).find("project > metadata > organization").text(); $('#prestitle').attr('innerHTML', displayName || title); document.title = displayName || title; KVPlr_parseAttachXML($(xml).find("staticContent > attachmentLists > attachmentList").first()); var $combo = $(xml).find('timeline>media'); KVPlr_comboVideoStream = $combo.find('type:contains(application/x-mpegURL)').parent().find('fileURL').text(); KVPlr_comboVideo = $combo.find('type:contains(application/mp4)').parent().find('fileURL').text(); //for supporting old presentations wich video type is "video/mp4" if(!KVPlr_comboVideo){ KVPlr_comboVideo =$combo.find('type:contains(video/mp4)').parent().find('fileURL').text(); } KVPlr_videoDuration = $(xml).find("project > metadata > stats > duration").text(); KVPlr_ConfigureVideoPlayer($(xml).find('timeline > sequences > sequence > segments > segment').first().find('media')); var $templateProperty = $(xml).find('id:contains(Mobile Player Template)').parent(); KVPLr_component = $templateProperty.find("value").text(); KVPlr_parseVideoXML($(xml).find('timeline')); // didn't see a mobile element in config.xml, explain that mobile is not supported for this presentation if (!KVPLr_loadedVideo) { $('#page').attr('innerHTML', PRESENTATION_NOT_AVAILABLE_FOR_MOBILE); } } function KVPlr_CheckPlaybackPercentage(playbackTime){ if((KVPlr_videoDuration > 0) && (playbackTime > 0)){ var playbackPercent = (playbackTime / KVPlr_videoDuration) *100; if((playbackPercent >= KVPlr_nextPlaybackToReport) && (playbackPercent >= KVPlr_lastPlaybackReported)){ //track it KVPlr_trackPlayback(playbackPercent); KVPlr_lastPlaybackReported = KVPlr_nextPlaybackToReport; KVPlr_nextPlaybackToReport = KVPlr_nextPlaybackToReport + KVPlr_playbackInterval; // if the user scrubbed way ahead, keep adding to the next to report until it's set // for the next interval past current position while(KVPlr_nextPlaybackToReport < playbackPercent) { KVPlr_nextPlaybackToReport = KVPlr_nextPlaybackToReport + KVPlr_playbackInterval; } } } } /** * Function called continuously with event listener listening for changes * to the video elements 'currentTime' property */ function KVPlr_processTimeChange() { var currentTime; if(KVPlr_videoType != "brightcove") { currentTime = parseFloat($("#KVPlr_video").attr("currentTime")); // currentTime from video element } else { currentTime = KVPlr_Playback_Time; } if (KVPlr_gotoCurrentTime >= 0.0) { if (currentTime <= KVPlr_gotoCurrentTime) { currentTime = KVPlr_gotoCurrentTime; // special kludge to compensate for strange currentTime behavior // where going to a particular time actually takes you to a time // a few seconds earlier } else { KVPlr_gotoCurrentTime = -10.0; // turn off kludge, we're past where it's needed } } KVPlr_CheckPlaybackPercentage(currentTime); // check to see if we have moved to a new chapter, slide, zoom, or footnote if (KVPlr_curArray >= 0) { if (currentTime >= KVPlr_cueTime[KVPlr_curArray]) { if (KVPlr_curArray >= KVPlr_maxArray) { return; // no change } else { if (currentTime < KVPlr_cueTime[KVPlr_curArray+1]) return; // no change } } } // if here, need to change current slide var titleIndex = -1; var footnoteIndex = -1; var newZoom; var curZoom; KVPlr_curArray=-1; for (var i=0;i<=KVPlr_maxArray-1;i++) { if (KVPlr_title[i]) titleIndex = i; // title may come from earlier slide, so store it if (KVPlr_footnote[i]) footnoteIndex = i; // ditto for footnote if (currentTime >= KVPlr_cueTime[i] && KVPlr_curArray == -1) { if ((i >= KVPlr_maxArray-1)) { KVPlr_curArray = i; // new current slide must be last slide } else if (currentTime < KVPlr_cueTime[i+1]) { KVPlr_curArray = i; // found the new current slide } // if we found the new slide, process it if ((KVPlr_curArray >= 0) && (KVPlr_curArray != KVPlr_visibleIndex)) { //console.log("\n*******time to change to slide index " + KVPlr_curArray); $("#KVPlr_slideImage").attr("src", KVPlr_imgSrc[KVPlr_curArray]); // change the image in the slide KVPlr_visibleIndex = KVPlr_curArray; newZoom = parseFloat(50 + parseInt(50 * parseFloat(KVPlr_zoom[KVPlr_curArray]))); // 0 - 100 curZoom = parseFloat($('a[role*="slider"]').attr("aria-valuenow")); // 0 - 100 // if title (chapter) has changed, process that change if (titleIndex>=0 && titleIndex != KVPlr_chapterIdx) { // un-highlight old chapter if (KVPlr_chapterIdx >= 0) $("#KVPlr_chapterA_" + KVPlr_chapterIdx).attr("class", "ui-li ui-li-divider ui-bar-d"); KVPlr_chapterIdx = titleIndex; // highlight new chapter $("#KVPlr_chapterA_" + titleIndex).attr("class", "ui-li ui-li-divider ui-bar-e"); KVPlr_myScroll.scrollToElement("#KVPlr_chapterA_" + KVPlr_chapterIdx, '100ms'); // chapter changed, scroll to new chapter } // if note has change, process it if (footnoteIndex != KVPlr_footnoteIdx) { var $KVPlrFootnoteDiv = $("#KVPlr_footnoteDiv"); if (footnoteIndex>=0) { $KVPlrFootnoteDiv.attr("innerHTML", KVPlr_footnote[footnoteIndex]); $KVPlrFootnoteDiv.unbind(); // first remove any previously bound click events $KVPlrFootnoteDiv.bind("click", function(event){ var footnoteUrl = String(KVPlr_parseUrl(KVPlr_footnote[footnoteIndex])); if(footnoteUrl) { KVPlr_trackFootnote(footnoteUrl); } }); } else { $KVPlrFootnoteDiv.attr("innerHTML", ""); $KVPlrFootnoteDiv.unbind(); } KVPlr_footnoteIdx = footnoteIndex; } // if zoom change, process it if (curZoom != newZoom && (newZoom != 50 || !KVPlr_zoomOverride)) { KVPlr_resize (newZoom, 'auto'); // KVPlr_resize will refresh the scroll } else if (footnoteIndex != KVPlr_footnoteIdx) { KVPlr_myScroll2.refresh(); // footnote changed, but size not changed, still need to refresh the scroll } //track slide change KVPlr_trackCuePoint(KVPlr_curArray, KVPlr_title[KVPlr_curArray], KVPlr_type[KVPlr_curArray], KVPlr_zoom[KVPlr_curArray], KVPlr_cueTime[KVPlr_curArray]); } } } } ////////////////////////////////////////////////// // One-time functions called to launch elements // ////////////////////////////////////////////////// /** * Function (called once) to put video url into video element * and set up listener for changes to currentTime */ function KVPlr_launchVideo() { // determine which video to load - based on device var videoToLoad; if(navigator.userAgent.match(/(iPad)/i)) { KVPlr_device = KVDEVICE_IPAD; } else if (navigator.userAgent.match(/(iPhone|iPod)/i)){ KVPlr_device = KVDEVICE_IPHONE; } else if (navigator.userAgent.match(/(android)/i)){ KVPlr_device = KVDEVICE_ANDROID; } else { KVPlr_device = KVDEVICE_PHONE; } if (KVPlr_device === KVDEVICE_IPAD){ videoToLoad = KVPlr_videoURL; } else if (KVPlr_device === KVDEVICE_IPHONE){ videoToLoad = KVPlr_comboVideoStream; } else if (KVPlr_device === KVDEVICE_ANDROID){ videoToLoad = KVPlr_comboVideo; } else { videoToLoad = KVPlr_comboVideo; } var $KVPlrVideo = $('#KVPlr_video'); $KVPlrVideo.append(' '); if(KVPlr_device === KVDEVICE_IPHONE){ $KVPlrVideo.append(' '); $KVPlrVideo.append(' '); } $KVPlrVideo.append(' '); // default fallback $KVPlrVideo.bind('timeupdate', function() { KVPlr_processTimeChange(); }); $KVPlrVideo.bind('ended', function() { // if we need to do clean up or track end....do it here }); $KVPlrVideo.bind('durationchange', function() { KVPlr_videoDuration = $("#KVPlr_video").attr("duration"); }); //UI Reformat for the iPhone. if((KVPlr_device === KVDEVICE_IPHONE) || (KVPlr_device === KVDEVICE_ANDROID)) { KVPlr_resize = function () {}; $("#sliderBlock").remove(); $("#slideBlock").remove(); $(".ui-grid-a").removeClass("ui-grid-a").addClass("ui-grid-solo"); $(".ui-block-a").removeClass("ui-block-a").addClass("ui-block-solo"); $(".ui-block-b").removeClass("ui-block-b").addClass("ui-block-solo"); $("#FootnotesWidth").width("100%"); $("#ChaptersWidth").width("100%"); $("#AttachmentsWidth").width("100%"); } } function KVPlr_launchSlides() { $("#KVPlr_slideImage").attr("src", KVPlr_imgSrc[KVPlr_curArray]); } function KVPlr_launchChapters() { var a; var chapNo=0; var div = document.getElementById('KVPlr_chapterDiv'); for (var i=0;i<=KVPlr_maxArray;i++) { if (KVPlr_title[i]) { chapNo++; a = document.createElement('div'); a.id = 'KVPlr_chapterA_' + i; a.innerHTML = chapNo + '. ' + KVPlr_title[i]; div.appendChild(a); if (i == 0) { $("#KVPlr_chapterA_" + i).attr("class", "ui-li ui-li-divider ui-bar-e"); KVPlr_chapterIdx = i; } else { $("#KVPlr_chapterA_" + i).attr("class", "ui-li ui-li-divider ui-bar-d"); } $('#KVPlr_chapterA_' + i).bind( "click", { slideNo: i }, function( event ){ if (KVPlr_chapterIdx >= 0) $("#KVPlr_chapterA_" + KVPlr_chapterIdx).attr("class", "ui-li ui-li-divider ui-bar-d"); KVPlr_chapterIdx = event.data.slideNo; // sets "selected state in view $("#KVPlr_chapterA_" + event.data.slideNo).attr("class", "ui-li ui-li-divider ui-bar-e"); // do quickly to provide feedback // updates playback to tiome associated with chapter cue if(KVPlr_videoType != "brightcove"){ $('#KVPlr_video').attr('currentTime', KVPlr_cueTime[event.data.slideNo]); } else { // tell SmartPlayer to seek to time modVP.seek(KVPlr_cueTime[event.data.slideNo]); } KVPlr_gotoCurrentTime = KVPlr_cueTime[event.data.slideNo]; // track the chapter click KVPlr_trackChapter(KVPlr_chapterIdx, KVPlr_title[KVPlr_chapterIdx], KVPlr_type[KVPlr_chapterIdx], KVPlr_zoom[KVPlr_chapterIdx], KVPlr_cueTime[KVPlr_chapterIdx]); } ); } } $('#KVPlr_chapterDiv').page(); } function KVPlr_launchAttachments() { var a; var count=KVPlr_attachment.length; var div = document.getElementById('KVPlr_attachmentDiv'); for (var i=0;i<=count;i++) { if (KVPlr_attachmentN[i]) { a = document.createElement('div'); a.id = 'KVPlr_attachA_' + i; // a.innerHTML = ''+KVPlr_attachmentN[i]+''; a.innerHTML = ''+KVPlr_attachmentN[i]+''; div.appendChild(a); $("#KVPlr_attachA_" + i).attr("class", "ui-li ui-li-divider ui-bar-d"); } } $('#KVPlr_attachmentDiv').page(); } /** * Loads up the first footnote - only one footnote is displayed at a time. * Logic to change footnotes is above in KVPlr_porcessTimeChange */ function KVPlr_launchFootnotes() { if (KVPlr_footnote[0]) { var $KVPlrFootnoteDiv = $("#KVPlr_footnoteDiv"); $KVPlrFootnoteDiv.attr("innerHTML", KVPlr_footnote[0]); // add a click listener to send tracking event for footnote click $KVPlrFootnoteDiv.bind("click", function(event){ var footnoteUrl = String(KVPlr_parseUrl(KVPlr_footnote[0])); if(footnoteUrl) { KVPlr_trackFootnote(footnoteUrl); } }); } } /////////////////////////////// // End of one-time functions // /////////////////////////////// /** * Utility function to process queryString * @param name */ $.urlParam = function(name){ var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href); if (!results) { return 0; } return results[1] || 0; }; /** * Takes in the chunk of HTML that was parsed from the Video.xml * and is currently in the DOM and returns the url from the href attribute. */ function KVPlr_parseUrl(htmlIn){ var url = $("div#KVPlr_footnoteDiv a[href]"); if(url){ return url[0].href; } else { return null; } } function KVPlr_stripFont(oldString) { var newString = oldString; var i = (newString.toLowerCase()).indexOf('= 0 || j >= 0) { if (i >= 0 && (i < j || j < 0)) { l = i; } else { l = j; } r = newString.indexOf('>', l); if (l == 0) { newString = newString.substr(r+1); } else if (r < newString.length - 1) { newString = newString.substr(0,l) + newString.substr(r+1); } else { newString = newString.substr(0,l); } i = (newString.toLowerCase()).indexOf(' -1; var isStage = configUrl.indexOf('//stage-') > -1; var isLocal = window.location.href.indexOf('localhost') > -1; var pageUrl = 'presentation/' + (embedId || ''); if(isLocal || isDev || isStage) { window.ga('create', 'UA-20738830-5', 'auto'); window.ga('send', 'pageview', pageUrl); } else { window.ga('create', 'UA-20738830-4', 'auto'); window.ga('send', 'pageview', pageUrl); } } }