fragmentEmbedder.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. // Licensed Materials - Property of IBM
  2. //
  3. // IBM Cognos Products: cogadmin
  4. //
  5. // (C) Copyright IBM Corp. 2005, 2012
  6. //
  7. // US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  8. //
  9. //
  10. /**
  11. * Attach an event to the given element
  12. * capture flag is not specified
  13. * @param object
  14. * @param eventType
  15. * @param func
  16. * @return
  17. */
  18. function addEventToObject(object, eventType, func){
  19. var isEventAdded = false;
  20. if (object && eventType && func) {
  21. eventType = eventType.toLowerCase();
  22. if (object.addEventListener){
  23. object.addEventListener(eventType, func, false);
  24. isEventAdded = true;
  25. } else if (object.attachEvent){
  26. isEventAdded = object.attachEvent("on" + eventType, func);
  27. }
  28. }
  29. return isEventAdded;
  30. }
  31. /*
  32. This class allows a fragment to be embedded in any html document
  33. */
  34. /**
  35. * Constructor
  36. * The parameters are either:
  37. * An object with the following attribute:
  38. * gateway: path to the gateway [mandatory]
  39. * webRoot: path to the webroot [mandatory]
  40. * skinRoot: path to the skin root [optional for backward compatibility]
  41. *
  42. *
  43. */
  44. function FragmentEmbedder() {
  45. var args = arguments;
  46. this._configuration = null;
  47. this._frags = [];
  48. this._loadedScripts = 0;
  49. this._loadedCssStyles = 0;
  50. this._retrievedFragments = 0;
  51. //for backward compatibility
  52. if (args && args.length == 1 && typeof args[0] != 'string') {
  53. this._configuration = args[0];
  54. } else if (args && args.length >= 2) {
  55. this._configuration = {"gateway":args[0],"webRoot":args[1]};
  56. }
  57. var _self = this;
  58. FragmentEmbedder.ERROR_UNDEFINED_CONF = "Illegal Argument Exception: No configuration is defined";
  59. FragmentEmbedder.ERROR_UNDEFINED_GATEWAY = "Illegal Argument Exception: No gateway is defined";
  60. FragmentEmbedder.ERROR_UNDEFINED_WEBROOT = "Illegal Argument Exception: No webRoot is defined";
  61. FragmentEmbedder.ERROR_UNDEFINED_FRAGDEF = "Illegal Argument Exception: No fragment definition is defined";
  62. /**
  63. * verifies the configuration
  64. */
  65. this._verifyConfiguration = function() {
  66. if (!_self._configuration || _self._configuration == null) {
  67. throw FragmentEmbedder.ERROR_UNDEFINED_CONF;
  68. }
  69. if (_self._configuration.gateway == null || _self._configuration.gateway == "") {
  70. throw FragmentEmbedder.ERROR_UNDEFINED_GATEWAY;
  71. }
  72. if (_self._configuration.webRoot == null) {
  73. throw FragmentEmbedder.ERROR_UNDEFINED_WEBROOT;
  74. }
  75. }
  76. this._verifyConfiguration();
  77. var scripts = [
  78. this._configuration.webRoot+'/dojo16/dojo/dojo.js',
  79. this._configuration.webRoot+'/fragments/xdojo/core.js',
  80. this._configuration.gateway+'/dashboard/messages/messages/pfmessages?section=JS,GEN',
  81. this._configuration.webRoot+'/fragments/fragments.js',
  82. this._configuration.webRoot+'/common/framework/validator/CValidator.js',
  83. this._configuration.webRoot+'/fragments/uicommon.js'
  84. ];
  85. /**
  86. * The following stylesheet is required when showing the details of an error.
  87. */
  88. var cssStyles = [
  89. this._configuration.skinRoot+'/fragments/portlet.css'
  90. ];
  91. /**
  92. * This method registers a fragment to be loaded; the parameter is either an object or a sequence of 3 strings:
  93. * fragUrl: url for the fragment
  94. * fragDivId: id of the fragment div,
  95. * retrieveParams: string or function providing the parameters to pass when retrieving the fragment
  96. * It is recommended to use the object
  97. */
  98. this.embed = function () {
  99. var fragDef = null;
  100. var args = arguments;
  101. if (!args || args.length == 0) {
  102. throw FragmentEmbedder.ERROR_UNDEFINED_FRAGDEF;
  103. }
  104. if (args.length == 1 && typeof args[0] != 'string') {
  105. _self._frags[_self._frags.length] = args[0];
  106. } else {
  107. fragDef = {};
  108. if (args[0]) {
  109. fragDef.fragUrl = args[0];
  110. } else {
  111. fragDef.fragUrl = null;
  112. }
  113. if (args[1]) {
  114. fragDef.fragDivId = args[1];
  115. } else {
  116. fragDef.fragDivId = null;
  117. }
  118. if (args[2]) {
  119. fragDef.retrieveParams = args[2];
  120. } else {
  121. fragDef.retrieveParams = null;
  122. }
  123. _self._frags[_self._frags.length] = fragDef;
  124. }
  125. /*
  126. * We return the fragDef object, but it should be treated as an opaque object by the client
  127. */
  128. return _self._frags[_self._frags.length];
  129. }
  130. /**
  131. * This methods loads the embedded fragments
  132. * the onload parameter is a flag indicating whether or not the load has to happen once the page is loaded
  133. */
  134. this.loadFragments = function(onLoad) {
  135. if (onLoad) {
  136. addEventToObject(window,"load",function() {_self._loadScriptsAndFragments();});
  137. } else {
  138. this._loadScriptsAndFragments();
  139. }
  140. }
  141. /**
  142. * This method raised the specified event on the specified embedded fragment
  143. */
  144. this.raiseEvent = function(fragDef, eventName, payload, type){
  145. fragDef.raiseEvent(eventName, payload, type);
  146. }
  147. /**
  148. * This method loads the necessary scripts, css stylesheets and then the fragments
  149. */
  150. this._loadScriptsAndFragments = function() {
  151. if (_self._loadedScripts < scripts.length) {
  152. _self._loadScript(scripts[_self._loadedScripts++],_self._loadScriptsAndFragments);
  153. } else if (_self._loadedCssStyles < cssStyles.length) {
  154. _self._loadCssStyle(cssStyles[_self._loadedCssStyles++],_self._loadScriptsAndFragments);
  155. } else {
  156. _self._loadFrags();
  157. }
  158. }
  159. this._canShowErrorDetails = function() {
  160. var canShow = false;
  161. if (_self._configuration.skinRoot) {
  162. canShow = true;
  163. }
  164. return canShow;
  165. }
  166. this._loadFrags = function() {
  167. if (!window._F_Config) {
  168. _F_Config = new Object();
  169. }
  170. _F_Config.gateway = _self._configuration.gateway;
  171. _F_Config.application = "/cogadmin";
  172. _F_Config.webContent = _self._configuration.webRoot;
  173. if (_self._canShowErrorDetails()) {
  174. ui_error.prototype.template = '<div id="_THIS_errormsg"></div><div><a id="_THIS_error_showdetails">' + PFM.GEN.IDS_GEN_DETAILS + '</a></div>';
  175. } else {
  176. ui_error.prototype.template = '<div id="_THIS_errormsg"></div>';
  177. }
  178. for (var i=0;i<_self._frags.length;i++) {
  179. _self._fragInit(_self._frags[i]);
  180. }
  181. this._retrieveFragment();
  182. }
  183. this._isScriptLoaded = function(src) {
  184. return this._isFileLoaded("src",src);
  185. }
  186. this._isCssStyleLoaded = function(src) {
  187. return this._isFileLoaded("href",src);
  188. }
  189. this._isFileLoaded = function(attribute,value) {
  190. var head = document.getElementsByTagName("head")[0];
  191. var isLoaded = false;
  192. var i=0;
  193. while (i<head.childNodes.length && !isLoaded) {
  194. isLoaded = (head.childNodes[i].attributes != null)
  195. && (head.childNodes[i].attributes[attribute] != null)
  196. && (value==head.childNodes[i].attributes[attribute].value);
  197. i++;
  198. }
  199. return isLoaded;
  200. }
  201. this._loadScript = function(scriptUrl,onloadHandler) {
  202. if (_self._isScriptLoaded(scriptUrl)) {
  203. if (onloadHandler) {
  204. onloadHandler();
  205. }
  206. } else {
  207. var s = document.createElement("script");
  208. s.src = scriptUrl;
  209. s.type="text/javascript";
  210. if (onloadHandler) {
  211. s.onload=onloadHandler; //Firefox
  212. s.onreadystatechange = function() { //IE
  213. if (this.readyState == 'complete' || this.readyState == 'loaded') {
  214. onloadHandler();
  215. }
  216. }
  217. }
  218. document.getElementsByTagName("head")[0].appendChild(s);
  219. }
  220. }
  221. this._loadCssStyle = function(cssStyleUrl,onloadHandler) {
  222. if (!_self._isCssStyleLoaded(cssStyleUrl)) {
  223. var node = document.createElement("link");
  224. node.type = 'text/css';
  225. node.rel = "stylesheet"
  226. node.href = cssStyleUrl;
  227. document.getElementsByTagName("head")[0].appendChild(node);
  228. }
  229. if (onloadHandler) {
  230. onloadHandler();
  231. }
  232. }
  233. this._addFragContentDiv = function(frag) {
  234. var fragId=frag.id;
  235. var contentId = fragId+'content';
  236. var contentDiv = $(contentId);
  237. if (!contentDiv) {
  238. contentDiv = document.createElement("div");
  239. contentDiv.id = contentId;
  240. contentDiv.className = "boxBody";
  241. $(fragId).appendChild(contentDiv);
  242. }
  243. var waitDiv = ui_templates.get(
  244. ui_templates.contentTemplate,
  245. 'CONTENTID', fragId + "wait",
  246. 'CONTENTCLASS', 'cogstyle-htabs-page-content'
  247. );
  248. contentDiv.innerHTML = waitDiv;
  249. return contentDiv;
  250. }
  251. this._generateRetrieveParams = function(registeredFrag) {
  252. var params = null;
  253. if (registeredFrag.retrieveParams) {
  254. if (typeof registeredFrag.retrieveParams == "string"){
  255. params = registeredFrag.retrieveParams;
  256. } else if (typeof registeredFrag.retrieveParams == "function") {
  257. params = registeredFrag.retrieveParams();
  258. } else {
  259. //unknown type: ignore it
  260. _F_log("W", "embedFragment(): Unsupported value for the retrieve params: " + registeredFrag.retrieveParams);
  261. }
  262. }
  263. return params;
  264. }
  265. this._fragInit = function(registeredFrag) {
  266. var params = null;
  267. fragDiv = $(registeredFrag.fragDivId);
  268. if (!fragDiv) {
  269. _F_log("E", "embedFragment(): DOM element not found for fragDivId="+registeredFrag.fragDivId);
  270. } else {
  271. _F_init();
  272. embeddedFrag = new fragment(registeredFrag.fragUrl, registeredFrag.fragDivId);
  273. embeddedFrag.setOnloadHandler(ui_init);
  274. embeddedFrag.div = _self._addFragContentDiv(embeddedFrag);
  275. embeddedFrag.addEventListener("fragment.retrieve.after",this._postFragRetrieve,false);
  276. registeredFrag.fragment = embeddedFrag;
  277. }
  278. }
  279. this._retrieveFragment = function() {
  280. var registeredFrag = null;
  281. var params = null;
  282. if (this._retrievedFragments < this._frags.length) {
  283. registeredFrag = this._frags[this._retrievedFragments];
  284. this._retrievedFragments++;
  285. if (registeredFrag.fragment) {
  286. params = _self._generateRetrieveParams(registeredFrag);
  287. registeredFrag.fragment.retrieve(params);
  288. } else {
  289. this._retrieveFragment();
  290. }
  291. }
  292. }
  293. this._postFragRetrieve = function(event) {
  294. var fragContentDiv = null;
  295. if (event && event.source && event.source.error) {
  296. fragContentDiv = $(event.source.div);
  297. if (fragContentDiv) {
  298. fragContentDiv.style.display = "none";
  299. }
  300. }
  301. _self._retrieveFragment();
  302. }
  303. }