diff --git a/teavm-samples/teavm-samples-benchmark/src/main/java/org/teavm/samples/benchmark/teavm/Performance.java b/teavm-jso/src/main/java/org/teavm/jso/browser/Performance.java similarity index 62% rename from teavm-samples/teavm-samples-benchmark/src/main/java/org/teavm/samples/benchmark/teavm/Performance.java rename to teavm-jso/src/main/java/org/teavm/jso/browser/Performance.java index a0fe3650c..3b6f14a1e 100644 --- a/teavm-samples/teavm-samples-benchmark/src/main/java/org/teavm/samples/benchmark/teavm/Performance.java +++ b/teavm-jso/src/main/java/org/teavm/jso/browser/Performance.java @@ -13,10 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.samples.benchmark.teavm; +package org.teavm.jso.browser; +import org.teavm.jso.JSBody; import org.teavm.jso.JSObject; -public interface Performance extends JSObject { - double now(); +public final class Performance implements JSObject { + private Performance() { + } + + @JSBody(params = {}, script = "return Performance.now();") + public static native double now(); + + @JSBody(params = {}, script = "return typeof(Performance) !== 'undefined';") + public static native boolean isSupported(); } diff --git a/teavm-platform/src/main/java/org/teavm/platform/Platform.java b/teavm-platform/src/main/java/org/teavm/platform/Platform.java index 02bd61ef8..9f68a024e 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/Platform.java +++ b/teavm-platform/src/main/java/org/teavm/platform/Platform.java @@ -19,7 +19,9 @@ import java.lang.annotation.Annotation; import org.teavm.dependency.PluggableDependency; import org.teavm.javascript.spi.GeneratedBy; import org.teavm.javascript.spi.InjectedBy; -import org.teavm.jso.plugin.JS; +import org.teavm.jso.JSBody; +import org.teavm.jso.JSObject; +import org.teavm.jso.browser.Window; import org.teavm.platform.metadata.ClassResource; import org.teavm.platform.metadata.StaticFieldResource; import org.teavm.platform.plugin.PlatformGenerator; @@ -32,19 +34,21 @@ public final class Platform { private Platform() { } - public static PlatformObject getPlatformObject(Object obj) { - return (PlatformObject) JS.marshall(obj); - } + @InjectedBy(PlatformGenerator.class) + public static native PlatformObject getPlatformObject(Object obj); @GeneratedBy(PlatformGenerator.class) @PluggableDependency(PlatformGenerator.class) public static native Object clone(Object obj); public static boolean isInstance(PlatformObject obj, PlatformClass cls) { - return obj != null && !JS.isUndefined(obj.getPlatformClass().getMetadata()) + return obj != null && !isUndefined(obj.getPlatformClass().getMetadata()) && isAssignable(obj.getPlatformClass(), cls); } + @JSBody(params = "object", script = "return typeof object === 'undefined';") + private static native boolean isUndefined(JSObject object); + public static boolean isAssignable(PlatformClass from, PlatformClass to) { if (from == to) { return true; @@ -63,15 +67,15 @@ public final class Platform { public static native Class asJavaClass(PlatformObject obj); public static PlatformPrimitives getPrimitives() { - return (PlatformPrimitives) JS.getGlobal(); + return (PlatformPrimitives) Window.current(); } public static PlatformConsole getConsole() { - return (PlatformConsole) JS.getGlobal(); + return (PlatformConsole) Window.current(); } public static int nextObjectId() { - return ((PlatformHelper) JS.getGlobal()).nextId(); + return ((PlatformHelper) Window.current()).nextId(); } public static T newInstance(PlatformClass cls) { @@ -127,14 +131,14 @@ public final class Platform { public static native int schedule(PlatformRunnable runnable, int timeout); public static void killSchedule(int id) { - ((PlatformHelper) JS.getGlobal()).killSchedule(id); + ((PlatformHelper) Window.current()).killSchedule(id); } public static PlatformQueue createQueue() { - return ((PlatformHelper) JS.getGlobal()).newQueue(); + return ((PlatformHelper) Window.current()).newQueue(); } public static PlatformString stringFromCharCode(int charCode) { - return ((PlatformHelper) JS.getGlobal()).getStringClass().fromCharCode(charCode); + return ((PlatformHelper) Window.current()).getStringClass().fromCharCode(charCode); } } diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java index f9f4b5d14..ecfea811f 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java @@ -69,6 +69,7 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin case "asJavaClass": case "classFromResource": case "objectFromResource": + case "marshall": context.writeExpr(context.getArgument(0)); break; } diff --git a/teavm-samples/teavm-samples-benchmark/src/main/java/org/teavm/samples/benchmark/teavm/BenchmarkStarter.java b/teavm-samples/teavm-samples-benchmark/src/main/java/org/teavm/samples/benchmark/teavm/BenchmarkStarter.java index 67d74a43f..10b87867c 100644 --- a/teavm-samples/teavm-samples-benchmark/src/main/java/org/teavm/samples/benchmark/teavm/BenchmarkStarter.java +++ b/teavm-samples/teavm-samples-benchmark/src/main/java/org/teavm/samples/benchmark/teavm/BenchmarkStarter.java @@ -22,13 +22,12 @@ import org.jbox2d.collision.shapes.ShapeType; import org.jbox2d.common.Vec2; import org.jbox2d.dynamics.Body; import org.jbox2d.dynamics.Fixture; -import org.teavm.jso.browser.TimerHandler; +import org.teavm.jso.browser.Performance; import org.teavm.jso.browser.Window; import org.teavm.jso.canvas.CanvasRenderingContext2D; import org.teavm.jso.dom.html.HTMLCanvasElement; import org.teavm.jso.dom.html.HTMLDocument; import org.teavm.jso.dom.html.HTMLElement; -import org.teavm.jso.plugin.JS; import org.teavm.samples.benchmark.Scene; /** @@ -36,11 +35,9 @@ import org.teavm.samples.benchmark.Scene; * @author Alexey Andreev */ public final class BenchmarkStarter { - private static Window window = (Window) JS.getGlobal(); - private static HTMLDocument document = window.getDocument(); + private static HTMLDocument document = Window.current().getDocument(); private static HTMLCanvasElement canvas = (HTMLCanvasElement) document.getElementById("benchmark-canvas"); private static HTMLElement resultTableBody = document.getElementById("result-table-body"); - private static Performance performance = (Performance) JS.get(window, JS.wrap("performance")); private static Scene scene = new Scene(); private static int currentSecond; private static long startMillisecond; @@ -55,9 +52,9 @@ public final class BenchmarkStarter { } private static void makeStep() { - double start = performance.now(); + double start = Performance.now(); scene.calculate(); - double end = performance.now(); + double end = Performance.now(); int second = (int) ((System.currentTimeMillis() - startMillisecond) / 1000); if (second > currentSecond) { HTMLElement row = document.createElement("tr"); @@ -74,11 +71,7 @@ public final class BenchmarkStarter { } timeSpentCalculating += end - start; render(); - window.setTimeout(new TimerHandler() { - @Override public void onTimer() { - makeStep(); - } - }, scene.timeUntilNextStep()); + Window.setTimeout(() -> makeStep(), scene.timeUntilNextStep()); } private static void render() { diff --git a/teavm-samples/teavm-samples-hello/src/main/java/org/teavm/samples/hello/Client.java b/teavm-samples/teavm-samples-hello/src/main/java/org/teavm/samples/hello/Client.java index 7d9695f33..ff4deb1f6 100644 --- a/teavm-samples/teavm-samples-hello/src/main/java/org/teavm/samples/hello/Client.java +++ b/teavm-samples/teavm-samples-hello/src/main/java/org/teavm/samples/hello/Client.java @@ -20,12 +20,10 @@ import org.teavm.jso.browser.Window; import org.teavm.jso.dom.html.HTMLButtonElement; import org.teavm.jso.dom.html.HTMLDocument; import org.teavm.jso.dom.html.HTMLElement; -import org.teavm.jso.plugin.JS; public final class Client { - private static Window window = (Window) JS.getGlobal(); - private static HTMLDocument document = window.getDocument(); - private static HTMLButtonElement helloButton = (HTMLButtonElement) document.getElementById("hello-button"); + private static HTMLDocument document = Window.current().getDocument(); + private static HTMLButtonElement helloButton = document.getElementById("hello-button").cast(); private static HTMLElement responsePanel = document.getElementById("response-panel"); private static HTMLElement thinkingPanel = document.getElementById("thinking-panel"); @@ -39,7 +37,7 @@ public final class Client { private static void sayHello() { helloButton.setDisabled(true); thinkingPanel.getStyle().setProperty("display", ""); - final XMLHttpRequest xhr = window.createXMLHttpRequest(); + XMLHttpRequest xhr = XMLHttpRequest.create(); xhr.setOnReadyStateChange(() -> { if (xhr.getReadyState() == XMLHttpRequest.DONE) { receiveResponse(xhr.getResponseText()); diff --git a/teavm-samples/teavm-samples-storage/src/main/java/org/teavm/samples/storage/Application.java b/teavm-samples/teavm-samples-storage/src/main/java/org/teavm/samples/storage/Application.java index 3bb8a8861..6acfae5c4 100644 --- a/teavm-samples/teavm-samples-storage/src/main/java/org/teavm/samples/storage/Application.java +++ b/teavm-samples/teavm-samples-storage/src/main/java/org/teavm/samples/storage/Application.java @@ -21,45 +21,42 @@ import org.teavm.jso.dom.html.HTMLButtonElement; import org.teavm.jso.dom.html.HTMLDocument; import org.teavm.jso.dom.html.HTMLElement; import org.teavm.jso.dom.html.HTMLInputElement; -import org.teavm.jso.plugin.JS; /** * * @author Junji Takakura */ public final class Application { - - private static Window window = (Window) JS.getGlobal(); - private static HTMLDocument document = window.getDocument(); - private static Storage storage = window.getSessionStorage(); + private static HTMLDocument document = Window.current().getDocument(); + private static Storage storage = Window.current().getSessionStorage(); private Application() { } public static void main(String[] args) { if (storage == null) { - window.alert("storage is not supported."); + Window.alert("storage is not supported."); } - HTMLButtonElement saveButton = (HTMLButtonElement) document.getElementById("save-button"); + HTMLButtonElement saveButton = document.getElementById("save-button").cast(); saveButton.addEventListener("click", e -> { - String key = ((HTMLInputElement) document.getElementById("key")).getValue(); - String value = ((HTMLInputElement) document.getElementById("value")).getValue(); + String key = document.getElementById("key").cast().getValue(); + String value = document.getElementById("value").cast().getValue(); if (key != null && key.length() > 0 && value != null && value.length() > 0) { storage.setItem(key, value); draw(); } }); - HTMLButtonElement deleteButton = (HTMLButtonElement) document.getElementById("delete-button"); + HTMLButtonElement deleteButton = document.getElementById("delete-button").cast(); deleteButton.addEventListener("click", e -> { - String key = ((HTMLInputElement) document.getElementById("key")).getValue(); + String key = document.getElementById("key").cast().getValue(); if (key != null && key.length() > 0) { storage.removeItem(key); draw(); } }); - HTMLButtonElement deleteAllButton = (HTMLButtonElement) document.getElementById("delete-all-button"); + HTMLButtonElement deleteAllButton = document.getElementById("delete-all-button").cast(); deleteAllButton.addEventListener("click", e -> { storage.clear(); draw(); diff --git a/teavm-samples/teavm-samples-video/src/main/java/org/teavm/samples/video/Player.java b/teavm-samples/teavm-samples-video/src/main/java/org/teavm/samples/video/Player.java index 6770d343d..983f66c9e 100644 --- a/teavm-samples/teavm-samples-video/src/main/java/org/teavm/samples/video/Player.java +++ b/teavm-samples/teavm-samples-video/src/main/java/org/teavm/samples/video/Player.java @@ -22,28 +22,25 @@ import org.teavm.jso.dom.html.HTMLDocument; import org.teavm.jso.dom.html.HTMLElement; import org.teavm.jso.dom.html.HTMLSourceElement; import org.teavm.jso.dom.html.HTMLVideoElement; -import org.teavm.jso.plugin.JS; public final class Player { - - private static Window window = (Window) JS.getGlobal(); - private static HTMLDocument document = window.getDocument(); + private static HTMLDocument document = Window.current().getDocument(); private Player() { } public static void main(String[] args) { - HTMLSourceElement sourceMp4 = (HTMLSourceElement) document.createElement("source"); + HTMLSourceElement sourceMp4 = document.createElement("source").cast(); sourceMp4.setAttribute("id", "mp4"); sourceMp4.setSrc("http://media.w3.org/2010/05/sintel/trailer.mp4"); sourceMp4.setAttribute("type", "video/mp4"); - HTMLSourceElement sourceWebm = (HTMLSourceElement) document.createElement("source"); + HTMLSourceElement sourceWebm = document.createElement("source").cast(); sourceWebm.setAttribute("id", "webm"); sourceWebm.setSrc("http://media.w3.org/2010/05/sintel/trailer.webm"); sourceWebm.setAttribute("type", "video/webm"); - HTMLSourceElement sourceOgv = (HTMLSourceElement) document.createElement("source"); + HTMLSourceElement sourceOgv = document.createElement("source").cast(); sourceOgv.setAttribute("id", "ogv"); sourceOgv.setSrc("http://media.w3.org/2010/05/sintel/trailer.ogv"); sourceOgv.setAttribute("type", "video/ogg"); @@ -51,7 +48,7 @@ public final class Player { HTMLElement p = document.createElement("p"); p.appendChild(document.createTextNode("Your user agent does not support the HTML5 Video element.")); - HTMLVideoElement video = (HTMLVideoElement) document.createElement("video"); + HTMLVideoElement video = document.createElement("video").cast(); video.setAttribute("id", "video"); video.setControls(true); video.setPreload("none"); @@ -65,61 +62,61 @@ public final class Player { HTMLElement divVideo = document.createElement("div"); divVideo.appendChild(video); - HTMLButtonElement loadButton = (HTMLButtonElement) document.createElement("button"); + HTMLButtonElement loadButton = document.createElement("button").cast(); loadButton.appendChild(document.createTextNode("load()")); loadButton.addEventListener("click", evt -> video.load()); - HTMLButtonElement playButton = (HTMLButtonElement) document.createElement("button"); + HTMLButtonElement playButton = document.createElement("button").cast(); playButton.appendChild(document.createTextNode("play()")); playButton.addEventListener("click", evt -> video.play()); - HTMLButtonElement pauseButton = (HTMLButtonElement) document.createElement("button"); + HTMLButtonElement pauseButton = document.createElement("button").cast(); pauseButton.appendChild(document.createTextNode("pause()")); pauseButton.addEventListener("click", evt -> video.pause()); - HTMLButtonElement currentTimePlusButton = (HTMLButtonElement) document.createElement("button"); + HTMLButtonElement currentTimePlusButton = document.createElement("button").cast(); currentTimePlusButton.appendChild(document.createTextNode("currentTime+=10")); currentTimePlusButton.addEventListener("click", evt -> video.setCurrentTime(video.getCurrentTime() + 10)); - HTMLButtonElement currentTimeMinusButton = (HTMLButtonElement) document.createElement("button"); + HTMLButtonElement currentTimeMinusButton = document.createElement("button").cast(); currentTimeMinusButton.appendChild(document.createTextNode("currentTime-=10")); currentTimeMinusButton.addEventListener("click", evt -> video.setCurrentTime(video.getCurrentTime() - 10)); - HTMLButtonElement currentTime50Button = (HTMLButtonElement) document.createElement("button"); + HTMLButtonElement currentTime50Button = document.createElement("button").cast(); currentTime50Button.appendChild(document.createTextNode("currentTime=50")); currentTime50Button.addEventListener("click", evt -> video.setCurrentTime(50)); - HTMLButtonElement playbackRateIncrementButton = (HTMLButtonElement) document.createElement("button"); + HTMLButtonElement playbackRateIncrementButton = document.createElement("button").cast(); playbackRateIncrementButton.appendChild(document.createTextNode("playbackRate++")); playbackRateIncrementButton.addEventListener("click", evt -> video.setPlaybackRate( video.getPlaybackRate() + 1)); - HTMLButtonElement playbackRateDecrementButton = (HTMLButtonElement) document.createElement("button"); + HTMLButtonElement playbackRateDecrementButton = document.createElement("button").cast(); playbackRateDecrementButton.appendChild(document.createTextNode("playbackRate--")); playbackRateDecrementButton.addEventListener("click", evt -> video.setPlaybackRate( video.getPlaybackRate() - 1)); - HTMLButtonElement playbackRatePlusButton = (HTMLButtonElement) document.createElement("button"); + HTMLButtonElement playbackRatePlusButton = document.createElement("button").cast(); playbackRatePlusButton.appendChild(document.createTextNode("playbackRate+=0.1")); playbackRatePlusButton.addEventListener("click", evt -> video.setPlaybackRate(video.getPlaybackRate() + 0.1)); - HTMLButtonElement playbackRateMinusButton = (HTMLButtonElement) document.createElement("button"); + HTMLButtonElement playbackRateMinusButton = document.createElement("button").cast(); playbackRateMinusButton.appendChild(document.createTextNode("playbackRate-=0.1")); playbackRateMinusButton.addEventListener("click", evt -> video.setPlaybackRate(video.getPlaybackRate() - 0.1)); - HTMLButtonElement volumePlusButton = (HTMLButtonElement) document.createElement("button"); + HTMLButtonElement volumePlusButton = document.createElement("button").cast(); volumePlusButton.appendChild(document.createTextNode("volume+=0.1")); volumePlusButton.addEventListener("click", evt -> video.setVolume(video.getVolume() + 0.1f)); - HTMLButtonElement volumeMinusButton = (HTMLButtonElement) document.createElement("button"); + HTMLButtonElement volumeMinusButton = document.createElement("button").cast(); volumeMinusButton.appendChild(document.createTextNode("volume-=0.1")); volumeMinusButton.addEventListener("click", evt -> video.setVolume(video.getVolume() - 0.1f)); - HTMLButtonElement muteButton = (HTMLButtonElement) document.createElement("button"); + HTMLButtonElement muteButton = document.createElement("button").cast(); muteButton.appendChild(document.createTextNode("muted=true")); muteButton.addEventListener("click", evt -> video.setMuted(true)); - HTMLButtonElement unmuteButton = (HTMLButtonElement) document.createElement("button"); + HTMLButtonElement unmuteButton = document.createElement("button").cast(); unmuteButton.appendChild(document.createTextNode("muted=false")); unmuteButton.addEventListener("click", evt -> video.setMuted(false)); diff --git a/teavm-tests/src/test/java/org/teavm/jso/test/JSOTest.java b/teavm-tests/src/test/java/org/teavm/jso/test/JSOTest.java index 7d3a78ab8..73ba3ca18 100644 --- a/teavm-tests/src/test/java/org/teavm/jso/test/JSOTest.java +++ b/teavm-tests/src/test/java/org/teavm/jso/test/JSOTest.java @@ -19,7 +19,6 @@ import static org.junit.Assert.*; import org.junit.Test; import org.teavm.jso.JSBody; import org.teavm.jso.JSObject; -import org.teavm.jso.plugin.JS; /** * @@ -28,14 +27,10 @@ import org.teavm.jso.plugin.JS; public class JSOTest { @Test public void complexConstructorParenthesized() { - RegExp regexp = getWindow().createRegExp("."); + RegExp regexp = RegExp.create(); assertEquals(".", regexp.getSource()); } - private static Window getWindow() { - return (Window)JS.getGlobal(); - } - @Test public void externalMethodsResolved() { int r = jsMethod(new Callback() { diff --git a/teavm-tests/src/test/java/org/teavm/jso/test/RegExp.java b/teavm-tests/src/test/java/org/teavm/jso/test/RegExp.java index 56f0161ba..6747fcecc 100644 --- a/teavm-tests/src/test/java/org/teavm/jso/test/RegExp.java +++ b/teavm-tests/src/test/java/org/teavm/jso/test/RegExp.java @@ -15,6 +15,7 @@ */ package org.teavm.jso.test; +import org.teavm.jso.JSBody; import org.teavm.jso.JSObject; import org.teavm.jso.JSProperty; @@ -22,7 +23,10 @@ import org.teavm.jso.JSProperty; * * @author Alexey Andreev */ -public interface RegExp extends JSObject { +public abstract class RegExp implements JSObject { @JSProperty - String getSource(); + public abstract String getSource(); + + @JSBody(params = {}, script = "return new RegExp();") + public static native RegExp create(); } diff --git a/teavm-tests/src/test/java/org/teavm/jso/test/Window.java b/teavm-tests/src/test/java/org/teavm/jso/test/Window.java deleted file mode 100644 index 991e755db..000000000 --- a/teavm-tests/src/test/java/org/teavm/jso/test/Window.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2015 Alexey Andreev. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.teavm.jso.test; - -import org.teavm.jso.JSConstructor; -import org.teavm.jso.JSObject; - -/** - * - * @author Alexey Andreev - */ -public interface Window extends JSObject { - @JSConstructor("RegExp") - RegExp createRegExp(String regex); -}