"use strict"; var FW_serverGenerated; var FW_serverFirstMsg = (new Date()).getTime()/1000; var FW_serverLastMsg = FW_serverFirstMsg; var FW_isIE = (navigator.appVersion.indexOf("MSIE") > 0); var FW_isiOS = navigator.userAgent.match(/(iPad|iPhone|iPod)/); var FW_scripts = {}, FW_links = {}; var FW_docReady = false; var FW_root = "/fhem"; // root // createFn returns an HTML Element, which may contain // - setValueFn, which is called when data via longpoll arrives // - activateFn, which is called after the HTML element is part of the DOM. var FW_widgets = { select: { createFn:FW_createSelect }, slider: { createFn:FW_createSlider }, time: { createFn:FW_createTime }, noArg: { createFn:FW_createNoArg }, multiple: { createFn:FW_createMultiple }, "multiple-strict": { createFn:FW_createMultiple }, textfield: { createFn:FW_createTextField }, "textfield-long": { createFn:FW_createTextField } }; window.onbeforeunload = function(e) { FW_leaving = 1; return undefined; } function FW_replaceWidgets(parent) { parent.find("div.fhemWidget").each(function() { var dev=$(this).attr("dev"); var cmd=$(this).attr("cmd"); var rd=$(this).attr("reading"); var params = cmd.split(" "); var type=$(this).attr("type"); if( type == undefined ) type = "set"; FW_replaceWidget(this, dev, $(this).attr("arg").split(","), $(this).attr("current"), rd, params[0], params.slice(1), function(arg) { FW_cmd(FW_root+"?cmd="+type+" "+dev+ (params[0]=="state" ? "":" "+params[0])+" "+arg+"&XHR=1"); }); }); } function FW_jqueryReadyFn() { FW_docReady = true; FW_serverGenerated = $("body").attr("generated"); if($("body").attr("longpoll")) setTimeout("FW_longpoll()", 100); $("a").each(function() { FW_replaceLink(this); }) $("head script").each(function() { var sname = $(this).attr("src"), p = FW_scripts[sname]; if(!p) { FW_scripts[sname] = { loaded:true }; return; } FW_scripts[sname].loaded = true; if(p.callbacks && !p.called) { p.called = true; // Avoid endless loop for(var i1=0; i1< p.callbacks.length; i1++) if(p.callbacks[i1]) // pushing undefined callbacks on the stack is ok p.callbacks[i1](); delete(p.callbacks); } }); $("head link").each(function() { FW_links[$(this).attr("href")] = 1 }); $("div.makeSelect select").each(function() { FW_detailSelect(this); $(this).change(FW_detailSelect); }); // Activate the widgets var r = $("head").attr("root"); if(r) FW_root = r; FW_replaceWidgets($("html")); // Fix the td count by setting colspan on the last column $("table.block.wide").each(function(){ // table var id = $(this).attr("id"); if(!id || id.indexOf("TYPE") != 0) return; var maxTd=0, tdCount=[]; $(this).find("tr").each(function(){ // count the td's var cnt=0; $(this).find("td").each(function(){ cnt++; }); if(maxTd < cnt) maxTd = cnt; tdCount.push(cnt); }); $(this).find("tr").each(function(){ // set the colspan $(this).find("td").last().attr("colspan", maxTd-tdCount.shift()+1); }); }); // Replace the FORM-POST in detail-view by XHR /* Inactive, as Internals and Attributes arent auto updated. $("form input[type=submit]").click(function(e) { var cmd = ""; $(this).parent().find("[name]").each(function() { cmd += (cmd?"&":"")+$(this).attr("name")+"="+$(this).val(); }); if(cmd.indexOf("detail=") < 0) return; e.preventDefault(); FW_cmd(FW_root+"?"+cmd+"&XHR=1"); }); */ $("form input.get[type=submit]").click(function(e) { //"get" via XHR to dialog e.preventDefault(); var cmd = "", el=this; $(el).parent().find("input,[name]").each(function() { cmd += (cmd?"&":"")+$(this).attr("name")+"="+$(this).val(); }); FW_cmd(FW_root+"?"+cmd+"&XHR=1&addLinks=1", function(data) { if(!data.match(/^[\r\n]*$/)) // ignore empty answers FW_okDialog('
'+data+'', el); }); }); $("#saveCheck") .css("cursor", "pointer") .click(function(){ var parent = this; FW_cmd(FW_root+"?cmd=save ?&XHR=1", function(data) { FW_okDialog('
'+data+'',parent); }); }); $("form").each(function(){ // shutdown handling var input = $(this).find("input.maininput"); if(!input.length) return; $(this).on("submit", function(e) { var val = $(input).val(); if(val.match(/^\s*shutdown/)) { FW_cmd(FW_root+"?XHR=1&cmd="+val); $(input).val(""); return false; } else if(val.match(/^\s*get\s+/)) { // make get use xhr instead of reload //return true; FW_cmd(FW_root+"?cmd="+val+"&XHR=1", function(data) { if( !data.match( /^.*<\/html>/ ) ) { data = data.replace( '<', '<' ); data = '
'+data+''; } if( location.href.indexOf('?') === -1 ) $('#content').html(data); else FW_okDialog(data); }); e.preventDefault(); $(input).val(""); return false; } return true; }); }); $("div.devSpecHelp a").each(function(){ // Help on detail window var dev = FW_getLink(this).split("#").pop(); $(this).unbind("click"); $(this).attr("href", "#"); // Desktop: show underlined Text $(this).removeAttr("onclick"); $(this).click(function(evt){ if($("#devSpecHelp").length) { $("#devSpecHelp").remove(); return; } $("#content").append(''); FW_cmd(FW_root+"?cmd=help "+dev+"&XHR=1", function(data) { $("#devSpecHelp").html(data); var off = $("#devSpecHelp").position().top-20; $('body, html').animate({scrollTop:off}, 500); }); }); }); $("table.attributes tr div.dname") // Click on attribute fills input value .each(function(){ $(this) .html(''+$(this).html()+'') .css({cursor:"pointer"}) .click(function(){ var aname = "#sel_attr"+$(this).attr("data-name").replace(/\./g,'_'); $(aname).val($(this).text()); FW_detailSelect(aname); }); }); FW_smallScreenCommands(); FW_inlineModify(); } // Show the webCmd list in a dialog if: smallScreen & hiddenroom=detail & room function FW_smallScreenCommands() { if($("div#menu select").length == 0 || // not SmallScreen $("div#content").attr("room") == undefined || // not room Overview $("div#content div.col1 a").length > 0) // no hiddenroom=detail return; $("div#content div.col1").each(function(){ var tr = $(this).closest("tr"); if($(tr).find("> td").length <= 2) return; $(this).html(""+$(this).html()+""); $(this).find("a").click(function(){ var t = $("
'+newDef+''; $("div#disp").html(newDef).css("display", ""); $("div#edit").css("display", "none"); }); }); } /*************** LONGPOLL START **************/ var FW_pollConn; var FW_longpollOffset = 0; var FW_leaving; function FW_doUpdate() { if(FW_pollConn.readyState == 4 && !FW_leaving) { FW_errmsg("Connection lost, trying a reconnect every 5 seconds.", 4900); setTimeout(FW_longpoll, 5000); return; // some problem connecting } if(FW_pollConn.readyState != 3) return; var input = FW_pollConn.responseText; var devs = new Array(); if(input.length <= FW_longpollOffset) return; FW_serverLastMsg = (new Date()).getTime()/1000; for(;;) { var nOff = input.indexOf("\n", FW_longpollOffset); if(nOff < 0) break; var l = input.substr(FW_longpollOffset, nOff-FW_longpollOffset); FW_longpollOffset = nOff+1; log("Rcvd: "+(l.length>132 ? l.substring(0,132)+"...("+l.length+")":l)); if(!l.length) continue; var d = JSON.parse(l); if(d.length != 3) continue; if( d[0].match(/^#FHEMWEB:/) ) { eval(d[1]); } else { $("[informId='"+d[0]+"']").each(function(){ if(this.setValueFn) { // change the select/etc value this.setValueFn(d[1]); } else { $(this).html(d[2]); // Readings-Value if(d[0].match(/-ts$/)) // timestamps $(this).addClass('changed'); $(this).find("a").each(function() { FW_replaceLink(this) }); } }); } for(var w in FW_widgets) if(FW_widgets[w].updateLine) // updateLine is deprecated, use setValueFn FW_widgets[w].updateLine(d); devs.push(d); } for(var w in FW_widgets) if(FW_widgets[w].updateDevs) // used for SVG to avoid double-reloads FW_widgets[w].updateDevs(devs); // reset the connection to avoid memory problems if(FW_longpollOffset > 1024*1024 && FW_longpollOffset==input.length) FW_longpoll(); } function FW_longpoll() { FW_longpollOffset = 0; if(FW_pollConn) { FW_leaving = 1; FW_pollConn.abort(); } FW_pollConn = new XMLHttpRequest(); FW_leaving = 0; // Build the notify filter for the backend var filter = $("body").attr("longpollfilter"); if(filter == null) filter = ""; if(filter == "") { $("embed").each(function() { if($(this.getSVGDocument()).find("svg[flog]").attr("flog")) filter=".*"; }); } if(filter == "") { var sa = location.search.substring(1).split("&"); for(var i = 0; i < sa.length; i++) { if(sa[i].substring(0,5) == "room=") filter=sa[i]; if(sa[i].substring(0,7) == "detail=") filter=sa[i].substring(7); } } if($("#floorplan").length>0) //floorplan special filter += ";iconPath="+$("body").attr("name"); if(filter == "") { var content = document.getElementById("content"); if(content) { var room = content.getAttribute("room"); if(room) filter="room="+room; } } var iP = $("body").attr("iconPath"); if(iP != null) filter = filter +";iconPath="+iP; var since = "null"; if(FW_serverGenerated) since = FW_serverLastMsg + (FW_serverGenerated-FW_serverFirstMsg); var query = location.pathname+"?XHR=1"+ "&inform=type=status;filter="+filter+";since="+since+";fmt=JSON"+ '&fw_id='+$("body").attr('fw_id')+ "×tamp="+new Date().getTime(); query = addcsrf(query); FW_pollConn.open("GET", query, true); FW_pollConn.onreadystatechange = FW_doUpdate; FW_pollConn.send(null); log("Longpoll with filter "+filter); } /*************** LONGPOLL END **************/ /*************** WIDGETS START **************/ /*************** "Double" select in detail window ****/ function FW_detailSelect(selEl) { if(selEl.target) selEl = selEl.target; var selVal = $(selEl).val(); var div = $(selEl).closest("div.makeSelect"); var arg, listArr = $(div).attr("list").split(" "), devName = $(div).attr("dev"), cmd = $(div).attr("cmd"); for(var i1=0; i1