You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

vaadinBootstrap.js 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. (function() {
  2. var apps = {};
  3. var themesLoaded = {};
  4. var widgetsets = {};
  5. var log;
  6. if (typeof console === "undefined" || !window.location.search.match(/[&?]debug(&|$)/)) {
  7. //If no console.log present, just use a no-op
  8. log = function() {};
  9. } else if (typeof console.log === "function") {
  10. //If it's a function, use it with apply
  11. log = function() {
  12. console.log.apply(console, arguments);
  13. };
  14. } else {
  15. //In IE, its a native function for which apply is not defined, but it works without a proper 'this' reference
  16. log = console.log;
  17. }
  18. var loadTheme = function(url) {
  19. if(!themesLoaded[url]) {
  20. log("loadTheme", url);
  21. var stylesheet = document.createElement('link');
  22. stylesheet.setAttribute('rel', 'stylesheet');
  23. stylesheet.setAttribute('type', 'text/css');
  24. stylesheet.setAttribute('href', url + "/styles.css");
  25. document.getElementsByTagName('head')[0].appendChild(stylesheet);
  26. themesLoaded[url] = true;
  27. }
  28. };
  29. var isWidgetsetLoaded = function(widgetset) {
  30. var className = widgetset.replace(/\./g, "_");
  31. return (typeof window[className]) != "undefined";
  32. };
  33. var loadWidgetset = function(basePath, widgetset) {
  34. if (widgetsets[widgetset]) {
  35. return;
  36. }
  37. log("load widgetset", basePath, widgetset);
  38. setTimeout(function() {
  39. if (!isWidgetsetLoaded(widgetset)) {
  40. alert("Failed to load the widgetset: " + url);
  41. }
  42. }, 15000);
  43. var url = basePath + widgetset + "/" + widgetset + ".nocache.js?" + new Date().getTime();
  44. var scriptTag = document.createElement('script');
  45. scriptTag.setAttribute('type', 'text/javascript');
  46. scriptTag.setAttribute('src', url);
  47. document.getElementsByTagName('head')[0].appendChild(scriptTag);
  48. widgetsets[widgetset] = {
  49. pendingApps: []
  50. };
  51. };
  52. window.vaadin = window.vaadin || {
  53. initApplication: function(appId, config) {
  54. if (apps[appId]) {
  55. throw "Application " + appId + " already initialized";
  56. }
  57. log("init application", appId, config);
  58. var testbenchId = appId.replace(/-\d+$/, '');
  59. window.vaadin.clients[testbenchId] = {
  60. isActive: function() {
  61. return true;
  62. }
  63. };
  64. var getConfig = function(name) {
  65. var value = config[name];
  66. return value;
  67. };
  68. var fetchRootConfig = function() {
  69. log('Fetching root config');
  70. var url = getConfig('browserDetailsUrl');
  71. if (!url) {
  72. // No special url defined, use the same URL that loaded this page (without the fragment)
  73. url = window.location.href.replace(/#.*/,'');
  74. }
  75. url += ((/\?/).test(url) ? "&" : "?") + "browserDetails=1";
  76. var rootId = getConfig("rootId");
  77. if (rootId !== undefined) {
  78. url += "&rootId=" + rootId;
  79. }
  80. // Tell the UI what theme it is configured to use
  81. var theme = getConfig('theme');
  82. if (theme !== undefined) {
  83. url += '&theme=' + encodeURIComponent(theme);
  84. }
  85. url += '&' + vaadin.getBrowserDetailsParameters(appId);
  86. // Timestamp to avoid caching
  87. url += '&' + (new Date()).getTime();
  88. var r = new XMLHttpRequest();
  89. r.open('POST', url, true);
  90. r.onreadystatechange = function (aEvt) {
  91. if (r.readyState == 4) {
  92. if (r.status == 200){
  93. log("Got root config response", r.responseText);
  94. var updatedConfig = JSON.parse(r.responseText);
  95. // Copy new properties to the config object
  96. for (var property in updatedConfig) {
  97. if (updatedConfig.hasOwnProperty(property)) {
  98. config[property] = updatedConfig[property];
  99. }
  100. }
  101. // Try bootstrapping again, this time without fetching missing info
  102. bootstrapApp(false);
  103. } else if (r.status == 500) {
  104. document.write(r.responseText);
  105. } else {
  106. log('Error', r.statusText);
  107. }
  108. }
  109. };
  110. r.send(null);
  111. log('sending request to ', url);
  112. };
  113. //Export public data
  114. var app = {
  115. 'getConfig': getConfig
  116. };
  117. apps[appId] = app;
  118. if (!window.name) {
  119. window.name = appId + '-' + Math.random();
  120. }
  121. var bootstrapApp = function(mayDefer) {
  122. var vaadinDir = getConfig('vaadinDir');
  123. var themeUri = vaadinDir + 'themes/' + getConfig('theme')
  124. loadTheme(themeUri);
  125. var widgetset = getConfig('widgetset');
  126. loadWidgetset(vaadinDir + 'widgetsets/', widgetset);
  127. if (getConfig('uidl') === undefined) {
  128. if (mayDefer) {
  129. fetchRootConfig();
  130. } else {
  131. throw "May not defer bootstrap any more";
  132. }
  133. } else {
  134. if (widgetsets[widgetset].callback) {
  135. log("Starting from bootstrap", appId);
  136. widgetsets[widgetset].callback(appId);
  137. } else {
  138. log("Setting pending startup", appId);
  139. widgetsets[widgetset].pendingApps.push(appId);
  140. }
  141. }
  142. };
  143. bootstrapApp(true);
  144. if (getConfig("debug")) {
  145. // TODO debug state is now global for the entire page, but should somehow only be set for the current application
  146. window.vaadin.debug = true;
  147. }
  148. return app;
  149. },
  150. clients: {},
  151. getApp: function(appId) {
  152. var app = apps[appId];
  153. return app;
  154. },
  155. loadTheme: loadTheme,
  156. registerWidgetset: function(widgetset, callback) {
  157. log("Widgetset registered", widgetset);
  158. widgetsets[widgetset].callback = callback;
  159. for(var i = 0; i < widgetsets[widgetset].pendingApps.length; i++) {
  160. var appId = widgetsets[widgetset].pendingApps[i];
  161. log("Starting from register widgetset", appId);
  162. callback(appId);
  163. }
  164. widgetsets[widgetset].pendingApps = null;
  165. },
  166. getBrowserDetailsParameters: function(parentElementId) {
  167. // Screen height and width
  168. var url = 'sh=' + window.screen.height;
  169. url += '&sw=' + window.screen.width;
  170. // Window height and width
  171. var cw = 0;
  172. var ch = 0;
  173. if(typeof(window.innerWidth) == 'number') {
  174. // Modern browsers
  175. cw = window.innerWidth;
  176. ch = window.innerHeight;
  177. } else {
  178. // IE 8
  179. cw = document.documentElement.clientWidth;
  180. ch = document.documentElement.clientHeight;
  181. }
  182. url += '&cw=' + cw + '&ch=' + ch;
  183. var d = new Date();
  184. url += '&curdate=' + d.getTime();
  185. var tzo1 = d.getTimezoneOffset(); // current offset
  186. var dstDiff = 0;
  187. var rtzo = tzo1;
  188. for (var m=12;m>0;m--) {
  189. d.setUTCMonth(m);
  190. var tzo2 = d.getTimezoneOffset();
  191. if (tzo1 != tzo2) {
  192. dstDiff = (tzo1 > tzo2 ? tzo1-tzo2 : tzo2-tzo1); // offset w/o DST
  193. rtzo = (tzo1 > tzo2 ? tzo1 : tzo2); // offset w/o DST
  194. break;
  195. }
  196. }
  197. // Time zone offset
  198. url += '&tzo=' + tzo1;
  199. // DST difference
  200. url += '&dstd=' + dstDiff;
  201. // Raw time zone offset
  202. url += '&rtzo=' + rtzo;
  203. // DST in effect?
  204. url += '&dston=' + (tzo1 != rtzo);
  205. var pe = document.getElementById(parentElementId);
  206. if (pe) {
  207. url += '&vw=' + pe.offsetWidth;
  208. url += '&vh=' + pe.offsetHeight;
  209. }
  210. // Location
  211. url += '&loc=' + encodeURIComponent(location.href);
  212. // Window name
  213. if (window.name) {
  214. url += '&wn=' + encodeURIComponent(window.name);
  215. }
  216. // Detect touch device support
  217. try { document.createEvent("TouchEvent"); url += "&td=1";} catch(e){};
  218. return url;
  219. }
  220. };
  221. log('Vaadin bootstrap loaded');
  222. })();