diff --git a/fhem/FHEM/01_FHEMWEB.pm b/fhem/FHEM/01_FHEMWEB.pm
index d6b197f97..7ca4f30b3 100755
--- a/fhem/FHEM/01_FHEMWEB.pm
+++ b/fhem/FHEM/01_FHEMWEB.pm
@@ -2926,6 +2926,20 @@ FW_ActivateInform()
FHEM-Server, and iPad/iPhone as Web-client.
+
+
JavaScripts
+ Space separated list of JavaScript files to be included. The filenames
+ are relative to the www directory. For each file an additional
+ user-settable FHEMWEB attribute will be created, to pass parameters to
+ the script. The name of this additional attribute gets the Param
+ suffix, directory and the fhem_ prefix will be deleted. Example:
+
+ attr WEB JavaScripts codemirror/fhem_codemirror.js
+ attr WEB codemirrorParam { "theme":"blackboard", "lineNumbers":true }
+
+
+
+
@@ -3432,6 +3446,21 @@ FW_ActivateInform()
beheben.
+
+ JavaScripts
+ Leerzeichen getrennte Liste von JavaScript Dateien, die geladen werden.
+ Die Dateinamen sind relativ zum www Verzeichnis anzugeben. Für
+ jede Datei wird ein zusätzliches Attribut angelegt, damit der
+ Benutzer dem Skript Parameter weiterreichen kann. Bei diesem
+ Attributnamen werden Verzeichnisname und fhem_ Präfix entfernt
+ und Param als Suffix hinzugefügt. Beispiel:
+
+
+ attr WEB JavaScripts codemirror/fhem_codemirror.js
+ attr WEB codemirrorParam { "theme":"blackboard", "lineNumbers":true }
+
+
+
diff --git a/fhem/www/codemirror/fhem_codemirror.js b/fhem/www/codemirror/fhem_codemirror.js
new file mode 100644
index 000000000..b16e1fb21
--- /dev/null
+++ b/fhem/www/codemirror/fhem_codemirror.js
@@ -0,0 +1,75 @@
+var cm_loaded = 0, cm_editor;
+
+loadScript("pgm2/jquery.min.js", function(){
+ $(document).ready(function(){
+ var els = document.getElementsByTagName("textarea");
+ if(els.length == 0)
+ return;
+
+ if($(els[0]).closest("div#edit").css("display")=="none") { // DEF special
+ $("table.internals a").each(function(){
+ var oc = $(this).attr("onclick");
+ if(oc) {
+ $(this).attr("onclick", oc+
+ 's=document.getElementById("edit").getElementsByTagName("textarea");'+
+ 'if(!s[0].editor) s[0].editor=AddCodeMirror(s[0]);');
+ }
+ });
+ } else {
+ AddCodeMirror(els[0]);
+ }
+ });
+});
+
+function
+AddCodeMirror(e)
+{
+ cm_editor = e;
+ loadLink("codemirror/codemirror.css");
+ loadLink("codemirror/show-hint.css");
+ loadScript("codemirror/codemirror.js", function(){cm_loaded++;} );
+ loadScript("codemirror/closebrackets.js",function(){cm_loaded++;} );
+ loadScript("codemirror/matchbrackets.js",function(){cm_loaded++;} );
+ loadScript("codemirror/show-hint.js", function(){cm_loaded++;cm_wait()});
+}
+
+function
+cm_wait()
+{
+ if(cm_loaded != 4) {
+ setTimeout(cm_wait, 10);
+ return;
+ }
+
+ var ltype,type="fhem"; // get the type from the hidden filename extension
+ $("input[name=save]").each(function(){
+ ltype = $(this).attr("value");
+ ltype = ltype.substr(ltype.lastIndexOf(".")+1);
+ if(ltype=="css") type = "css";
+ if(ltype=="svg") type = "xml";
+ });
+ var attr = {
+ theme: "blackboard",
+ lineNumbers: true,
+ matchBrackets: true,
+ autoCloseBrackets: true,
+ extraKeys:{'Ctrl-Space':'autocomplete'}
+ };
+ var userAttr = scriptAttribute("fhem_codemirror.js");
+ for(var a in userAttr)
+ attr[a] = userAttr[a];
+
+ loadLink("codemirror/"+attr.theme+".css");
+ if(ltype) {
+ $("head").append(
+ '');
+ }
+
+ loadScript("codemirror/"+type+".js", function(){
+ log("Calling CodeMirror");
+ CodeMirror.fromTextArea(cm_editor, attr);
+ });
+}
diff --git a/fhem/www/pgm2/fhemweb.js b/fhem/www/pgm2/fhemweb.js
index 7f2599640..db3c6444b 100644
--- a/fhem/www/pgm2/fhemweb.js
+++ b/fhem/www/pgm2/fhemweb.js
@@ -288,6 +288,71 @@ FW_querySetSelected(el, val)
}
}
+//////////////////////////
+// start of script functions
+function
+loadScript(sname, cb)
+{
+ var h = document.head || document.getElementsByTagName('head')[0];
+ var r = h.getAttribute("root");
+ if(!r)
+ r = "/fhem";
+ sname = r+"/"+sname;
+ var arr = h.getElementsByTagName("script");
+ for(var i1=0; i1= 0)
+ attr = $(this).attr("attr");
+ });
+
+ var ua={};
+ try {ua=JSON.parse(attr);} catch(e){FW_errmsg(sname+" Parameter "+e,5000);}
+ return ua;
+}
+// end of script functions
+//////////////////////////
+
window.onbeforeunload = function(e)
{
FW_leaving = 1;