01_FHEMWEB.js: on demand loading of fhemweb_*.js (Forum #76868)

git-svn-id: https://svn.fhem.de/fhem/trunk@15176 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2017-10-02 14:50:03 +00:00
parent f16928a190
commit e609f098ec
3 changed files with 104 additions and 62 deletions

View File

@ -1,5 +1,6 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
# Do not insert empty lines here, update check depends on it. # Do not insert empty lines here, update check depends on it.
- change: 01_FHEMWEB.js: on demand loading of fhemweb_*.js (Forum #76868)
- bugfix: 73_GardenaSmartBridge: fix part of code - bugfix: 73_GardenaSmartBridge: fix part of code
- feature: 49_SSCam: V3.1.0, move extevent from CAM- to SVS-model, Reading - feature: 49_SSCam: V3.1.0, move extevent from CAM- to SVS-model, Reading
PollState enhanced, minor fixes PollState enhanced, minor fixes

View File

@ -77,6 +77,7 @@ use vars qw($FW_plotmode);# Global plot mode (WEB attribute), used by SVG
use vars qw($FW_plotsize);# Global plot size (WEB attribute), used by SVG use vars qw($FW_plotsize);# Global plot size (WEB attribute), used by SVG
use vars qw(%FW_webArgs); # all arguments specified in the GET use vars qw(%FW_webArgs); # all arguments specified in the GET
use vars qw(@FW_fhemwebjs);# List of fhemweb*js scripts to load use vars qw(@FW_fhemwebjs);# List of fhemweb*js scripts to load
use vars qw($FW_fhemwebjs);# List of fhemweb*js scripts to load
use vars qw($FW_detail); # currently selected device for detail view use vars qw($FW_detail); # currently selected device for detail view
use vars qw($FW_cmdret); # Returned data by the fhem call use vars qw($FW_cmdret); # Returned data by the fhem call
use vars qw($FW_room); # currently selected room use vars qw($FW_room); # currently selected room
@ -208,11 +209,13 @@ FHEMWEB_Initialize($)
$FW_cssdir = "$FW_dir/pgm2"; $FW_cssdir = "$FW_dir/pgm2";
$FW_gplotdir = "$FW_dir/gplot"; $FW_gplotdir = "$FW_dir/gplot";
# Blacklist is needed due to an update bug, where MOV was not implemented
my %bl = (_multiple=>1,_noArg=>1,_slider=>1,_svg=>1,_textField=>1,_time=>1);
if(opendir(DH, "$FW_dir/pgm2")) { if(opendir(DH, "$FW_dir/pgm2")) {
@FW_fhemwebjs = sort grep { $_ =~ m/^fhemweb(.*).js$/ && !$bl{$1}; } $FW_fhemwebjs = join(",", map { $_ = ~m/^fhemweb_(.*).js$/; $1 }
readdir(DH); grep { /fhemweb_(.*).js$/ }
readdir(DH));
$data{FWEXT}{"readingsGroup" }{SCRIPT} = "fhemweb_readingsGroup.js";
$data{FWEXT}{"readingsHistory"}{SCRIPT} = "fhemweb_readingsHistory.js";
@FW_fhemwebjs = ("fhemweb.js");
closedir(DH); closedir(DH);
} }
@ -890,10 +893,7 @@ FW_answerCall($)
no strict "refs"; no strict "refs";
($FW_RETTYPE, $FW_RET) = &{$h->{FUNC}}($arg); ($FW_RETTYPE, $FW_RET) = &{$h->{FUNC}}($arg);
if(defined($FW_RETTYPE) && $FW_RETTYPE =~ m,text/html,) { if(defined($FW_RETTYPE) && $FW_RETTYPE =~ m,text/html,) {
my $dataAttr = my $dataAttr = FW_dataAttr();
"data-confirmDelete='" .AttrVal($FW_wname,"confirmDelete",1) ."' ".
"data-confirmJSError='".AttrVal($FW_wname,"confirmJSError",1)."' ".
"data-webName='$FW_wname '";
$FW_RET =~ s/<body/<body $dataAttr/; $FW_RET =~ s/<body/<body $dataAttr/;
} }
use strict "refs"; use strict "refs";
@ -987,7 +987,7 @@ FW_answerCall($)
FW_pO sprintf($jsTemplate, "", "$FW_ME/pgm2/jquery.min.js"); FW_pO sprintf($jsTemplate, "", "$FW_ME/pgm2/jquery.min.js");
FW_pO sprintf($jsTemplate, "", "$FW_ME/pgm2/jquery-ui.min.js"); FW_pO sprintf($jsTemplate, "", "$FW_ME/pgm2/jquery-ui.min.js");
my (%jsNeg, @jsList); my (%jsNeg, @jsList); # jsNeg was used to exclude automatically loaded files
map { $_ =~ m/^-(.*)$/ ? $jsNeg{$1} = 1 : push(@jsList, $_); } map { $_ =~ m/^-(.*)$/ ? $jsNeg{$1} = 1 : push(@jsList, $_); }
split(" ", AttrVal($FW_wname, "JavaScripts", "")); split(" ", AttrVal($FW_wname, "JavaScripts", ""));
map { FW_pO sprintf($jsTemplate, "", "$FW_ME/pgm2/$_") if(!$jsNeg{$_}); } map { FW_pO sprintf($jsTemplate, "", "$FW_ME/pgm2/$_") if(!$jsNeg{$_}); }
@ -1017,11 +1017,7 @@ FW_answerCall($)
my $lp = 'longpoll="'.AttrVal($FW_wname,"longpoll",1).'"'; my $lp = 'longpoll="'.AttrVal($FW_wname,"longpoll",1).'"';
$FW_id = $FW_chash->{NR} if( !$FW_id ); $FW_id = $FW_chash->{NR} if( !$FW_id );
my $dataAttr = my $dataAttr = FW_dataAttr();
"data-confirmDelete='" .AttrVal($FW_wname,"confirmDelete", 1)."' ".
"data-confirmJSError='".AttrVal($FW_wname,"confirmJSError",1)."' ".
"data-addHtmlTitle='" .AttrVal($FW_wname,"addHtmlTitle", 1)."' ".
"data-webName='$FW_wname '";
FW_pO "</head>\n<body name='$t' fw_id='$FW_id' $gen $lp $csrf $dataAttr>"; FW_pO "</head>\n<body name='$t' fw_id='$FW_id' $gen $lp $csrf $dataAttr>";
if($FW_activateInform) { if($FW_activateInform) {
@ -1084,6 +1080,17 @@ FW_answerCall($)
return 0; return 0;
} }
sub
FW_dataAttr()
{
return
"data-confirmDelete='" .AttrVal($FW_wname,"confirmDelete", 1)."' ".
"data-confirmJSError='".AttrVal($FW_wname,"confirmJSError",1)."' ".
"data-addHtmlTitle='" .AttrVal($FW_wname,"addHtmlTitle", 1)."' ".
"data-availableJs='$FW_fhemwebjs' ".
"data-webName='$FW_wname '";
}
sub sub
FW_addContent(;$) FW_addContent(;$)
{ {
@ -1337,7 +1344,7 @@ FW_doDetail($)
$t = "MISSING" if(!defined($t)); $t = "MISSING" if(!defined($t));
FW_addContent(); FW_addContent();
if($FW_ss) { # FS20MS2 special: on and off, is not the same as toggle if($FW_ss) {
my $webCmd = AttrVal($d, "webCmd", undef); my $webCmd = AttrVal($d, "webCmd", undef);
if($webCmd) { if($webCmd) {
FW_pO "<table class=\"webcmd\">"; FW_pO "<table class=\"webcmd\">";
@ -3618,8 +3625,6 @@ FW_widgetOverride($$)
attr WEB JavaScripts codemirror/fhem_codemirror.js<br> attr WEB JavaScripts codemirror/fhem_codemirror.js<br>
attr WEB codemirrorParam { "theme":"blackboard", "lineNumbers":true } attr WEB codemirrorParam { "theme":"blackboard", "lineNumbers":true }
</code></ul> </code></ul>
Note: if the filename starts with - then it will be excluded for the
automatically loaded list (e.g. -fhemweb_fbcalllist.js)
</li><br> </li><br>
<a name="longpoll"></a> <a name="longpoll"></a>
@ -4412,9 +4417,6 @@ FW_widgetOverride($$)
attr WEB JavaScripts codemirror/fhem_codemirror.js<br> attr WEB JavaScripts codemirror/fhem_codemirror.js<br>
attr WEB codemirrorParam { "theme":"blackboard", "lineNumbers":true } attr WEB codemirrorParam { "theme":"blackboard", "lineNumbers":true }
</code></ul> </code></ul>
Falls der Dateiname mit - anf&auml;ngt, dann wird diese sonst
aus www/pgm2 automatisch geladene Datei nicht geladen. (z.Bsp.:
-fhemweb_fbcalllist.js)
</li><br> </li><br>
<a name="longpoll"></a> <a name="longpoll"></a>

View File

@ -10,6 +10,7 @@ var FW_isiOS = navigator.userAgent.match(/(iPad|iPhone|iPod)/);
var FW_scripts = {}, FW_links = {}; var FW_scripts = {}, FW_links = {};
var FW_docReady = false, FW_longpollType, FW_csrfToken, FW_csrfOk=true; var FW_docReady = false, FW_longpollType, FW_csrfToken, FW_csrfOk=true;
var FW_root = "/fhem"; // root var FW_root = "/fhem"; // root
var FW_availableJs=[];
var embedLoadRetry = 100; var embedLoadRetry = 100;
// createFn returns an HTML Element, which may contain // createFn returns an HTML Element, which may contain
@ -50,7 +51,8 @@ FW_replaceWidgets(parent)
var rd=$(this).attr("reading"); var rd=$(this).attr("reading");
var params = cmd.split(" "); var params = cmd.split(" ");
var type=$(this).attr("type"); var type=$(this).attr("type");
if( type == undefined ) type = "set"; if(type == undefined)
type = "set";
FW_replaceWidget(this, dev, $(this).attr("arg").split(","), FW_replaceWidget(this, dev, $(this).attr("arg").split(","),
$(this).attr("current"), rd, params[0], params.slice(1), $(this).attr("current"), rd, params[0], params.slice(1),
function(arg) { function(arg) {
@ -68,6 +70,13 @@ FW_jqueryReadyFn()
FW_docReady = true; FW_docReady = true;
FW_serverGenerated = $("body").attr("generated"); FW_serverGenerated = $("body").attr("generated");
FW_longpollType = $("body").attr("longpoll"); FW_longpollType = $("body").attr("longpoll");
var ajs = $("body").attr("data-availableJs");
if(ajs) {
ajs = ajs.split(",");
for(var i1=0; i1<ajs.length; i1++)
FW_availableJs[ajs[i1]] = 1;
}
if(FW_longpollType != "0") if(FW_longpollType != "0")
setTimeout("FW_longpoll()", 100); setTimeout("FW_longpoll()", 100);
FW_csrfToken = $("body").attr('fwcsrf'); FW_csrfToken = $("body").attr('fwcsrf');
@ -1022,18 +1031,46 @@ FW_detailSelect(selEl, mayMissing)
vArr = arg.substr(selVal.length+1).split(","); vArr = arg.substr(selVal.length+1).split(",");
} }
var newEl = FW_replaceWidget($(selEl).next(), devName, vArr,undefined,selVal); FW_replaceWidget($(selEl).next(), devName, vArr,undefined,selVal,
undefined, undefined, undefined,
function(newEl) {
if(cmd == "attr") if(cmd == "attr")
FW_queryValue('{AttrVal("'+devName+'","'+selVal+'","")}', newEl); FW_queryValue('{AttrVal("'+devName+'","'+selVal+'","")}', newEl);
if(cmd == "set") if(cmd == "set")
FW_queryValue('{ReadingsVal("'+devName+'","'+selVal+'","")}', newEl); FW_queryValue('{ReadingsVal("'+devName+'","'+selVal+'","")}', newEl);
});
} }
function function
FW_replaceWidget(oldEl, devName, vArr, currVal, reading, set, params, cmd) FW_callCreateFn(elName, devName, vArr, currVal, set, params, cmd, finishFn)
{
for(var wn in FW_widgets) {
if(FW_widgets[wn].createFn) {
var newEl = FW_widgets[wn].createFn(elName, devName, vArr,
currVal, set, params, cmd);
if(newEl)
return finishFn(wn, newEl);
}
}
var v0 = vArr[0].split("-")[0];
if(v0.indexOf("uzsu") == 0)
v0 = "uzsu";
if(FW_availableJs[v0]) {
loadScript("pgm2/fhemweb_"+v0+".js", function() {
if(FW_widgets[vArr[0]].createFn)
var newEl = FW_widgets[vArr[0]].createFn(elName, devName, vArr,
currVal, set, params, cmd);
finishFn(vArr[0], newEl);
});
} else {
finishFn();
}
}
function
FW_replaceWidget(oldEl,devName,vArr,currVal,reading,set,params,cmd,readyFn)
{ {
var newEl, wn;
var elName = $(oldEl).attr("name"); var elName = $(oldEl).attr("name");
if(!elName) if(!elName)
elName = $(oldEl).find("[name]").attr("name"); elName = $(oldEl).find("[name]").attr("name");
@ -1041,31 +1078,32 @@ FW_replaceWidget(oldEl, devName, vArr, currVal, reading, set, params, cmd)
if(vArr.length == 0) { // No parameters, input field if(vArr.length == 0) { // No parameters, input field
newEl = FW_createTextField(elName, devName, ["textField"], currVal, newEl = FW_createTextField(elName, devName, ["textField"], currVal,
set, params, cmd); set, params, cmd);
wn = "textField"; finishFn("textField", newEl);
} else { } else {
for(wn in FW_widgets) {
if(FW_widgets[wn].createFn) { return FW_callCreateFn(elName, devName, vArr, currVal, set,
newEl = FW_widgets[wn].createFn(elName, devName, vArr, currVal, params, cmd, finishFn);
set, params, cmd);
if(newEl)
break;
}
} }
if(!newEl) { // Select as fallback function
finishFn(wn, newEl)
{
if(!newEl) {
vArr.unshift("select"); vArr.unshift("select");
newEl = FW_createSelect(elName,devName,vArr,currVal,set,params,cmd); newEl = FW_createSelect(elName,devName,vArr,currVal,set,params,cmd);
wn = "select"; wn = "select";
} }
}
if(!newEl) { // Simple link if(!newEl) { // Simple link
newEl = $('<div class="col3"><a style="cursor: pointer;">'+ newEl = $('<div class="col3"><a style="cursor: pointer;">'+
set+' '+params.join(' ')+ '</a></div>'); set+' '+params.join(' ')+ '</a></div>');
$(newEl).click(function(arg) { cmd(params[0]) }); $(newEl).click(function(arg) { cmd(params[0]) });
$(oldEl).replaceWith(newEl); $(oldEl).replaceWith(newEl);
return newEl; if(readyFn)
return readyFn(newEl);
return;
} }
$(newEl).addClass(wn+"_widget"); $(newEl).addClass(wn+"_widget");
@ -1077,12 +1115,13 @@ FW_replaceWidget(oldEl, devName, vArr, currVal, reading, set, params, cmd)
if(reading != "state" && addTitle==1) if(reading != "state" && addTitle==1)
$(newEl).attr("title", reading); $(newEl).attr("title", reading);
} }
$(oldEl).replaceWith(newEl); $(oldEl).replaceWith(newEl);
if(newEl.activateFn) // CSS is not applied if newEl is not in the document if(newEl.activateFn) // CSS is not applied if newEl is not in the document
newEl.activateFn(); newEl.activateFn();
return newEl; if(readyFn)
readyFn(newEl);
}
} }
function function