@zohodesk/platform-middleware
Version:
Generalized Contract for the events from Marketplace App, In-App widgets, CRM-Plus and EFC
1,121 lines (907 loc) • 34 kB
JavaScript
/*$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 || {});