123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
'use strict';
modulum('WebComponentWidget', ['FieldWidgetBase', 'WidgetFactory'],
function(context, cls) {
cls.WebComponentWidget = context.oo.Class(cls.FieldWidgetBase, function($super) {
return {
$static: {
gICAPIVersion: '1.0',
focusEvent: context.constants.widgetEvents.focus,
dataEvent: 'wc_data',
actionEvent: 'wc_action',
ready: 'wc_ready'
},
__name: 'WebComponentWidget',
__dataContentPlaceholderSelector: cls.WidgetBase.selfDataContent,
_webComponentType: null,
_webComponentWindow: null,
_webComponentProxy: null,
_webComponentWindowKeyDown: null,
_webComponentWindowClick: null,
_webComponentWindowDblClick: null,
_webComponentWindowContextMenu: null,
_flushValue: '',
_flushingData: false,
_url: null,
_isReady: false,
_value: null,
_stopOnError: true,
_iframeElement: null,
_properties: null,
_initLayout: function() {
if (!this._ignoreLayout) {
this._layoutInformation = new cls.LayoutInformation(this);
this._layoutInformation.shouldFillStack = true;
this._layoutEngine = new cls.LeafLayoutEngine(this);
this._layoutInformation.forcedMinimalWidth = 20;
this._layoutInformation.forcedMinimalHeight = 20;
}
},
_initElement: function() {
$super._initElement.call(this);
this._iframeElement = this._element.getElementsByTagName('iframe')[0];
this._iframeElement.on('load.WebComponentWidget', this._onLoad.bind(this));
this._properties = "{}";
},
destroy: function() {
this._delegatesKeyboard(false);
this._delegatesMouse(false);
try {
this._webComponentWindow.gICAPI = null;
} catch (e) {}
this._webComponentWindow = null;
this._iframeElement.off('load.WebComponentWidget');
this._iframeElement = null;
$super.destroy.call(this);
},
_onReadyData: function() {
if (this.value !== this._flushValue) {
this._toICAPI('onData', this._value ? this._value : '');
}
},
_onLoad: function() {
if (this.getUrl()) {
if (this._webComponentType === 'api') {
this._injectApi();
this._delegatesMouse(true);
this._delegatesKeyboard(true);
} else if (this._webComponentType === 'url') {
this.emit(context.constants.widgetEvents.change);
}
this._onReady();
}
},
_onReadyFocus: function() {
if (this._uiWidget && this._uiWidget.getVMFocusedWidget() !== this) {
this.emit(context.constants.widgetEvents.change);
this._toICAPI('onFocus', false);
} else {
if (this._iframeElement !== document.activeElement) {
this._toICAPI('onFocus', true);
} else {
this._toICAPI('onFocus', false);
}
}
},
_onReadyBlur: function() {
this.getValue();
this.emit(context.constants.widgetEvents.blur);
this._toICAPI('onFocus', false);
},
_onReadyStateChanged: function(active, dialogType) {
this._toICAPI('onStateChanged', JSON.stringify({
'active': parseInt(active),
'dialogType': dialogType.toString()
}));
},
setProperty: function(property) {
if (this._isReady) {
this._toICAPI('onProperty', property);
} else {
this.when(cls.WebComponentWidget.ready, this._onReadyProperty.bind(this, property));
}
},
_onReady: function() {
this._isReady = true;
this.emit(context.constants.widgetEvents.ready);
},
_onReadyProperty: function(property) {
this._toICAPI('onProperty', property);
},
_injectApi: function() {
context.WebComponentService.setProxy(this.getUniqueIdentifier());
this._webComponentProxy = context.WebComponentService.getProxy(this.getUniqueIdentifier());
this._webComponentWindow = this._iframeElement.contentWindow;
try {
Function.noop(this._webComponentWindow.DocURL);
} catch (e) {
context.LogService.gICAPI.error('Webcomponent not found:', this._url);
context.LogService.gICAPI.error('onICHostReady no present in webcomponent, cannot continue!');
this.webComponentNotFound();
return false;
}
try {
this._webComponentWindow.gICAPIVersion = cls.WebComponentWidget.gICAPIVersion;
this._webComponentWindow.gICAPI = this._gICAPI();
if (this._webComponentWindow.onICHostReady) {
this._webComponentWindow.onICHostReady('1.0');
} else {
context.LogService.gICAPI.error('onICHostReady no present in webcomponent, cannot continue!');
this.webComponentNotFound();
return false;
}
} catch (e) {
this.error(e, true);
return false;
}
this.emit(cls.WebComponentWidget.ready);
},
_gICAPI: function() {
return {
SetFocus: function() {
this._webComponentProxy.setFocus(this);
}.bind(this),
SetData: function(dataStr) {
this._webComponentProxy.setData(this, dataStr);
}.bind(this),
Action: function(actionName) {
this._webComponentProxy.action(this, actionName);
}.bind(this),
version: '1.0'
};
},
_delegatesKeyboard: function(delegate) {
try {
if (!this._webComponentWindow) {
this._webComponentWindow = this._iframeElement.contentWindow;
}
if (delegate) {
if (this._webComponentWindowKeyDown) {
this._webComponentWindow.document.body.removeEventListener('keydown', this._webComponentWindowKeyDown);
}
this._webComponentWindowKeyDown = function(evt) {
this.emit(gbc.constants.widgetEvents.webcomponentKeyDown, evt);
}.bind(this);
this._webComponentWindow.document.body.addEventListener('keydown', this._webComponentWindowKeyDown);
} else {
if (this._webComponentWindowKeyDown) {
this._webComponentWindow.document.body.removeEventListener('keydown', this._webComponentWindowKeyDown);
this._webComponentWindowKeyDown = null;
}
}
} catch (error) {
context.LogService.gICAPI.warn("Can not use GBC accelerators in a cross-domain Webcomponents (" + this._url + ")");
}
},
_delegatesMouse: function(delegate) {
try {
if (!this._webComponentWindow) {
this._webComponentWindow = this._iframeElement.contentWindow;
}
if (delegate) {
if (this._webComponentWindowClick) {
this._webComponentWindow.document.body.removeEventListener('click', this._webComponentWindowClick);
}
if (this._webComponentWindowDblClick) {
this._webComponentWindow.document.body.removeEventListener('dblclick', this._webComponentWindowDblClick);
}
if (this._webComponentWindowContextMenu) {
this._webComponentWindow.document.body.removeEventListener('contextmenu', this._webComponentWindowContextMenu);
}
this._webComponentWindowClick = function(evt) {
this.emit(gbc.constants.widgetEvents.webcomponentClick, evt);
}.bind(this);
this._webComponentWindowDblClick = function(evt) {
this.emit(gbc.constants.widgetEvents.webcomponentDblClick, evt);
}.bind(this);
this._webComponentWindowContextMenu = function(evt) {
this.emit(gbc.constants.widgetEvents.webcomponentContextMenu, evt);
}.bind(this);
this._webComponentWindow.document.body.addEventListener('click', this._webComponentWindowClick);
this._webComponentWindow.document.body.addEventListener('dblclick', this._webComponentWindowDblClick);
this._webComponentWindow.document.body.addEventListener('contextmenu', this._webComponentWindowContextMenu);
} else {
if (this._webComponentWindowClick) {
this._webComponentWindow.document.body.removeEventListener('click', this._webComponentWindowClick);
this._webComponentWindowClick = null;
}
if (this._webComponentWindowDblClick) {
this._webComponentWindow.document.body.removeEventListener('dblclick', this._webComponentWindowDblClick);
this._webComponentWindowDblClick = null;
}
if (this._webComponentWindowContextMenu) {
this._webComponentWindow.document.body.removeEventListener('contextmenu', this._webComponentWindowContextMenu);
this._webComponentWindowContextMenu = null;
}
}
} catch (error) {
context.LogService.gICAPI.warn("Can not propagate mouse events to GBC context in a cross-domain Webcomponents (" + this._url +
")");
}
},
_toICAPI: function(verb, args) {
try {
var arg = args;
if (verb === 'onData' && arg === null) {
arg = [null];
} else {
if (!arg && arg !== false && arg !== '' && arg !== 0) {
arg = [];
}
if (arg.prototype !== Array) {
arg = [arg];
}
}
if (this._webComponentWindow && this._webComponentWindow.gICAPI && this._webComponentWindow.gICAPI[verb]) {
this._webComponentWindow.gICAPI[verb].apply(this._webComponentWindow.gICAPI, arg);
if (verb === "onFlushData") {
this._flushingData = false;
}
}
} catch (e) {
this.error(e);
}
},
_onReadyExecute: function(callback) {
if (this._isReady) {
callback();
} else {
this.when(cls.WebComponentWidget.ready, function() {
callback();
}.bind(this));
}
},
managePriorityKeyDown: function(keyString, domKeyEvent, repeat) {
if (keyString === "home" || keyString === "end") {
return false;
} else {
return $super.managePriorityKeyDown.call(this, keyString, domKeyEvent, repeat);
}
},
error: function(e, stop) {
context.LogService.gICAPI.error(i18next.t('gwc.app.webcompError.message'));
context.LogService.gICAPI.error(">>> " + ': ' + e.toString(), e);
if (this._stopOnError || stop) {
this.webComponentNotFound(i18next.t('gwc.app.webcompError.message') + ' : "' + e.toString() +
'"--> see console for more details');
} else {
var errorLayer = document.createElement("div");
var errorStyle =
'position: fixed;top: 0; color: #721c24; background-color: #f8d7da;border-color: #f5c6cb;border: 1px solid; padding: 10px; border-radius: .25rem;';
errorLayer.innerHTML = '<b>' + i18next.t('gwc.app.webcompError.message') + ' :</b> <i>' + e.toString() +
'</i><br> See console for more info';
errorLayer.setAttribute("style", errorStyle);
errorLayer.addEventListener("click", function() {
this.setAttribute("style", "display:none;");
});
this._webComponentWindow.document.querySelector("body").appendChild(errorLayer);
}
},
setFocus: function(fromMouse) {
if (this._isReady) {
this._iframeElement.domFocus();
this._toICAPI('onFocus', true);
} else {
this.when(cls.WebComponentWidget.ready, this._onReadyFocus.bind(this));
}
$super.setFocus.call(this, fromMouse);
},
hasDOMFocus: function() {
return document.activeElement === this._iframeElement;
},
loseFocus: function() {
$super.loseFocus.call(this);
this._onReadyExecute(function() {
this._onReadyBlur();
}.bind(this));
},
onStateChanged: function(active, dialogType) {
this._onReadyExecute(function() {
this._onReadyStateChanged(active, dialogType);
}.bind(this));
},
setUrl: function(url) {
this._url = url;
url = url ? url : 'about:blank';
this._iframeElement.setAttribute('src', url);
},
getUrl: function() {
var url = this._iframeElement.getAttribute('src') || this._url;
var contentUrl = false;
if (this._webComponentType === 'url') {
try {
contentUrl = this._iframeElement.contentWindow && this._iframeElement.contentWindow.location.href;
} catch (e) {
contentUrl = false;
}
}
return contentUrl ? contentUrl : url;
},
setValue: function(value, fromVM) {
var empty = value === '';
if (typeof value !== 'string') {
value = JSON.stringify(value);
}
this._value = value;
if (this._webComponentType === 'url') {
this.setUrl(empty ? '' : value);
} else {
this._onReadyExecute(function() {
this._toICAPI('onData', this._value ? this._value : '');
}.bind(this));
}
},
getValue: function() {
this.flushWebcomponentData();
var result = this._webComponentType === 'api' ? this._flushValue ? this._flushValue : this._value : this.getUrl();
this._flushValue = null;
return result;
},
setWebComponentType: function(type) {
this._webComponentType = type;
},
getWebComponentType: function() {
return this._webComponentType;
},
flushWebcomponentData: function() {
if (!this._flushingData) {
this._flushingData = true;
this._toICAPI('onFlushData');
}
},
webComponentNotFound: function(message) {
if (!context.bootstrapInfo.ignoreWebComponentFails) {
var currentApp = gbc.SessionService.getCurrent() && gbc.SessionService.getCurrent().getCurrentApplication();
if (currentApp) {
currentApp.fail(message ? message : i18next.t('gwc.app.webcompNotFound.message'));
}
}
}
};
});
cls.WidgetFactory.registerBuilder('WebComponent', cls.WebComponentWidget);
});