index.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  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 savingXhr;
  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. var xhr = new XMLHttpRequest();
  50. xhr.open("POST", "file-api.lc", true);
  51. xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  52. xhr.onreadystatechange = function () {
  53. if (isXhrSuccess(xhr)) {
  54. //setRemoteStatus("");
  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. curFileItem = null;
  68. fileItemList = document.getElementsByClassName("fileItem");
  69. for (i = 0; i < fileItemList.length; i++) {
  70. fileItemList[i].addEventListener("click", function (e) {
  71. handleFileClick(e.target||e.srcElement);
  72. });
  73. }
  74. setLocalStatus("");
  75. } else {
  76. //setRemoteStatus(xhr.responseText);
  77. }
  78. };
  79. setLocalStatus("<span class=\"icon icon-loading\"></span> Loading file list");
  80. xhr.send("action=list");
  81. }
  82. function handleSaveCallback() {
  83. if (isXhrSuccess(savingXhr)) {
  84. setRemoteStatus("");
  85. savingFileOffset += blockSize;
  86. if (savingFileOffset < savingText.length) {
  87. var params = "action=append&filename=" + savingFilename + "&data=" + encodeURIComponent(savingText.substring(savingFileOffset, savingFileOffset + blockSize));
  88. savingXhr = new XMLHttpRequest();
  89. savingXhr.open("POST", "file-api.lc", true);
  90. savingXhr.onreadystatechange = handleSaveCallback;
  91. savingXhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  92. setLocalStatus("<span class=\"icon icon-loading\"></span> Saving file: " + savingFilename + " " + savingFileOffset + "/" + savingText.length + " bytes");
  93. savingXhr.send(params);
  94. } else {
  95. if ((savingFilename.split(".").pop() == "lua") && (savingFilename != "config.lua") && (savingFilename != "init.lua")) {
  96. params = "action=compile&filename=" + savingFilename;
  97. var xhr = new XMLHttpRequest();
  98. xhr.open("POST", "file-api.lc", true);
  99. xhr.onreadystatechange = handleCompileCallback;
  100. xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  101. setLocalStatus("<span class=\"icon icon-loading\"></span> Compiling file: " + savingFilename);
  102. xhr.send(params);
  103. } else {
  104. setLocalStatus("Saved file: " + savingFilename + " " + savingText.length + " bytes");
  105. }
  106. }
  107. } else {
  108. setRemoteStatus(savingXhr.responseText);
  109. }
  110. }
  111. function handleCompileCallback() {
  112. if (isXhrSuccess(xhr)) {
  113. setLocalStatus("");
  114. }
  115. setRemoteStatus(xhr.responseText);
  116. }
  117. function handleFileCallback(xhr) {
  118. setRemoteStatus(xhr.responseText);
  119. if (isXhrSuccess(xhr)) {
  120. loadFilelist();
  121. setLocalStatus("");
  122. }
  123. }
  124. function loadFile() {
  125. var filename = curFileItem.id;
  126. var params = "action=load&filename=" + filename;
  127. var xhr = new XMLHttpRequest();
  128. xhr.open("POST", "file-api.lc", true);
  129. xhr.onreadystatechange = function () {
  130. if (isXhrSuccess(xhr)) {
  131. setRemoteStatus("");
  132. editor.setValue(xhr.responseText);
  133. editor.markClean();
  134. var extension = filename.split(".").pop();
  135. switch (extension) {
  136. case "css":
  137. editor.setOption("mode", "css");
  138. break;
  139. case "htm":
  140. case "html":
  141. editor.setOption("mode", "htmlmixed");
  142. break;
  143. case "js":
  144. case "json":
  145. editor.setOption("mode", "javascript");
  146. break;
  147. case "lua":
  148. editor.setOption("mode", "lua");
  149. break;
  150. case "xml":
  151. editor.setOption("mode", "xml");
  152. break;
  153. }
  154. setLocalStatus("");
  155. } else {
  156. //setRemoteStatus(xhr.responseText);
  157. }
  158. }
  159. xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  160. setLocalStatus("<span class=\"icon icon-loading\"></span> Loading file: " + filename);
  161. xhr.send(params);
  162. }
  163. function undo() {
  164. setLocalStatus("undo");
  165. editor.undo();
  166. }
  167. function save() {
  168. savingText = editor.getValue();
  169. savingFilename = curFileItem.id;
  170. savingFileOffset = 0;
  171. var params = "action=save&filename=" + savingFilename + "&data=" + encodeURIComponent(savingText.substring(savingFileOffset, savingFileOffset + blockSize));
  172. savingXhr = new XMLHttpRequest();
  173. savingXhr.open("POST", "file-api.lc", true);
  174. savingXhr.onreadystatechange = handleSaveCallback;
  175. savingXhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  176. setLocalStatus("<span class=\"icon icon-loading\"></span> Saving file: " + savingFilename + " " + savingFileOffset + "/" + savingText.length + " bytes");
  177. savingXhr.send(params);
  178. }
  179. function preview() {
  180. if (curFileItem) {
  181. var url = curFileItem.id;
  182. setLocalStatus("Preview: "+url);
  183. var win = window.open(url+'?', '_blank');
  184. win.focus();
  185. }
  186. }
  187. function new_file() {
  188. var xhr = new XMLHttpRequest();
  189. xhr.open("POST", "file-api.lc", true);
  190. xhr.onreadystatechange = function() {
  191. handleFileCallback(xhr);
  192. };
  193. xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  194. setLocalStatus("<span class=\"icon icon-loading\"></span> Creating new file");
  195. xhr.send("action=new");
  196. }
  197. function rename_file() {
  198. if (curFileItem) {
  199. var filename = curFileItem.id;
  200. var newfilename = prompt("Rename " + filename + " to:", filename);
  201. if (newfilename != null) {
  202. var xhr = new XMLHttpRequest();
  203. xhr.open("POST", "file-api.lc", true);
  204. xhr.onreadystatechange = function() {
  205. handleFileCallback(xhr);
  206. };
  207. xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  208. setLocalStatus("<span class=\"icon icon-loading\"></span> Renaming file from \""+filename+"\" to \""+newfilename+"\"");
  209. xhr.send("action=rename&filename="+escape(filename)+"&newfilename="+escape(newfilename));
  210. }
  211. }
  212. }
  213. function delete_file() {
  214. if (curFileItem) {
  215. var filename = curFileItem.id;
  216. var xhr = new XMLHttpRequest();
  217. xhr.open("POST", "file-api.lc", true);
  218. xhr.onreadystatechange = function() {
  219. handleFileCallback(xhr);
  220. };
  221. xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  222. setLocalStatus("<span class=\"icon icon-loading\"></span> Deleting file: \""+filename+"\"");
  223. xhr.send("action=delete&filename="+escape(filename));
  224. }
  225. }
  226. function init() {
  227. editor = CodeMirror(document.getElementById("editor"), {
  228. lineNumbers: true,
  229. lineWrapping: true,
  230. styleActiveLine: true, // activeline
  231. matchBrackets: true,
  232. matchTags: true,
  233. autoCloseBrackets: true,
  234. autoCloseTags: true,
  235. showTrailingSpace: true
  236. });
  237. loadFilelist();
  238. document.getElementById("undo").addEventListener("click", undo);
  239. document.getElementById("save").addEventListener("click", save);
  240. document.getElementById("preview").addEventListener("click", preview);
  241. document.getElementById("new").addEventListener("click", new_file);
  242. document.getElementById("rename").addEventListener("click", rename_file);
  243. document.getElementById("delete").addEventListener("click", delete_file);
  244. }
  245. // load large size script in sequence to avoid NodeMCU overflow
  246. // http://codemirror.net/doc/compress.html
  247. loadScript("codemirror.js", function () {
  248. // css.js, htmlmixed.js, javascript.js, lua.js, xml.js
  249. loadScript("modes.js", function () {
  250. // active-line.js, closebrackets.js, closetag.js,
  251. // matchbrackets.js, matchtags.js, trailingspace.js, xml-fold.js
  252. loadScript("addons.js", function () {
  253. init();
  254. })
  255. })
  256. })