index.js 8.9 KB

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