123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- (function() {
- var apps = {};
- var themesLoaded = {};
- var widgetsets = {};
-
-
- var log;
- if (typeof console === "undefined" || !window.location.search.match(/[&?]debug(&|$)/)) {
- //If no console.log present, just use a no-op
- log = function() {};
- } else if (typeof console.log === "function") {
- //If it's a function, use it with apply
- log = function() {
- console.log.apply(console, arguments);
- };
- } else {
- //In IE, its a native function for which apply is not defined, but it works without a proper 'this' reference
- log = console.log;
- }
-
- var loadTheme = function(url) {
- if(!themesLoaded[url]) {
- log("loadTheme", url);
- var stylesheet = document.createElement('link');
- stylesheet.setAttribute('rel', 'stylesheet');
- stylesheet.setAttribute('type', 'text/css');
- stylesheet.setAttribute('href', url + "/styles.css");
- document.getElementsByTagName('head')[0].appendChild(stylesheet);
- themesLoaded[url] = true;
- }
- };
-
- var isWidgetsetLoaded = function(widgetset) {
- var className = widgetset.replace(/\./g, "_");
- return (typeof window[className]) != "undefined";
- };
-
- var loadWidgetset = function(url, widgetset) {
- if (widgetsets[widgetset]) {
- return;
- }
- log("load widgetset", url, widgetset);
- setTimeout(function() {
- if (!isWidgetsetLoaded(widgetset)) {
- alert("Failed to load the widgetset: " + url);
- }
- }, 15000);
-
- var scriptTag = document.createElement('script');
- scriptTag.setAttribute('type', 'text/javascript');
- scriptTag.setAttribute('src', url);
- document.getElementsByTagName('head')[0].appendChild(scriptTag);
-
- widgetsets[widgetset] = {
- pendingApps: []
- };
- };
-
- var isInitializedInDom = function(appId) {
- var appDiv = document.getElementById(appId);
- if (!appDiv) {
- return false;
- }
- for ( var i = 0; i < appDiv.childElementCount; i++) {
- var className = appDiv.childNodes[i].className;
- // If the app div contains a child with the class
- // "v-app-loading" we have only received the HTML
- // but not yet started the widget set
- // (UIConnector removes the v-app-loading div).
- if (className && className.contains("v-app-loading")) {
- return false;
- }
- }
- return true;
- };
-
- window.vaadin = window.vaadin || {
- initApplication: function(appId, config) {
- var testbenchId = appId.replace(/-\d+$/, '');
-
- if (apps[appId]) {
- if (window.vaadin && window.vaadin.clients && window.vaadin.clients[testbenchId] && window.vaadin.clients[testbenchId].initializing) {
- throw "Application " + appId + " is already being initialized";
- }
- if (isInitializedInDom(appId)) {
- throw "Application " + appId + " already initialized";
- }
- }
-
- log("init application", appId, config);
-
- window.vaadin.clients[testbenchId] = {
- isActive: function() {
- return true;
- },
- initializing: true
- };
-
- var getConfig = function(name) {
- var value = config[name];
- return value;
- };
-
- var fetchRootConfig = function() {
- log('Fetching root config');
- var url = getConfig('browserDetailsUrl');
- if (!url) {
- // No special url defined, use the same URL that loaded this page (without the fragment)
- url = window.location.href.replace(/#.*/,'');
- }
- url += ((/\?/).test(url) ? "&" : "?") + "v-browserDetails=1";
- var rootId = getConfig("v-rootId");
- if (rootId !== undefined) {
- url += "&v-rootId=" + rootId;
- }
-
- // Tell the UI what theme it is configured to use
- var theme = getConfig('theme');
- if (theme !== undefined) {
- url += '&theme=' + encodeURIComponent(theme);
- }
-
- // Tell the UI what pushMode it is configured to use
- var pushMode = getConfig('pushMode');
- if (pushMode !== undefined) {
- url += '&v-pushMode=' + encodeURIComponent(pushMode);
- }
-
- var extraParams = getConfig('extraParams')
- if (extraParams !== undefined) {
- url += extraParams;
- }
-
- url += '&' + vaadin.getBrowserDetailsParameters(appId);
-
- // Timestamp to avoid caching
- url += '&v-' + (new Date()).getTime();
-
- var r;
- try {
- r = new XMLHttpRequest();
- } catch (e) {
- r = new ActiveXObject("MSXML2.XMLHTTP.3.0");
- }
- r.open('POST', url, true);
- r.onreadystatechange = function (aEvt) {
- if (r.readyState == 4) {
- var text = r.responseText;
- if (r.status == 200){
- log("Got root config response", text);
- var updatedConfig = JSON.parse(text);
-
- // Copy new properties to the config object
- for (var property in updatedConfig) {
- if (updatedConfig.hasOwnProperty(property)) {
- config[property] = updatedConfig[property];
- }
- }
-
- // Try bootstrapping again, this time without fetching missing info
- bootstrapApp(false);
- } else {
- log('Error', r.statusText, text);
-
- //Let TB waitForVaadin work again
- delete window.vaadin.clients[testbenchId];
-
- // Show the error in the app's div
- var appDiv = document.getElementById(appId);
- appDiv.innerHTML = text;
- appDiv.style['overflow'] = 'auto';
- }
- }
- };
- r.send(null);
-
- log('sending request to ', url);
- };
-
- //Export public data
- var app = {
- 'getConfig': getConfig
- };
- apps[appId] = app;
-
- if (!window.name) {
- window.name = appId + '-' + Math.random();
- }
-
- var bootstrapApp = function(mayDefer) {
- var vaadinDir = getConfig('vaadinDir');
-
- var themeUri = vaadinDir + 'themes/' + getConfig('theme');
- loadTheme(themeUri);
-
- var widgetset = getConfig('widgetset');
- var widgetsetUrl = getConfig('widgetsetUrl');
- if (!widgetsetUrl) {
- widgetsetUrl = vaadinDir + 'widgetsets/' + widgetset + "/" + widgetset + ".nocache.js?" + new Date().getTime();
- }
- loadWidgetset(widgetsetUrl, widgetset);
-
- if (getConfig('uidl') === undefined) {
- if (mayDefer) {
- fetchRootConfig();
- } else {
- throw "May not defer bootstrap any more";
- }
- } else {
- if (widgetsets[widgetset].callback) {
- log("Starting from bootstrap", appId);
- widgetsets[widgetset].callback(appId);
- } else {
- log("Setting pending startup", appId);
- widgetsets[widgetset].pendingApps.push(appId);
- }
- }
- };
- bootstrapApp(true);
-
- if (getConfig("debug")) {
- // TODO debug state is now global for the entire page, but should somehow only be set for the current application
- window.vaadin.debug = true;
- }
-
- return app;
- },
- clients: {},
- getApp: function(appId) {
- var app = apps[appId];
- return app;
- },
- loadTheme: loadTheme,
- registerWidgetset: function(widgetset, callback) {
- log("Widgetset registered", widgetset);
- widgetsets[widgetset].callback = callback;
- for(var i = 0; i < widgetsets[widgetset].pendingApps.length; i++) {
- var appId = widgetsets[widgetset].pendingApps[i];
- log("Starting from register widgetset", appId);
- callback(appId);
- }
- widgetsets[widgetset].pendingApps = null;
- },
- getBrowserDetailsParameters: function(parentElementId) {
- // Screen height and width
- var url = 'v-sh=' + window.screen.height;
- url += '&v-sw=' + window.screen.width;
-
- // Window height and width
- var cw = 0;
- var ch = 0;
- if(typeof(window.innerWidth) == 'number') {
- // Modern browsers
- cw = window.innerWidth;
- ch = window.innerHeight;
- } else {
- // IE 8
- cw = document.documentElement.clientWidth;
- ch = document.documentElement.clientHeight;
- }
- url += '&v-cw=' + cw + '&v-ch=' + ch;
-
-
- var d = new Date();
-
- url += '&v-curdate=' + d.getTime();
-
- var tzo1 = d.getTimezoneOffset(); // current offset
- var dstDiff = 0;
- var rtzo = tzo1;
-
- for (var m=12;m>0;m--) {
- d.setUTCMonth(m);
- var tzo2 = d.getTimezoneOffset();
- if (tzo1 != tzo2) {
- dstDiff = (tzo1 > tzo2 ? tzo1-tzo2 : tzo2-tzo1); // offset w/o DST
- rtzo = (tzo1 > tzo2 ? tzo1 : tzo2); // offset w/o DST
- break;
- }
- }
-
- // Time zone offset
- url += '&v-tzo=' + tzo1;
-
- // DST difference
- url += '&v-dstd=' + dstDiff;
-
- // Raw time zone offset
- url += '&v-rtzo=' + rtzo;
-
- // DST in effect?
- url += '&v-dston=' + (tzo1 != rtzo);
-
- var pe = document.getElementById(parentElementId);
- if (pe) {
- url += '&v-vw=' + pe.offsetWidth;
- url += '&v-vh=' + pe.offsetHeight;
- }
-
- // Location
- url += '&v-loc=' + encodeURIComponent(location.href);
-
- // Window name
- if (window.name) {
- url += '&v-wn=' + encodeURIComponent(window.name);
- }
-
- // Detect touch device support
- var supportsTouch = false;
- try {
- document.createEvent("TouchEvent");
- supportsTouch = true;
- } catch (e) {
- // Chrome and IE10 touch detection
- supportsTouch = 'ontouchstart' in window
- || navigator.msMaxTouchPoints;
- }
-
- if (supportsTouch) {
- url += "&v-td=1";
- }
-
- return url;
- }
- };
-
- log('Vaadin bootstrap loaded');
- })();
|