espelhamento de
https://github.com/vaadin/framework.git
sincronizado 2024-07-29 08:17:37 +02:00
325 linhas
8.7 KiB
JavaScript
325 linhas
8.7 KiB
JavaScript
(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);
|
|
}
|
|
|
|
url += "&v-appId=" + appId;
|
|
|
|
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');
|
|
})();
|