UNPKG

@zohodesk/platform-middleware

Version:

Generalized Contract for the events from Marketplace App, In-App widgets, CRM-Plus and EFC

1,068 lines (913 loc) 34 kB
/*$Id$*/ let ZAppUtil = (function (ZAppUtil) { // eslint-disable-line no-unused-vars, no-shadow // Global Logger instance which will be acquired and shared by other modules. let GlobalLogger; // minimal Logging utility. function ZLogger() { } ZLogger.prototype.Info = function () { // if (ZAppUtil.isDevMode()) { // // eslint-disable-next-line no-console // console.info.apply(console, arguments); // } }; ZLogger.prototype.Error = function () { console.log(...arguments); // eslint-disable-line no-console console.error(new Error()); // eslint-disable-line no-console }; function getLogger() { if (!GlobalLogger || !(GlobalLogger instanceof ZLogger)) { GlobalLogger = new ZLogger(); // Logging instance for Core Framework } return GlobalLogger; } function constructQueryParamsString(qpMap) { let qpPairs = []; for (let k in qpMap) { if (k && qpMap[k]) { qpPairs.push(`${k}=${qpMap[k]}`); } } return qpPairs.join('&'); } function getURLOrigin(URL) { let currentLocation = URL || document.location.href; let aEle = document.createElement('a'); aEle.setAttribute('href', currentLocation); return `${aEle.protocol}//${aEle.host}`; } function isURL(URL) { return URL.indexOf('http') !== -1; } // Custom Error function. function AuthenticationError(message) { this.name = 'AuthenticationError'; this.message = message; this.stack = (new Error()).stack; } AuthenticationError.prototype = Object.create(Error.prototype); AuthenticationError.prototype.constructor = AuthenticationError; ZAppUtil.getURLOrigin = getURLOrigin; ZAppUtil.isURL = isURL; ZAppUtil.getLogger = getLogger; ZAppUtil.constructQueryParamsString = constructQueryParamsString; ZAppUtil.AuthenticationError = AuthenticationError; return ZAppUtil; }(window.ZAppUtil || {})); /* eslint-disable */ function ZWidgetRuntime(widgetProps) { this.__WIDGET__ = widgetProps; this._hasLoaded = false; this._isActive = false; this._bindedEvents = {}; this._hasRegistered = false; this._origin; this._type; } ZWidgetRuntime.prototype.getWidgetInfo = function () { var info = { 'url': this.getURL(), 'location': this.getLocation(), 'widgetID': this.getUniqueID(), 'name': this.getProp('name') }; return info; } ZWidgetRuntime.prototype.hasLoaded = function () { return !!this._hasLoaded; }; ZWidgetRuntime.prototype.isActive = function () { return this._isActive; }; ZWidgetRuntime.prototype.getOrigin = function () { return this._origin; }; ZWidgetRuntime.prototype.activate = function (shouldSendEvent) { this._isActive = true; // TODO: Send Event to the App if shouldSendEvent is set return this._isActive; }; ZWidgetRuntime.prototype.deActivate = function (shouldSendEvent) { this._isActive = false; // TODO: Send Event to the App if shouldSendEvent is set return this._isActive; }; ZWidgetRuntime.prototype.getConfig = function () { return this.__WIDGET__ && this.__WIDGET__.config; }; ZWidgetRuntime.prototype.getFrameOrigin = function () { return this.__WIDGET__.frameOrigin; } ZWidgetRuntime.prototype.getURL = function () { return this.__WIDGET__.url; } ZWidgetRuntime.prototype.getLocation = function () { return this.__WIDGET__.location; } ZWidgetRuntime.prototype.getExtensionID = function () { return this.__WIDGET__ && this.__WIDGET__.extension_id; } ZWidgetRuntime.prototype.getExtensionVersion = function () { return this.__WIDGET__ && this.__WIDGET__.extension_version; } ZWidgetRuntime.prototype.getZAppID = function () { return this.__WIDGET__ && this.__WIDGET__.zappid; } ZWidgetRuntime.prototype.getResolvedURL = function () { return this._resolvedURL; } ZWidgetRuntime.prototype.getUniqueID = function () { return this._uniqueID; } ZWidgetRuntime.prototype.getProp = function (propName) { return this.__WIDGET__ && this.__WIDGET__[propName]; } ZWidgetRuntime.prototype.getIFrame = function () { return document.getElementById(this._uniqueID); }; ZWidgetRuntime.prototype.getWindow = function () { var _iframe = document.getElementById(this._uniqueID); return _iframe && _iframe.contentWindow; }; ZWidgetRuntime.prototype.SendEvent = function (eventName, data, isPromise) { var eventObj = { type: '__EVENT__', data: data, uniqueID: this.getUniqueID(), widgetID: this.getUniqueID(), eventName: eventName, isPromise: isPromise }; var bindedEvents = this._bindedEvents[eventName]; var widgetInstance, returnVal = []; if (typeof bindedEvents !== 'undefined') { for (var k in bindedEvents) { if (bindedEvents.hasOwnProperty(k)) { widgetInstance = ZApp.GetWidgetInstance(k); if (widgetInstance && widgetInstance.isActive()) { if (isPromise) { returnVal.push(MessageManager.SendMessage(widgetInstance, eventObj)); } else { MessageManager.SendMessage(widgetInstance, eventObj); } } } } } if (isPromise) { return returnVal; } }; ZWidgetRuntime.prototype.addEventInfo = function () { } ZWidgetRuntime.prototype.removeEventInfo = function () { } ZWidgetRuntime.prototype.getEvents = function () { return Object.keys(this._bindedEvents); } var MessageManager = (function (MessageManager) { // eslint-disable-line no-unused-vars, no-shadow var Context; var Logger = ZAppUtil.getLogger(); var promiseIDCtr = 100; var PromiseQueue = {}; function Init(ctx, config) { // config for any future use if (!ctx || typeof ctx !== 'object') { throw Error('Invalid Context object passed'); } if (config && typeof config !== 'object') { throw Error('Invalid Configuration Passed to MessageHandler'); } Context = ctx; return MessageHandler.bind(MessageManager); } function SendMessage(widgetInstance, message) { var isPromiseEvent = message.isPromise; var PromiseID; if (isPromiseEvent) { PromiseID = getNextPromiseID(); message.promiseID = PromiseID; // eslint-disable-line } var frameURL = getURLWithPath(widgetInstance.getResolvedURL()); var ctxWindow = widgetInstance.getWindow(); if (!ctxWindow || !frameURL) { Logger.Error('Invalid IFrame object. Can\'t send Message to Widget'); return; } message.__time__ = new Date().getTime(); ctxWindow.postMessage(message, frameURL); if (isPromiseEvent) { return AddToPromiseQueue(PromiseID); } } function getNextPromiseID() { return 'Promise' + promiseIDCtr++; } function AddToPromiseQueue(promiseID) { var promise = new Promise(function (resolve, reject) { // Adding the promise to queue. PromiseQueue[promiseID] = { resolve: resolve, reject: reject, time: new Date().getTime() }; }); return promise; } function BroadcastEvent(eventName, data, isPromise) { var widgetInstances = Context.GetAllWidgetInstance(), widgetInstance; var returnArr = []; for (var k in widgetInstances) { if (widgetInstances.hasOwnProperty(k)) { widgetInstance = widgetInstances[k]; if (widgetInstance && widgetInstance.isActive()) { var eventPromise = widgetInstance.SendEvent(eventName, data, isPromise); if (isPromise && eventPromise) { for (var i = 0; i < eventPromise.length; i++) { returnArr.push(eventPromise[i]); } } } } } return isPromise ? returnArr : Promise.resolve(); } // Event Handlers function MessageHandler(MessageEvent) { /* Added for backward compatibility support */ var data; try { data = typeof MessageEvent.data === 'string' ? JSON.parse(MessageEvent.data) : MessageEvent.data; } catch (e) { data = MessageEvent.data; } var messageType = data.type; try { if (['__REGISTER__', '__DEREGISTER__'].indexOf(messageType) !== -1 || isAuthorizedMessage(MessageEvent, data)) { switch (messageType) { case '__REGISTER__': HandleRegister(MessageEvent, data); break; case '__DEREGISTER__': HandleDeRegister(MessageEvent, data); break; case '__EVENT_BIND__': HandleEventBind(MessageEvent, data); break; case '__EMIT__': HandleEmitEvent(MessageEvent, data); break; case '__EVENT_RESPONSE__': HandleEventResponse(MessageEvent, data); break; default: HandleInternalEvent(MessageEvent, data); break; } } } catch (e) { if (!(e instanceof ZAppUtil.AuthenticationError)) { Logger.Error('[MessageHandler] => ', e.stack); } } } function isAuthorizedMessage(MessageEvent, data) { var widgetInstance = Context.GetWidgetInstance(data.uniqueID); var WindowRef = widgetInstance && widgetInstance.getWindow(); if (typeof data.uniqueID !== 'string' && !WindowRef) { throw new ZAppUtil.AuthenticationError('Message from Invalid window from received'); } var Origin = getURLWithPath(widgetInstance.getResolvedURL()); var widgetUniqueID = widgetInstance.getUniqueID(); var MessageWindowRef = MessageEvent.source; var MessageUniqueID = data.uniqueID; var MessageOrigin = getURLWithPath(decodeURIComponent(data.widgetOrigin)); if (WindowRef !== MessageWindowRef || Origin !== MessageOrigin || widgetUniqueID !== MessageUniqueID) { throw new Error('Message from UnAuthorized Source'); } return true; } // Register SDK function HandleRegister(MessageEvent, data) { var sourceWindow = MessageEvent.source; var origin = MessageEvent.origin; var uniqueID = data.uniqueID; var widgetInstance = Context.GetWidgetInstance(uniqueID); if (!widgetInstance || (widgetInstance && sourceWindow !== widgetInstance.getWindow())) { Logger.Error('Message from Invalid IFrame arrived.'); return; } widgetInstance._origin = origin; widgetInstance._isActive = true; widgetInstance._hasRegistered = true; } function WidgetLoadHandler(widgetInstance) { var widgetLocation = widgetInstance.getIFrame() && widgetInstance.getIFrame().getAttribute('data-location'); var metaData = widgetInstance.getProp('meta') //Context.GetMeta(widgetLocation); var extensionID = widgetInstance.getExtensionID(); var localeResourceURL = widgetInstance.getProp("localeResourceUrl"); var defaultLocaleResourceUrl = widgetInstance.getProp("defaultLocaleResourceUrl"); var locale = widgetInstance.getProp("locale"); var PluginContext = { type: '__REGISTER__', uniqueID: widgetInstance.getUniqueID(), data: { meta: metaData, // NO I18N uniqueID: widgetInstance.getUniqueID(), extensionID: extensionID, location: widgetInstance.getLocation() } }; Context .FetchLocaleResource(localeResourceURL, locale, defaultLocaleResourceUrl) .then(function (localeResponse) { if (typeof localeResponse !== 'undefined') { PluginContext.data.locale = localeResponse.locale; PluginContext.data.localeResource = localeResponse.content; } SendRegisterEvent(widgetInstance, PluginContext); }) .catch(function (error) { Logger.Info('Error occured while fetching I18NResource ', error); SendRegisterEvent(widgetInstance, PluginContext); }); } function SendRegisterEvent(widgetInstance, contextObject) { if (!widgetInstance) { Logger.Info('Invalid WidgetInstance passed'); } widgetInstance._hasLoaded = true; widgetInstance.activate(); SendMessage(widgetInstance, contextObject); // In case Modal box if (widgetInstance.getLocation() === '__MODAL__') { setTimeout(function () { widgetInstance.SendEvent('modal.opened'); }, 0); } // Invoking the App Lifecycle event : Onload if (typeof widgetInstance.getProp('onload') === 'function') { setTimeout(widgetInstance.getProp('onload').bind(null, [widgetInstance.getConfig()]), widgetInstance.AppOnLoadDelay || 0); } } function HandleDeRegister(MessageEvent, data) { Context.DeleteWidgetInstance(data.uniqueID); } function HandleEventBind(MessageEvent, data) { var sourceWidgetID = data.uniqueID; var targetWidgetID = data.widgetID; var eventName = data.eventName; var targetWidget = ZApp.GetWidgetInstance(targetWidgetID); var eventObj; if (targetWidget && !targetWidget._bindedEvents[eventName]) { targetWidget._bindedEvents[eventName] = {}; } eventObj = targetWidget._bindedEvents[eventName]; eventObj[sourceWidgetID] = data.count; } function HandleCreateInstance(MessageEvent, data) { var uniqueID = data.uniqueID; var widgetInstance = ZApp.GetWidgetInstance(uniqueID); var modalProps = { extension_id: widgetInstance.getExtensionID(), extension_version: widgetInstance.getExtensionVersion() }; for (var k in data.options) { if (data.options.hasOwnProperty(k)) { modalProps[k] = data.options[k]; } } var eventObj = { type: '__EVENT_RESPONSE__', eventName: '__INVOKE_MODAL__', promiseID: data.promiseID, time: new Date().getTime() }; try { var ModalRuntime = new ZWidgetRuntime(modalProps); // eslint-disable-line Context.RenderWidget(modalProps.location, ModalRuntime); eventObj.isSuccess = true; eventObj.data = ModalRuntime.getWidgetInfo(); } catch (e) { eventObj.isSuccess = false; eventObj.data = e.message; } SendMessage(widgetInstance, eventObj); } function HandleWidgetInfo(MessageEvent, data) { var uniqueID = data.uniqueID; var widgetInstance = ZApp.GetWidgetInstance(uniqueID); var extensionID = widgetInstance.getExtensionID(); var instanceList = []; var eventObj = { type: '__EVENT_RESPONSE__', eventName: '__WIDGETS_INFO__', promiseID: data.promiseID, time: new Date().getTime() }; try { var allWidgets = ZApp.GetAllWidgetInstance(); for (var k in allWidgets) { if (allWidgets.hasOwnProperty(k)) { var instance = allWidgets[k]; if ( instance && instance.getUniqueID() !== uniqueID && instance.getExtensionID() === extensionID && instance.isActive() ) { instanceList.push(instance.getWidgetInfo()); } } } eventObj.isSuccess = true; eventObj.data = instanceList; } catch (e) { Logger.Error(e.message); eventObj.isSuccess = false; } SendMessage(widgetInstance, eventObj); } function HandleEmitEvent(MessageEvent, data) { var targetWidgetID = data.widgetID; var eventName = data.eventName; var eventObj = { widgetID: targetWidgetID, data: data.data, eventName: eventName, type: '__EMIT__' }; var targetWidget = ZApp.GetWidgetInstance(targetWidgetID); var bindedEvents = targetWidget._bindedEvents[eventName]; var targetWidgetKeys = bindedEvents && Object.keys(targetWidget._bindedEvents[eventName]); if (Array.isArray(targetWidgetKeys)) { targetWidgetKeys.forEach(function (widgetID) { var widgetInstance = ZApp.GetWidgetInstance(widgetID); if (widgetInstance && widgetInstance.isActive()) { SendMessage(widgetInstance, eventObj); } }); } } function HandleInternalEvent(MessageEvent, data) { var eventHandlerMap = { '__HTTP__': HandleHTTPRequest, '__WIDGETS_INFO__': HandleWidgetInfo, '__CREATE_INSTANCE__': HandleCreateInstance }; var handleFn = eventHandlerMap[data.eventName]; if (handleFn) { handleFn(MessageEvent, data); return; } // In case if its custome Event HandleCustomEvent(MessageEvent, data); } function HandleCustomEvent(MessageEvent, data) { var eventName = data.eventName; var promiseID = data.promiseID; var eventPayload = data.data; var uniqueID = data.uniqueID; var widgetInstance = Context.GetWidgetInstance(uniqueID); var appConfig = widgetInstance.getConfig(); var extensionID = widgetInstance.getExtensionID(); Logger.Info('Event from SDK => Eventname : ', eventName, ', Time : ', data.time, ', Eventpayload : ', eventPayload); var eventObj = { 'data': eventPayload, 'config': appConfig, 'iframe': widgetInstance.getIFrame() }; if (promiseID) { var promiseObject = { 'resolve': PromiseCallback.bind(null, widgetInstance, promiseID, eventName, true), 'reject': PromiseCallback.bind(null, widgetInstance, promiseID, eventName, false) }; eventObj.promise = promiseObject; } if (typeof extensionID !== 'undefined') { eventObj.extension_id = extensionID; // TODO: Will be removed in future. Added for backward compatibility. eventObj.widgetID = uniqueID; } Context.TriggerEventListeners(eventName, eventObj); } function HandleEventResponse(MessageEvent, data) { var promiseID = data.promiseID; var eventPayload = data.data; if (PromiseQueue.hasOwnProperty(promiseID)) { PromiseQueue[promiseID].resolve(eventPayload); PromiseQueue[promiseID] = undefined; // eslint-disable-line delete PromiseQueue[promiseID]; } } // TODO: Experiemental Currently. need to refactor. function PromiseCallback(widgetInstance, promiseID, eventName, isSuccess, response) { var eventObj = { type: '__EVENT_RESPONSE__', eventName: 'eventName', promiseID: promiseID, time: new Date().getTime(), data: response, isSuccess: isSuccess }; SendMessage(widgetInstance, eventObj); } function HandleHTTPRequest(MessageEvent, data) { var options = data.options; var promiseID = data.promiseID; var uniqueID = data.uniqueID; var promiseObj = { 'resolve': NotifyRequestProcessedResult.bind(null, uniqueID, MessageEvent.origin, promiseID, true), 'reject': NotifyRequestProcessedResult.bind(null, uniqueID, MessageEvent.origin, promiseID, false) }; Context.ProcessGetRequest(promiseID, uniqueID, options, promiseObj); } function NotifyRequestProcessedResult(uniqueID, windowOrigin, promiseID, isSuccess, response) { var sourceWindow = ZApp.GetWidgetInstance(uniqueID).getWindow(); var eventObj = { type: '__EVENT_RESPONSE__', // NO I18N eventName: '__HTTP__', data: response, time: new Date().getTime(), promiseID: promiseID, isSuccess: isSuccess }; setTimeout(function () { sourceWindow.postMessage(eventObj, windowOrigin) }, 0); // eslint-disable-line semi } // Util function getURLWithPath(url) { var a = document.createElement('a'); a.setAttribute('href', url); return a.protocol + '//' + a.host + a.pathname; } MessageManager.Init = Init; MessageManager.SendMessage = SendMessage; MessageManager.BroadcastEvent = BroadcastEvent; MessageManager.WidgetLoadHandler = WidgetLoadHandler; return MessageManager; })(window.MessageManager || {}); // $Id$ var DefaultRenderHandlers = (function (DefaultRenderHandlers) { // eslint-disable-line function WidgetHandler(appConfig) { var appLocation = appConfig.location; var appURL = appConfig.resolvedURL; var IFrameComponent; if (appLocation && typeof appLocation === 'string') { appLocation = IFrameComponent = document.getElementById(appLocation); // No I18N } if (appLocation instanceof HTMLIFrameElement) { IFrameComponent = appLocation; IFrameComponent.setAttribute('src', appURL); } return IFrameComponent; } DefaultRenderHandlers.WidgetHandler = WidgetHandler; return DefaultRenderHandlers; })(window.DefaultRenderHandlers || {}); // $Id$ var ZApp = (function (Framework) { Framework.isDevMode = () => { return localStorage && !!localStorage.getItem('isDevMode'); } var Logger = ZAppUtil.getLogger(); // Logging instance for Core Framework try { var REGISTER_CHECK_TIMEOUT = 15 * 1000; // Seconds to schedule for check // var CLEAN_RUNTIME_TIMEOUT = 2 * 1000; // Seconds to schedule for invalid runtime clearance var TLD = window.location.origin.split(".").pop().toLowerCase(); // Top Level Domain var origin = window.location.origin.toLowerCase(); var dCType = "US"; if (TLD === "cn") { dCType = "CN"; TLD = 'com.cn'; } else if (TLD === "au") { dCType = "AU"; TLD = 'com.au'; } else if (TLD === "eu") { dCType = "EU"; } else if (origin.endsWith("hq.in")) { dCType = "INEC"; TLD = 'hq.in'; } else if (TLD === "in") { dCType = "IN"; } else if (TLD === "jp") { dCType = "JP"; } else if (TLD === "ca") { dCType = "CA"; } else if (TLD === "sa") { dCType = "SA"; } else if (TLD === "ae") { dCType = "AE"; } else if (TLD === "sg") { dCType = "SG"; } var isInit = false, _isDevMode = false, MetaStore = {}, serverConfig = { devHost: { host: '127.0.0.1', port: '5000', path: '' }, zappsHost: { host: dCType === "INEC" ? '{{zappid}}.zappsusercontent' + TLD : '{{zappid}}.zappsusercontent.' + TLD, port: '', path: '/appfiles/{{zappid}}/{{version}}/{{hashkey}}' } }, preRenderApp, postRenderApp, defaultLocale, ExtensionData = {}, // Extension Modules config data - Widgets, Buttons, Webtabs WidgetRuntimes = {}, // All the individual widget runtimes RenderHandlers, // Function which handles the render of the Widgets RequestHandler, // Function which handles API Request handling of the app. FrameworkContext = {}; // Context Object which is passed around Individual modules function isInitialized() { return isInit; } function GetDCType() { return dCType; } function GetWidgetInstance(uniqueID) { return WidgetRuntimes[uniqueID]; } function GetAllWidgetInstance() { return WidgetRuntimes; } function DeleteWidgetInstance(uniqueID, forceDelete) { var IFrameEle = document.getElementById(uniqueID); if (forceDelete) { WidgetRuntimes[uniqueID] = undefined; // eslint-disable-line no-undefined delete WidgetRuntimes[uniqueID]; if (IFrameEle) { IFrameEle.parentElement.removeChild(IFrameEle); } } else if (!IFrameEle) { WidgetRuntimes[uniqueID] = undefined; // eslint-disable-line no-undefined delete WidgetRuntimes[uniqueID]; } } function RenderWidgets(data, metaData) { if (Array.isArray(data)) { for (var i = 0; i < data.length; i++) { var widgetProps = data[i]; var locationID = widgetProps.location; Logger.Info('Render Apps with LocationID => ', locationID); MetaStore[locationID] = metaData; try { var widgetInstance = new ZWidgetRuntime(widgetProps); // eslint-disable-line no-undef // TODO: have to handle forceRender, which in case will render the app forcefully. RenderWidget(locationID, widgetInstance); } catch (e) { Logger.Error('Exception while Rendering Widget ==> ', e); } } } else { Logger.Error('Expected array of widgets ==> '); } } // Private API to render passed in Widget configuration function RenderWidget(renderLocation, widgetInstance) { try { var uniqueID = generateSecretKey(); widgetInstance._uniqueID = uniqueID; widgetInstance._resolvedURL = getResolvedAppURL(widgetInstance); executeCallback(preRenderApp, widgetInstance); let widgetLoadFunc = MessageManager.WidgetLoadHandler.bind(null, widgetInstance) widgetInstance.handleLoad = widgetLoadFunc; var windowRef = RenderHandlers.WidgetHandler(renderLocation, widgetInstance); if (windowRef instanceof HTMLIFrameElement) { windowRef.setAttribute('data-location', renderLocation); windowRef.setAttribute('id', uniqueID); WidgetRuntimes[uniqueID] = widgetInstance; // Listening for OnUnload event on the IFrame var iframeElement = document.getElementById(uniqueID); if (iframeElement !== null) { iframeElement.addEventListener('DOMNodeRemovedFromDocument', function () { WidgetRuntimes[uniqueID] = undefined; // eslint-disable-line no-undefined delete WidgetRuntimes[uniqueID]; }); } // Listening for OnLoad event on the IFrame windowRef.onload = widgetLoadFunc; ScheduleRegisterCheck(uniqueID); executeCallback(postRenderApp, widgetInstance); } else { Logger.Info('[windowRef] is not an IFrameElement.' + renderLocation + ' , ' + widgetInstance.getURL()); } } catch (e) { throw e; } return widgetInstance; } function ScheduleRegisterCheck(widgetID) { setTimeout(function () { var widgetInstance = WidgetRuntimes[widgetID]; if (widgetInstance && widgetInstance._hasLoaded && !widgetInstance._hasRegistered) { WidgetRuntimes[widgetID] = undefined; delete WidgetRuntimes[widgetID]; } }, REGISTER_CHECK_TIMEOUT); } function isDevMode() { return _isDevMode; } function executeCallback(fn, appInstance) { if (fn && typeof fn === 'function') { return fn(appInstance); } } function getResolvedAppURL(widgetConfig) { var widgetURL = widgetConfig.getURL(); var resolvedURL = ''; var serviceOrigin = ZAppUtil.getURLOrigin(); var frameOrigin = widgetConfig.getFrameOrigin() || serviceOrigin; var resolvedURL = ""; var qpMap = { 'serviceOrigin': encodeURIComponent(serviceOrigin), 'isDevMode': isDevMode(), 'frameorigin' : encodeURIComponent(frameOrigin) }; var QPString = ZAppUtil.constructQueryParamsString(qpMap); if (ZAppUtil.isURL(widgetURL)) { // If the URL is external (absolute) URL. resolvedURL = widgetURL; } var index = resolvedURL.indexOf("?"); if (index === -1) { var hashIndex = resolvedURL.indexOf("#"); if (hashIndex === -1) { resolvedURL += '?' + QPString; } else { resolvedURL = resolvedURL.slice(0, hashIndex) + '?' + QPString + resolvedURL.slice(hashIndex); } } else { index += 1; resolvedURL = resolvedURL.slice(0, index) + QPString + '&' + resolvedURL.slice(index); } return resolvedURL; } // Event Operations var _EventListeners = {}; function AttachEventListener(eventName, fn) { if (!_EventListeners.hasOwnProperty(eventName)) { _EventListeners[eventName] = []; } _EventListeners[eventName].push(fn); } function GetWidgetsByEvent(eventName) { var widgetInstances = GetAllWidgetInstance(); var eventWidget = []; for (var key in widgetInstances) { if (widgetInstances.hasOwnProperty(key)) { var events = widgetInstances[key]._bindedEvents; if (events[eventName] !== undefined) { eventWidget.push(key); } } } return eventWidget; } // Meta operations function GetMeta(location) { return MetaStore[location]; } // Event operations function BroadcastEvent(eventName, payload, isPromise) { return MessageManager.BroadcastEvent(eventName, payload, isPromise); } function ProcessGetRequest(promiseId, uniqueID, options, promiseObj) { var uniqueID = uniqueID; var widgetInstance = GetWidgetInstance(uniqueID); var extensionID = widgetInstance.getExtensionID(); var eventObj = { 'data': { 'value': options }, 'iframe': widgetInstance.getIFrame(), 'promise': promiseObj }; if (typeof extensionID !== 'undefined') { eventObj.extension_id = extensionID; eventObj.widgetID = uniqueID; } try { Logger.Info('ProcessGetRequest : PromiseID: ', promiseId, ', Options: ', options); options.contentType = options && options.contentType ? options.contentType : 'application/text'; options.dataType = options && options.dataType ? options.dataType : 'text'; // options.widgetID = uniqueID; if (typeof RequestHandler !== 'function') { throw new Error('Provide Request handler implementation in the Bootstrap.'); } RequestHandler(eventObj); } catch (e) { Logger.Error('ProcessGetRequest : Error => ', e); // NO I18N } } function TriggerEventListeners(eventName, evt) { var eventListeners = _EventListeners[eventName]; if (Array.isArray(eventListeners)) { for (var i = 0; i < eventListeners.length; i++) { eventListeners[i](evt); } } } function FetchLocaleResource(localeResourceURL, locale, defaultLocaleResourceUrl) { return new Promise(function (resolve, reject) { FetchResource(localeResourceURL, locale).then(function (localeResponse) { resolve(localeResponse); }).catch(function () { if (locale !== defaultLocale) { FetchResource(defaultLocaleResourceUrl, defaultLocale).then(function (localeResponse) { resolve(localeResponse); }).catch(function (e) { reject(e); }); } else { reject(); } }); }); } function FetchResource(url, locale) { return new Promise(function (resolve, reject) { try { var XHR = new XMLHttpRequest(); XHR.onreadystatechange = function () { if (XHR.readyState === XMLHttpRequest.DONE && XHR.status === 200) { var responseJSON; try { responseJSON = JSON.parse(XHR.responseText); } catch (e) { reject(e); } resolve({ locale: locale, content: responseJSON }); } else if (XHR.readyState === XMLHttpRequest.DONE) { reject(XHR.status); } }; XHR.open('GET', url); XHR.send(); } catch (e) { reject(); } }); } // Framework Initializer function Bootstrap(config) { return new Promise(function (resolve, reject) { var MessageHandler; try { if (!config || typeof config !== 'object') { throw new Error('Invalid configurations passed to Bootstrap.'); // NO I18N } RenderHandlers = config.RenderHandlers || DefaultRenderHandlers; RequestHandler = config.RequestHandler; preRenderApp = config.preRenderApp; postRenderApp = config.postRenderApp; _isDevMode = Boolean(config.isDevMode); // Pre filling defaults for (var k in config.serverConfig) { if (serverConfig.hasOwnProperty(k)) { serverConfig[k] = config.serverConfig[k]; } } defaultLocale = config.defaultLocale || 'en'; FrameworkContext.defaultLocale = defaultLocale; FrameworkContext.ProcessGetRequest = ProcessGetRequest; FrameworkContext.Logger = Logger; FrameworkContext.RenderWidget = RenderWidget; FrameworkContext.GetWidgetInstance = GetWidgetInstance; FrameworkContext.GetAllWidgetInstance = GetAllWidgetInstance; FrameworkContext.DeleteWidgetInstance = DeleteWidgetInstance; FrameworkContext.dcType = dCType; FrameworkContext.GetMeta = GetMeta; FrameworkContext.TriggerEventListeners = TriggerEventListeners; FrameworkContext.FetchLocaleResource = FetchLocaleResource; // Attaching event handlers var EventListeners = config.EventListeners || {}; for (k in EventListeners) { if (EventListeners.hasOwnProperty(k)) { AttachEventListener(k, EventListeners[k]); } } MessageHandler = MessageManager.Init(FrameworkContext); window.addEventListener('message', MessageHandler); isInit = true; // CleanRuntimeScheduler(); Logger.Info('Running in Dev Mode : ', isDevMode()); // No I18N resolve(Framework); } catch (e) { reject(e.message); } }); } // Utils function generateSecretKey() { var d = new Date().getTime(); var secretKey = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = (d + Math.random() * 16) % 16 | 0; d = Math.floor(d / 16); return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16); }); return secretKey; } // Public API's Framework.Bootstrap = Bootstrap; Framework.isInitialized = isInitialized; // Rendering widgets and other types Framework.RenderWidgets = RenderWidgets; // Getting widgets reference Framework.GetWidgetInstance = GetWidgetInstance; Framework.GetWidgetsByEvent = GetWidgetsByEvent; Framework.GetAllWidgetInstance = GetAllWidgetInstance; Framework.DeleteWidgetInstance = DeleteWidgetInstance; Framework.BroadcastEvent = BroadcastEvent; Framework.GetDCType = GetDCType; // Returning public API return Framework; } catch (e) { Logger.Error('Error Occured ', e.message); } })(window.ZApp || {});