var apiURL = "https://api.businesswire.com/contentapi"; var imageURL = "https://www.businesswire.com/images/restcontent_loading.gif"; /** * ensure all of the variables we need are here; load container page * @param uri */ function loadContainerPage(uri){ if(!varExists("apiURL")){ alert("No api URL provided - sleepycat-properties.js file must be included."); } var encodedURI = encodeURIComponent(uri); var containerSrc = apiURL + "/containerpage/" + encodedURI; replaceBwContent(containerSrc); } /** * returns true if variable defined; else false * @param varToCheck * @returns {Boolean} */ function varExists(varToCheck){ if(typeof(window[varToCheck]) == 'undefined'){ return false; }else{ return true; } } function replaceBwContent(src) { return replaceBwElement('#bwContent', src); } var bwComponents = { bwEventLinks: apiURL + '/profile/bwEventLinks/', bwPressKitLinks: apiURL + '/profile/bwPressKitLinks/', bwEventDetails: apiURL + '/event/bwEventDetails/', bwEventLogo: apiURL + '/event/bwEventLogo/', bwPressKitLogo: apiURL + '/presskit/bwPressKitLogo/', bwEventDesc: apiURL + '/event/bwEventDesc/', bwPressKitDesc: apiURL + '/presskit/bwPressKitDesc/', bwEventTitle: apiURL + '/event/bwEventTitle/', bwPressKitBooth: apiURL + '/presskit/bwPressKitBooth/', bwPressKitTitle: apiURL + '/presskit/bwPressKitTitle/', bwEventSharing: apiURL + '/event/bwEventSharing/', bwPressKitSharing: apiURL + '/presskit/bwPressKitSharing/', bwNewsHeadlines: apiURL + '/headlines/bwNewsHeadlines/', bwNewsRelease: apiURL + '/release/bwNewsRelease/', bwEventNavigation: apiURL + '/event/bwEventNavigation/', bwPressKitNavigation: apiURL + '/presskit/bwPressKitNavigation/', bwBackToEvent: apiURL + '/event/bwBackToEvent/', bwEventPressKits: apiURL + '/event/bwEventPressKits/', bwPressKitAddress: apiURL + '/profile/bwPressKitAddress/', bwPressKitFiles: apiURL + '/presskit/bwPressKitFiles/', bwPressKitContacts: apiURL + '/profile/bwPressKitContacts/', // The following are view only components, meaning they don't have an underlying model but are used // for the layout or presentation of the page only. Examples include search or backTo links bwSearch: apiURL + '/view/bwSearch/', bwBackTo: apiURL + '/view/bwBackTo/', bwNewPopularNavigation: apiURL + '/view/bwNewPopularNavigation/' }; function getBwComponentURL(component) { return bwComponents[component]; } /** * populate the bw Elements * criteria is in the parameters for the page. Each model has it's own criteria * * Example for a pressKit criteria * presskit=IBC2010/ibc2010 * * For headlines * headlines=event/IBC2010?headlines.page=3 * @param criteria */ function populateBwElements(criteria) { bwJQuery(function (){ bwJQuery('div[class^="bw"]').each(function() { var bwObj = this.className; // check if it's a known component if (bwObj in bwComponents) { // check if criteria is available for the component var criteriaValue = getCriteriaForComponent(criteria, bwObj); if (criteriaValue != null) { replaceBwElement('.' + bwObj, bwComponents[bwObj] + criteriaValue); } else if (isViewComponent(bwObj)) { replaceBwElement('.' + bwObj, bwComponents[bwObj]); } } }); }); } function populateTargetBwElements(releaseTargetClass, criteria) { bwJQuery(function (){ var bwObj = "bwNewsRelease"; var criteriaValue = getCriteriaForComponent(criteria, bwObj); if (criteriaValue != null) { replaceBwElement(releaseTargetClass, bwComponents[bwObj] + criteriaValue); } }); } function isViewComponent(component) { if (bwComponents[component] != null && bwComponents[component].indexOf(apiURL + '/view/') == 0) { return true; } else { return false; } } function getComponentCriteria(component) { return getCriteriaForComponent(containerPage.split('?')[1], component); } function getModelCriteria(model) { var criteria = containerPage.split('?')[1]; var criterias = criteria.split('&'); // Can not use foreach syntax - prototyped methods on Array will break // our code // for (idx in criterias) { var len = criterias.length; for(var i=0; i < len; i++){ var modelCriteria = criterias[i]; var split = modelCriteria.split('='); if (split[0] == model) { if ('view' == model){ return split[1] + getQueryParamsForModel(criteria, model); } else { return decodeURIComponent(split[1]) + getQueryParamsForModel(criteria, model); } } } } /** * Use this if you have a select box that changes the headline config. * @param selector jQuery type selector of select list */ function setVnsHeadlineSelect(selector) { if (containerPage.indexOf('headlines.searchTerm=') == -1) { var vnsPatt = /vns\/\d+\/(\d+)/; var vnsId = vnsPatt.exec(getModelCriteria('headlines')); if (vnsId != null && vnsId.length > 1) { bwJQuery(selector).val(vnsId[1]); } } } /** * TODO: Refactor this to put all criteria into an Object, then pull from that object. * Extract the specific criteria for a component from * the URL containing all the criteria for the page * @param criteria the entire page criteria such as 'event=IBC2010&headlines=event%2FIBC2010' * @param component the component such as 'bwEventTitle' * @returns criteria URL decoded for normal components, not decoded for view components */ function getCriteriaForComponent(criteria, component) { var criterias = criteria.split('&'); // Can not use foreach syntax - prototyped methods on Array will break // our code // for (idx in criterias) { var len = criterias.length; for(var i=0; i < len; i++){ var modelCriteria = criterias[i]; var split = modelCriteria.split('='); var criteriaModel = split[0]; // check if this model is appropriate for the Component OR it's a view component. if (bwComponents[component].indexOf(criteriaModel + "/" + component) != -1) { // console.log( decodeURIComponent(split[1]) + getQueryParamsForModel(criteria, criteriaModel)); return decodeURIComponent(split[1]) + getQueryParamsForModel(criteria, criteriaModel); } else if (bwComponents[component].indexOf("view/" + criteriaModel) != -1) { // console.log(split[1] + getQueryParamsForModel(criteria, 'view')); return split[1] + getQueryParamsForModel(criteria, 'view'); } } return null; } /** * Get any params for the model * Example: headlines.page=5 * @param criteria event=IBC2010&presskit=IBC2010/ibc2010&profile=IBC2010/ibc2010&headlines=presskit/IBC2010/ibc2010&bwTabContent=bwNewsHeadlines&headlines.page=2 * @param model headlines or view */ function getQueryParamsForModel(criteria, model) { var params = criteria.split('&'); var modelParams = new Array(); // Can not use foreach syntax - prototyped methods on Array will break // our code // for (idx in params) { var len = params.length; for(var i=0; i < len; i++){ if (params[i].indexOf(model + '.') == 0) { modelParams[modelParams.length] = params[i]; } } if (modelParams.length != 0) { return '?' + modelParams.join('&'); } else { return ''; } } /** * Replace the content of a bw (div) element, optionally adding a new element in the process * @param selector * @param src * @param newBwElement Optional - if specified, create this newBwElement in the selector. * This is currently used with tab navigation (the old content is removed and a new element is created) * @returns {Boolean} */ function replaceBwElement(selector, src, newBwElement) { var element = bwJQuery(selector); // verify the element if (!element.length) { // the bwTabContent may not exist //alert('Cannot find element: ' + selector); return false; } element.empty(); if (newBwElement != undefined) { element.append('
'); } else { element.prepend(''); } element.append(''); return false; } function removeParameter(url, param) { param = param.replace('.','\\.'); // TODO: loop through all the regex special chars... url = url.replace(new RegExp("(&|\\?)" + param + "=[^&]*&?", "g"), "$1"); // leave the ? or & url = url.replace(new RegExp("(.*)(&|\\?)$"), "$1"); // remove a possible trailing & or ? return url; } function addParameter(url, param, value) { url = removeParameter(url, param); // split at the &bwBackTo to add the param to the 'current' page var curBack = url.split("&bwBackTo="); if (curBack[0].indexOf('?') > 0) { curBack[0] += '&'; } else { curBack[0] += '?'; } curBack[0] += param + '=' + value; if (curBack.length > 1) { return curBack[0] + "&bwBackTo=" + curBack[1]; } else { return curBack[0]; } } function getBwReleaseParams() { var bwReleaseParams = window.location.href.match(/(\?|&)BusinessWireRelease=([^&$]+)/); if (bwReleaseParams != null) { var idAndLang = bwReleaseParams[2].split('-'); return new Array(idAndLang[0],idAndLang[1]); } } function navToReleaseView(releaseId, lang, vnsId, releaseTargetClass, clientReleaseDivId, clientReleaseDivClass) { // use the current page without query as a starting point... var lastSlash = currentPage.lastIndexOf("/"); var vnsIdParam = ""; if (vnsId !== undefined || vnsId != "") { vnsIdParam = "&release.vnsId=" + vnsId; } // at this point, we need a way to navigate back to the current page (event or presskit or headlines) if (releaseTargetClass === undefined || releaseTargetClass == "") { var encodedURI = encodeURIComponent(currentPage.substr(0, lastSlash + 1) + "release_container.html?release=" + releaseId + "/" + lang + vnsIdParam + "&bwBackTo=" + encodeURIComponent(containerPage)); var containerSrc = apiURL + "/containerpage/" + encodedURI; replaceBwContent(containerSrc); } else { var encodedURI = encodeURIComponent(currentPage.substr(0, lastSlash + 1) + "release_container.html?release=" + releaseId + "/" + lang + vnsIdParam + "&release.releaseTargetClass=" + releaseTargetClass + "&release.clientReleaseDivId=" + clientReleaseDivId + "&release.clientReleaseDivClass=" + clientReleaseDivClass); var containerSrc = apiURL + "/containerpage/" + encodedURI; $("." + releaseTargetClass).empty(); $("." + releaseTargetClass).append(''); } return false; } // This is called when 'Home' button is clicked on targetted release. This reverts the client's content div back and removes our release function navReturn(clientReleaseTarget, releaseTargetClass) { if (clientReleaseTarget != "") { $(clientReleaseTarget).fadeIn(2000); $('.' + releaseTargetClass).empty(); } } // This is called when a targetted release loads. This hides the client's content div so our release is shown function navHideClientTarget(clientReleaseTarget, releaseTargetClass) { if (clientReleaseTarget != "") { $(clientReleaseTarget).fadeOut(2000); } if (clientReleaseTarget == "") { $('html, body').animate({ scrollTop: $('.' + releaseTargetClass).offset().top }, 'fast'); } else { $('html, body').animate({ scrollTop: $(clientReleaseTarget).offset().top }, 'fast'); } } function trackEvent(action, label, value){ postToAnalytics('_trackEvent', action, label, value); } function postToAnalytics(category, action, label, value){ //make sure we have google analytics... if(typeof _gaq == 'object' && typeof _gaq.push == 'function'){ _gaq.push([category, action, label, value]); } } var iconDir='https://www.businesswire.com/images/icons/'; var bwJQuery = jQuery.noConflict(); // document.write(''); bwJQuery('script[src*="businesswire.com/contentapi"]').after(''); var tmpCustDollarVar = undefined; if(typeof $ != 'undefined'){ tmpCustDollarVar = $; } bwJQuery.ajaxSetup({cache: true}); var releaseParams = getBwReleaseParams(); if (releaseParams != null) { var currentPage = 'pharmatutor'; var containerPage = 'pharmatutor'; navToReleaseView(releaseParams[0], releaseParams[1]); } else { loadContainerPage('pharmatutor'); } if (typeof tmpCustDollarVar != 'undefined'){ $ = tmpCustDollarVar; }