diff --git a/README.md b/README.md index 7ed7571..d980cba 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Java to JavaScript (java2js) -java2js can translate simple Java programs to JavaScript and runs them using a JavaScript based JDK. +java2js can translate simple Java programs to JavaScript and runs them using a JavaScript based JDK in the browser without the use of a VM on a server. [Try it out!](https://quinton-ashley.github.io/java2js/) The demo files are located in the docs folder of this repository, its a barebones implementation that shows what is possible with java2js. diff --git a/ide.js b/ide.js index d30777a..6345d24 100644 --- a/ide.js +++ b/ide.js @@ -15,3 +15,82 @@ run(); })(); + +// Adds support for tabs in the textarea. +// https://css-tricks.com/snippets/javascript/support-tabs-in-textareas/ + +HTMLTextAreaElement.prototype.getCaretPosition = function () { + //return the caret position of the textarea + return this.selectionStart; +}; +HTMLTextAreaElement.prototype.setCaretPosition = function (position) { + //change the caret position of the textarea + this.selectionStart = position; + this.selectionEnd = position; + this.focus(); +}; +HTMLTextAreaElement.prototype.hasSelection = function () { + //if the textarea has selection then return true + if (this.selectionStart == this.selectionEnd) { + return false; + } else { + return true; + } +}; +HTMLTextAreaElement.prototype.getSelectedText = function () { + //return the selection text + return this.value.substring(this.selectionStart, this.selectionEnd); +}; +HTMLTextAreaElement.prototype.setSelection = function (start, end) { + //change the selection area of the textarea + this.selectionStart = start; + this.selectionEnd = end; + this.focus(); +}; + +var textarea = document.getElementsByTagName('textarea')[0]; + +textarea.onkeydown = function (event) { + //support tab on textarea + if (event.keyCode == 9) { + //tab was pressed + var newCaretPosition; + newCaretPosition = textarea.getCaretPosition() + ' '.length; + textarea.value = + textarea.value.substring(0, textarea.getCaretPosition()) + + ' ' + + textarea.value.substring(textarea.getCaretPosition(), textarea.value.length); + textarea.setCaretPosition(newCaretPosition); + return false; + } + if (event.keyCode == 8) { + //backspace + if (textarea.value.substring(textarea.getCaretPosition() - 4, textarea.getCaretPosition()) == ' ') { + //it's a tab space + var newCaretPosition; + newCaretPosition = textarea.getCaretPosition() - 3; + textarea.value = + textarea.value.substring(0, textarea.getCaretPosition() - 3) + + textarea.value.substring(textarea.getCaretPosition(), textarea.value.length); + textarea.setCaretPosition(newCaretPosition); + } + } + if (event.keyCode == 37) { + //left arrow + var newCaretPosition; + if (textarea.value.substring(textarea.getCaretPosition() - 4, textarea.getCaretPosition()) == ' ') { + //it's a tab space + newCaretPosition = textarea.getCaretPosition() - 3; + textarea.setCaretPosition(newCaretPosition); + } + } + if (event.keyCode == 39) { + //right arrow + var newCaretPosition; + if (textarea.value.substring(textarea.getCaretPosition() + 4, textarea.getCaretPosition()) == ' ') { + //it's a tab space + newCaretPosition = textarea.getCaretPosition() + 3; + textarea.setCaretPosition(newCaretPosition); + } + } +}; diff --git a/index.html b/index.html index 5ab2b21..cf6cb2f 100755 --- a/index.html +++ b/index.html @@ -56,10 +56,25 @@ autocapitalize="off" placeholder="Create a Java class with a main method here..." > -public class HelloWorld { - public static void main(String[] args){ - System.out.println("hello world!"); - } +package tests; + +import java.util.Scanner; + +public class ScannerTest { + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + System.out.println("Hello world!"); + + System.out.print("What's your name: "); + String name = sc.nextLine(); + System.out.println("Hello " + name); + + System.out.print("What's your favorite number: "); + int age = sc.nextInt(); + System.out.println(age + "? That's my favorite too!"); + + sc.close(); + } } diff --git a/jdk.js b/jdk.js index be85ca7..c5580c4 100755 --- a/jdk.js +++ b/jdk.js @@ -95,9 +95,6 @@ window[name] = this.java.lang[name]; } - System.in.reset(); - System.out.reset(); - // stub main this.main = () => { console.error('No main method found in loaded classes!'); @@ -105,6 +102,10 @@ } run(jvmArgs) { + // reset + System.in.reset(); + System.out.reset(); + this.main(jvmArgs); } diff --git a/jdk/java/util/Scanner.js b/jdk/java/util/Scanner.js index 46d1778..918741d 100755 --- a/jdk/java/util/Scanner.js +++ b/jdk/java/util/Scanner.js @@ -24,29 +24,31 @@ jdk.imports['java.util.Scanner'].load = async () => { if (this._loading) { await this._loadFile(this._filePath); } + let s = this.in.stream.slice(this.in.mark); + if (!s) return; if (pattern instanceof RegExp) { - return pattern.test(this.in.stream.slice(this.in.mark)); + return pattern.test(s); } // if pattern is string - return this.in.stream.slice(this.in.mark).includes(pattern); + return s.includes(pattern); } hasNextLine() { return this.hasNext('\n'); } nextLine() { - return this.next(/.*/); + return this.next(/(.*)\r*\n/); } async next(pattern) { while (this._loading || !(await this.hasNext(pattern))) { await new Promise((resolve) => setTimeout(resolve, 100)); } let buf = this.in.stream.slice(this.in.mark); - let substr = buf.match(pattern)[0]; - let start = buf.indexOf(substr); let end = buf.indexOf('\n'); - if (end == -1) { + let substr = buf.match(pattern)[1]; + if (!substr || end == -1) { throw 'NoSuchElementException: No ' + pattern.toString() + ' found in buffer ' + buf; } + let start = buf.indexOf(substr); this.in.read(end - start + 1); return buf.slice(start, substr.length); } @@ -54,13 +56,13 @@ jdk.imports['java.util.Scanner'].load = async () => { return this.nextInt(); } async nextInt() { - return Number(await this.next(/\d+/)); + return Number(await this.next(/(\d+)\r*\n/)); } nextLong() { return this.nextInt(); } async nextFloat() { - return Number(await this.next(/[0-9\.]+/)); + return Number(await this.next(/([0-9\.]+)\r*\n/)); } nextDouble() { return this.nextFloat(); diff --git a/package.json b/package.json index 441b291..5174e19 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "java2js", - "version": "1.2.16", + "version": "1.2.17", "description": "Converts Java to JavaScript and runs it with a JS JDK", "main": "jdk.js", "scripts": { diff --git a/tests/ScannerTest.java b/tests/ScannerTest.java new file mode 100644 index 0000000..4c41274 --- /dev/null +++ b/tests/ScannerTest.java @@ -0,0 +1,20 @@ +package tests; + +import java.util.Scanner; + +public class ScannerTest { + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + System.out.println("Hello world!"); + + System.out.print("What's your name: "); + String name = sc.nextLine(); + System.out.println("Hello " + name); + + System.out.print("What's your favorite number: "); + int age = sc.nextInt(); + System.out.println(age + "? That's my favorite too!"); + + sc.close(); + } +}