/**
* 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);
}
}
}