Browse Source

Initial commit

Aleksi Talarmo 4 years ago
commit
2823b4f33b
15 changed files with 4023 additions and 0 deletions
  1. 3
    0
      .gitignore
  2. 41
    0
      README.md
  3. 24
    0
      index.html
  4. 4
    0
      lib/jquery-3.1.0.min.js
  5. 43
    0
      scss/custom.scss
  6. 22
    0
      scss/jsterminal.scss
  7. 237
    0
      ts/jash.ts
  8. 168
    0
      ts/jsterminal.ts
  9. 47
    0
      ts/jsx.ts
  10. 13
    0
      ts/main.ts
  11. 7
    0
      ts/program.ts
  12. 127
    0
      ts/std.ts
  13. 34
    0
      ts/testprogram.ts
  14. 3240
    0
      ts/typedefs/jquery.d.ts
  15. 13
    0
      tsconfig.json

+ 3
- 0
.gitignore View File

@@ -0,0 +1,3 @@
1
+.sass-cache/
2
+css/
3
+js/

+ 41
- 0
README.md View File

@@ -0,0 +1,41 @@
1
+
2
+JavaScript Terminal
3
+===================
4
+
5
+JavaScript Terminal is a fun-project which allows people to create command line apps
6
+(like they would regularly in Python on Java) but in JavaScript.
7
+
8
+To get quickly started:
9
+- [Okay, so _what_ is it?](#okay-so-what-is-it)
10
+- [So how do I build it?](#so-how-do-i-build-it)
11
+- [How do I use it?](#how-i-use-it)
12
+
13
+Okay, so _what_ is it?
14
+----------------------
15
+
16
+The JavaScript Terminal is split into three major components
17
+- `jsterminal.ts`
18
+   is the actual engine which displays the terminal and is able to draw text at certain style to a  point on the terminal. It doesn't know any of the regular text-wrapping logic etc.
19
+- `jash.ts`
20
+   is the bash of jsterminal.ts. Jash knows all of the text-wrapping logics, how 'history' should work and knows how to give print/println/readline to `Std.IO`
21
+- `jsx.ts` is the final abstraction layer on top of all. This is probably neglected by many, but it's an "emulation" of the UNIX bash. It knows how to take commands and can traverse through directories even run commands and launch files. (Though all of this is happening in a virtualized file-system contained in RAM and possibly in cookies)
22
+
23
+If you start working with this engine you should probably use TypeScript. It's a superset of JavaScript, but if you insist on working with JavaScript, that works out too, because TypeScript compiles to JavaScript!
24
+
25
+So how do I build it?
26
+---------------------
27
+
28
+To run the engine you need [TypeScript][ts] to build the sources into browser-compatible JavaScript and [SASS][sass] to compile the sass into browser-compatible css. After that you're ready to go! I recommen building the JavaScript into ES6 because it's just superior to regular ES5 but _that's just my opinion_.
29
+
30
+You also need [jQuery][jquery] (Tested with version 3.1.0+)
31
+
32
+How do I use it?
33
+----------------
34
+
35
+I'm not sure :(
36
+
37
+A lot of the usage you can find from the TypeScript docs included in the sources and `main.ts` and `testprogram.ts`
38
+
39
+[sass]: http://sass-lang.com/
40
+[ts]: http://www.typescriptlang.org/
41
+[jquery]: https://jquery.com/

+ 24
- 0
index.html View File

@@ -0,0 +1,24 @@
1
+<html>
2
+   <head>
3
+      <title>JavaScript Terminal</title>
4
+      <link rel="stylesheet" href= "css/custom.css">
5
+      <link rel="stylesheet" href= "css/jsterminal.css">
6
+
7
+      <meta charset="utf-8">
8
+
9
+      <script src="lib/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script>
10
+      <script src="js/std.js"></script>
11
+      <script src="js/jsterminal.js"></script>
12
+      <script src="js/jash.js"></script>
13
+      <script src="js/jsx.js"></script>
14
+      <script src="js/main.js"></script>
15
+   </head>
16
+   <body onload="main()">
17
+      <div class="terminal-area">
18
+         <h1>JavaScript Terminal</h1>
19
+         <p>A completely useless project!</p>
20
+         <div class="js-terminal">
21
+         </div>
22
+      </div>
23
+   </body>
24
+</html>

+ 4
- 0
lib/jquery-3.1.0.min.js
File diff suppressed because it is too large
View File


+ 43
- 0
scss/custom.scss View File

@@ -0,0 +1,43 @@
1
+
2
+html, body {
3
+   width: 100%;
4
+   height: 100%;
5
+   margin: 0;
6
+   padding: 0;
7
+   background-color: #333;
8
+   color: #eaeaea;
9
+}
10
+
11
+h1, p {
12
+
13
+   font-family: helvetica;
14
+}
15
+
16
+.terminal-area {
17
+   text-align: center;
18
+
19
+   position: fixed;
20
+   top: 40%;
21
+   left: 50%;
22
+   /* bring your own prefixes */
23
+   transform: translate(-50%, -50%);
24
+}
25
+
26
+.test {
27
+
28
+}
29
+
30
+.red {
31
+   @extend .test !optional;
32
+   color: #f88;
33
+}
34
+
35
+.green {
36
+   @extend .text !optional;
37
+   color: #8f8;
38
+}
39
+
40
+.yellow {
41
+   @extend .text !optional;
42
+   color: #ff8;
43
+}

+ 22
- 0
scss/jsterminal.scss View File

@@ -0,0 +1,22 @@
1
+.js-terminal-style {
2
+   background-color: #202020;
3
+   color: #cecece;
4
+
5
+   font-family: monospace;
6
+   font-size: 15px;
7
+
8
+   overflow: hidden;
9
+
10
+   p {
11
+      text-align: left;
12
+
13
+      font-family: inherit;
14
+      white-space: pre-wrap;
15
+      word-wrap: break-word;
16
+
17
+      margin: 0;
18
+
19
+      line-height: 1em;
20
+   }
21
+
22
+}

+ 237
- 0
ts/jash.ts View File

@@ -0,0 +1,237 @@
1
+
2
+namespace Jash {
3
+
4
+   export class SH implements Program, TerminalInput.KeyListener, Std.Input, Std.Output {
5
+
6
+      terminal: JSTerminal.Terminal;
7
+      stdio: Std.IO;
8
+
9
+      cursor: {x: number, y: number} = {x: 0, y: 0};
10
+      scroll: number = 0;
11
+      messages: JSTerminal.Character[][] = [];
12
+
13
+      defaultStyle = "";
14
+      currentPrintStyle = "";
15
+
16
+      listenerId = 0;
17
+
18
+      currentReadlines: Std.Readline[] = [];
19
+      currentReadline = "";
20
+
21
+      create(terminal: JSTerminal.Terminal, stdio: Std.IO) {
22
+         this.terminal = terminal;
23
+         this.stdio = stdio;
24
+         this.stdio.setOutput(this);
25
+         this.stdio.setInput(this);
26
+         this.stdio.addListener(this);
27
+      }
28
+
29
+      enable() {
30
+         this.refresh();
31
+         if (this.listenerId < 0) {
32
+            this.stdio.addListener(this);
33
+         }
34
+      }
35
+
36
+      disable() {
37
+         if (this.listenerId >= 0) {
38
+            this.stdio.removeListener(this.listenerId);
39
+            this.listenerId = -1;
40
+         }
41
+      }
42
+
43
+      onClose() {
44
+         if (this.listenerId >= 0) {
45
+            this.stdio.removeListener(this.listenerId);
46
+            this.listenerId = -1;
47
+         }
48
+      }
49
+
50
+      onListen(listenerId: number) {
51
+         this.listenerId = listenerId;
52
+      }
53
+
54
+      handleKeypress(keypress: JQueryKeyEventObject) {
55
+
56
+      }
57
+
58
+      handleKeydown(keydown: JQueryKeyEventObject) {
59
+         if (this.currentReadlines.length == 0) { return; }
60
+
61
+         let key = keydown.key
62
+         if (key.length == 1) {
63
+            this.currentReadline += key;
64
+         }
65
+         else {
66
+            switch (keydown.keyCode) {
67
+               case (32): {
68
+                  this.currentReadline += " ";
69
+                  break;
70
+               }
71
+               case (8): {
72
+                  this.currentReadline = this.currentReadline.substr(0, this.currentReadline.length - 1);
73
+                  break;
74
+               }
75
+               case (13): {
76
+                  let currReadline = this.currentReadlines[0];
77
+                  if (currReadline.printAfterDone) {
78
+                     let text = currReadline.prefix + this.currentReadline;
79
+                     this.print(text, currReadline.style);
80
+                  }
81
+                  this.currentReadlines.shift().callback(this.currentReadline);
82
+                  this.currentReadline = "";
83
+               }
84
+            }
85
+         }
86
+         this.refresh();
87
+      }
88
+
89
+      handleKeyup(keyup: JQueryKeyEventObject) {
90
+
91
+      }
92
+
93
+      readline(readline: Std.Readline) {
94
+         this.currentReadlines.push(readline);
95
+         this.refresh();
96
+      }
97
+
98
+      print(text: string, style?: string) {
99
+         style = style || this.currentPrintStyle || this.defaultStyle;
100
+
101
+         for (let i = 0; i < text.length; i++) {
102
+            let char = text[i];
103
+            if (char == "\n") {
104
+               if (this.cursor.y != 0 || this.cursor.x != 0) {
105
+                  this.moveCursorNewline();
106
+               }
107
+               continue;
108
+            }
109
+            this.putCharacter(new JSTerminal.Character(char, style));
110
+         }
111
+      }
112
+
113
+      println(text: string, style?: string) {
114
+         this.print("\n" + text, style || this.currentPrintStyle || this.defaultStyle);
115
+      }
116
+
117
+      clear(style?: string) {
118
+         this.messages = [];
119
+         this.scroll = 0;
120
+      }
121
+
122
+      refresh(alsoRenderTerminal: boolean = true) {
123
+         this.terminal.clearScreen(this.defaultStyle);
124
+
125
+         let toDraw: JSTerminal.Character[][] = [];
126
+
127
+         let messages: JSTerminal.Character[][] = [];
128
+         for (let i in this.messages) {
129
+            messages.push(this.messages[i].slice());
130
+         }
131
+         if (this.currentReadlines.length > 0) {
132
+            let readline = this.currentReadlines[0];
133
+            let readlinePart = (readline.prefix || "") + this.currentReadline;
134
+            let tempCursorPos = {x: this.cursor.x, y: this.cursor.y};
135
+            for (let i = 0; i < readlinePart.length; i++) {
136
+               let char = readlinePart[i];
137
+               if (char == "\n") {
138
+                  this.moveCursorNewline();
139
+                  continue;
140
+               }
141
+               this.putCharacterTo(
142
+                  new JSTerminal.Character(char, (readline.style || this.defaultStyle)),
143
+                  messages);
144
+
145
+            }
146
+            this.cursor = tempCursorPos;
147
+         }
148
+
149
+
150
+         let start = messages.length - 1;
151
+
152
+         for (let i = this.scroll;
153
+               i < messages.length && toDraw.length < this.terminal.height;
154
+               i++) {
155
+            if (i < 0 || messages[i].length == 0) { toDraw.push([]); continue; }
156
+            let rows = Math.ceil(messages[i].length/this.terminal.width);
157
+            for (let r = 0; r < rows; r++) {
158
+               toDraw.push(
159
+                  messages[i].slice(
160
+                     r * this.terminal.width,
161
+                     (r + 1) * this.terminal.width));
162
+            }
163
+         }
164
+         toDraw = toDraw.slice(-this.terminal.height);
165
+
166
+         toDraw.forEach((row, y) => {
167
+            row.forEach((c, x) => {
168
+               this.terminal.putTrueChar(c, x, y);
169
+            });
170
+         });
171
+
172
+         if (!alsoRenderTerminal) { return; }
173
+         terminal.render();
174
+      }
175
+
176
+      putCharacter(character: JSTerminal.Character) {
177
+         this.putCharacterTo(character, this.messages);
178
+      }
179
+
180
+      private putCharacterTo(character: JSTerminal.Character, charArray: JSTerminal.Character[][]) {
181
+         while (this.cursor.y >= charArray.length) {
182
+            charArray.push([]);
183
+         }
184
+         if (this.cursor.x >= charArray[this.cursor.y].length) {
185
+            charArray[this.cursor.y].push(character);
186
+            this.moveCursor(1);
187
+            return;
188
+         }
189
+         charArray[this.cursor.y][this.cursor.x] = character;
190
+         this.moveCursor(1);
191
+      }
192
+
193
+      removeCharacter() {
194
+         if (this.messages[this.cursor.y] == []) {
195
+            let rowToRemove = this.cursor.y;
196
+            this.moveCursor(-1);
197
+            this.messages.splice(this.cursor.y, 1);
198
+            return;
199
+         }
200
+         let toRemove = {x: this.cursor.x, y: this.cursor.y};
201
+         this.moveCursor(-1);
202
+         this.messages[toRemove.y].splice(toRemove.x - 1, 1);
203
+      }
204
+
205
+      setDefaultStyle(style: string) {
206
+         this.defaultStyle = style;
207
+      }
208
+
209
+      setStyle(style: string) {
210
+         this.currentPrintStyle = style;
211
+      }
212
+
213
+      moveCursor(amount: number) {
214
+         this.cursor.x += amount;
215
+         this.cursor.y += Math.floor((this.cursor.x)/(this.terminal.width));
216
+         this.cursor.x = this.cursor.x % (this.terminal.width);
217
+         if (this.cursor.x < 0) {
218
+            this.cursor.x = this.messages[this.cursor.y].length - 1 - this.cursor.x;
219
+         }
220
+      }
221
+
222
+      moveCursorVertically(amount: number) {
223
+         this.cursor.y += amount;
224
+      }
225
+
226
+      moveCursorNewline() {
227
+         this.moveCursorVertically(1);
228
+         this.cursor.x = 0;
229
+      }
230
+
231
+      moveCursorPreviousLine() {
232
+         this.moveCursorVertically(-1);
233
+         this.cursor.x = this.terminal.width - 1;
234
+      }
235
+   }
236
+
237
+}

+ 168
- 0
ts/jsterminal.ts View File

@@ -0,0 +1,168 @@
1
+namespace JSTerminal {
2
+
3
+   class TerminalProgram implements Program {
4
+      create(terminal: Terminal, stdio: Std.IO) {}
5
+      enable() {}
6
+      disable() {}
7
+      onClose() {}
8
+   }
9
+
10
+   export class Terminal {
11
+      selector: string;
12
+      width: number;
13
+      height: number;
14
+      lineElems: JQuery[];
15
+      characters: Character[][];
16
+
17
+      programStack: Program[];
18
+
19
+      stdio: Std.IO;
20
+
21
+      constructor(selector: string, width: number, height: number) {
22
+         this.selector = selector;
23
+         this.width = width;
24
+         this.height = height;
25
+
26
+         this.lineElems = [];
27
+         this.characters = [];
28
+         for (let i = 0; i < this.height; i++) {
29
+            let characterLine: Character[] = [];
30
+            for (let i2 = 0; i2 < this.width; i2 ++) {
31
+               characterLine.push(new Character(" ", ""));
32
+            }
33
+            this.characters.push(characterLine);
34
+
35
+            let line = " ".repeat(this.width);
36
+            let element = $(document.createElement("p"));
37
+            element.text(line);
38
+            this.lineElems.push(element);
39
+            $(selector).append(element);
40
+         }
41
+
42
+         this.stdio = new Std.IO();
43
+
44
+         this.programStack = [];
45
+         this.programStack.push(new TerminalProgram());
46
+      }
47
+
48
+      /**
49
+      * Used to simply clear the terminal screen.
50
+      * Useful for when you don't use bash/JSX.
51
+      */
52
+      clearScreen(styles: string = "") {
53
+         for (let y = 0; y < this.height; y++) {
54
+            for (let x = 0; x < this.width; x ++) {
55
+               this.characters[y][x] = new Character(" ", styles);
56
+            }
57
+         }
58
+      }
59
+
60
+      /**
61
+      * Used to write text at a certain coordinate on screen.
62
+      * Useful for when you want to make your own rendering systems
63
+      * and don't want to use regular text-based systems.
64
+      */
65
+      writeText(text: string, x: number, y: number, styles: string = "") {
66
+         for (let i = 0; i < text.length; i++) {
67
+            this.putChar(text[i], x + i, y, styles);
68
+         }
69
+      }
70
+
71
+      /**
72
+      * Utility function for writeText. Can also be used but probably not as useful.
73
+      * Prints only one char (first from given string).
74
+      */
75
+      putChar(char: string, x: number, y: number, styles: string = "") {
76
+         this.putTrueChar(new Character(char, styles), x, y);
77
+      }
78
+
79
+      /**
80
+      * Utility function when you might want to print out a true
81
+      * Character-class. (works similarily to putChar)
82
+      */
83
+      putTrueChar(char: Character, x: number, y: number) {
84
+         if (x >= this.width || y >= this.height) { return; }
85
+         this.characters[y][x] = char;
86
+      }
87
+
88
+      /**
89
+      * Empties the screen and re-draws it. Required to call every time
90
+      * you want to change the screen.
91
+      */
92
+      render() {
93
+         for (let y = 0; y < this.characters.length; y++) {
94
+            let line = this.characters[y];
95
+            let lineElem = this.lineElems[y];
96
+
97
+            lineElem.empty();
98
+            let currSpan = null;
99
+            let currStyle = null;
100
+            let currText = "";
101
+            for (let x = 0; x < line.length + 1; x++) {
102
+               let currChar = line[x];
103
+               if (x == line.length || currStyle != currChar.styles) {
104
+                  if (currSpan != null) {
105
+                     currSpan.text(currText);
106
+                     currSpan.addClass(currStyle);
107
+                     lineElem.append(currSpan);
108
+                  }
109
+                  if (x >= line.length) {
110
+                     break;
111
+                  }
112
+
113
+                  currText = "";
114
+                  currSpan = $(document.createElement("span"));
115
+                  currStyle = currChar.styles;
116
+               }
117
+               currText += currChar.char;
118
+            }
119
+         }
120
+      }
121
+
122
+      /**
123
+      * Used to launch programs like Jash.
124
+      */
125
+      launchProgram(program: Program) {
126
+         this.programStack.slice(-1).pop().disable();
127
+         program.create(this, this.stdio);
128
+         this.programStack.push(program);
129
+      }
130
+
131
+      /**
132
+      * Used to close programs like Jash.
133
+      */
134
+      closeProgram(program: Program) {
135
+         let idx = this.programStack.indexOf(program);
136
+         if (idx == -1) {
137
+            return;
138
+         }
139
+         this.programStack.pop().onClose();
140
+         this.programStack.slice(-1).pop().enable();
141
+      }
142
+   }
143
+
144
+   /**
145
+   * Utility function for creating the terminal.
146
+   * Initializes the class and sets up some classes you might want to use.
147
+   */
148
+   export function createTerminal(selector: string, width: number, height: number) {
149
+      console.info(`Creating a terminal with ${width}x${height}`);
150
+
151
+      $(selector).addClass("js-terminal-style");
152
+      $(selector).css('width', width + "ch");
153
+      $(selector).css('height', height + "em");
154
+      $(selector).empty();
155
+
156
+      return new Terminal(selector, width, height);
157
+   }
158
+
159
+   export class Character {
160
+      char: string;
161
+      styles: string;
162
+
163
+      constructor(char: string, styles: string) {
164
+         this.char = char[0];
165
+         this.styles = styles;
166
+      }
167
+   }
168
+}

+ 47
- 0
ts/jsx.ts View File

@@ -0,0 +1,47 @@
1
+
2
+namespace JavaScriptX {
3
+   export class JSX implements Program {
4
+
5
+      stdio: Std.IO;
6
+
7
+      create(terminal: JSTerminal.Terminal, stdio: Std.IO) {
8
+         this.stdio = stdio;
9
+
10
+         stdio.println("Welcome to ");
11
+         stdio.print("JSX", "red");
12
+         stdio.print(" version ");
13
+         stdio.print("0.0.1\n", "green");
14
+         stdio.refresh();
15
+
16
+         this.takeCommand();
17
+      }
18
+
19
+      enable() {
20
+
21
+      }
22
+
23
+      disable() {
24
+
25
+      }
26
+
27
+      onClose() {
28
+
29
+      }
30
+
31
+      takeCommand() {
32
+         let name = window.location.hostname || "localhost";
33
+         this.stdio.println(`Anonymous@${name}`, "yellow");
34
+         this.stdio.print(":");
35
+         this.stdio.print("~/", "green");
36
+         this.stdio.readline({
37
+            callback(result: string) {
38
+
39
+            },
40
+            prefix: " > ",
41
+            printAfterDone: true,
42
+            style: "red"
43
+         })
44
+         this.stdio.refresh();
45
+      }
46
+   }
47
+}

+ 13
- 0
ts/main.ts View File

@@ -0,0 +1,13 @@
1
+var terminal;
2
+var jsh;
3
+
4
+function main() {
5
+   terminal = JSTerminal.createTerminal(".js-terminal", 80, 20);
6
+
7
+   jsh = new Jash.SH();
8
+   terminal.launchProgram(jsh);
9
+
10
+   jsh.setDefaultStyle("test");
11
+
12
+   terminal.launchProgram(new JavaScriptX.JSX());
13
+}

+ 7
- 0
ts/program.ts View File

@@ -0,0 +1,7 @@
1
+
2
+interface Program {
3
+   create(terminal: JSTerminal.Terminal, stdio: Std.IO);
4
+   enable();
5
+   disable();
6
+   onClose();
7
+}

+ 127
- 0
ts/std.ts View File

@@ -0,0 +1,127 @@
1
+
2
+namespace Std {
3
+
4
+   export class IO {
5
+
6
+      listenerCounter: number;
7
+      listeners: {[id: number]: TerminalInput.KeyListener};
8
+
9
+      output: Output;
10
+      input: Input;
11
+
12
+      constructor() {
13
+         this.listeners = {};
14
+         $(document).keypress((evt) => {
15
+            Object.getOwnPropertyNames(this.listeners).forEach(id => {
16
+               this.listeners[parseInt(id)].handleKeypress(evt);
17
+            });
18
+         });
19
+         $(document).keydown((evt) => {
20
+            Object.getOwnPropertyNames(this.listeners).forEach(id => {
21
+               this.listeners[parseInt(id)].handleKeydown(evt);
22
+            });
23
+         });
24
+         $(document).keyup((evt) => {
25
+            Object.getOwnPropertyNames(this.listeners).forEach(id => {
26
+               this.listeners[parseInt(id)].handleKeyup(evt);
27
+            });
28
+         });
29
+      }
30
+
31
+      addListener(listener: TerminalInput.KeyListener): number {
32
+         let id = this.listenerCounter++;
33
+         this.listeners[id] = listener;
34
+         listener.onListen(id);
35
+         return id;
36
+      }
37
+
38
+      removeListener(id: number) {
39
+         delete this.listeners[id];
40
+      }
41
+
42
+      setOutput(output: Output) {
43
+         this.output = output;
44
+      }
45
+
46
+      setInput(input: Input) {
47
+         this.input = input;
48
+      }
49
+
50
+      /**
51
+      * Calls print for the assigned IO interface.
52
+      * Standard IO prints out a line to the cursor's last location
53
+      */
54
+      print(text: string, style?: string) {
55
+         if (!this.output) { return; }
56
+         this.output.print(text, style);
57
+      }
58
+
59
+      /**
60
+      * Calls println for the assigned IO interface.
61
+      * Standard IO prints out a line to a new line relatively to the cursor's last location.
62
+      */
63
+      println(text: string, style?: string) {
64
+         if (!this.output) { return; }
65
+         this.output.println(text, style);
66
+      }
67
+
68
+      /**
69
+      * Calls refresh for the assigned IO interface.
70
+      * Standard IO refreshes the IO buffer so it can be drawn and then draws this.
71
+      * This last step can be avouded though with the boolean parameter.
72
+      */
73
+      refresh(alsoRefreshTerminal: boolean = true) {
74
+         if (!this.output) { return; }
75
+         this.output.refresh(alsoRefreshTerminal);
76
+      }
77
+
78
+      /**
79
+      * Calls clear for the assigned IO interface.
80
+      * Standard IO clears the (bash and terminal) screen.
81
+      */
82
+      clear(style?: string) {
83
+         if (!this.output) { return; }
84
+         this.output.clear(style);
85
+      }
86
+
87
+      /**
88
+      * Calls readline for the assigned IO inteface
89
+      * Sandard IO starts taking input and calls the callback with a string it readed while printing it out.
90
+      * Note: Some IO interfaces might not implement this method. Only use it
91
+      * When using stdio
92
+      */
93
+      readline(readline: Readline) {
94
+         if (!this.input) { return; }
95
+         this.input.readline(readline);
96
+      }
97
+   }
98
+
99
+   export interface Input {
100
+      readline(readline: Readline);
101
+   }
102
+
103
+   export interface Output {
104
+      print(text: string, style?: string);
105
+      println(text: string, style?: string);
106
+      refresh(alsoRefreshTerminal?: boolean);
107
+      clear(style?: string);
108
+   }
109
+
110
+   export interface Readline {
111
+      callback: (response: string) => void;
112
+      style?: string;
113
+      prefix?: string;
114
+      printAfterDone?: boolean;
115
+   }
116
+
117
+}
118
+
119
+namespace TerminalInput {
120
+
121
+   export interface KeyListener {
122
+      onListen(id: number);
123
+      handleKeypress(keypress: JQueryKeyEventObject);
124
+      handleKeydown(keydown: JQueryKeyEventObject);
125
+      handleKeyup(keyup: JQueryKeyEventObject);
126
+   }
127
+}

+ 34
- 0
ts/testprogram.ts View File

@@ -0,0 +1,34 @@
1
+
2
+class TestProgram implements Program {
3
+
4
+   create(terminal: JSTerminal.Terminal, stdio: Std.IO) {
5
+      stdio.println("Welcome to a tour! This is a tour for JSh, a platform for the upcoming JSX!");
6
+      stdio.println("\nFirst things first:\nWho are you?");
7
+      stdio.refresh();
8
+      stdio.readline({
9
+         prefix: "\n> ",
10
+         callback: (resp: string) => {
11
+            console.log("got: " + resp);
12
+            stdio.println("Hello, '");
13
+            stdio.print(resp, "red");
14
+            stdio.print("', I am JSh, the JavaScript Bash.");
15
+            stdio.println("I am but a mere tool that can print and read stuff from the terminal");
16
+         },
17
+         printAfterDone: true,
18
+         style: "red"
19
+      });
20
+   }
21
+
22
+   enable() {
23
+
24
+   }
25
+
26
+   disable() {
27
+
28
+   }
29
+
30
+   onClose() {
31
+
32
+   }
33
+
34
+}

+ 3240
- 0
ts/typedefs/jquery.d.ts
File diff suppressed because it is too large
View File


+ 13
- 0
tsconfig.json View File

@@ -0,0 +1,13 @@
1
+{
2
+    "compilerOptions": {
3
+        "rootDir": "ts/",
4
+        "outDir": "js/",
5
+        "module": "commonjs",
6
+        "target": "es6",
7
+        "noImplicitAny": false,
8
+        "sourceMap": false
9
+    },
10
+    "exclude": [
11
+        "node_modules"
12
+    ]
13
+}