SeleniumBase/seleniumbase/js_code/live_js.py

182 lines
6.5 KiB
Python

###############################################################################
# live_js - Reload web pages when changes are detected on the server side.
###############################################################################
live_js = r"""
(function () {
var headers = {
"Etag": 1, "Last-Modified": 1, "Content-Length": 1, "Content-Type": 1 },
resources = {},
pendingRequests = {},
currentLinkElements = {},
oldLinkElements = {},
interval = 1000,
loaded = false,
active = { "html": 1, "css": 1, "js": 1 };
var Live = {
heartbeat: function () {
if (document.body) {
if (!loaded) Live.loadresources();
Live.checkForChanges();
}
setTimeout(Live.heartbeat, interval);
},
loadresources: function () {
function isLocal(url) {
var loc = document.location,
reg = new RegExp("^\\.|^\/(?!\/)|^[\\w]((?!://).)*$|"
+ loc.protocol + "//" + loc.host);
return url.match(reg);
}
var scripts = document.getElementsByTagName("script"),
links = document.getElementsByTagName("link"),
uris = [];
for (var i = 0; i < scripts.length; i++) {
var script = scripts[i], src = script.getAttribute("src");
if (src && isLocal(src))
uris.push(src);
if (src && src.match(/\blive.js#/)) {
for (var type in active)
active[type] = src.match("[#,|]" + type) != null
if (src.match("notify"))
alert("Live.js is loaded.");
}
}
if (!active.js) uris = [];
if (active.html) uris.push(document.location.href);
for (var i = 0; i < links.length && active.css; i++) {
var link = links[i], rel = link.getAttribute("rel"
),href = link.getAttribute("href", 2);
if (href && rel && rel.match(new RegExp("stylesheet", "i")
) && isLocal(href)) {
uris.push(href);
currentLinkElements[href] = link;
}
}
for (var i = 0; i < uris.length; i++) {
var url = uris[i];
Live.getHead(url, function (url, info) {
resources[url] = info;
});
}
var head = document.getElementsByTagName("head")[0],
style = document.createElement("style"),
rule = "transition: all .3s ease-out;"
css = [".livejs-loading * { ",
rule, " -webkit-", rule, "-moz-", rule, "-o-", rule, "}"].join('');
style.setAttribute("type", "text/css");
head.appendChild(style);
style.styleSheet ? style.styleSheet.cssText = css :
style.appendChild(document.createTextNode(css));
loaded = true;
},
checkForChanges: function () {
for (var url in resources) {
if (pendingRequests[url])
continue;
Live.getHead(url, function (url, newInfo) {
var oldInfo = resources[url],
hasChanged = false;
resources[url] = newInfo;
for (var header in oldInfo) {
var oldValue = oldInfo[header],
newValue = newInfo[header],
contentType = newInfo["Content-Type"];
switch (header.toLowerCase()) {
case "etag":
if (!newValue) break;
default:
hasChanged = oldValue != newValue;
break;
}
if (hasChanged) {
Live.refreshResource(url, contentType);
break;
}
}
});
}
},
refreshResource: function (url, type) {
switch (type.toLowerCase()) {
case "text/css":
var link = currentLinkElements[url],
html = document.body.parentNode,
head = link.parentNode,
next = link.nextSibling,
newLink = document.createElement("link");
html.className = html.className.replace(/\s*livejs\-loading/gi, ''
) + ' livejs-loading';
newLink.setAttribute("type", "text/css");
newLink.setAttribute("rel", "stylesheet");
newLink.setAttribute("href", url + "?now=" + new Date() * 1);
next ? head.insertBefore(newLink, next) : head.appendChild(
newLink);
currentLinkElements[url] = newLink;
oldLinkElements[url] = link;
Live.removeoldLinkElements();
break;
case "text/html":
if (url != document.location.href)
return;
case "text/javascript":
case "application/javascript":
case "application/x-javascript":
document.location.reload();
}
},
removeoldLinkElements: function () {
var pending = 0;
for (var url in oldLinkElements) {
try {
var link = currentLinkElements[url],
oldLink = oldLinkElements[url],
html = document.body.parentNode,
sheet = link.sheet || link.styleSheet,
rules = sheet.rules || sheet.cssRules;
if (rules.length >= 0) {
oldLink.parentNode.removeChild(oldLink);
delete oldLinkElements[url];
setTimeout(function () {
html.className = html.className.replace(
/\s*livejs\-loading/gi, '');
}, 100);
}
} catch (e) {
pending++;
}
if (pending) setTimeout(Live.removeoldLinkElements, 50);
}
},
getHead: function (url, callback) {
pendingRequests[url] = true;
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() :
new ActiveXObject("Microsoft.XmlHttp");
xhr.open("HEAD", url, true);
xhr.onreadystatechange = function () {
delete pendingRequests[url];
if (xhr.readyState == 4 && xhr.status != 304) {
xhr.getAllResponseHeaders();
var info = {};
for (var h in headers) {
var value = xhr.getResponseHeader(h);
if (h.toLowerCase() == "etag" && value)
value = value.replace(/^W\//, '');
if (h.toLowerCase() == "content-type" && value)
value = value.replace(/^(.*?);.*?$/i, "$1");
info[h] = value;
}
callback(url, info);
}
}
xhr.send();
}
};
if (document.location.protocol != "file:") {
if (!window.liveJsLoaded)
Live.heartbeat();
window.liveJsLoaded = true;
}
})();
"""