PageRenderTime 47ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/cfidescripts/ajax/spry/widgets/htmlpanel/SpryHTMLPanel.js

https://gitlab.com/marioalvarez/ferrominio
JavaScript | 478 lines | 334 code | 81 blank | 63 comment | 92 complexity | de7b9295535e9f77befcee34bc97b2e5 MD5 | raw file
  1. // SpryHTMLPanel.js - version 0.4 - Spry Pre-Release 1.6
  2. //
  3. // Copyright (c) 2006. Adobe Systems Incorporated.
  4. // All rights reserved.
  5. //
  6. // Redistribution and use in source and binary forms, with or without
  7. // modification, are permitted provided that the following conditions are met:
  8. //
  9. // * Redistributions of source code must retain the above copyright notice,
  10. // this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above copyright notice,
  12. // this list of conditions and the following disclaimer in the documentation
  13. // and/or other materials provided with the distribution.
  14. // * Neither the name of Adobe Systems Incorporated nor the names of its
  15. // contributors may be used to endorse or promote products derived from this
  16. // software without specific prior written permission.
  17. //
  18. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  19. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  22. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  23. // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  24. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  25. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  26. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  28. // POSSIBILITY OF SUCH DAMAGE.
  29. var Spry; if (!Spry) Spry = {}; if (!Spry.Widget) Spry.Widget = {};
  30. Spry.Widget.HTMLPanel = function(ele, opts)
  31. {
  32. Spry.Widget.HTMLPanel.Notifier.call(this);
  33. this.element = Spry.Widget.HTMLPanel.$(ele);
  34. // evalScripts controls whether or not we execute any script that is within
  35. // an HTML fragment we load into the panel's container. The default value for
  36. // this comes from our global flag, but users can override this setting for
  37. // a specific HTMLPanel instance with an evalScripts constructor option.
  38. this.evalScripts = Spry.Widget.HTMLPanel.evalScripts;
  39. // These class names are used to identify content *inside* the panel's container
  40. // when the panel is first created. If the HTMLPanel finds any elements
  41. // with these class names, it will remove the elements from the document
  42. // and tuck away their content. The HTMLPanel will then inject this content
  43. // back into the its container at the appropriate time.
  44. //
  45. // This gives the designer an option for specifying content they want shown
  46. // when the HTMLPanel is loading content or has encountered an error.
  47. this.loadingContentClass = "HTMLPanelLoadingContent";
  48. this.errorContentClass = "HTMLPanelErrorContent";
  49. this.loadingStateContent = "";
  50. this.errorStateContent = "";
  51. // These class names are placed on the panel's container whenever the HTMLPanel
  52. // loads content, or has encountered an error. This is an alternative to specifying
  53. // content to use during loading and error states. Instead, the designer would simply
  54. // define CSS rules that use these class names to alter the appearance of the panel's
  55. // container.
  56. this.loadingStateClass = "HTMLPanelLoading";
  57. this.errorStateClass = "HTMLPanelError";
  58. // The current request that is pending completion.
  59. this.pendingRequest = null;
  60. Spry.Widget.HTMLPanel.setOptions(this, opts);
  61. // Find any content within the panel's container that is supposed to be
  62. // used for the loading and error states.
  63. var elements = this.element.getElementsByTagName("*");
  64. var numElements = elements.length;
  65. var errorEle = null;
  66. var loadingEle = null;
  67. var d = document.createElement("div");
  68. for (var i = 0; i < numElements && (!loadingEle || !errorEle); i++)
  69. {
  70. var e = elements[i];
  71. if (Spry.Widget.HTMLPanel.hasClassName(e, this.loadingContentClass))
  72. loadingEle = e;
  73. if (Spry.Widget.HTMLPanel.hasClassName(e, this.errorContentClass))
  74. errorEle = e;
  75. }
  76. if (loadingEle)
  77. this.loadingStateContent = Spry.Widget.HTMLPanel.removeAndExtractContent(loadingEle, this.loadingContentClass);
  78. if (errorEle)
  79. this.errorStateContent = Spry.Widget.HTMLPanel.removeAndExtractContent(errorEle, this.errorContentClass);
  80. };
  81. // Global switch that decides whether or not HTMLPanels execute
  82. // script embedded within HTML fragments, after the fragment is inserted
  83. // into the DOM. If false, no HTMLPanel will execute any script embedded
  84. // within an HTML fragment.
  85. Spry.Widget.HTMLPanel.evalScripts = false;
  86. Spry.Widget.HTMLPanel.Notifier = function()
  87. {
  88. this.observers = [];
  89. this.suppressNotifications = 0;
  90. };
  91. Spry.Widget.HTMLPanel.Notifier.prototype.addObserver = function(observer)
  92. {
  93. if (!observer)
  94. return;
  95. // Make sure the observer isn't already on the list.
  96. var len = this.observers.length;
  97. for (var i = 0; i < len; i++)
  98. {
  99. if (this.observers[i] == observer)
  100. return;
  101. }
  102. this.observers[len] = observer;
  103. };
  104. Spry.Widget.HTMLPanel.Notifier.prototype.removeObserver = function(observer)
  105. {
  106. if (!observer)
  107. return;
  108. for (var i = 0; i < this.observers.length; i++)
  109. {
  110. if (this.observers[i] == observer)
  111. {
  112. this.observers.splice(i, 1);
  113. break;
  114. }
  115. }
  116. };
  117. Spry.Widget.HTMLPanel.Notifier.prototype.notifyObservers = function(methodName, data)
  118. {
  119. if (!methodName)
  120. return;
  121. if (!this.suppressNotifications)
  122. {
  123. var len = this.observers.length;
  124. for (var i = 0; i < len; i++)
  125. {
  126. var obs = this.observers[i];
  127. if (obs)
  128. {
  129. if (typeof obs == "function")
  130. obs(methodName, this, data);
  131. else if (obs[methodName])
  132. obs[methodName](this, data);
  133. }
  134. }
  135. }
  136. };
  137. Spry.Widget.HTMLPanel.Notifier.prototype.enableNotifications = function()
  138. {
  139. if (--this.suppressNotifications < 0)
  140. {
  141. this.suppressNotifications = 0;
  142. Spry.Debug.reportError("Unbalanced enableNotifications() call!\n");
  143. }
  144. };
  145. Spry.Widget.HTMLPanel.Notifier.prototype.disableNotifications = function()
  146. {
  147. ++this.suppressNotifications;
  148. };
  149. Spry.Widget.HTMLPanel.prototype = new Spry.Widget.HTMLPanel.Notifier();
  150. Spry.Widget.HTMLPanel.prototype.constructor = Spry.Widget.HTMLPanel;
  151. Spry.Widget.HTMLPanel.$ = function(ele)
  152. {
  153. if (ele && typeof ele == "string")
  154. return document.getElementById(ele);
  155. return ele;
  156. };
  157. Spry.Widget.HTMLPanel.setOptions = function(dstObj, srcObj, ignoreUndefinedProps)
  158. {
  159. if (srcObj)
  160. {
  161. for (var optionName in srcObj)
  162. {
  163. if (ignoreUndefinedProps && srcObj[optionName] == undefined)
  164. continue;
  165. dstObj[optionName] = srcObj[optionName];
  166. }
  167. }
  168. };
  169. Spry.Widget.HTMLPanel.addClassName = function(ele, className)
  170. {
  171. ele = Spry.Widget.HTMLPanel.$(ele);
  172. if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) != -1))
  173. return;
  174. ele.className += (ele.className ? " " : "") + className;
  175. };
  176. Spry.Widget.HTMLPanel.removeClassName = function(ele, className)
  177. {
  178. ele = Spry.Widget.HTMLPanel.$(ele);
  179. if (Spry.Widget.HTMLPanel.hasClassName(ele, className))
  180. ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");
  181. };
  182. Spry.Widget.HTMLPanel.hasClassName = function(ele, className)
  183. {
  184. ele = Spry.Widget.HTMLPanel.$(ele);
  185. if (!ele || !className || !ele.className || ele.className.search(new RegExp("\\b" + className + "\\b")) == -1)
  186. return false;
  187. return true;
  188. };
  189. Spry.Widget.HTMLPanel.removeAndExtractContent = function(ele, className)
  190. {
  191. var d = document.createElement("div");
  192. if (ele)
  193. {
  194. d.appendChild(ele);
  195. if (className)
  196. Spry.Widget.HTMLPanel.removeClassName(ele, className);
  197. }
  198. return d.innerHTML;
  199. };
  200. Spry.Widget.HTMLPanel.findNodeById = function(id, node)
  201. {
  202. if (node && node.nodeType == 1 /* NODE.ELEMENT_NODE */)
  203. {
  204. if (node.id == id)
  205. return node;
  206. var child = node.firstChild;
  207. while (child)
  208. {
  209. var result = Spry.Widget.HTMLPanel.findNodeById(id, child);
  210. if (result)
  211. return result;
  212. child = child.nextSibling;
  213. }
  214. }
  215. return null;
  216. };
  217. Spry.Widget.HTMLPanel.disableSrcReferences = function (source)
  218. {
  219. if (source)
  220. source = source.replace(/<(img|script|link|frame|iframe|input)([^>]+)>/gi, function(a,b,c) {
  221. // b=tag name, c=tag attributes
  222. return '<' + b + c.replace(/\b(src|href)\s*=/gi, function(a, b) {
  223. // b=attribute name
  224. return 'spry_'+ b + '=';
  225. }) + '>';
  226. });
  227. return source;
  228. };
  229. Spry.Widget.HTMLPanel.enableSrcReferences = function (source)
  230. {
  231. source = source.replace(/<(img|script|link|frame|iframe|input)([^>]+)>/gi, function(a,b,c) {
  232. // b=tag name, c=tag attributes
  233. return '<' + b + c.replace(/\bspry_(src|href)\s*=/gi, function(a, b) {
  234. // b=attribute name
  235. return b + '=';
  236. }) + '>';
  237. });
  238. return source;
  239. };
  240. Spry.Widget.HTMLPanel.getFragByID = function(id, contentStr)
  241. {
  242. var frag = Spry.Widget.HTMLPanel.disableSrcReferences(contentStr);
  243. var div = document.createElement("div");
  244. div.innerHTML = frag;
  245. frag = "";
  246. var node = Spry.Widget.HTMLPanel.findNodeById(id, div);
  247. if (node)
  248. frag = node.innerHTML;
  249. return Spry.Widget.HTMLPanel.enableSrcReferences(frag);
  250. };
  251. Spry.Widget.HTMLPanel.prototype.setContent = function(contentStr, id)
  252. {
  253. var data = { content: contentStr, id: id };
  254. this.notifyObservers("onPreUpdate", data);
  255. // Observers are allowed to modify the data. Make sure
  256. // the fragment and id we use are from the data that was
  257. // past to our observers.
  258. contentStr = data.content;
  259. id = data.id;
  260. // If we have a valid id, extract the markup underneath
  261. // the element with that id from our html fragment.
  262. if (typeof id != "undefined")
  263. contentStr = Spry.Widget.HTMLPanel.getFragByID(id, contentStr);
  264. // Slam the html fragment into the DOM.
  265. Spry.Widget.HTMLPanel.setInnerHTML(this.element, contentStr, !this.evalScripts);
  266. this.removeStateClasses();
  267. this.notifyObservers("onPostUpdate", data);
  268. };
  269. Spry.Widget.HTMLPanel.prototype.loadContent = function(url, opts)
  270. {
  271. if (!this.element)
  272. return;
  273. this.cancelLoad();
  274. if (!opts)
  275. opts = new Object;
  276. opts.url = opts.url ? opts.url : url;
  277. opts.method = opts.method ? opts.method : "GET";
  278. opts.async = opts.async ? opts.async : true;
  279. opts.id = opts.id ? opts.id : undefined;
  280. var self = this;
  281. opts.errorCallback = function(req) { self.onLoadError(req); };
  282. this.notifyObservers("onPreLoad", opts);
  283. if (this.loadingStateContent)
  284. this.setContent(this.loadingStateContent);
  285. Spry.Widget.HTMLPanel.addClassName(this.element, this.loadingStateClass);
  286. this.pendingRequest = Spry.Widget.HTMLPanel.loadURL(opts.method, opts.url, opts.async, function(req){ self.onLoadSuccessful(req); }, opts);
  287. };
  288. Spry.Widget.HTMLPanel.prototype.cancelLoad = function()
  289. {
  290. try
  291. {
  292. if (this.pendingRequest && this.pendingRequest.xhRequest)
  293. {
  294. var xhr = this.pendingRequest.xhRequest;
  295. if (xhr.abort)
  296. xhr.abort();
  297. xhr.onreadystatechange = null;
  298. this.notifyObservers("onLoadCancelled", this.pendingRequest);
  299. }
  300. }
  301. catch(e) {}
  302. this.pendingRequest = null;
  303. };
  304. Spry.Widget.HTMLPanel.prototype.removeStateClasses = function()
  305. {
  306. Spry.Widget.HTMLPanel.removeClassName(this.element, this.loadingStateClass);
  307. Spry.Widget.HTMLPanel.removeClassName(this.element, this.errorStateClass);
  308. };
  309. Spry.Widget.HTMLPanel.prototype.onLoadSuccessful = function(req)
  310. {
  311. this.notifyObservers("onPostLoad", req);
  312. this.setContent(req.xhRequest.responseText, req.id);
  313. this.pendingRequest = null;
  314. };
  315. Spry.Widget.HTMLPanel.prototype.onLoadError = function(req)
  316. {
  317. this.notifyObservers("onLoadError", req);
  318. if (this.errorStateContent)
  319. this.setContent(this.errorStateContent);
  320. Spry.Widget.HTMLPanel.addClassName(this.element, this.errorStateClass);
  321. this.pendingRequest = null;
  322. };
  323. Spry.Widget.HTMLPanel.msProgIDs = ["MSXML2.XMLHTTP.6.0", "MSXML2.XMLHTTP.3.0"];
  324. Spry.Widget.HTMLPanel.createXMLHttpRequest = function()
  325. {
  326. var req = null;
  327. if (window.ActiveXObject)
  328. {
  329. while (!req && Spry.Widget.HTMLPanel.msProgIDs.length)
  330. {
  331. try { req = new ActiveXObject(Spry.Widget.HTMLPanel.msProgIDs[0]); } catch (e) { req = null; }
  332. if (!req)
  333. Spry.Widget.HTMLPanel.msProgIDs.splice(0, 1);
  334. }
  335. }
  336. if (!req && window.XMLHttpRequest) { try { req = new XMLHttpRequest(); } catch (e) { req = null; } }
  337. return req;
  338. };
  339. Spry.Widget.HTMLPanel.loadURL = function(method, url, async, callback, opts)
  340. {
  341. var req = new Object;
  342. req.method = method;
  343. req.url = url;
  344. req.async = async;
  345. req.successCallback = callback;
  346. Spry.Widget.HTMLPanel.setOptions(req, opts);
  347. try
  348. {
  349. req.xhRequest = Spry.Widget.HTMLPanel.createXMLHttpRequest();
  350. if (!req.xhRequest)
  351. return null;
  352. if (req.async)
  353. req.xhRequest.onreadystatechange = function() { Spry.Widget.HTMLPanel.loadURL.callback(req); };
  354. req.xhRequest.open(method, req.url, req.async, req.username, req.password);
  355. if (req.headers)
  356. {
  357. for (var name in req.headers)
  358. req.xhRequest.setRequestHeader(name, req.headers[name]);
  359. }
  360. req.xhRequest.send(req.postData);
  361. if (!req.async)
  362. Spry.Widget.HTMLPanel.loadURL.callback(req);
  363. }
  364. catch(e) { if (req.errorCallback) req.errorCallback(req); req = null; }
  365. return req;
  366. };
  367. Spry.Widget.HTMLPanel.loadURL.callback = function(req)
  368. {
  369. if (!req || req.xhRequest.readyState != 4)
  370. return;
  371. if (req.successCallback && (req.xhRequest.status == 200 || req.xhRequest.status == 0))
  372. req.successCallback(req);
  373. else if (req.errorCallback)
  374. req.errorCallback(req);
  375. };
  376. Spry.Widget.HTMLPanel.eval = function(str) { return eval(str); };
  377. Spry.Widget.HTMLPanel.setInnerHTML = function(ele, str, preventScripts)
  378. {
  379. if (!ele)
  380. return;
  381. if (!str) str = "";
  382. ele = Spry.Widget.HTMLPanel.$(ele);
  383. var scriptExpr = "<script[^>]*>(.|\s|\n|\r)*?</script>";
  384. ele.innerHTML = str.replace(new RegExp(scriptExpr, "img"), "");
  385. if (preventScripts)
  386. return;
  387. var matches = str.match(new RegExp(scriptExpr, "img"));
  388. if (matches)
  389. {
  390. var numMatches = matches.length;
  391. for (var i = 0; i < numMatches; i++)
  392. {
  393. var s = matches[i].replace(/<script[^>]*>[\s\r\n]*(<\!--)?|(-->)?[\s\r\n]*<\/script>/img, "");
  394. Spry.Widget.HTMLPanel.eval(s);
  395. }
  396. }
  397. };