f18.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. "use strict";
  2. FW_version["f18.js"] = "$Id: f18.js 16268 2018-02-25 18:32:02Z rudolfkoenig $";
  3. // TODO: absPos,hierMenu+Pin,menuBorder,f18style.css,SVGcolors,floorplan
  4. var f18_attr, f18_aCol, f18_sd, f18_isMobile, f18_icon={}, f18_hasPos, f18_room;
  5. var f18_small = (screen.width < 480 || screen.height < 480);
  6. $(window).resize(f18_resize);
  7. $(document).ready(function(){
  8. f18_room = $("div#content").attr("room");
  9. f18_sd = $("body").attr("data-styleData");
  10. if(f18_sd) {
  11. eval("f18_sd="+f18_sd);
  12. if(!f18_sd)
  13. f18_sd = {};
  14. f18_attr = f18_sd.f18;
  15. delete(f18_attr.cols); // fix the past
  16. } else {
  17. f18_sd = {};
  18. }
  19. if(!f18_attr) {
  20. f18_attr = { "Pinned.menu":"true" };
  21. f18_resetCol();
  22. f18_sd.f18 = f18_attr;
  23. }
  24. if(typeof f18_attr.savePinChanges == "undefined")
  25. f18_attr.savePinChanges = true;
  26. f18_setCss('init');
  27. var icon = FW_root+"/images/default/fhemicon_ios.png";
  28. $('head').append(
  29. '<meta name="viewport" content="initial-scale=1.0,user-scalable=1">'+
  30. '<meta name= "mobile-web-app-capable" content="yes">'+
  31. '<meta name="apple-mobile-web-app-capable" content="yes">'+
  32. '<link rel="apple-touch-icon" href="'+icon+'">');
  33. if('ontouchstart' in window) $("body").addClass('touch');
  34. if(f18_small) {
  35. $("body").addClass('small');
  36. f18_attr["Pinned.menu"] = false;
  37. }
  38. if(f18_attr.rightMenu)
  39. $("body").addClass("rightMenu");
  40. f18_aCol = getComputedStyle($("a").get(0),null).getPropertyValue('color');
  41. for(var i in f18_icon)
  42. f18_icon[i] = f18_icon[i].replace('gray', f18_aCol);
  43. f18_icon.pinOut = f18_icon.pinIn
  44. .replace('/>',' transform="rotate(90,896,896)"/>');
  45. f18_menu();
  46. f18_tables();
  47. f18_svgSetCols();
  48. if(typeof svgCallback != "undefined")
  49. svgCallback.f18 = f18_svgSetCols;
  50. });
  51. function
  52. f18_menu()
  53. {
  54. if($("#menuScrollArea #menuBtn").length)
  55. return fixMenu();
  56. $("<div id='menuBtn'></div>").prependTo("div#menuScrollArea")
  57. .css( {"background-image":"url('"+f18_icon.bars+"')", "cursor":"pointer" })
  58. .click(function(){ $("#menu").toggleClass("visible") });
  59. $("div#menu").prepend("<div></div>");
  60. f18_addPin("div#menu > div:first", "menu", true, fixMenu, f18_small);
  61. setTimeout(function(){ $("#menu,#content,#logo,#hdr").addClass("animated"); },
  62. 10);
  63. function
  64. fixMenu()
  65. {
  66. $("#menuScrollArea #logo").css("display",
  67. f18_getAttr("hideLogo") ? "none" : "block");
  68. if(f18_getAttr("Pinned.menu")) {
  69. $("body").addClass("pinnedMenu");
  70. $("#menu").removeClass("visible");
  71. $("#content").css("left", (parseInt($("div#menu").width())+20)+"px");
  72. } else {
  73. $("body").removeClass("pinnedMenu");
  74. $("#content").css("left", "");
  75. }
  76. f18_resize();
  77. }
  78. }
  79. function
  80. f18_tables()
  81. {
  82. $("table.roomoverview > tbody > tr > td > .devType:not(:first)")
  83. .css("margin-top", "20px");
  84. $("table.column tbody tr:not(:first-child) .devType")
  85. .css("margin-top", "20px");
  86. $("#content .devType").each(function(){
  87. var el = this, grp = $(el).text();
  88. f18_addPin(el, "Room."+FW_urlParams.room+".grp."+grp, true,
  89. function(isFixed){
  90. var ntr = $(el).closest("tr").next("tr");
  91. isFixed ? $(ntr).show() : $(ntr).hide();
  92. });
  93. f18_setPos(el);
  94. if(f18_getAttr("showDragger"))
  95. f18_addDragger(el);
  96. });
  97. $("div.SVGlabel").each(function(){
  98. f18_setPos(this);
  99. if(f18_getAttr("showDragger"))
  100. f18_addDragger(this);
  101. });
  102. if(FW_urlParams.detail) {
  103. $("div.makeTable > span").each(function(){
  104. var el = this, grp = $(el).text();
  105. var nel = $("<div>"+grp+"</div>");
  106. $(el).replaceWith(nel);
  107. f18_addPin(nel, "detail."+grp, true,
  108. function(isFixed){
  109. var ntr = $(nel).next("table");
  110. isFixed ? $(ntr).show() : $(ntr).hide();
  111. });
  112. });
  113. }
  114. if(FW_urlParams.cmd == "style%20select")
  115. f18_special();
  116. if(FW_urlParams.cmd == "style%20list" ||
  117. FW_urlParams.cmd == "style%20select")
  118. $("div.fileList").each(function(){ f18_addPinToStyleDiv(this) });
  119. if(f18_hasPos || f18_getAttr("showDragger"))
  120. $("div.pinHeader:not(.menu) div.pin").hide();
  121. }
  122. function
  123. f18_special()
  124. {
  125. var row, room='all', appendTo;
  126. var attr = function(attrName, inRoom)
  127. {
  128. if(inRoom && room != "all") {
  129. var val = f18_attr["Room."+room+"."+attrName];
  130. if(val != undefined)
  131. return val;
  132. }
  133. return f18_attr[attrName];
  134. };
  135. var setAttr = function(attrName, attrVal, inRoom)
  136. {
  137. if(inRoom && room != "all")
  138. attrName = "Room."+room+"."+attrName;
  139. f18_setAttr(attrName, attrVal);
  140. };
  141. var addRow = function(name, desc, val)
  142. {
  143. $(appendTo)
  144. .append("<tr class='ar_"+name+" "+(++row%2 ? "even":"odd")+"'>"+
  145. "<td "+(val ? "" : "colspan='2'")+">"+
  146. "<div class='col1'>"+desc+"</div></td>"+
  147. (val ? "<td><div class='col2'>"+val+"</div></div></td>" : '')+
  148. "</tr>");
  149. };
  150. var addHider = function(name, inRoom, desc, fn)
  151. {
  152. addRow(name, desc, "<input type='checkbox'>");
  153. $(appendTo+" tr.ar_"+name+" input")
  154. .prop("checked", attr(name, inRoom))
  155. .click(function(){
  156. var c = $(this).is(":checked");
  157. setAttr(name, c, inRoom);
  158. fn(c);
  159. });
  160. };
  161. var addColorChooser = function(name, desc)
  162. {
  163. addRow(name, desc, "<div class='cp'></div>");
  164. FW_replaceWidget(appendTo+" tr.ar_"+name+" div.col2 div.cp", name,
  165. ["colorpicker","RGB"], attr("cols."+name, true), name, "rgb", undefined,
  166. function(value) {
  167. setAttr("cols."+name, value, true);
  168. f18_setCss(name);
  169. });
  170. };
  171. // call drawspecial after got the roomlist...
  172. var f18_drawSpecial = function()
  173. {
  174. var roomHash={};
  175. var cleanRoom = function(){
  176. for(var k in f18_attr) {
  177. var m = k.match(/^room\.([^.]*)\..*/);
  178. if(m && !roomHash[m[1]])
  179. delete f18_attr[k];
  180. }
  181. };
  182. row = 0;
  183. $("div#content tr.f18").remove();
  184. $("div#content > table").append("<tr id='f18rs' class='f18'></tr>");
  185. $("tr#f18rs").append("<div class='fileList f18colors'>f18 special</div>");
  186. $("tr#f18rs").append("<table id='f18ts' class='block wide'></table>");
  187. appendTo = "table#f18ts";
  188. addHider("rightMenu", false, "MenuBtn right<br>on SmallScreen", function(c){
  189. $("body").toggleClass("rightMenu");
  190. });
  191. addHider("savePinChanges", false, "Save pin changes", function(){});
  192. addHider("showDragger", false, "Dragging active", function(c){
  193. if(c) {
  194. $("div.fileList").each(function(){ f18_addDragger(this) });
  195. $("div.pinHeader:not(.menu) div.pin").hide();
  196. } else {
  197. $("div.pinHeader div.dragger").remove();
  198. }
  199. });
  200. addRow("editStyle", "<a href='#'>Additional CSS</a>");
  201. $(appendTo+" tr.ar_editStyle a").click(function(){
  202. $('body').append(
  203. '<div id="editdlg" style="display:none">'+
  204. '<textarea id="f18_cssEd" rows="25" cols="60" style="width:99%"/>'+
  205. '</div>');
  206. $("#f18_cssEd").val($("head #fhemweb_css").html());
  207. $('#editdlg').dialog(
  208. { modal:true, closeOnEscape:true, width:$(window).width()*3/4,
  209. height:$(window).height()*3/4, title:$(this).text(),
  210. close:function(){ $('#editdlg').remove(); },
  211. buttons:[
  212. { text: "Cancel",click:function(){$(this).dialog('close')}},
  213. { text: "OK", click:function(){
  214. if(!$("head #fhemweb_css"))
  215. $("head").append("<style id='fhemweb_css'>\n</style>");
  216. var txt = $("#f18_cssEd").val();
  217. $("head #fhemweb_css").html(txt);
  218. var wn = $("body").attr("data-webName");
  219. FW_cmd(FW_root+"?cmd=attr "+wn+" Css "+
  220. encodeURIComponent(txt.replace(/;/g,";;"))+"&XHR=1");
  221. $(this).dialog('close');
  222. }}]
  223. });
  224. });
  225. $("div#content > table").append("<tr id='f18rr' class='f18'></tr>");
  226. $("tr#f18rr").append("<div class='fileList f18colors'>"+
  227. "f18: Room specific</div>");
  228. $("tr#f18rr").append("<table id='f18tr' class='block wide'></table>");
  229. appendTo = "table#f18tr";
  230. addRow("room", "Target", '<select><option>all</option></select>');
  231. FW_cmd(FW_root+"?cmd=jsonlist2 .* room&XHR=1", function(data) {
  232. var d;
  233. try { d=JSON.parse(data); } catch(e){ log(data); return FW_okDialog(e); }
  234. for(var i1=0; i1<d.Results.length; i1++) {
  235. var rname = d.Results[i1].Attributes.room;
  236. if(!rname || rname == "hidden")
  237. continue;
  238. var rl = rname.split(",")
  239. for(var i2=0; i2<rl.length; i2++)
  240. roomHash[rl[i2]] = true;
  241. }
  242. cleanRoom();
  243. var rArr = Object.keys(roomHash); rArr.sort();
  244. $(appendTo+" tr.ar_room select")
  245. .html("<option>all</option><option>"+
  246. rArr.join("</option><option>")+
  247. "</option>")
  248. .change(function(e){
  249. room = $(e.target).val();
  250. f18_drawSpecial();
  251. });
  252. $("tr.ar_room select").val(room);
  253. });
  254. addRow("reset", "Preset colors: "+
  255. "<a href='#'>default</a> "+
  256. "<a href='#'>light</a> "+
  257. "<a href='#'>dark</a> "+
  258. (room=='all' ? '': "<a href='#'>like:all</a>"));
  259. $(appendTo+" tr.ar_reset a").click(function(){
  260. var txt = $(this).text();
  261. if(txt == "like:all") {
  262. delete(roomHash[room]);
  263. cleanRoom();
  264. } else {
  265. f18_resetCol(txt, room);
  266. if(room == "all")
  267. f18_setCss('preset');
  268. }
  269. f18_setAttr();
  270. f18_drawSpecial();
  271. });
  272. addColorChooser("bg", "Background");
  273. addColorChooser("fg", "Foreground");
  274. addColorChooser("link", "Link");
  275. addColorChooser("evenrow", "Even row");
  276. addColorChooser("oddrow", "Odd row");
  277. addColorChooser("header", "Header row");
  278. addColorChooser("menu", "Menu");
  279. addColorChooser("sel", "Menu:Selected");
  280. addColorChooser("inpBack", "Input bg");
  281. $("table.f18colors input").attr("size", 8);
  282. var bgImg = attr("bgImg", true);
  283. addRow("bgImg", "<a href='#'>Background image: <span>"+
  284. (bgImg ? bgImg : "none")+"</span></a>");
  285. $(appendTo+" tr.ar_bgImg a").click(function(){
  286. FW_cmd(FW_root+'?cmd='+
  287. '{join("\\n",FW_fileList("$FW_icondir/background/.*.(jpg|png)"))}&XHR=1',
  288. function(data) {
  289. if(data)
  290. data += "none";
  291. var imgList = data.split(/\n/);
  292. FW_okDialog("List of files in www/images/background:<br><ul>"+
  293. "<a href='#'>"+imgList.join("</a><br><a href='#'>")+'</a></ul>');
  294. $("#FW_okDialog a").click(function(){
  295. var txt = $(this).text();
  296. setAttr("bgImg", txt == 'none' ? undefined : txt, true);
  297. $(appendTo+" tr.ar_bgImg span").html(txt);
  298. f18_setCss("bgImg");
  299. });
  300. });
  301. });
  302. addHider("hideLogo", true, "Hide logo", f18_menu);
  303. addHider("hideInput", true, "Hide input", f18_menu);
  304. addHider("hidePin", true, "Hide pin", function(c){
  305. if(f18_hasPos || f18_getAttr("showDragger"))
  306. $("div.pinHeader.menu div.pin").css("display", c ? "none":"block");
  307. else
  308. $("div.pinHeader div.pin").css("display", c ? "none":"block");
  309. });
  310. $("div.f18colors").css("margin-top", "20px");
  311. $("tr.f18 div.fileList").each(function(e){f18_addPinToStyleDiv(this)});
  312. };
  313. loadScript("pgm2/fhemweb_colorpicker.js", f18_drawSpecial);
  314. }
  315. function
  316. f18_addPinToStyleDiv(el)
  317. {
  318. var grp = $(el).text();
  319. f18_addPin(el, "style.list."+grp, true,
  320. function(isFixed){
  321. var ntr = $(el).next("table");
  322. isFixed ? $(ntr).show() : $(ntr).hide();
  323. });
  324. if(f18_getAttr("showDragger"))
  325. f18_addDragger(el);
  326. f18_setPos(el);
  327. if(f18_hasPos || f18_getAttr("showDragger"))
  328. $("div.pinHeader:not(.menu) div.pin").hide();
  329. }
  330. function
  331. f18_resize()
  332. {
  333. var w=$(window).width();
  334. log("f18.js W:"+w+" S:"+screen.width);
  335. var hl = f18_getAttr("hideLogo"),
  336. hi = f18_getAttr("hideInput"),
  337. pm = f18_getAttr("Pinned.menu");
  338. var diff = 0;
  339. diff += hl ? 0 : 40;
  340. diff += pm ? 0 : 44;
  341. $("input.maininput")
  342. .css("width", (w-(FW_isiOS ? 40 : 30)-diff)+'px')
  343. .css("display", hi ? "none":"block");
  344. $("#menu,#content").css("top", (hi && pm && hl) ? "10px" : "50px");
  345. }
  346. function
  347. f18_addPin(el, name, defVal, fn, hidePin)
  348. {
  349. var init = f18_getAttr("Pinned."+name);
  350. if(init == undefined)
  351. init = defVal;
  352. $("<div class='pin'></div>")
  353. .appendTo(el)
  354. .css("background-image", "url('"+
  355. (init ? f18_icon.pinIn : f18_icon.pinOut)+"')");
  356. var f18_name = name.replace(/[^A-Z0-9]/ig,'_');
  357. $(el)
  358. .addClass("col_header pinHeader "+f18_name)
  359. .attr("data-name", f18_name);
  360. el = $(el).find("div.pin");
  361. $(el)
  362. .addClass(init ? "pinIn" : "")
  363. .css("cursor", "pointer")
  364. .css("display", (f18_getAttr("hidePin") || hidePin) ? "none" : "block")
  365. .click(function(){
  366. var nextVal = !$(el).hasClass("pinIn");
  367. $(el).toggleClass("pinIn");
  368. $(el).css("background-image","url('"+
  369. (nextVal ? f18_icon.pinIn : f18_icon.pinOut)+"')")
  370. f18_setAttr("Pinned."+name, nextVal);
  371. fn(nextVal);
  372. });
  373. fn(init);
  374. }
  375. function
  376. f18_addDragger(el)
  377. {
  378. if(f18_small)
  379. return;
  380. var comp = $(el).hasClass("fileList") ? $(el).next("table") :
  381. $(el).hasClass("SVGlabel") ? $(el).prev(".SVGplot") :
  382. $(el).closest("tr").next().find(">td>table").first();
  383. $("<div class='dragger dragMove'></div>")
  384. .appendTo(el)
  385. .css({"cursor":"pointer",
  386. "background-image":"url('"+f18_icon.arrows+"')"})
  387. $(el).draggable({
  388. drag:function(evt,ui){
  389. $(comp).css({ left:ui.position.left, top:ui.position.top});
  390. },
  391. start:function(evt,ui){
  392. $(comp).css({ position:"relative",
  393. left:0, top:0, right:"auto", bottom:"auto" });
  394. },
  395. stop:function(evt,ui){
  396. f18_setAttr("Pos."+$(el).attr("data-name"), ui.position);
  397. },
  398. });
  399. $("<div class='dragger dragReset'></div>")
  400. .appendTo(el)
  401. .css({"cursor":"pointer",
  402. "background-image":"url('"+f18_icon.ban+"')"})
  403. .click(function(){
  404. $(el) .css({ left:0, top:0 });
  405. $(comp).css({ left:0, top:0 });
  406. delete(f18_attr["Pos."+$(el).attr("data-name")]);
  407. f18_setAttr();
  408. });
  409. }
  410. function
  411. f18_setPos(el)
  412. {
  413. if(f18_small)
  414. return;
  415. var name = $(el).attr("data-name");
  416. var pos = f18_attr["Pos."+name];
  417. if(!pos)
  418. return;
  419. f18_hasPos = true;
  420. var comp = $(el).hasClass("fileList") ? $(el).next("table") :
  421. $(el).hasClass("SVGlabel") ? $(el).prev(".SVGplot") :
  422. $(el).closest("tr").next().find(">td>table").first();
  423. $(el).css({ position:"relative",
  424. left:pos.left, top:pos.top, right:"auto", bottom:"auto" });
  425. $(comp).css({ position:"relative",
  426. left:pos.left, top:pos.top, right:"auto", bottom:"auto" });
  427. }
  428. function
  429. f18_getAttr(attrName)
  430. {
  431. if(f18_room != undefined) {
  432. var val = f18_attr["Room."+f18_room+"."+attrName];
  433. if(val != undefined)
  434. return val
  435. }
  436. return f18_attr[attrName];
  437. }
  438. function
  439. f18_setAttr(name, value)
  440. {
  441. if(name)
  442. f18_attr[name]=value;
  443. if(name && value == undefined)
  444. delete f18_attr[name];
  445. if(name && name.indexOf("Pinned.") == 0 && !f18_attr.savePinChanges)
  446. return;
  447. var wn = $("body").attr("data-webName");
  448. FW_cmd(FW_root+"?cmd=attr "+wn+" styleData "+
  449. encodeURIComponent(JSON.stringify(f18_sd, undefined, 1))+"&XHR=1");
  450. }
  451. function
  452. f18_resetCol(name, room)
  453. {
  454. var cols = {
  455. "default":{ bg: "FFFFE7", fg: "000000", link: "278727",
  456. evenrow:"F8F8E0", oddrow:"F0F0D8", header: "E0E0C8",
  457. menu: "D7FFFF", sel: "A0FFFF", inpBack:"FFFFFF" },
  458. light: { bg: "F8F8F8", fg: "465666", link: "4C9ED9",
  459. evenrow:"E8E8E8", oddrow:"F0F0F0", header: "DDDDDD",
  460. menu: "EEEEEE", sel: "CAC8CF", inpBack:"FFFFFF" },
  461. dark: { bg: "444444", fg: "CCCCCC", link: "FF9900",
  462. evenrow:"333333", oddrow:"111111", header: "222222",
  463. menu: "111111", sel: "333333", inpBack:"444444" }
  464. };
  465. var col = (name ? cols[name] : cols["default"]);
  466. var prefix = (room && room != 'all' ? "Room."+room+".cols." : "cols.");
  467. for(var c in col)
  468. f18_attr[prefix+c] = col[c];
  469. }
  470. // Put all the colors into a head style tag, send background changes to FHEM
  471. function
  472. f18_setCss(why)
  473. {
  474. var style = "";
  475. function col(n) { return f18_getAttr("cols."+n, true) };
  476. function bg(c) { return "{ background:#"+c+"; fill:#"+c+"; }\n" }
  477. function fg(c) { return "{ color:#"+c+"; }\n" }
  478. style += ".col_fg, body, input, textarea "+fg(col("fg"));
  479. style += ".col_bg, #menu, textarea, input, option "+bg(col("bg"));
  480. style += ".col_link,a:not(.changed),.handle,.fhemlog,input[type=submit],"+
  481. "select,div.ui-widget-content a "+
  482. "{color:#"+col("link")+"!important; stroke:#"+col("link")+";}\n";
  483. style += "svg:not([fill]):not(.jssvg) { fill:#"+col("link")+"; }\n";
  484. style += ".col_evenrow, table.block,div.block "+bg(col("evenrow"));
  485. style += ".col_oddrow,table.block tr.odd,table.block tr.sel "+
  486. bg(col("oddrow"));
  487. style += ".col_header "+bg(col("header"));
  488. style += ".col_menu, table.room "+bg(col("menu"));
  489. style += ".col_sel, table.room tr.sel "+bg(col("sel"));
  490. style += ".col_inpBack, input "+bg(col("inpBack"));
  491. if(col("bg") == "FFFFE7") // default
  492. style += "div.pinHeader.menu {background:#"+col("sel")+";}\n";
  493. style += "div.ui-dialog-titlebar "+bg(col("header"));
  494. style += "div.ui-widget-content "+bg(col("bg"));
  495. style += "div.ui-widget-content, .ui-button-text "+fg(col("fg")+"!important");
  496. style += "div.ui-dialog { border:1px solid #"+col("link")+"; }";
  497. style += "button.ui-button { background:#"+col("oddrow")+"!important; "+
  498. "border:1px solid #"+col("link")+"!important; }\n";
  499. if(typeof DashboardDraggable != "undefined") {
  500. var db = "#dashboard ";
  501. style += db+".dashboard_widgetheader "+bg(col("header"));
  502. style += db+".dashboard_tabnav "+bg(col("menu")+"!important");
  503. style += db+".ui-widget-header .ui-state-default "+bg(col("menu"));
  504. style += db+".ui-widget-header .ui-state-active "+bg(col("sel"));
  505. style += db+".ui-widget-header "+fg(col("fg")+"!important;");
  506. style += db+".ui-widget-header li { border:none!important; }";
  507. style += db+".ui-widget-content a "+fg(col("link")+"!important" );
  508. }
  509. var bgImg = f18_getAttr("bgImg", true);
  510. if(bgImg) {
  511. style += 'body { background-image: url('+FW_root+
  512. '/images/background/'+bgImg+');}';
  513. } else {
  514. style += "body "+bg(col("bg"));
  515. }
  516. $("head style#f18_css").remove();
  517. style = "<style id='f18_css'>"+style+"</style>";
  518. if($("head style#fhemweb_css").length)
  519. $("head style#fhemweb_css").before(style);
  520. else
  521. $("head").append(style);
  522. $("head meta[name=theme-color]").remove();
  523. $("head").append('<meta name="theme-color" content="#'+col("bg")+'">');
  524. // Recolor the menu arrows. CSS does not apply to such SVGs :(
  525. if(why=='init' || why=='preset' || why=='link') {
  526. var a = $("a").get(0);
  527. if(window.getComputedStyle && a) {
  528. var col = getComputedStyle(a,null).getPropertyValue('color');
  529. FW_arrowRight = FW_arrowRight.replace(/rgb[^)]*\)/,col);
  530. FW_arrowDown = FW_arrowDown.replace(/rgb[^)]*\)/,col);
  531. $("div#menu table.room tr.menuTree > td > div > div")
  532. .css("background-image", "url('"+FW_arrowRight+"')");
  533. $("div#menu table.room tr.menuTree.open > td > div > div")
  534. .css("background-image", "url('"+FW_arrowDown+"')");
  535. }
  536. }
  537. }
  538. // SVG color tuning
  539. function
  540. f18_svgSetCols(svg)
  541. {
  542. function col(n) { return f18_getAttr("cols."+n, true) };
  543. if(!svg || !svg.getAttribute("data-origin"))
  544. return;
  545. var style = $(svg).find("> style").first();
  546. var sTxt = $(style).text();
  547. sTxt = sTxt.replace(/font-family:Times/, "fill:#"+col("fg"));
  548. $(style).text(sTxt);
  549. function
  550. addCol(c, d)
  551. {
  552. var r="";
  553. for(var i1=0; i1<6; i1+=2) {
  554. var n = parseInt(c.substr(i1,2), 16);
  555. n += d;
  556. if(n>255) n = 255;
  557. if(n< 0) n = 0;
  558. n = n.toString(16);
  559. if(n.length < 2)
  560. n = "0"+n;
  561. r += n;
  562. }
  563. return r;
  564. }
  565. // SVG background gradient: .css does not work in Firefox, has to use .attr
  566. var stA = $(svg).find("> defs > #gr_bg").children();
  567. var so = "; stop-opacity:1;";
  568. $(stA[0]).attr("style", "stop-color:#"+addCol(col("bg"),10)+so);
  569. $(stA[1]).attr("style", "stop-color:#"+addCol(col("bg"),-10)+so);
  570. }
  571. // font-awesome
  572. var f18_svgPrefix='data:image/svg+xml;utf8,<svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="gray" ';
  573. f18_icon.pinIn=f18_svgPrefix+'d="M896 1088q66 0 128-15v655q0 26-19 45t-45 19h-128q-26 0-45-19t-19-45v-655q62 15 128 15zm0-1088q212 0 362 150t150 362-150 362-362 150-362-150-150-362 150-362 362-150zm0 224q14 0 23-9t9-23-9-23-23-9q-146 0-249 103t-103 249q0 14 9 23t23 9 23-9 9-23q0-119 84.5-203.5t203.5-84.5z"/></svg>';
  574. f18_icon.bars=f18_svgPrefix+'d="M1664 1344v128q0 26-19 45t-45 19h-1408q-26 0-45-19t-19-45v-128q0-26 19-45t45-19h1408q26 0 45 19t19 45zm0-512v128q0 26-19 45t-45 19h-1408q-26 0-45-19t-19-45v-128q0-26 19-45t45-19h1408q26 0 45 19t19 45zm0-512v128q0 26-19 45t-45 19h-1408q-26 0-45-19t-19-45v-128q0-26 19-45t45-19h1408q26 0 45 19t19 45z"/></svg>';
  575. f18_icon.arrows=f18_svgPrefix+'d="M1792 896q0 26-19 45l-256 256q-19 19-45 19t-45-19-19-45v-128h-384v384h128q26 0 45 19t19 45-19 45l-256 256q-19 19-45 19t-45-19l-256-256q-19-19-19-45t19-45 45-19h128v-384h-384v128q0 26-19 45t-45 19-45-19l-256-256q-19-19-19-45t19-45l256-256q19-19 45-19t45 19 19 45v128h384v-384h-128q-26 0-45-19t-19-45 19-45l256-256q19-19 45-19t45 19l256 256q19 19 19 45t-19 45-45 19h-128v384h384v-128q0-26 19-45t45-19 45 19l256 256q19 19 19 45z"/></svg>';
  576. f18_icon.ban=f18_svgPrefix+'d="M1440 893q0-161-87-295l-754 753q137 89 297 89 111 0 211.5-43.5t173.5-116.5 116-174.5 43-212.5zm-999 299l755-754q-135-91-300-91-148 0-273 73t-198 199-73 274q0 162 89 299zm1223-299q0 157-61 300t-163.5 246-245 164-298.5 61-298.5-61-245-164-163.5-246-61-300 61-299.5 163.5-245.5 245-164 298.5-61 298.5 61 245 164 163.5 245.5 61 299.5z"/></svg>';
  577. /*!
  578. * jQuery UI Touch Punch 0.2.3
  579. *
  580. * Copyright 2011-2014, Dave Furfero
  581. * Dual licensed under the MIT or GPL Version 2 licenses.
  582. *
  583. * Depends:
  584. * jquery.ui.widget.js
  585. * jquery.ui.mouse.js
  586. */
  587. !function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);