var loadImageCount = 30; var refreshCounterHandle = null; var counterIsActive = true; window.addEventListener("load", function() { // Replace placeholders // Note: This should be called before anything else replacePlaceholders(); // Toggle images for (var i in localStorage) { if (i.substr(0, ("toggle_").length) == "toggle_") { if (localStorage.getItem(i) == "1") { var e = document.getElementById(i.substr(("toggle_").length)); if (e) { document.getElementById(i.substr(("toggle_").length)).classList.add("expanded"); } } } } // Set / update / check timeout for the values in the localStorage and remove // outdated settings to keep the storage clean. var storageTimeout = localStorage.getItem("timeout"); var currentTimestamp = Date.now() / 1000 | 0; if ( (storageTimeout === null) || (storageTimeout < currentTimestamp) ) { // Remove "frame toggle" entries for (var i in localStorage) { if (i.substr(0, 7) == 'toggle_') { localStorage.removeItem(i); } } // Set / update timestamp localStorage.setItem("timeout", currentTimestamp + 60 * 60 * 24 * 30); // ca. 1 month } // Restore scroll position (wait until the CSS animation from toggling the images has finished) var scrolly = localStorage.getItem("scrolly"); scrolly = scrolly !== null ? scrolly : 0; window.setTimeout("document.documentElement.scrollTop = document.body.scrollTop = " + scrolly + ";", 200); // Start countdown timer (if set) if (typeof(refreshCounter) != "undefined") { refreshCounterHandle = window.setTimeout("updateRefreshCounter();", 0); } // Deactive counter again, if user previously deactivated it. if (localStorage && localStorage.getItem('counterInactive') == '1') { toggleCounter(document.getElementsByClassName('refreshCounterMenu')[0]); } // Start content wrapper resizer window.setInterval("resizeContentWrapper();", 500); }); window.addEventListener("beforeunload", function() { // Backup scroll position localStorage.setItem("scrolly", parseInt(document.documentElement.scrollTop || document.body.scrollTop)); }); function replacePlaceholders() { var placeholders = []; // Decimal separator var tmp = (1.2).toLocaleString(); tmp = tmp.replace(new RegExp(/[12]*/, 'g'), ''); if (tmp == '.') { tmp = tmp + ' (point)'; } else if (tmp == ',') { tmp = tmp + ' (comma)'; } placeholders.push({ search: '{DECIMAL_SEPARATOR}', replace: tmp, }); // Replace all placeholders var e = document.querySelectorAll("div, span, small, p, sub, sup, a, td, th, button"); for (var ei=0; ei < e.length; ++ei) { // Skip elements which has child nodes if (e[ei].children.length > 0) { continue; } for (var i=0; i < placeholders.length; ++i) { e[ei].innerHTML = e[ei].innerHTML.replace( placeholders[i].search, placeholders[i].replace ); } } } function updateRefreshCounter() { if ( (counterIsActive) && (typeof(refreshCounter) != "undefined") ) { if (refreshCounter <= 0) { window.location.reload(true); } else { // Update text on all counter elements var refreshCounterElements = document.getElementsByClassName("refreshCounterElement"); for (var i=0; i < refreshCounterElements.length; i++) { refreshCounterElements[i].innerHTML = refreshCounterElements[i].dataset.text1 + refreshCounter + refreshCounterElements[i].dataset.text2; } // Decrement counter and recall function refreshCounter--; refreshCounterHandle = window.setTimeout("updateRefreshCounter();", 1000); } } } function toggleFrame(e) { e.classList.toggle("expanded"); window.setTimeout("document.getElementById('" + e.id + "').scrollIntoView();", 200); localStorage.setItem("toggle_" + e.id, e.classList.contains("expanded") ? 1 : 0); } function toggleMenu(showhide) { if (typeof(showhide) == "undefined") { document.getElementsByClassName("leftMenu")[0].classList.toggle("show"); } else { if (showhide) { document.getElementsByClassName("leftMenu")[0].classList.add("show"); } else { document.getElementsByClassName("leftMenu")[0].classList.remove("show"); } } } function mobileMenuSelect(page, basefile) { if (page != '') { window.location.href = basefile + '?page=' + page; toggleMenu(false); } } function resizeContentWrapper() { var contentWrapper = document.getElementsByClassName("contentWrapper")[0]; //contentWrapper.style.width = (document.getElementsByTagName("body")[0].offsetWidth - 25 /* right border */ - contentWrapper.offsetLeft) + "px"; contentWrapper.style.width = (window.innerWidth - 25 /* right border */ - contentWrapper.offsetLeft) + "px"; } function sendDelete(btn, action, text) { if ( (typeof(text) == "undefined") || (text == "") || (confirm(text)) ) { var form = btn.parentNode.parentNode; form.elements["action"].value = action; form.submit(); } } function cancel_bubble(e) { if (e !== undefined) { if (!e) { var e = window.event; } e.cancelBubble = true; if (e.stopPropagation) { e.stopPropagation(); } } } function toggleSMD(img_id) { var motion_img = document.getElementById(img_id); var smd_status = 1; var nocache_timestamp = Math.floor(Date.now() / 1000); if (motion_img) { smd_status = (motion_img.dataset.smd == "0") ? "1" : "0"; motion_img.dataset.smd = smd_status; if (smd_status == "1") { motion_img.src = motion_img.dataset.src + "&nocache=" + nocache_timestamp + "&smd=1"; } else { motion_img.src = motion_img.dataset.src + "&nocache=off"; } } } function showDayImages(imageContainer, btn, loadAllImages) { // [SE 20151218]: This procedure has been changed. Instead that PHP creates the HTML source, JS will do that at runtime /* var imageContainer = document.getElementById(imageContainer); var images = imageContainer.getElementsByTagName("img"); // Hide toggle button btn.style.display = "none"; // Show image container imageContainer.style.display = "block"; // Set path for each image for (var sdiI=0; sdiI < images.length; sdiI++) { if ( (images[sdiI].dataset) && (images[sdiI].dataset.src) ) { images[sdiI].src = images[sdiI].dataset.src + "&nocache=off"; } } */ // Get reference to images container & get JSON data var imageContainer = document.getElementById(imageContainer); var imagesData = imageContainer.getAttribute('data-images'); var showMoreBtn = imageContainer.querySelector(".motionImagesShowMoreDayImagesBtn"); var showAllBtn = imageContainer.querySelector(".motionImagesShowAllDayImagesBtn"); var imageHeader = document.getElementById(imageContainer.id.replace('dayimgcontainer_', 'dayimgheader_')); // Decode JSON imagesData = JSON.parse(imagesData); // Create (next) images var loadedImages = 0; for (var i=0, i_len=imagesData.images.length; i < i_len; i++) { // Skip already loaded images if (imagesData.images[i].v) { continue; } // Mark image as loaded imagesData.images[i].v = 1; loadedImages++; // Ok, start creating image container var frame = document.createElement("div"); frame.setAttribute("class", "frame_live motion"); frame.setAttribute("onclick", "toggleFrame(this);"); frame.setAttribute("id", "serviceImage_" + imagesData.images[i].f); var e1; var e2; // time (wrapper) e1 = document.createElement("span"); e1.setAttribute("class", "frame_description_time"); frame.appendChild(e1); // time e2 = document.createElement("div"); e2.textContent = imagesData.images[i].t; e1.appendChild(e2); // temperature e2 = document.createElement("div"); e2.setAttribute("class", "frame_description_temperature"); e2.textContent = imagesData.images[i].tp; e1.appendChild(e2); // service group description e1 = document.createElement("span"); e1.setAttribute("class", "frame_description_serviceGroupDescription"); e1.textContent = imagesData.sgd; frame.appendChild(e1); // service description e1 = document.createElement("span"); e1.setAttribute("class", "frame_description_serviceDescription"); e1.textContent = imagesData.sd; frame.appendChild(e1); // image and motion data button e1 = document.createElement("div"); e1.setAttribute("style", "position: relative"); frame.appendChild(e1); // image and motion data button: button e2 = document.createElement("button"); e2.setAttribute("type", "button"); e2.setAttribute("class", "frame_motion_button"); e2.setAttribute("onclick", "cancel_bubble(event); toggleSMD('i" + imagesData.images[i].fs + "');"); e2.textContent = "R"; e1.appendChild(e2); // image and motion data button: image e2 = document.createElement("img"); e2.setAttribute("id", "i" + imagesData.images[i].fs); e2.setAttribute("src", "includes/getimg.php?fn=" + imagesData.images[i].fs /*+ "&nocache=off"*/); e2.setAttribute("data-src", "includes/getimg.php?fn=" + imagesData.images[i].fs); e2.setAttribute("data-smd", "0"); e1.appendChild(e2); // Append entire "frame" to the list here, not above like with the rest elements, because I think this is a bit faster for rendering in browser imageContainer.insertBefore(frame, showMoreBtn); // Load only X-amount images (defined in constant IMAGE_LOADIMAGECOUNT) // except if loadAllImages is set to TRUE. if (!loadAllImages && loadedImages >= loadImageCount) { break; } } // Hide toggle button if (btn !== null) { btn.classList.remove("show"); } // Show "hide images" button imageHeader.querySelector(".motionImagesHideDayImagesBtn").classList.add('show'); // Hide "Load next X images" & "Load all images" buttons, if there are no left more var notLoadedImages = 0; for (var i=0, i_len=imagesData.images.length; i < i_len; i++) { // Skip already loaded images if (!imagesData.images[i].v) { notLoadedImages++; } } if (!notLoadedImages) { showMoreBtn.classList.remove("show"); showAllBtn.classList.remove("show"); } // Encode image data and put back to DOM imagesData = JSON.stringify(imagesData); imageContainer.setAttribute('data-images', imagesData); // Show images container imageContainer.style.display = "block"; } function hideDayImages(imageContainer) { // Get reference to images container & get JSON data var imageContainer = document.getElementById(imageContainer); var imagesData = imageContainer.getAttribute('data-images'); var imageHeader = document.getElementById(imageContainer.id.replace('dayimgcontainer_', 'dayimgheader_')); // Decode JSON imagesData = JSON.parse(imagesData); // Set loaded status of images in data to (0) for (var i=0, i_len=imagesData.images.length; i < i_len; i++) { imagesData.images[i].v = 0; } // Encode image data and put back to DOM imagesData = JSON.stringify(imagesData); imageContainer.setAttribute('data-images', imagesData); // Remove all images var images = imageContainer.querySelectorAll(".frame_live.motion"); for (var i=0; i < images.length; i++) { images[i].delete(); } // Hide "Hide images" button imageHeader.querySelector(".motionImagesHideDayImagesBtn").classList.remove("show"); // Show "Show images" button imageHeader.querySelector(".motionImagesShowDayImagesBtn").classList.add("show"); // Show list sub buttons imageContainer.querySelector(".motionImagesShowMoreDayImagesBtn").classList.add("show"); imageContainer.querySelector(".motionImagesShowAllDayImagesBtn").classList.add("show"); // Hide images container imageContainer.style.display = "none"; } function deleteDayImages(imageContainer) { alert('Currently not implemented'); } function downloadDayImages(date, service_id) { window.open('../includes/dlimg.php?date=' + date + '&sid=' + service_id); } function toggleCounter(btn) { if (btn) { counterIsActive = !counterIsActive; if (counterIsActive) { btn.title = "Counter is active"; btn.getElementsByClassName("refreshCounterBtn")[0].classList.remove("inactive"); // Stop counter (just in case it is still active) and restart counter window.clearTimeout(refreshCounterHandle); refreshCounterHandle = window.setTimeout("updateRefreshCounter();", 0); // Save setting localStorage.setItem('counterInactive', '0'); } else { btn.title = "Counter deactivated"; btn.getElementsByClassName("refreshCounterBtn")[0].classList.add("inactive"); document.getElementsByClassName("refreshCounterElement")[0].innerHTML = "Counter deactivated"; window.clearTimeout(refreshCounterHandle); // Save setting localStorage.setItem('counterInactive', '1'); } } } function formOnSubmit(event, confirmation) { if (typeof confirmation === "undefined") { confirmation = "Do you really want to proceed?"; } if (!confirm(confirmation)) { // Prevent browser sending form (we send it by ourself through AJAX) event.preventDefault(); } } function surveillanceMapTriggerPopup(state) { var surveillanceMapServicePopup = document.getElementById("surveillanceMapServicePopup"); if (!state) { surveillanceMapServicePopup.style.visibility = "hidden"; } else { // Fill information document.getElementById("surveillanceMapServiceDescription").textContent = Base64.decode(state.datasetRef.description); if (Base64.decode(state.datasetRef.liveimage) == "") { document.getElementById("surveillanceMapLiveImageWrapper").style.display = "none"; document.getElementById("surveillanceMapNoLiveImage").style.display = "block"; } else { document.getElementById("surveillanceMapLiveImageWrapper").style.display = "block"; document.getElementById("surveillanceMapNoLiveImage").style.display = "none"; document.getElementById("surveillanceMapLiveImage").src = ""; // set to empty to show that it is loading (otherwise it might show the old image for a few seconds) document.getElementById("surveillanceMapLiveImage").src = Base64.decode(state.datasetRef.liveimage); document.getElementById("surveillanceMapLiveImageLastUpdate").textContent = Base64.decode(state.datasetRef.lastupdate); } if (state.datasetRef.active == "1") { document.getElementById("surveillanceMapServiceStatus").textContent = "Online"; document.getElementById("surveillanceMapServiceStatus").className = "surveillanceMapServiceStatusActive"; document.getElementById("surveillanceMapServiceStatusBtnActivate").style.display = "none"; document.getElementById("surveillanceMapServiceStatusBtnDeactivate").style.display = "inline-block"; document.getElementsByName("action")[0].value = "deactivate"; } else { document.getElementById("surveillanceMapServiceStatus").textContent = "Offline"; document.getElementById("surveillanceMapServiceStatus").className = "surveillanceMapServiceStatusInactive"; document.getElementById("surveillanceMapServiceStatusBtnActivate").style.display = "inline-block"; document.getElementById("surveillanceMapServiceStatusBtnDeactivate").style.display = "none"; document.getElementsByName("action")[0].value = "activate"; } document.getElementById("surveillanceMapServiceTemperature").textContent = Base64.decode(state.datasetRef.temperature); // Set service ID document.getElementsByName("id")[0].value = state.datasetRef.id; // Show popup surveillanceMapServicePopup.style.visibility = "visible"; surveillanceMapServicePopup.style.left = state.x + "px"; surveillanceMapServicePopup.style.top = state.y + "px"; } } //**************************************************************** //** Add delete() function for every element to make ** //** it easier to delete it (syntax: element.delete()) ** //**************************************************************** if (!Element.prototype.delete) { Element.prototype.delete = function() { this.parentNode.removeChild(this); }; } //**************************************************************** //** Base64 class ** //**************************************************************** var Base64 = { // private property _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", // public method for encoding encode : function (input) { var output = ""; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0; input = Base64._utf8_encode(input); while (i < input.length) { chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output = output + this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4); } return output; }, // public method for decoding decode : function (input) { var output = ''; var chr1, chr2, chr3; var enc1, enc2, enc3, enc4; var i = 0; input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ''); while (i < input.length) { enc1 = this._keyStr.indexOf(input.charAt(i++)); enc2 = this._keyStr.indexOf(input.charAt(i++)); enc3 = this._keyStr.indexOf(input.charAt(i++)); enc4 = this._keyStr.indexOf(input.charAt(i++)); chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4; output = output + String.fromCharCode(chr1); if (enc3 != 64) { output = output + String.fromCharCode(chr2); } if (enc4 != 64) { output = output + String.fromCharCode(chr3); } } output = Base64._utf8_decode(output); return output; }, // private method for UTF-8 encoding _utf8_encode : function (string) { string = string.replace(/\r\n/g,'\n'); var utftext = ''; for (var n = 0; n < string.length; n++) { var c = string.charCodeAt(n); if (c < 128) { utftext += String.fromCharCode(c); } else if((c > 127) && (c < 2048)) { utftext += String.fromCharCode((c >> 6) | 192); utftext += String.fromCharCode((c & 63) | 128); } else { utftext += String.fromCharCode((c >> 12) | 224); utftext += String.fromCharCode(((c >> 6) & 63) | 128); utftext += String.fromCharCode((c & 63) | 128); } } return utftext; }, // private method for UTF-8 decoding _utf8_decode : function (utftext) { var string = ''; var i = 0; var c = c1 = c2 = 0; while (i < utftext.length) { c = utftext.charCodeAt(i); if (c < 128) { string += String.fromCharCode(c); i++; } else if((c > 191) && (c < 224)) { c2 = utftext.charCodeAt(i+1); string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); i += 2; } else { c2 = utftext.charCodeAt(i+1); c3 = utftext.charCodeAt(i+2); string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3; } } return string; } };