This class is used to interact with other native JavaScript codes. Basically, this class is used to build the UI in the platform's main UI. It also contains the functions to include JavaScript and other static resources to the page, adding callbacks, and so on.
/**
* Native JS utilities. Singleton to simulate static functions in Java.
*/
Ext.ns('JxNativeJsUtils');
// wrapper to provide OO javascript capability when dealing with
// javascript event handling. Sample usage:
// window.onload = Jx.JxUtilities.addCallback(myFuncName, thisUsedInMyFunc)
JxNativeJsUtils.addCallback = function(method, obj) {
var temp = function() {
return method.apply(obj, arguments);
} ;
return temp;
};
// enable native scripts to
JxNativeJsUtils.addToUICanvas = function(oldCompId, newComp) {
var oldComp = Ext.getCmp(oldCompId);
var container = oldComp.ownerCt;
container.remove(oldComp);
container.add(newComp);
if (oldComp.selectedData != undefined) {
newComp.selectedData = oldComp.selectedData;
newComp.getSelectedRecord = function () {return newComp.selectedData;};
}
// hook for notification, path is now a reserve word
if (! oldComp.keepNewCompPath)
newComp.initialConfig.path = oldComp.path;
newComp.nativeJsPageId = oldComp.pageId;
JxObjLocator.getIdSetter().init(newComp);
// now layout the container
if (container.rendered) {
container.doLayout();
}
};
////////////////////////////////////////////////////////////////////////////////
// Utility to add window to Module Panel.
///////////////////////////////////////////////////////////////////////////////
JxNativeJsUtils.createBubblePanel = function(oldCompId, cmp, title, buttons) {
var mPanel = Ext.getCmp("my.mainviewpanel");
var config = {
category: 'base',
width: cmp.width + 35,
height: cmp.height + 35,
y: 0,
maximized: false,
xtype: 'jxpanel',
autoScroll: true,
items: [ cmp ],
nativeJsPageId: cmp.nativeJsPageId,
initDraggable: Ext.emptyFn //Workaround: Disable drag
};
if (cmp.reloadData) {
Ext.apply(config, {
reloadData: function() { cmp.reloadData(); }
});
}
//Add place for Buttons
if (buttons) {
var extraConfig = {
buttons: buttons,
height: config.height + 40
};
Ext.apply(config, extraConfig);
}
//Not able to put new comp on framework provided
//component. Need to close that before adding new window.
if (oldCompId) {
var oldComp = Ext.getCmp(oldCompId);
if (oldComp) {
oldComp = oldComp.findParentByType('window');
if (oldComp) {
oldComp.destroy();
}
}
}
//Hide Active Window
var lastWindow = mPanel.getLastWindow();
if (lastWindow) {
lastWindow.hide();
}
//Show New Window
Ext.apply(config, { x : mPanel.computeXPosition(config)} );
mPanel.createWindowFromConfig(config, title, 'jx-window-transparent', true);
};
/**
* Workaround for Ext 3.1.1 and IE7 issue
* of "parentNode null or not an object".
*/
JxNativeJsUtils.overrideInsertAfter = function() {
if (Ext.version === '3.1.1' && Ext.isIE7) {
Ext.override(Ext.Element, {
insertAfter: function(el){
el = Ext.getDom(el);
if (el.parentNode) {
el.parentNode.insertBefore(this.dom, el.nextSibling);
}
return this;
}
});
}
};
// include anything used by native java script. currently support only 2 types, 'css' or 'js'
// return dom element created/found
JxNativeJsUtils.includeAny = function(type, src, onloadCallback) {
var el;
if (type == 'js') {
var selstr = 'script[src='+ src + ']';
el = Ext.DomQuery.selectNode(selstr);
if (! el) {
el = document.createElement('script');
el.type = 'text/javascript';
el.src = src;
}
} else if (type == 'css') {
var selstr = 'link[href=' + src + ']';
el = Ext.DomQuery.selectNode(selstr);
if (! el) {
el = document.createElement('link');
el.type = 'text/css';
el.rel = 'stylesheet';
el.href = src;
}
}
// real loading
el = Ext.get(el);
if (el.jxloaded === undefined) {
// never loaded before
el.jxloaded = false;
if (type == 'js') {
if (Ext.isIE) {
var func = function() {
var el = this.jxel;
if ("loaded" === el.dom.readyState || "complete" === el.dom.readyState) {
el.jxloaded = true;
onloadCallback();
el.un('readystatechange', this, this);
delete this.jxel;
}
};
func.jxel = el;
el.on('readystatechange', func, func);
} else {
var func = function() {
var el = this.jxel;
el.jxloaded = true;
onloadCallback();
el.un('load', this, this);
delete this.jxel;
};
func.jxel = el;
el.on('load', func, func );
}
} else { // type == 'css'
if (Ext.isIE) {
el.jxloaded = true;
// TODO: IE cant detect if css is loaded completely
onloadCallback();
} else {
var func = function() {
var el = this.jxel;
try {
el.dom.sheet.cssRules;
el.jxloaded = true;
onloadCallback();
delete this.jxel;
window.clearInterval(this.jxintid);
} catch (e) {
}
};
func.jxel = el;
func.jxintid = window.setInterval(func.createDelegate(func), 100);
}
}
// launching loading
var head = document.getElementsByTagName('head')[0];
head.appendChild(el.dom);
} else if (el.jxloaded) {
// loaded
onloadCallback();
} else {
// in the middle of loading
var func = function() {
var el = this.jxel;
if (el.jxloaded) {
onloadCallback();
delete this.jxel;
window.clearInterval(this.jxintid);
}
};
func.jxel = el;
func.jxintid = window.setInterval(func.createDelegate(func), 100);
}
};
// include multiple files used by native java script. When every file is loaded
// onloadCallback is called.
// currently support only 2 types, 'css' or 'js'
// @param file Array of files (each item contains type and path
// @param onloadCallback Callback when all files are loaded
JxNativeJsUtils.includeMany = function(files, onloadCallback) {
var includeAnyCallback = {
indx: 0,
files: files,
exec: function() {
var lastIndx = files.length -1;
var nextIndx = this.indx;
this.indx++;
if (nextIndx < lastIndx) {
JxNativeJsUtils.includeAny(files[nextIndx][0],
files[nextIndx][1],
this.exec.createDelegate(this));
} else if (nextIndx === lastIndx) {
JxNativeJsUtils.includeAny(files[nextIndx][0], files[nextIndx][1], onloadCallback)
}
}
};
includeAnyCallback.exec();
};
// interceptor of JxConnection.request
// the idea was to figure out if request is js related, if so, make it a local request
JxNativeJsUtils.jsReader = function(o) {
if (!o.url || o.url.match('/CMPServlet'))
return true; // old framework stuff
// process params
//
var fnm;
var qMrk = o.url.indexOf('?');
var params = {};
var url;
if (qMrk > 0) {
params = Ext.urlDecode(o.url.substring(qMrk + 1));
if (params.jxtype && params.jxtype != 'js') {
delete params.jxtype;
}
url = fnm = o.url.substring(0, qMrk);
} else {
url = fnm = o.url;
}
var index = fnm.lastIndexOf('.js');// /a/b/c.js
if (index > 0) {
params.jxtype = 'js';
fnm = fnm.substring(0, index);
}
if (! params.jxtype) {
return true; // not a nativejs
}
fnm = fnm.substring(fnm.lastIndexOf('/') + 1);
var fnmEntry;
if (params.jxentry) {
fnmEntry = params.jxentry;
} else {
fnmEntry = fnm;
}
var result = {
data: {
xtype: 'jxnativejscontainer',
category: 'base',
jsFilename: url,
entryFunc: fnmEntry,
pageId: '$' + fnm,
path: '$' + fnm,
jxoptions: o, // old options preserved
items: [ { }]
}};
Ext.applyIf(result.data, params);
if (o.success) {
myExecute(o.success, o.scope, [result.data, result.message, o]);
}
return false;
};
// interceptor of JxConnection.request
// the idea was to figure out if request is iframe related, if so, make it a local request
JxNativeJsUtils.ifReader = function(o) {
if (!o.url || o.url.match('/CMPServlet'))
return true; // old framework stuff
// for url does not ends with .html...need to add parameter jxtype=html
var index = o.url.lastIndexOf('.html'); // /a/b/c.html
var frameSize = {
jxwidth: 300,
jxheight: 500
};
var hasHtmlExt = false;
if (index < 0) {
// case without .html, look for jxtype=html
// /a/b/c?jxtype=html
index = o.url.lastIndexOf('jxtype=html');
if (index < 0) {
return true; // definitely not an iframe request
}
o.url = o.url.replace('jxtype=html', ''); // consume it
} else {
hasHtmlExt = true;
}
// /a/b/c.html?jxwidth=100&jxheight=100 or /a/b/c?jxwidth=100&jxheight=100&jxtype=html
index = o.url.lastIndexOf('?');
if (index < 0) {
index = o.url.length;
} else {
// see if there is size parameters
var paramsStr = o.url.substring(index+1);
var params = Ext.urlDecode(paramsStr);
Ext.apply(frameSize, params);
}
var fnm = o.url.substring(0, index);
index = fnm.lastIndexOf('/') + 1;
var endIndex;
if (hasHtmlExt) {
endIndex = fnm.length - ".html".length;
} else {
endIndex = fnm.length;
}
fnm = fnm.substring(index, endIndex); // file name is also name space...
var result = {
data: {
width: frameSize.jxwidth,
height: frameSize.jxheight,
xtype: 'jxifnativejscontainer',
category: 'base',
fileName: o.url,
nativeJsPageId: '$' + fnm,
path: '$' + fnm,
items: [ { }]
}};
if (o.success) {
myExecute(o.success, o.scope, [result.data, result.message, o]);
}
return false;
};