index.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. var blockSize = 1024;
  2. var normalColor = "#0067B0";
  3. var selectedColor = "#CCCCCC";
  4. var showInvisibles = false;
  5. var editor;
  6. var curFileItem;
  7. var savingText;
  8. var savingFilename;
  9. var savingFileOffset;
  10. var xhr; // reuse
  11. function setLocalStatus(msg) {
  12. document.getElementById("localStatus").innerHTML = msg;
  13. }
  14. function setRemoteStatus(msg) {
  15. document.getElementById("remoteStatus").innerHTML = msg;
  16. }
  17. function loadScript(url, callback) {
  18. setLocalStatus("<span class=\"icon icon-loading\"></span> Loading " + url);
  19. var script = document.createElement("script");
  20. script.type = "text/javascript";
  21. if (script.readyState) { //IE
  22. script.onreadystatechange = function () {
  23. if (script.readyState == "loaded" || script.readyState == "complete") {
  24. script.onreadystatechange = null;
  25. callback();
  26. }
  27. };
  28. } else { //Others
  29. script.onload = function () {
  30. setLocalStatus("");
  31. callback();
  32. };
  33. }
  34. script.src = url;
  35. document.getElementsByTagName("head")[0].appendChild(script);
  36. }
  37. function isXhrSuccess(xhr) {
  38. return ((xhr.readyState === 4) && (xhr.status == 200));
  39. }
  40. function handleFileClick(item) {
  41. if (curFileItem) {
  42. curFileItem.classList.remove("selected");
  43. }
  44. item.classList.add("selected");
  45. curFileItem = item;
  46. loadFile();
  47. }
  48. function loadFilelist() {
  49. setLocalStatus("<span class=\"icon icon-loading\"></span> Loading file list");
  50. if (!xhr) xhr = new XMLHttpRequest();
  51. xhr.open("POST", "file-api.lc", true);
  52. xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  53. xhr.onreadystatechange = function () {
  54. if (isXhrSuccess(xhr)) {
  55. var filelistHtml = "";
  56. var json = JSON.parse(xhr.responseText);
  57. var files = new Array(json.length);
  58. var i = 0;
  59. for (var filename in json) {
  60. files[i++] = filename;
  61. }
  62. files.sort();
  63. for (i = 0; i < files.length; i++) {
  64. filelistHtml += '<div class="fileItem" id="' + files[i] + '"><span class="icon icon-file"></span> ' + files[i] + '</div>'
  65. }
  66. document.getElementById("filelist").innerHTML = filelistHtml;
  67. fileItemList = document.getElementsByClassName("fileItem");
  68. for (i = 0; i < fileItemList.length; i++) {
  69. fileItemList[i].addEventListener("click", function (e) {
  70. handleFileClick(e.srcElement);
  71. });
  72. }
  73. setLocalStatus("");
  74. }
  75. };
  76. xhr.send("action=list");
  77. }
  78. function handleSaveCallback() {
  79. if (isXhrSuccess(xhr)) {
  80. setRemoteStatus("");
  81. savingFileOffset += blockSize;
  82. if (savingFileOffset < savingText.length) {
  83. setLocalStatus("<span class=\"icon icon-loading\"></span> Saving file: " + savingFilename + " " + savingFileOffset + "/" + savingText.length + " bytes");
  84. var params = "action=append&filename=" + savingFilename + "&data=" + encodeURIComponent(savingText.substring(savingFileOffset, savingFileOffset + blockSize));
  85. if (!xhr) xhr = new XMLHttpRequest();
  86. xhr.open("POST", "file-api.lc", true);
  87. xhr.onreadystatechange = handleSaveCallback;
  88. xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  89. xhr.send(params);
  90. } else {
  91. if ((savingFilename.split(".").pop() == "lua") && (savingFilename != "config.lua") && (savingFilename != "config.lua")) {
  92. setLocalStatus("<span class=\"icon icon-loading\"></span> Compiling file: " + savingFilename);
  93. params = "action=compile&filename=" + savingFilename;
  94. if (!xhr) xhr = new XMLHttpRequest();
  95. xhr.open("POST", "file-api.lc", true);
  96. xhr.onreadystatechange = handleCompileCallback;
  97. xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  98. xhr.send(params);
  99. } else {
  100. setLocalStatus("Saved file: " + savingFilename + " " + savingText.length + " bytes");
  101. }
  102. }
  103. } else {
  104. setRemoteStatus("");
  105. setRemoteStatus(xhr.responseText);
  106. }
  107. }
  108. function handleCompileCallback() {
  109. if (isXhrSuccess(xhr)) {
  110. setLocalStatus("Compiled file: " + savingFilename);
  111. setRemoteStatus("");
  112. }
  113. }
  114. function loadFile() {
  115. var filename = curFileItem.id;
  116. setLocalStatus("Loading: " + filename);
  117. setLocalStatus("<span class=\"icon icon-loading\"></span> Loading file: " + filename);
  118. var params = "action=load&filename=" + filename;
  119. if (!xhr) xhr = new XMLHttpRequest();
  120. xhr.open("POST", "file-api.lc", true);
  121. xhr.onreadystatechange = function () {
  122. if (isXhrSuccess(xhr)) {
  123. editor.setValue(xhr.responseText);
  124. var extension = filename.split(".").pop();
  125. switch (extension) {
  126. case "css":
  127. editor.setOption("mode", "css");
  128. break;
  129. case "htm":
  130. case "html":
  131. editor.setOption("mode", "htmlmixed");
  132. break;
  133. case "js":
  134. case "json":
  135. editor.setOption("mode", "javascript");
  136. break;
  137. case "lua":
  138. editor.setOption("mode", "lua");
  139. break;
  140. case "xml":
  141. editor.setOption("mode", "xml");
  142. break;
  143. }
  144. setLocalStatus("");
  145. }
  146. }
  147. xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  148. xhr.send(params);
  149. }
  150. function undo() {
  151. editor.undo();
  152. }
  153. function save() {
  154. savingText = editor.getValue();
  155. savingFilename = curFileItem.id;
  156. savingFileOffset = 0;
  157. setLocalStatus("<span class=\"icon icon-loading\"></span> Saving file: " + savingFilename + " " + savingFileOffset + "/" + savingText.length + " bytes");
  158. setRemoteStatus("");
  159. var params = "action=save&filename=" + savingFilename + "&data=" + encodeURIComponent(savingText.substring(savingFileOffset, savingFileOffset + blockSize));
  160. if (!xhr) xhr = new XMLHttpRequest();
  161. xhr.open("POST", "file-api.lc", true);
  162. xhr.onreadystatechange = handleSaveCallback;
  163. xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  164. xhr.send(params);
  165. }
  166. function preview() {
  167. if (curFileItem) {
  168. var url = curFileItem.id;
  169. var win = window.open(url, '_blank');
  170. win.focus();
  171. }
  172. }
  173. function init() {
  174. editor = CodeMirror(document.getElementById("editor"), {
  175. styleActiveLine: true, // activeline
  176. lineNumbers: true,
  177. lineWrapping: true,
  178. autoCloseBrackets: true, // closebrackets
  179. autoCloseTags: true, //closetag
  180. gutters: ["CodeMirror-lint-markers"],
  181. lint: true
  182. });
  183. loadFilelist();
  184. document.getElementById("undo").addEventListener("click", undo);
  185. document.getElementById("save").addEventListener("click", save);
  186. document.getElementById("preview").addEventListener("click", preview);
  187. }
  188. // load large size script in sequence to avoid NodeMCU overflow
  189. // CodeMirror Compression helper https://codemirror.net/doc/compress.html
  190. // codemirror.js, css.js, htmlmixed.js, javascript.js, lua.js, xml.js
  191. // active-line.js, css-hint.js, html-hint.js, javascript-hint.js, trailingspace.js, xml-hint.js
  192. loadScript("codemirror-compressed.js", function () {
  193. //loadScript("further-script.js", function () {
  194. init();
  195. //})
  196. })