core-webinterface.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. // Copyright (c) 2013 Datenstrom, http://datenstrom.se
  2. // This file may be used and distributed under the terms of the public license.
  3. // Yellow main API
  4. var yellow =
  5. {
  6. version: "0.2.2",
  7. onClick: function(e) { yellow.webinterface.hidePanesOnClick(yellow.toolbox.getEventElement(e)); },
  8. onKeydown: function(e) { yellow.webinterface.hidePanesOnKeydown(yellow.toolbox.getEventKeycode(e)); },
  9. onResize: function() { yellow.webinterface.resizePanes(); },
  10. onShow: function(id) { yellow.webinterface.showPane(id); },
  11. onLogout: function() { yellow.toolbox.submitForm({"action":"logout"}); },
  12. webinterface:{}, page:{}, pages:{}, toolbox:{}, config:{}, text:{}
  13. }
  14. // Yellow web interface
  15. yellow.webinterface =
  16. {
  17. created: false, //interface created? (boolean)
  18. intervalId: 0, //interface timer interval ID
  19. // Initialise web interface
  20. init: function()
  21. {
  22. this.intervalId = setInterval("yellow.webinterface.create()", 1);
  23. yellow.toolbox.addEvent(window, "resize", yellow.onResize);
  24. yellow.toolbox.addEvent(document, "click", yellow.onClick);
  25. yellow.toolbox.addEvent(document, "keydown", yellow.onKeydown);
  26. },
  27. // Create web interface
  28. create: function()
  29. {
  30. var body = document.getElementsByTagName("body")[0];
  31. if(body && body.firstChild && !this.created)
  32. {
  33. this.created = true;
  34. if(yellow.debug) console.log("yellow.webinterface.create email:"+yellow.config.userEmail+" "+yellow.config.userName);
  35. if(yellow.config.userEmail)
  36. {
  37. yellow.toolbox.insertBefore(this.createBar("yellow-bar"), body.firstChild);
  38. yellow.toolbox.insertAfter(this.createPane("yellow-pane-edit"), body.firstChild);
  39. yellow.toolbox.insertAfter(this.createPane("yellow-pane-show"), body.firstChild);
  40. yellow.toolbox.insertAfter(this.createPane("yellow-pane-user"), body.firstChild);
  41. yellow.toolbox.setText(document.getElementById("yellow-edit-text"), yellow.page.rawData);
  42. } else {
  43. yellow.toolbox.insertBefore(this.createBar("yellow-bar", true), body.firstChild);
  44. yellow.toolbox.insertAfter(this.createPane("yellow-pane-login", true), body.firstChild);
  45. this.showPane("yellow-pane-login");
  46. }
  47. clearInterval(this.intervalId);
  48. }
  49. },
  50. // Create bar
  51. createBar: function(id, simple)
  52. {
  53. if(yellow.debug) console.log("yellow.webinterface.createBar id:"+id);
  54. var elementBar = document.createElement("div");
  55. elementBar.className = "yellow-bar yellow";
  56. elementBar.setAttribute("id", id);
  57. if(!simple)
  58. {
  59. var location = yellow.config.serverBase+yellow.config.pluginLocation;
  60. elementBar.innerHTML =
  61. "<div class=\"yellow-bar-left\">"+
  62. "<a href=\"http://datenstrom.se/yellow/\" target=\"_blank\"><i class=\"yellow-icon\"></i> Yellow</a>"+
  63. "<a href=\"#\" onclick=\"yellow.onShow('yellow-pane-edit'); return false;\">"+this.getText("Edit")+"</a>"+
  64. "<a href=\"#\" onclick=\"yellow.onShow('yellow-pane-show'); return false;\">"+this.getText("Show")+"</a>"+
  65. "</div>"+
  66. "<div class=\"yellow-bar-right\">"+
  67. "<a href=\"#\" onclick=\"yellow.onShow('yellow-pane-user'); return false;\" id=\"yellow-username\">"+yellow.config.userName+" <i class=\"yellow-icon-caret-down\"></i></a>"+
  68. "</div>";
  69. }
  70. return elementBar;
  71. },
  72. // Create pane
  73. createPane: function(id, simple)
  74. {
  75. if(yellow.debug) console.log("yellow.webinterface.createPane id:"+id);
  76. var elementPane = document.createElement("div");
  77. elementPane.className = simple ? "yellow-pane" : "yellow-pane yellow-pane-bubble";
  78. elementPane.setAttribute("id", id);
  79. elementPane.style.display = "none";
  80. var elementDiv = document.createElement("div");
  81. elementDiv.setAttribute("id", id+"-content");
  82. if(id == "yellow-pane-login")
  83. {
  84. elementDiv.innerHTML =
  85. "<h1>"+this.getText("LoginText")+"</h1>"+
  86. "<form method=\"post\">"+
  87. "<input type=\"hidden\" name=\"action\" value=\"login\" />"+
  88. "<p><label for=\"email\">"+this.getText("LoginEmail")+"</label> <input name=\"email\" id=\"email\" maxlength=\"64\" /></p>"+
  89. "<p><label for=\"password\">"+this.getText("LoginPassword")+"</label> <input type=\"password\" name=\"password\" id=\"password\" maxlength=\"64\" /></p>"+
  90. "<p><input class=\"yellow-btn\" type=\"submit\" value=\""+this.getText("LoginButton")+"\" /></p>"+
  91. "</form>";
  92. } else if(id == "yellow-pane-edit") {
  93. elementDiv.innerHTML =
  94. "<p>Editing page...</p>"+
  95. "<form method=\"post\">"+
  96. "<input type=\"hidden\" name=\"action\" value=\"edit\" />"+
  97. "<textarea id=\"yellow-edit-text\" name=\"rawdata\"></textarea>"+
  98. "<div id=\"yellow-edit-info\" /></div>"+
  99. "<div id=\"yellow-edit-buttons\">"+
  100. "<input class=\"yellow-btn\" type=\"submit\" value=\""+this.getText("SaveButton")+"\" />"+
  101. "</div>"+
  102. "</form>";
  103. } else if(id == "yellow-pane-show") {
  104. elementDiv.innerHTML = "<p>Showing files...</p>";
  105. var elementUl = document.createElement("ul");
  106. for(var n in yellow.pages)
  107. {
  108. var elementLi = document.createElement("li");
  109. var elementA = document.createElement("a");
  110. elementA.setAttribute("href", yellow.pages[n]["location"]);
  111. yellow.toolbox.setText(elementA, yellow.pages[n]["title"]);
  112. elementLi.appendChild(elementA);
  113. elementUl.appendChild(elementLi);
  114. }
  115. elementDiv.appendChild(elementUl);
  116. } else if(id == "yellow-pane-user") {
  117. elementDiv.innerHTML =
  118. "<p>"+yellow.config.userEmail+"</p>"+
  119. "<p><a href=\"#\" onclick=\"yellow.onLogout(); return false;\">"+this.getText("UserLogout")+"</a></p>";
  120. }
  121. elementPane.appendChild(elementDiv);
  122. return elementPane;
  123. },
  124. // Show or hide pane
  125. showPane: function(id)
  126. {
  127. if(!yellow.toolbox.isVisible(document.getElementById(id)))
  128. {
  129. this.hidePanes();
  130. if(yellow.debug) console.log("yellow.webinterface.showPane id:"+id);
  131. document.getElementById(id).style.display = "block";
  132. this.resizePanes();
  133. } else {
  134. this.hidePane(id);
  135. }
  136. },
  137. // Hide pane
  138. hidePane: function(id)
  139. {
  140. if(yellow.toolbox.isVisible(document.getElementById(id)))
  141. {
  142. if(yellow.debug) console.log("yellow.webinterface.hidePane id:"+id);
  143. document.getElementById(id).style.display = "none";
  144. }
  145. },
  146. // Hide all panes
  147. hidePanes: function()
  148. {
  149. for(var element=document.getElementById("yellow-bar"); element; element=element.nextSibling)
  150. {
  151. if(element.className && element.className.indexOf("yellow-pane")>=0)
  152. {
  153. this.hidePane(element.getAttribute("id"));
  154. }
  155. }
  156. },
  157. // Hide all panes on mouse click outside
  158. hidePanesOnClick: function(element)
  159. {
  160. while(element = element.parentNode)
  161. {
  162. if(element.className)
  163. {
  164. if(element.className.indexOf("yellow-pane")>=0 || element.className.indexOf("yellow-bar")>=0) return;
  165. }
  166. }
  167. this.hidePanes();
  168. },
  169. // Hide all panes on ESC key
  170. hidePanesOnKeydown: function(keycode)
  171. {
  172. if(keycode == 27) this.hidePanes();
  173. },
  174. // Resize panes, recalculate width and height where needed
  175. resizePanes: function()
  176. {
  177. if(document.getElementById("yellow-bar"))
  178. {
  179. var elementBar = document.getElementById("yellow-bar");
  180. var paneTop = yellow.toolbox.getOuterTop(elementBar) + yellow.toolbox.getOuterHeight(elementBar);
  181. var paneWidth = yellow.toolbox.getOuterWidth(elementBar, true);
  182. var paneHeight = yellow.toolbox.getWindowHeight() - paneTop - yellow.toolbox.getOuterHeight(elementBar);
  183. if(yellow.toolbox.isVisible(document.getElementById("yellow-pane-login")))
  184. {
  185. yellow.toolbox.setOuterWidth(document.getElementById("yellow-pane-login"), paneWidth);
  186. }
  187. if(yellow.toolbox.isVisible(document.getElementById("yellow-pane-edit")))
  188. {
  189. yellow.toolbox.setOuterTop(document.getElementById("yellow-pane-edit"), paneTop);
  190. yellow.toolbox.setOuterHeight(document.getElementById("yellow-pane-edit"), paneHeight);
  191. yellow.toolbox.setOuterWidth(document.getElementById("yellow-pane-edit"), paneWidth);
  192. yellow.toolbox.setOuterWidth(document.getElementById("yellow-edit-text"), yellow.toolbox.getWidth(document.getElementById("yellow-pane-edit")));
  193. var height1 = yellow.toolbox.getHeight(document.getElementById("yellow-pane-edit"));
  194. var height2 = yellow.toolbox.getOuterHeight(document.getElementById("yellow-pane-edit-content"));
  195. var height3 = yellow.toolbox.getOuterHeight(document.getElementById("yellow-edit-text"));
  196. yellow.toolbox.setOuterHeight(document.getElementById("yellow-edit-text"), height1 - height2 + height3);
  197. }
  198. if(yellow.toolbox.isVisible(document.getElementById("yellow-pane-show")))
  199. {
  200. yellow.toolbox.setOuterTop(document.getElementById("yellow-pane-show"), paneTop);
  201. yellow.toolbox.setOuterHeight(document.getElementById("yellow-pane-show"), paneHeight, true);
  202. }
  203. if(yellow.toolbox.isVisible(document.getElementById("yellow-pane-user")))
  204. {
  205. yellow.toolbox.setOuterTop(document.getElementById("yellow-pane-user"), paneTop);
  206. yellow.toolbox.setOuterHeight(document.getElementById("yellow-pane-user"), paneHeight, true);
  207. yellow.toolbox.setOuterLeft(document.getElementById("yellow-pane-user"), paneWidth - yellow.toolbox.getOuterWidth(document.getElementById("yellow-pane-user")), true);
  208. }
  209. if(yellow.debug) console.log("yellow.webinterface.resizePanes bar:"+elementBar.offsetWidth+"/"+elementBar.offsetHeight);
  210. }
  211. },
  212. // Return text string
  213. getText: function(key)
  214. {
  215. return ("webinterface"+key in yellow.text) ? yellow.text["webinterface"+key] : "[webinterface"+key+"]";
  216. }
  217. }
  218. // Yellow toolbox with helpers
  219. yellow.toolbox =
  220. {
  221. // Set element text
  222. setText: function(element, text)
  223. {
  224. while(element.firstChild !== null) element.removeChild(element.firstChild);
  225. element.appendChild(document.createTextNode(text));
  226. },
  227. // Insert element before element
  228. insertBefore: function(newElement, referenceElement)
  229. {
  230. referenceElement.parentNode.insertBefore(newElement, referenceElement);
  231. },
  232. // Insert element after element
  233. insertAfter: function(newElement, referenceElement)
  234. {
  235. referenceElement.parentNode.insertBefore(newElement, referenceElement.nextSibling);
  236. },
  237. // Add event handler
  238. addEvent: function(element, type, handler)
  239. {
  240. if(element.addEventListener) element.addEventListener(type, handler, false);
  241. else element.attachEvent('on'+type, handler);
  242. },
  243. // Return element of event
  244. getEventElement: function(e)
  245. {
  246. e = e ? e : window.event;
  247. return e.target ? e.target : e.srcElement;
  248. },
  249. // Return keycode of event
  250. getEventKeycode: function(e)
  251. {
  252. e = e ? e : window.event;
  253. return e.keyCode
  254. },
  255. // Set element width/height in pixel, including padding and border
  256. setOuterWidth: function(element, width, maxWidth)
  257. {
  258. width -= this.getBoxSize(element).width;
  259. if(maxWidth)
  260. {
  261. element.style.maxWidth = Math.max(0, width) + "px";
  262. } else {
  263. element.style.width = Math.max(0, width) + "px";
  264. }
  265. },
  266. setOuterHeight: function(element, height, maxHeight)
  267. {
  268. height -=this.getBoxSize(element).height;
  269. if(maxHeight)
  270. {
  271. element.style.maxHeight = Math.max(0, height) + "px";
  272. } else {
  273. element.style.height = Math.max(0, height) + "px";
  274. }
  275. },
  276. // Return element width/height in pixel, including padding and border
  277. getOuterWidth: function(element, includeMargin)
  278. {
  279. width = element.offsetWidth;
  280. if(includeMargin) width += this.getMarginSize(element).width;
  281. return width;
  282. },
  283. getOuterHeight: function(element, includeMargin)
  284. {
  285. height = element.offsetHeight;
  286. if(includeMargin) height += this.getMarginSize(element).height;
  287. return height;
  288. },
  289. // Return element width/height in pixel
  290. getWidth: function(element)
  291. {
  292. return element.offsetWidth - this.getBoxSize(element).width;
  293. },
  294. getHeight: function(element)
  295. {
  296. return element.offsetHeight - this.getBoxSize(element).height;
  297. },
  298. // Set element top/left position in pixel
  299. setOuterTop: function(element, top, marginTop)
  300. {
  301. if(marginTop)
  302. {
  303. element.style.marginTop = Math.max(0, top) + "px";
  304. } else {
  305. element.style.top = Math.max(0, top) + "px";
  306. }
  307. },
  308. setOuterLeft: function(element, left, marginLeft)
  309. {
  310. if(marginLeft)
  311. {
  312. element.style.marginLeft = Math.max(0, left) + "px";
  313. } else {
  314. element.style.left = Math.max(0, left) + "px";
  315. }
  316. },
  317. // Return element top/left position in pixel
  318. getOuterTop: function(element)
  319. {
  320. var top = element.getBoundingClientRect().top;
  321. return top + (window.pageYOffset || document.documentElement.scrollTop);
  322. },
  323. getOuterLeft: function(element)
  324. {
  325. var left = element.getBoundingClientRect().left;
  326. return left + (window.pageXOffset || document.documentElement.scrollLeft);
  327. },
  328. // Return window width/height in pixel
  329. getWindowWidth: function()
  330. {
  331. return window.innerWidth || document.documentElement.clientWidth;
  332. },
  333. getWindowHeight: function()
  334. {
  335. return window.innerHeight || document.documentElement.clientHeight;
  336. },
  337. // Return element CSS property
  338. getStyle: function(element, property)
  339. {
  340. var string = "";
  341. if(window.getComputedStyle)
  342. {
  343. string = window.getComputedStyle(element, null).getPropertyValue(property);
  344. } else {
  345. property = property.replace(/\-(\w)/g, function(match, m) { return m.toUpperCase(); });
  346. string = element.currentStyle[property];
  347. }
  348. return string;
  349. },
  350. // Return element CSS padding and border
  351. getBoxSize: function(element)
  352. {
  353. var paddingLeft = parseFloat(this.getStyle(element, "padding-left")) || 0;
  354. var paddingRight = parseFloat(this.getStyle(element, "padding-right")) || 0;
  355. var borderLeft = parseFloat(this.getStyle(element, "border-left-width")) || 0;
  356. var borderRight = parseFloat(this.getStyle(element, "border-right-width")) || 0;
  357. var width = paddingLeft + paddingRight + borderLeft + borderRight;
  358. var paddingTop = parseFloat(this.getStyle(element, "padding-top")) || 0;
  359. var paddingBottom = parseFloat(this.getStyle(element, "padding-bottom")) || 0;
  360. var borderTop = parseFloat(this.getStyle(element, "border-top-width")) || 0;
  361. var borderBottom = parseFloat(this.getStyle(element, "border-bottom-width")) || 0;
  362. var height = paddingTop + paddingBottom + borderTop + borderBottom;
  363. return { "width":width, "height":height };
  364. },
  365. // Return element CSS margin
  366. getMarginSize: function(element)
  367. {
  368. var marginLeft = parseFloat(this.getStyle(element, "margin-left")) || 0;
  369. var marginRight = parseFloat(this.getStyle(element, "margin-right")) || 0;
  370. var width = marginLeft + marginRight;
  371. var marginTop = parseFloat(this.getStyle(element, "margin-top")) || 0;
  372. var marginBottom = parseFloat(this.getStyle(element, "margin-bottom")) || 0;
  373. var height = marginTop + marginBottom;
  374. return { "width":width, "height":height };
  375. },
  376. // Check if element exists and is visible
  377. isVisible: function(element)
  378. {
  379. return element && element.style.display != "none";
  380. },
  381. // Submit form with post method
  382. submitForm: function(params)
  383. {
  384. var elementForm = document.createElement("form");
  385. elementForm.setAttribute("method", "post");
  386. for(var key in params)
  387. {
  388. if(!params.hasOwnProperty(key)) continue;
  389. var elementInput = document.createElement("input");
  390. elementInput.setAttribute("type", "hidden");
  391. elementInput.setAttribute("name", key);
  392. elementInput.setAttribute("value", params[key]);
  393. elementForm.appendChild(elementInput);
  394. }
  395. document.body.appendChild(elementForm);
  396. elementForm.submit();
  397. }
  398. }
  399. yellow.webinterface.init();