From 993054ce9debd3f2dcd4df87f25c9bd598aff216 Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Mon, 16 Jan 2017 15:24:44 +0000 Subject: [PATCH] Merge the editor and the terminal view. I think it will be nicer to work with them always side-by-side. git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3380 ed5197a5-7fde-0310-b194-c3ffbd925b24 --- core/agplv3-88x31.png | Bin 1883 -> 0 bytes core/client.js | 210 +++++++++++++++++++++++++++++++++++++++++- core/edit.html | 34 ------- core/editor.js | 118 ------------------------ core/index.html | 24 ++++- core/style.css | 5 - core/terminal.js | 1 - 7 files changed, 226 insertions(+), 166 deletions(-) delete mode 100644 core/agplv3-88x31.png delete mode 100644 core/edit.html delete mode 100644 core/editor.js diff --git a/core/agplv3-88x31.png b/core/agplv3-88x31.png deleted file mode 100644 index 7a472a0d8f3dca824af43755da32020507ae3a69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1883 zcmV-h2c-CkP)Px#32;bRa{vGWCjbBfCjq_^R0se700(qQO+^RT0tgi!FnpsB!~g&Q24YJ`L;(K) z{{a7>y{D4^00!GhL_t(&-tC$RY*s}O#|sp>t0@RH$`M3?qQO!`swg240Y$7Lq)?2A z<`WPjLJ1;BOOT?}h7^jTP&q{95U5-ckN`!D+(8Zt=#A{%7I_Oky6S& zu=N)9e-Pw@s~`tVfI=S>ioXYJ0Poop+!Wj>#bklKCEVvZZ~*)cj)D{@Fv4MV*8m4> z3hr0R6`TY%l~7+hzz^Us_y>#!RXv)IBQ^zR6k#BLgGt~ckjc7hU?Z4mVK&$;`dH&2 ztN4Z!RkFFFP9IApli_ zohGF`c$j^tm6#{`%rRVdMzsH;Y@8@>G01Nf2k?2&jpZSl+#1%W7D2gRgAw48sM`jr ziG?x%tmMucX;E-GNU^Qnu097fkk?HHQ6Q89T*UfXmg~M}yIO63f#ob$;pwc)Pu33L z+APo4|PqnEwpVFtI?lr(rpU#H%Pk2zC@u^&8(&~6{ z(Q-g7n}QcO+#rL8SR~!9Q-XA1kCkj3%WrCqdlG5N_Ltb!kL9YMu7UcXJM#cpl)cNc zy@!bTRMBMSux_6Z#j0Q_Q9RU!-05KkwBdp3)i<664jI}`26v%Q zaEdj!;6QpCI$B20qOs-h`7a_90mVX=!z~fv3e96#$#P{&fT0sX`MH+%b=th%k6KLzV%R>2 z@|{^u@G!yo!rNGD=sRCa8Yv&VjdlPRb=AINIMf<|J)oVNa%+fyVJ}TWBfiyeyZQ4x z>4WxDDY}-!y{f6GO+-oItpCnyXztMWSCs3;l;si^6X?Z*NYz7PDmM!31D!%VocK>ngg4Ikxq2{blB=n^}C_SE<}6Z~05uMISf+lPCYhfcISSIZK+ez-MaIE9;o! z2-Ds(rn#hDRbKiHlaDK21APX5v<4Fv1+Vlm_-7dLO%$(D^0bIeZn2)s7pGJ9B+XF( zyw6PBS>|}J@}1XN`k>c%50%b5?c-rw3g(Xub8W@@j%FYf%WPV0mk2G6QQB~8D$;Vp z@?1$?27ZCIS%tWxl;P(<`|>SD0uQ&~E2lz+w}bhLr$7DDB@7ha;`Q-#=98H%Q~frh zC)15ielIODbYp1=y_#>z{B9S z{8X+Sm4I2!wB%4Kz6J9e>S27zw+4@cvGij4@=e1iA7kBFOvP3O<7sQV7QLhY6E0r; zz+hzaZ7^`)$}8k4o+hHDV^m}YxBEoq0}j$gX43nZ#$?KNCcYCHW-kzlmPDTk8a0MT zi=bHbKCKVU!8lN*cw6A+X?dfJa^94?wJ5eeNMyQkh6*4`=JTJMtLa7=<|^%ajHXca z^-X)AzRKAJwu1x^Ub5d;-Hg`imRVW`p5?b=+2FYP7=+)D?FREeKi4q#&hPg9{R?~S VPG}_jwHp8c002ovPDHLkV1iNPinag% diff --git a/core/client.js b/core/client.js index a97fbd5d..788da5ca 100644 --- a/core/client.js +++ b/core/client.js @@ -8,8 +8,30 @@ var gSendKeyEvents = false; var gSendDeviceOrientationEvents = false; var gGeolocatorWatch; +var gEditor; +var gBackup; + var kMaxCommandHistory = 16; +window.addEventListener("keydown", function(event) { + if (event.keyCode == 69 && event.altKey) { + if (!editing()) { + edit(); + event.preventDefault(); + } + } else if (event.keyCode == 83 && (event.altKey || event.ctrlKey)) { + if (editing()) { + save(); + event.preventDefault(); + } + } else if (event.keyCode == 66 && event.altKey) { + if (editing()) { + closeEditor(); + event.preventDefault(); + } + } +}); + function keydown(event) { if (event.keyCode == 13) { gCommandHistory.push(document.getElementById("input").value); @@ -32,9 +54,181 @@ function keydown(event) { input.value = gCommandHistory.shift(); event.preventDefault(); } - } else if (event.keyCode == 69 && event.altKey) { - window.location.href = url() + "/edit"; - event.preventDefault(); + } +} + +function ensureLoaded(nodes, callback) { + if (!nodes.length) { + callback(); + return; + } + + var search = nodes.shift(); + var head = document.head; + var found = false; + for (var i = 0; i < head.childNodes.length; i++) { + if (head.childNodes[i].tagName == search.tagName) { + var match = true; + for (var attribute in search.attributes) { + if (head.childNodes[i].attributes[attribute].value != search.attributes[attribute]) { + match = false; + } + } + if (match) { + found = true; + break; + } + } + } + if (found) { + ensureLoaded(nodes, callback); + } else { + var node = document.createElement(search.tagName); + node.onreadystatechange = node.onload = function() { + ensureLoaded(nodes, callback); + }; + for (var attribute in search.attributes) { + node.setAttribute(attribute, search.attributes[attribute]); + } + head.insertBefore(node, head.firstChild); + } +} + +function editing() { + return document.getElementById("editPane").style.display != 'none'; +} + +function edit() { + if (editing()) { + return; + } + + ensureLoaded([ + {tagName: "script", attributes: {src: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.12.0/codemirror.min.js"}}, + {tagName: "link", attributes: {rel: "stylesheet", href: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.12.0/theme/base16-dark.min.css"}}, + {tagName: "link", attributes: {rel: "stylesheet", href: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.12.0/addon/search/matchesonscrollbar.min.css"}}, + {tagName: "link", attributes: {rel: "stylesheet", href: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.12.0/addon/dialog/dialog.min.css"}}, + {tagName: "link", attributes: {rel: "stylesheet", href: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.12.0/codemirror.min.css"}}, + {tagName: "script", attributes: {src: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.12.0/addon/edit/trailingspace.min.js"}}, + {tagName: "script", attributes: {src: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.12.0/addon/dialog/dialog.min.js"}}, + {tagName: "script", attributes: {src: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.12.0/addon/search/search.min.js"}}, + {tagName: "script", attributes: {src: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.12.0/addon/search/searchcursor.min.js"}}, + {tagName: "script", attributes: {src: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.12.0/addon/search/jump-to-line.min.js"}}, + {tagName: "script", attributes: {src: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.12.0/addon/search/matchesonscrollbar.min.js"}}, + {tagName: "script", attributes: {src: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.12.0/addon/scroll/annotatescrollbar.min.js"}}, + {tagName: "script", attributes: {src: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.12.0/mode/javascript/javascript.min.js"}}, + ], function() { + load(); + }); + +} + +function load() { + var request = new XMLHttpRequest(); + request.addEventListener("loadend", function() { + if (request.status == 200) { + document.getElementById("editPane").style.display = 'flex'; + if (!gEditor) { + gEditor = CodeMirror.fromTextArea(document.getElementById("editor"), { + 'theme': 'base16-dark', + 'lineNumbers': true, + 'tabSize': 4, + 'indentUnit': 4, + 'indentWithTabs': true, + 'showTrailingSpace': true, + }); + } + gEditor.setValue(request.responseText); + gEditor.focus(); + gBackup = request.responseText; + } + }); + request.addEventListener("error", function() { + alert("Error loading source."); + closeEditor(); + }); + request.addEventListener("timeout", function() { + alert("Timed out loading source."); + closeEditor(); + }); + request.addEventListener("abort", function() { + alert("Loading source aborted."); + closeEditor(); + }); + request.open("GET", url() + "/view"); + request.send(); +} + +function closeEditor() { + document.getElementById("editPane").style.display = 'none'; +} + +function revert() { + gEditor.setValue(gBackup); +} + +function explodePath() { + return /^\/~([^\/]+)\/([^\/]+)(.*)/.exec(window.location.pathname); +} + +function packageOwner() { + return explodePath()[1]; +} + +function packageName() { + return explodePath()[2]; +} + +function save(newName) { + document.getElementById("save").disabled = true; + document.getElementById("saveAs").disabled = true; + + var contents = gEditor.getValue(); + var run = document.getElementById("run").checked; + + var request = new XMLHttpRequest(); + + var always = function() { + document.getElementById("save").disabled = false; + document.getElementById("saveAs").disabled = false; + }; + + request.addEventListener("error", function() { + alert("Error saving: " + request.responseText); + always(); + }); + request.addEventListener("loadend", function() { + if (request.status == 200) { + gBackup = contents; + if (run) { + if (newName) { + window.location.href = "/~" + packageOwner() + "/" + newName + hash(); + } else { + reconnect(); + } + } + } else { + alert("Unable to save: " + request.responseText); + } + always(); + }); + request.addEventListener("timeout", function() { + alert("Timed out saving: " + request.responseText); + always(); + }); + request.addEventListener("abort", function() { + alert("Save aborted: " + request.responseText); + always(); + }); + request.open("POST", newName ? newName + "/save" : packageName() + "/save", true); + request.setRequestHeader("Content-Type", "text/plain"); + request.send(contents); +} + +function saveAs() { + var newName = prompt("Save as:", packageName()); + if (newName) { + save(newName); } } @@ -553,6 +747,16 @@ function submitButton() { send({event: "submit", value: data}); } +function reconnect() { + let oldSocket = gSocket; + gSocket = null + oldSocket.onclose = function() {} + oldSocket.onmessage = function() {} + oldSocket.close(); + split(document.getElementById("terminals"), [{name: "terminal_"}]); + connectSocket(); +} + function connectSocket() { if (!gSocket || gSocket.readyState == gSocket.CLOSED) { gSocket = new WebSocket( diff --git a/core/edit.html b/core/edit.html deleted file mode 100644 index a84b3b25..00000000 --- a/core/edit.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - Web Terminal - - - - - - - - - - - - - - - - - - - - - - - diff --git a/core/editor.js b/core/editor.js deleted file mode 100644 index db9c2a10..00000000 --- a/core/editor.js +++ /dev/null @@ -1,118 +0,0 @@ -var gBackup; -var gEditor; - -window.addEventListener("load", function() { - gEditor = CodeMirror.fromTextArea(document.getElementById("editor"), { - 'theme': 'base16-dark', - 'lineNumbers': true, - 'tabSize': 4, - 'indentUnit': 4, - 'indentWithTabs': true, - 'showTrailingSpace': true, - }); - gBackup = gEditor.getValue(); - gEditor.focus(); -}); - -window.addEventListener("keydown", function(event) { - if (event.keyCode == 83 && event.altKey) { - save(); - } else if (event.keyCode == 66 && event.altKey) { - back(); - } -}); - -function explodePath() { - return /^\/~([^\/]+)\/([^\/]+)(.*)/.exec(window.location.pathname); -} - -function packageOwner() { - return explodePath()[1]; -} - -function packageName() { - return explodePath()[2]; -} - -function back(uri) { - if (uri) { - window.location.pathname = uri; - } else { - window.location.pathname = "/~" + packageOwner() + "/" + packageName(); - } -} - -function save(newName) { - document.getElementById("save").disabled = true; - document.getElementById("saveAs").disabled = true; - - var contents = gEditor.getValue(); - var run = document.getElementById("run").checked; - - var request = new XMLHttpRequest(); - - var always = function() { - document.getElementById("save").disabled = false; - document.getElementById("saveAs").disabled = false; - }; - - request.addEventListener("error", function() { - alert("Error saving: " + request.responseText); - always(); - }); - request.addEventListener("loadend", function() { - if (request.status == 200) { - gBackup = contents; - if (run) { - back(request.responseText); - } - } else { - alert("Unable to save: " + request.responseText); - } - always(); - }); - request.addEventListener("timeout", function() { - alert("Timed out saving: " + request.responseText); - always(); - }); - request.addEventListener("abort", function() { - alert("Save aborted: " + request.responseText); - always(); - }); - request.open("POST", newName ? "../" + newName + "/save" : "save", true); - request.setRequestHeader("Content-Type", "text/plain"); - request.send(contents); -} - -function saveAs() { - var newName = prompt("Save as:", packageName()); - if (newName) { - save(newName); - } -} - -function revert() { - gEditor.setValue(gBackup); -} - -function addLicense() { - var contents = "/*\n" + - "\n" + - "Copyright (C) \n".replace("", new Date().getFullYear()) + - "\n" + - "This program is free software: you can redistribute it and/or modify\n" + - "it under the terms of the GNU Affero General Public License as published by\n" + - "the Free Software Foundation, either version 3 of the License, or\n" + - "(at your option) any later version.\n" + - "\n" + - "This program is distributed in the hope that it will be useful,\n" + - "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + - "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + - "GNU Affero General Public License for more details.\n" + - "\n" + - "You should have received a copy of the GNU Affero General Public License\n" + - "along with this program. If not, see .\n" + - "*/\n\n" + - gEditor.getValue(); - gEditor.setValue(contents); -} diff --git a/core/index.html b/core/index.html index 822d3617..9734ed7e 100644 --- a/core/index.html +++ b/core/index.html @@ -12,17 +12,31 @@ 😎 Tilde Friends home - edit + edit view source about update available! refresh to update -
-
- > - +
+ +
+
+
+ > + +
+
diff --git a/core/style.css b/core/style.css index 180cbf2f..8f399b21 100644 --- a/core/style.css +++ b/core/style.css @@ -102,11 +102,6 @@ a:active, .command:active { padding: 0; } -.CodeMirror-scroll { - height: 100%; - padding: 0; -} - .cm-tab { background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=); background-position: right; diff --git a/core/terminal.js b/core/terminal.js index 547db2ec..9b47072c 100644 --- a/core/terminal.js +++ b/core/terminal.js @@ -7,7 +7,6 @@ var kStaticFiles = [ {uri: '/favicon.png', path: 'favicon.png', type: 'image/png'}, {uri: '/client.js', path: 'client.js', type: 'text/javascript; charset=UTF-8'}, {uri: '/editor.js', path: 'editor.js', type: 'text/javascript; charset=UTF-8'}, - {uri: '/agplv3-88x31.png', path: 'agplv3-88x31.png', type: 'image/png'}, {uri: '/robots.txt', path: 'robots.txt', type: 'text/plain; charset=UTF-8'}, ];