// Licensed Materials - Property of IBM // // IBM Cognos Products: cpscrn // // (C) Copyright IBM Corp. 2013, 2014 // // US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. // // (function() { // define namespace if (!window.com_ibm_cognos_cps){ com_ibm_cognos_cps = {} } if (com_ibm_cognos_cps.ApplicationContext){ // Stop if the ApplicationContext is already defined. return; } var _F_Array = { indexOf: function(array, value, begin, strict) { for (var i = +begin || 0, l = array.length; i < l; i++) { if (array[i] === value || strict && array[i] == value) { return i; } } return -1; }, unique: function (array, strict) { var a = [], i, l = array.length; for (i = 0; i < l; i++) { if (this.indexOf(a, array[i], 0, strict) < 0) { a.push(array[i]); } } return a; }, forEach: function(array, func, thisArg) { if (typeof func == "function") { var i, v, l = array.length; if (thisArg === undefined) { for (i = 0; i < l; i++) { func(array[i]); } } else { for (i = 0; i < l; i++) { func.call(thisArg, array[i]); } } } }, insert: function(array, i, obj) { if (i !== undefined && obj !==undefined) { array.splice(i, 0, obj); } }, remove: function(array, obj) { if (obj !== undefined) { var i = this.indexOf(array, obj); if (i >= 0) { array.splice(i, 1); return obj; } } return null; }, removeAt: function(array, i) { if (i !== undefined) { array.splice(i, 1); } } }; // Helper object used to create the xmlHttpRequest based on the current browser var CPSConfig = { browser: 'unknown', browserVersion: 'unknown', OS: 'unknown', xmlHttpDefault: null, emptyFunction:function(){}, initialize: function() { this.browser = this.lookup(this.browsers).toLowerCase() || 'unknown'; this.browserVersion = this.parseVersion(navigator.userAgent) || this.parseVersion(navigator.appVersion) || 'unknown'; this.OS = this.lookup(this.systems) || 'unknown'; this.xmlHttpDefault = this.findXMLHttpActiveXVersion(); }, lookup: function(data) { var i, l = data.length; for (i = 0; i < l; i++) { this.versionKey = data[i].partialKey || data[i].identity; var agent = data[i].agent; if (agent) { if (agent.indexOf(data[i].key) != -1) return data[i].identity; } else if (data[i].prop) return data[i].identity; } }, parseVersion: function(s) { var index = s.indexOf(this.versionKey); if (index == -1) return; return parseFloat(s.substring(index + this.versionKey.length + 1).replace(/[^\d\.\-\+]/g, '_')); //sanitize before parse to avoid XSS vulnerability! }, findXMLHttpActiveXVersion: function() { if (window.ActiveXObject) { var i, l = this.xmlHttpVersions.length; for (i = 0; i < l; i++) { try { // Try and create the ActiveXObject for Internet Explorer, if it doesn't work, try again. var xmlhttp = new ActiveXObject(this.xmlHttpVersions[i]); if (xmlhttp) return this.xmlHttpVersions[i]; } catch (e) { // this ActiveX is not there, continue with next one in list } } } return null; }, browsers: [ { agent: navigator.userAgent, key: 'MSIE', identity: 'Explorer', partialKey: 'MSIE' }, { agent: navigator.userAgent, key: 'Firefox', identity: 'Firefox' }, { agent: navigator.userAgent, key: 'Gecko', identity: 'Mozilla', partialKey: 'rv' }, { agent: navigator.userAgent, key: 'Mozilla', identity: 'Netscape', partialKey: 'Mozilla' }, { agent: navigator.userAgent, key: 'Netscape', identity: 'Netscape' }, { prop: window.opera, identity: 'Opera' }, { agent: navigator.vendor, key: 'Apple', identity: 'Safari' } ], systems: [ { agent: navigator.platform, key: 'Win', identity: 'Windows' }, { agent: navigator.platform, key: 'Mac', identity: 'Mac' }, { agent: navigator.platform, key: 'Linux', identity: 'Linux' } ], xmlHttpVersions: [ 'Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.3.0', 'Msxml2.XMLHTTP', 'Microsoft.XMLHTTP' ] } CPSConfig.initialize(); /* Helper DOM utils. */ com_ibm_cognos_cps._F_DOM = { addEventListener: function (node, type, callback, capture) { type = type.toLowerCase(); if (node.addEventListener) { node.addEventListener(type, callback, capture); } else if (node.attachEvent) { node.attachEvent('on' + type, callback); } else { node['on' + type] = callback; } }, selectNodes: function(node, xpath) { if (document.all) { var arr = new Array(); var nodes = node.selectNodes(xpath); var i, l = nodes.length; for (i=0; i<l; i++) { arr.push(nodes.item(i)); } return arr; } else { var doc = (node.ownerDocument) ? node.ownerDocument : node; var results = doc.evaluate(xpath, node, doc.createNSResolver(doc.documentElement), XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); if (results) { var arr = new Array(); var node = results.iterateNext(); while (node != null) { arr.push(node); node = results.iterateNext(); } return arr; } return null; } }, selectSingleNode: function (node, xpath) { if (document.all) { return node.selectSingleNode(xpath); } else { var doc = (node.ownerDocument) ? node.ownerDocument : node; var results = doc.evaluate(xpath, node, doc.createNSResolver(doc.documentElement), XPathResult.FIRST_ORDERED_NODE_TYPE, null); if (results && results.singleNodeValue) return results.singleNodeValue; return null; } }, getAttribute: function(node, name) { return node.getAttribute(name); }, text: function(node) { function deepScanText(node) { var v = ''; var n = node.firstChild; while (n != null) { if (n.nodeType == 3) v += n.nodeValue; else if (n.nodeType == 4) v += n.data; else if (n.nodeType == 1) v += deepScanText(n); n = n.nextSibling; } return v; } if (node == null || node === undefined) return ''; if (document.all) return node.text; else if (node.nodeValue) return node.nodeValue; return deepScanText(node); }, parseXml: function(xmlString) { var xmlDoc = null; if (window.ActiveXObject){ xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); xmlDoc.async="false"; xmlDoc.loadXML(xmlString); } if (xmlDoc == null){ var parser = new DOMParser(); xmlDoc = parser.parseFromString(xmlString,"text/xml"); } return xmlDoc; } } /* This class provides the APS that enables our content to work in enterprise portals. getWebContentResource: return an absolute url that will be used to retrieve a webcontent resource getGatewayResource: return an absolute url that will be used to retrieve a gateway resource getProxiedResource: return a url that can be used to do ajax request without running into cross domain issues getXHR: creates an xmlHttpRequest object. */ CPSWebApplication = com_ibm_cognos_cps.ApplicationContext = function(spec){ if (spec){ this.initialize(spec); } } //013 Create event handler map CPSWebApplication.eventHandler = {}; CPSWebApplication.prototype = com_ibm_cognos_cps.ApplicationContext.prototype = { /* * Sets the configuration object */ initialize: function(spec){ if (this.initialized){ return; } this.eventSubscriptions = {}; this.properties = {}; //deprecated this.id = spec.namespacePrefix ? spec.namespacePrefix : ''; this.userpreferences = spec.userPreferences; if (!this.userprefjson){ this.userprefjson = {}; } this.settings = spec.applicationSettings; if (!this.settings){ this.settings = {}; } this.cssmapping = spec.cssMapping; if (!this.cssmapping){ this.cssmapping = {}; } this.events = spec.events; if (!this.events){ this.events = {listen:[], publish:[]}; } this.navstate = spec.navigationState; if (!this.navstate){ this.navstate = {}; } this.navstatedirty = false; this.webcontent = spec.webcontent; this.gateway = spec.gateway; this.getProperty = function(name){ if (spec[name]){ return spec[name]; }else{ return this.properties[name]; //deprecated } } if (!com_ibm_cognos_cps.ApplicationContext.instances){ com_ibm_cognos_cps.ApplicationContext.instances = []; } this.instanceIndex = com_ibm_cognos_cps.ApplicationContext.instances.length; com_ibm_cognos_cps.ApplicationContext.instances.push(this); // Check if we need to do a client login var features = this.getProperty('features'); if (features && features.indexOf('BrowserLogin') != -1){ this.login(); } this.initialized = true; }, /* * Return the portlet's unique ID, ex. "p134677430" * This is prepended to all element ids in the portlet's html, and changes each page load */ getID: function(){ return this.id; }, /* * Get the URI root for web content, ex. "http://exampleserver/cognos/" */ getWebContentURI:function(){ return this.webcontent; }, setWebContentURI:function(value){ this.webcontent=value; }, /* * get the URI for the gateway, ex. "http://exampleserver/cognos/cgi-bin/cognos.cgi" */ getGatewayURI:function(){ return this.gateway; }, setGatewayURI:function(value){ this.gateway=value; }, /* * Get the value of the named setting. * Settings include things such as the portlet alias, and any settings the user can set from the portlet config page. */ getSetting:function(name){ var value = this.settings[name]; if (value === undefined){ // The legacy sdk portlet appends 'sdk_' to the custom properties if (name.indexOf('sdk_') != 0) { name = 'sdk_' + name; } value=this.settings[name]; } if(value && (typeof value == 'object') && value.length != undefined){ value = value[0]; } return value; }, getMessage:function(resourceID) { var message = eval(resourceID); return message; }, getSettingValues:function(name){ var value = this.settings[name]; if (value === undefined){ // The legacy sdk portlet appends 'sdk_' to the custom properties if (name.indexOf('sdk_') != 0) { name = 'sdk_' + name; } value=this.settings[name]; } if(value && (typeof value == 'string')){ var arr = []; arr.push(value); value = arr; } return value; }, /* * get css mappings, used to change css classes */ getCssMapping:function(origialCss){ return this.cssmapping[origialCss]; }, /* * get user preferences, which are set from the containing portal */ getUserPreference:function(name){ return this.userpreferences[name]; }, /* * Retrieve a value from the navigational state of the portlet. */ getNavState:function(name){ return this.navstate[name]; }, /* * Add key=value type information to the navigational state of the portlet, * This allows state to be kept across page loads within the user session. * Both key and value must be string type data. * May cause delays when unloading the page, to write the changed state back */ setNavState:function(name, value){ this.navstate[name] = value; if (! this.navstatedirty){ this.navstatedirty = true; document.body.onbeforeunload = this._hitch(this, this._writeNavState); } }, /* * This removes the key=value pair from the navigational state of the portlet. * Keys removed in this manner will no longer appear in the user session. * May cause delays when unloading the page, to write the changed state back */ delNavState:function(name){ delete this.navstate[name]; if (! this.navstatedirty){ this.navstatedirty = true; document.body.onbeforeunload = this._hitch(this, this._writeNavState); } }, /* * private helper function for setNavState() and delNavState() */ _writeNavState:function(){ var query = []; for (key in this.navstate) { query.push(encodeURIComponent(key) + '=' + encodeURIComponent(this.navstate[key])); } var url = this._getActionURI(query.join('&')); var xhr = this._getXHR(); xhr.open('GET', url, false); xhr.send(); }, subscribe: function(name, func){ this.eventSubscriptions[name] = func; }, publish: function(name, data){ var invoked = false; for (var i = 0 ; i < com_ibm_cognos_cps.ApplicationContext.instances.length; i++){ var c = com_ibm_cognos_cps.ApplicationContext.instances[i]; if (c != this && c.eventSubscriptions[name]){ c.eventSubscriptions[name](data); invoked = true; } } return invoked; }, /* *Adds an event handler to the handler map //013 */ addListener: function(event, handler) { if (_F_Array.indexOf(this.events.listen, event) > -1) { if (CPSWebApplication.eventHandler[event]) { _F_Array.insert(CPSWebApplication.eventHandler[event], 0, handler); } else { CPSWebApplication.eventHandler[event] = new Array(handler); } } else { throw "This application does not listen for event: " + event; } }, publishEvent: function(event, payload) { if(_F_Array.indexOf(this.events.publish, event) > -1) { var handlerArray = CPSWebApplication.eventHandler[event] if (handlerArray) { for (var i = 0; i < handlerArray.length; i++) { var handler = handlerArray[i]; if (handler) { handler(payload); } } } else { throw "No listeners present for event: " + event; } } else { throw "This application does not publish event: " + event; } }, /* * makes an absolute url from a base and a url which maybe absolute or relative. */ makeAbsolute: function(base, url){ if(url.indexOf(base) !== 0){ var index = base.indexOf('://'); if (index !== -1){ index = base.indexOf('/', index + 3); if (index !== -1){ return base.substring(0, index) + (url.charAt(0) === '/' ? '' : '/' ) + url; } } } return url; }, /* * Return a URI which will be proxied by the portal, so as to avoid cross site request issues */ getProxiedURI:function(url){ var proxyTemplate = this.getProperty('proxyTemplate'); // no proxying in CC if (proxyTemplate && !('cognos' == this.getProperty('portalAgent'))){ return this._cpsresourceurl(this.getProperty('proxyTemplate'), url); } return url; }, /* * Save the setting in the given form as portlet settings. */ saveSettings: function(form){ var saveForm = document[this.getProperty('scope')+'_editSaveForm']; if (saveForm){ for (var i = 0 ; i < form.elements.length; i++){ if (form.elements[i].type != 'button'){ var input = document.createElement("input"); input.name = "p_" + form.elements[i].name; input.type = form.elements[i].type; input.value = form.elements[i].value; input.checked = form.elements[i].checked; saveForm.appendChild(input); } } saveForm.submit(); } }, /* * Reset the settings of a portlet. */ resetSettings: function(form){ if (this.getProperty('editResetTemplate')) { document.location.href = this.getProperty('editResetTemplate'); } }, /* * Cancel the editing of the setting and go back to view the app */ cancelSettings: function(){ if (this.getProperty('editCancelTemplate')) { document.location.href = this.getProperty('editCancelTemplate'); } }, getPortalAgent: function(){ return this.getProperty('portalAgent'); }, /* * Helper function that returns a url that will store the query to the nav state when accessed */ _getActionURI:function(query){ var actionTemplate = this.getProperty('actionTemplate'); if (actionTemplate){ return this._cpsactionurl(this.getProperty('actionTemplate'), query); } return null; }, /* * This will log into the gateway, then call the callback. * It may be called by many different portlets simultaneously */ login : function(callback){ var passport = this.getProperty('camPassport'); if (passport) { if (CPSWebApplication.loadState == 'unloaded') { CPSWebApplication.loadState = 'loading'; if (callback){ CPSWebApplication.pendingCallbacks.push(callback); } var div = document.createElement("div"); div.style.display='none'; var fr = document.createElement("iframe"); fr.src = this.gateway + "?b_action=xts.run&m=/cps4/common/sso.xts&m_passportID=" + encodeURIComponent(passport); fr.onload = window.parent.CPSWebApplication.postLogin(); div.appendChild(fr); document.body.appendChild(div); } else if (CPSWebApplication.loadState == 'loading' && callback) { CPSWebApplication.pendingCallbacks.push(callback); } else if (CPSWebApplication.loadState == 'loaded' && callback) { callback(); } } else if(callback){ callback(); } }, /* * helper function for getProxiedURI(), */ _cpsresourceurl: function(resourceTemplate, target){ var begin = resourceTemplate.indexOf('_cpsresourceurl'); if (begin != -1){ var endMarker='cpsendmarker_'; var end = resourceTemplate.indexOf(endMarker, begin); if (end != -1){ var marker = resourceTemplate.substring(begin, end + endMarker.length); var decodeCount = 0; var decodedMarker = marker; while(decodedMarker != '_cpsresourceurl:cpsendmarker_' && decodeCount ++ < 10){ decodedMarker = decodeURIComponent(decodedMarker); } if (decodeCount < 10){ var encodedTarget = target; for (i =0; i < decodeCount ; i++){ encodedTarget = encodeURIComponent(encodedTarget); } target = resourceTemplate.replace(marker, encodedTarget); } } } // Plumtree portletIds.. so we can synchronize passports. if (window.cognosPortletIds){ if(target.indexOf('?') != -1) target += '&'; else target += '?'; target += 'cognosPortletIds='+encodeURIComponent(cognosPortletIds.join('_')); } return target; }, /* * helper function for _getActionURI() */ _cpsactionurl: function(resourceTemplate, target){ var begin = resourceTemplate.indexOf('_cpsparamsurl'); if (begin != -1){ var endMarker='cpsendmarker_'; var end = resourceTemplate.indexOf(endMarker, begin); if (end != -1){ var marker = resourceTemplate.substring(begin, end + endMarker.length); var decodeCount = 0; var decodedMarker = marker; while(decodedMarker != '_cpsparamsurl=cpsendmarker_' && decodeCount ++ < 10){ decodedMarker = decodeURIComponent(decodedMarker); } if (decodeCount < 10){ var encodedTarget = target; for (i =0; i < decodeCount ; i++){ encodedTarget = encodeURIComponent(encodedTarget); } target = resourceTemplate.replace(marker, encodedTarget); } } } // Plumtree portletIds.. so we can synchronize passports. if (window.cognosPortletIds){ if(target.indexOf('?') != -1) target += '&'; else target += '?'; target += 'cognosPortletIds='+encodeURIComponent(cognosPortletIds.join('_')); } return target; }, /* * returns an XHR request in a cross-browser fashion */ _getXHR: function(options){ var obj; // plumtree xhr (knows how to handle timeouts ..) if (window.CustomPTHttpRequest !== undefined){ obj = new CustomPTHttpRequest(); } if (CPSConfig.xmlHttpDefault != null) { obj = new ActiveXObject(CPSConfig.xmlHttpDefault); } // Well if there is no ActiveXObject available it must be firefox, opera, or something else if (typeof XMLHttpRequest != 'undefined') { obj = new XMLHttpRequest(); } if (!obj){ throw 'No XMLHttpRequest object is available'; } if (options){ obj.onreadystatechange = function() { try { if (obj.readyState == 4) { if (obj.status >= 200 && obj.status < 300) { if (typeof options.onSuccess == "function") { options.onSuccess(obj); } } else { if (typeof options.onFailure == "function") { options.onFailure(obj); } } // fix for IE memory leak _self.transport.onreadystatechange = CPSConfig.emptyFunction; } } catch (e) { try { if (typeof options.onException == "function") { if (this.status !== 0) { options.onException(e); } } } catch (e1) { console.log('e1:' + e1); } } }; // of function } return obj; }, /* * returns a function that will be called with the object as its scope */ _hitch:function(obj, func){ return function(){ func.apply(obj); }; }, /* * This can be called to load a library in such a way that it will only be loaded once on the page. */ loadLibrary: function(href, callback, conditionFunction) { if (conditionFunction && !conditionFunction()){ if (callback){ callback(false); } return false; } if (!window.CognosCPSLoadedLibMap){ window.CognosCPSLoadedLibMap = {}; } if ( !window.CognosCPSLoadedLibMap[href]) { CognosCPSLoadedLibMap[href] = true; var callbacks = []; CPSWebApplication.loadingCallbacks[href] = callbacks; callbacks.push(callback); var head = document.getElementsByTagName('HEAD').item(0); var node = document.createElement('SCRIPT'); var _self = this; node.onload = node.onreadystatechange = function() { if (this.readyState && this.readyState != 'loaded' && this.readyState != 'complete') { return; } var callbacks = CPSWebApplication.loadingCallbacks[href]; for (var i = 0 ; i < callbacks.length; i++){ callbacks[i](true); } delete CPSWebApplication.loadingCallbacks[href]; }; node.type = 'text/javascript'; node.src = href; head.appendChild(node); return true; } if (callback){ var callbacks = CPSWebApplication.loadingCallbacks[href]; if (callbacks){ callbacks.push(callback); }else { callback(); } } return false; } } /* * helper function for login() */ CPSWebApplication.postLogin = function() { CPSWebApplication.loadState = 'loaded'; for (var i = 0; i < CPSWebApplication.pendingCallbacks.length; i++) { CPSWebApplication.pendingCallbacks[i](); } } CPSWebApplication.loadState = 'unloaded'; CPSWebApplication.pendingCallbacks = []; CPSWebApplication.loadingCallbacks = {}; })(); window.CognosConnect = new CPSWebApplication();