PageRenderTime 144ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/js/embed.js

http://github.com/vanillaforums/Garden
JavaScript | 367 lines | 293 code | 50 blank | 24 comment | 122 complexity | 432dfc8f9121aed47424ec9c61c4a164 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0, AGPL-1.0, BSD-3-Clause, MIT
  1. if (window.vanilla == undefined)
  2. window.vanilla = {};
  3. if (window.vanilla.embeds == undefined)
  4. window.vanilla.embeds = {};
  5. window.vanilla.embed = function(host) {
  6. var scripts = document.getElementsByTagName('script'),
  7. id = Math.floor((Math.random()) * 100000).toString(),
  8. embedUrl = window.location.href.split('#')[0],
  9. jsPath = '/js/embed.js',
  10. currentPath = window.location.hash.substr(1),
  11. disablePath = (window != top);
  12. var optStr = function(name, defaultValue, definedValue) {
  13. if (window['vanilla_' + name]) {
  14. if (definedValue == undefined)
  15. return window['vanilla_' + name];
  16. else
  17. return definedValue.replace('%s', window['vanilla_' + name]);
  18. }
  19. return defaultValue;
  20. }
  21. if (!currentPath || disablePath)
  22. currentPath = "/";
  23. if (currentPath.substr(0, 1) != '/')
  24. currentPath = '/' + currentPath;
  25. if (window.gadgets)
  26. embedUrl = '';
  27. if (typeof(host) == 'undefined') {
  28. host = '';
  29. host_base_url = '';
  30. for (i = 0; i < scripts.length; i++) {
  31. if (scripts[i].src.indexOf(jsPath) > 0) {
  32. host = scripts[i].src;
  33. host = host.replace('http://', '').replace('https://', '');
  34. host = host.substr(0, host.indexOf(jsPath));
  35. host_base_url = scripts[i].src;
  36. host_base_url = host_base_url.substr(0, host_base_url.indexOf(jsPath));
  37. if (host_base_url.substring(host_base_url.length - 1) != '/')
  38. host_base_url += '/';
  39. }
  40. }
  41. }
  42. window.vanilla.embeds[id] = this;
  43. if (window.postMessage) {
  44. onMessage = function(e) {
  45. // Check that we're getting a vanilla message
  46. if ((typeof e.data) === 'string') {
  47. var message = e.data.split(':');
  48. var frame = document.getElementById('vanilla' + id);
  49. // Unload event's source is undefined
  50. var isUnload = message[0] == 'unload';
  51. if (!frame || (!isUnload && frame.contentWindow != e.source)) {
  52. return;
  53. }
  54. processMessage(message);
  55. }
  56. };
  57. if (window.addEventListener) {
  58. window.addEventListener("message", onMessage, false);
  59. } else {
  60. window.attachEvent("onmessage", onMessage);
  61. }
  62. } else {
  63. var messageId = null;
  64. setInterval(function() {
  65. try {
  66. var vid = 'vanilla' + id;
  67. var hash = window.frames[vid].frames['messageFrame'].location.hash;
  68. hash = hash.substr(6);
  69. } catch (e) {
  70. return;
  71. }
  72. var message = hash.split(':');
  73. var newMessageId = message[0];
  74. if (newMessageId == messageId) {
  75. return;
  76. }
  77. messageId = newMessageId;
  78. message.splice(0, 1);
  79. processMessage(message);
  80. }, 200);
  81. }
  82. checkHash = function() {
  83. var path = window.location.hash.substr(1) || "/";
  84. if (path != currentPath) {
  85. currentPath = path;
  86. window.frames['vanilla' + id].location.replace(vanillaUrl(path));
  87. }
  88. };
  89. if (!window.gadgets) {
  90. if (!disablePath) {
  91. if ("onhashchange" in window) {
  92. if (window.addEventListener)
  93. window.addEventListener("hashchange", checkHash, false);
  94. else
  95. window.attachEvent("onhashchange", checkHash);
  96. } else {
  97. setInterval(checkHash, 300);
  98. }
  99. }
  100. }
  101. // Strip param out of str if it exists
  102. stripParam = function(str, param) {
  103. var pIndex = str.indexOf(param);
  104. if (pIndex > -1) {
  105. var pStr = str.substr(pIndex);
  106. var tIndex = pStr.indexOf('&');
  107. var trail = tIndex > -1 ? pStr.substr(tIndex + 1) : '';
  108. var pre = currentPath.substr(pIndex - 1, 1);
  109. if (pre == '&' || pre == '?')
  110. pIndex--;
  111. return str.substr(0, pIndex) + (trail.length > 0 ? pre : '') + trail;
  112. }
  113. return str;
  114. }
  115. processMessage = function(message) {
  116. var iframe = document.getElementById('vanilla' + id);
  117. if (message[0] == 'height') {
  118. setHeight(message[1]);
  119. if (message[1] > 0) {
  120. iframe.style.visibility = "visible";
  121. }
  122. } else if (message[0] == 'location') {
  123. if (message[1] != '') {
  124. iframe.style.visibility = "visible";
  125. }
  126. if (disablePath) {
  127. //currentPath = cmd[1];
  128. } else {
  129. currentPath = window.location.hash.substr(1);
  130. if (currentPath != message[1]) {
  131. currentPath = message[1];
  132. // Strip off the values that this script added
  133. currentPath = stripParam(currentPath, 'remote='); // 1
  134. currentPath = stripParam(currentPath, 'locale='); // 2
  135. window.location.hash = currentPath;
  136. }
  137. }
  138. } else if (message[0] == 'unload') {
  139. // Scroll to the top of the IFRAME if the top position is not in the view.
  140. var currentScrollAmount = (window.pageYOffset || document.documentElement.scrollTop);
  141. var offsetTop = offsetFromTop('vanilla' + id);
  142. if (offsetTop - currentScrollAmount < 0) {
  143. window.scrollTo(0, offsetTop);
  144. }
  145. iframe.style.visibility = "hidden";
  146. } else if (message[0] == 'scrolltop') {
  147. window.scrollTo(0, document.getElementById('vanilla' + id).offsetTop);
  148. } else if (message[0] == 'scrollto') {
  149. window.scrollTo(0, document.getElementById('vanilla' + id).offsetTop - 40 + (message[1] * 1));
  150. } else if (message[0] == 'unembed') {
  151. document.location = 'http://' + host + window.location.hash.substr(1);
  152. }
  153. }
  154. offsetFromTop = function(id) {
  155. var node = document.getElementById(id),
  156. top = 0,
  157. topScroll = 0;
  158. if (node.offsetParent) {
  159. do {
  160. top += node.offsetTop;
  161. topScroll += node.offsetParent ? node.offsetParent.scrollTop : 0;
  162. } while (node = node.offsetParent);
  163. return top - topScroll;
  164. }
  165. return -1;
  166. }
  167. setHeight = function(height) {
  168. if (optStr('height'))
  169. return;
  170. document.getElementById('vanilla' + id).style['height'] = height + "px";
  171. if (window.gadgets && gadgets.window && gadgets.window.adjustHeight) {
  172. try {
  173. gadgets.window.adjustHeight();
  174. } catch (ex) {
  175. // Do nothing...
  176. }
  177. }
  178. }
  179. vanillaUrl = function(path) {
  180. // What type of embed are we performing?
  181. var embed_type = typeof(vanilla_embed_type) == 'undefined' ? 'standard' : vanilla_embed_type;
  182. // Are we loading a particular discussion based on discussion_id?
  183. var discussion_id = typeof(vanilla_discussion_id) == 'undefined' ? 0 : vanilla_discussion_id;
  184. // Are we loading a particular discussion based on foreign_id?
  185. var foreign_id = typeof(vanilla_identifier) == 'undefined' ? '' : vanilla_identifier;
  186. // Is there a foreign type defined? Possibly used to render the discussion
  187. // body a certain way in the forum? Also used to filter down to foreign
  188. // types so that matching foreign_id's across type don't clash.
  189. var foreign_type = typeof(vanilla_type) == 'undefined' ? 'page' : vanilla_type;
  190. // If embedding comments, should the newly created discussion be placed in a specific category?
  191. var category_id = typeof(vanilla_category_id) == 'undefined' ? '' : vanilla_category_id;
  192. // If embedding comments, this value will be used to reference the foreign content. Defaults to the url of the page this file is included in.
  193. var foreign_url = typeof(vanilla_url) == 'undefined' ? document.URL.split('#')[0] : vanilla_url;
  194. // Are we forcing a locale via Multilingual plugin?
  195. var embed_locale = typeof(vanilla_embed_locale) == 'undefined' ? '' : vanilla_embed_locale;
  196. if (typeof(vanilla_lazy_load) == 'undefined')
  197. vanilla_lazy_load = true;
  198. // If path was defined, and we're sitting at app root, use the defined path instead.
  199. if (typeof(vanilla_path) != 'undefined' && path == '/')
  200. path = vanilla_path;
  201. // Force type based on incoming variables
  202. if (discussion_id != '' || foreign_id != '')
  203. embed_type = 'comments';
  204. var result = '';
  205. if (embed_type == 'comments') {
  206. result = '//' + host + '/discussion/embed/'
  207. // Break the cache. /embed/ gets cached, looks like you are not logged in.
  208. + '&c=' + new Date().getTime()
  209. + '&vanilla_identifier=' + encodeURIComponent(foreign_id)
  210. + '&vanilla_url=' + encodeURIComponent(foreign_url);
  211. if (typeof(vanilla_type) != 'undefined')
  212. result += '&vanilla_type=' + encodeURIComponent(vanilla_type)
  213. if (typeof(vanilla_discussion_id) != 'undefined')
  214. result += '&vanilla_discussion_id=' + encodeURIComponent(vanilla_discussion_id);
  215. if (typeof(vanilla_category_id) != 'undefined')
  216. result += '&vanilla_category_id=' + encodeURIComponent(vanilla_category_id);
  217. if (typeof(vanilla_title) != 'undefined')
  218. result += '&title=' + encodeURIComponent(vanilla_title);
  219. } else {
  220. result = '//'
  221. + host
  222. + path
  223. + '&remote='
  224. + encodeURIComponent(embedUrl)
  225. + '&locale='
  226. + encodeURIComponent(embed_locale);
  227. }
  228. if (window.vanilla_sso) {
  229. result += '&sso=' + encodeURIComponent(vanilla_sso);
  230. }
  231. return result.replace(/\?/g, '&').replace('&', '?'); // Replace the first occurrence of amp with question.
  232. }
  233. var vanillaIframe = document.createElement('iframe');
  234. vanillaIframe.id = "vanilla" + id;
  235. vanillaIframe.name = "vanilla" + id;
  236. vanillaIframe.src = vanillaUrl(currentPath);
  237. vanillaIframe.scrolling = "no";
  238. vanillaIframe.frameBorder = "0";
  239. vanillaIframe.allowTransparency = true;
  240. vanillaIframe.border = "0";
  241. vanillaIframe.width = "100%";
  242. vanillaIframe.style.width = "100%";
  243. vanillaIframe.style.border = "0";
  244. vanillaIframe.style.display = "block"; // must be block
  245. if (window.postMessage) {
  246. vanillaIframe.height = "0";
  247. vanillaIframe.style.height = "0";
  248. } else {
  249. vanillaIframe.height = "300";
  250. vanillaIframe.style.height = "300px";
  251. }
  252. var img = document.createElement('div');
  253. img.className = 'vn-loading';
  254. img.style.textAlign = 'center';
  255. img.innerHTML = window.vanilla_loadinghtml ? vanilla_loadinghtml : '<img src="https://images.v-cdn.net/progress.gif" />';
  256. var container = document.getElementById('vanilla-comments');
  257. // Couldn't find the container, so dump it out and try again.
  258. if (!container)
  259. document.write('<div id="vanilla-comments"></div>');
  260. container = document.getElementById('vanilla-comments');
  261. if (container) {
  262. var loaded = function() {
  263. if (img) {
  264. container.removeChild(img);
  265. img = null;
  266. }
  267. vanillaIframe.style.visibility = "visible";
  268. };
  269. if (vanillaIframe.addEventListener) {
  270. vanillaIframe.addEventListener('load', loaded, true);
  271. } else if (vanillaIframe.attachEvent) {
  272. vanillaIframe.attachEvent('onload', loaded);
  273. } else
  274. setTimeout(2000, loaded);
  275. container.appendChild(img);
  276. // If jQuery is present in the page, include our defer-until-visible script
  277. if (vanilla_lazy_load && typeof jQuery != 'undefined') {
  278. jQuery.ajax({
  279. url: host_base_url + 'js/library/jquery.appear.js',
  280. dataType: 'script',
  281. cache: true,
  282. success: function() {
  283. // setTimeout(function() {
  284. if (jQuery.fn.appear)
  285. jQuery('#vanilla-comments').appear(function() {
  286. container.appendChild(vanillaIframe);
  287. });
  288. else
  289. container.appendChild(vanillaIframe); // fallback
  290. // }, 10000);
  291. }
  292. });
  293. } else {
  294. container.appendChild(vanillaIframe); // fallback: just load it
  295. }
  296. }
  297. // Include our embed css into the page
  298. var vanilla_embed_css = document.createElement('link');
  299. vanilla_embed_css.rel = 'stylesheet';
  300. vanilla_embed_css.type = 'text/css';
  301. vanilla_embed_css.href = host_base_url + (host_base_url.substring(host_base_url.length - 1) == '/' ? '' : '/') + 'applications/dashboard/design/embed.css';
  302. (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(vanilla_embed_css);
  303. return this;
  304. };
  305. try {
  306. if (window.location.hash.substr(0, 6) != "#poll:")
  307. window.vanilla.embed();
  308. } catch (e) {
  309. var error = document.createElement('div');
  310. error.style.padding = "10px";
  311. error.style.fontSize = "12px";
  312. error.style.fontFamily = "lucida grande";
  313. error.style.background = "#ffffff";
  314. error.style.color = "#000000";
  315. error.appendChild(document.createTextNode("Failed to embed Vanilla: " + e));
  316. (document.getElementById('vanilla-comments')).appendChild(error);
  317. }