summaryrefslogtreecommitdiffstats
path: root/src/com
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2012-06-11 21:52:26 +0300
committerLeif Åstrand <leif@vaadin.com>2012-06-11 21:52:26 +0300
commit9b757f047fc8450d8a7d3d7aa5a7b7e43bfa1312 (patch)
treee3814cb6b78cb90570f2b9c31978728e44c7ec33 /src/com
parent24e3409e6ff117ff954f36a9c9378690c76634f8 (diff)
downloadvaadin-framework-9b757f047fc8450d8a7d3d7aa5a7b7e43bfa1312.tar.gz
vaadin-framework-9b757f047fc8450d8a7d3d7aa5a7b7e43bfa1312.zip
Initial javascript callback support (#6730)
Diffstat (limited to 'src/com')
-rw-r--r--src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerConnector.java78
-rw-r--r--src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerState.java22
-rw-r--r--src/com/vaadin/terminal/gwt/server/JsonCodec.java3
-rw-r--r--src/com/vaadin/ui/JavascriptCallback.java13
-rw-r--r--src/com/vaadin/ui/JavascriptManager.java53
-rw-r--r--src/com/vaadin/ui/Root.java12
6 files changed, 181 insertions, 0 deletions
diff --git a/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerConnector.java b/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerConnector.java
new file mode 100644
index 0000000000..979a6d22c4
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerConnector.java
@@ -0,0 +1,78 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.extensions.javascriptmanager;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.core.client.JsArray;
+import com.google.gwt.json.client.JSONArray;
+import com.vaadin.terminal.gwt.client.communication.MethodInvocation;
+import com.vaadin.terminal.gwt.client.communication.StateChangeEvent;
+import com.vaadin.terminal.gwt.client.ui.AbstractConnector;
+import com.vaadin.terminal.gwt.client.ui.Connect;
+import com.vaadin.ui.JavascriptManager;
+
+@Connect(JavascriptManager.class)
+public class JavascriptManagerConnector extends AbstractConnector {
+ private Set<String> currentNames = new HashSet<String>();
+
+ @Override
+ public void onStateChanged(StateChangeEvent stateChangeEvent) {
+ super.onStateChanged(stateChangeEvent);
+
+ Set<String> newNames = getState().getNames();
+
+ // Current names now only contains orphan callbacks
+ currentNames.removeAll(newNames);
+
+ for (String name : currentNames) {
+ removeCallback(name);
+ }
+
+ currentNames = new HashSet<String>(newNames);
+ for (String name : newNames) {
+ addCallback(name);
+ }
+ }
+
+ // TODO Ensure we don't overwrite anything (important) in $wnd
+ private native void addCallback(String name)
+ /*-{
+ var m = this;
+ $wnd[name] = $entry(function() {
+ //Must make a copy because arguments is an array-like object (not instanceof Array), causing suboptimal JSON encoding
+ var args = Array.prototype.slice.call(arguments, 0);
+ m.@com.vaadin.terminal.gwt.client.extensions.javascriptmanager.JavascriptManagerConnector::sendRpc(Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(name, args);
+ });
+ }-*/;
+
+ // TODO only remove what we actually added
+ private native void removeCallback(String name)
+ /*-{
+ delete $wnd[name];
+ }-*/;
+
+ public void sendRpc(String name, JsArray<JavaScriptObject> arguments) {
+ Object[] parameters = new Object[] { name, new JSONArray(arguments) };
+
+ /*
+ * Must invoke manually as the RPC interface can't be used in GWT
+ * because of the JSONArray parameter
+ */
+ getConnection()
+ .addMethodInvocationToQueue(
+ new MethodInvocation(
+ getConnectorId(),
+ "com.vaadin.ui.JavascriptManager$JavascriptCallbackRpc",
+ "call", parameters), true);
+ }
+
+ @Override
+ public JavascriptManagerState getState() {
+ return (JavascriptManagerState) super.getState();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerState.java b/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerState.java
new file mode 100644
index 0000000000..77794ffdca
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerState.java
@@ -0,0 +1,22 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.extensions.javascriptmanager;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import com.vaadin.terminal.gwt.client.communication.SharedState;
+
+public class JavascriptManagerState extends SharedState {
+ private Set<String> names = new HashSet<String>();
+
+ public Set<String> getNames() {
+ return names;
+ }
+
+ public void setNames(Set<String> names) {
+ this.names = names;
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/server/JsonCodec.java b/src/com/vaadin/terminal/gwt/server/JsonCodec.java
index fb2d289484..b693514a66 100644
--- a/src/com/vaadin/terminal/gwt/server/JsonCodec.java
+++ b/src/com/vaadin/terminal/gwt/server/JsonCodec.java
@@ -123,6 +123,9 @@ public class JsonCodec implements Serializable {
// Try to decode object using fields
if (value == JSONObject.NULL) {
return null;
+ } else if (targetType == JSONObject.class
+ || targetType == JSONArray.class) {
+ return value;
} else {
return decodeObject(targetType, (JSONObject) value, application);
}
diff --git a/src/com/vaadin/ui/JavascriptCallback.java b/src/com/vaadin/ui/JavascriptCallback.java
new file mode 100644
index 0000000000..4a34167256
--- /dev/null
+++ b/src/com/vaadin/ui/JavascriptCallback.java
@@ -0,0 +1,13 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.ui;
+
+import java.io.Serializable;
+
+import com.vaadin.external.json.JSONArray;
+
+public interface JavascriptCallback extends Serializable {
+ public void call(JSONArray arguments);
+}
diff --git a/src/com/vaadin/ui/JavascriptManager.java b/src/com/vaadin/ui/JavascriptManager.java
new file mode 100644
index 0000000000..e52962f177
--- /dev/null
+++ b/src/com/vaadin/ui/JavascriptManager.java
@@ -0,0 +1,53 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.ui;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.vaadin.external.json.JSONArray;
+import com.vaadin.terminal.AbstractExtension;
+import com.vaadin.terminal.gwt.client.communication.ServerRpc;
+import com.vaadin.terminal.gwt.client.extensions.javascriptmanager.JavascriptManagerState;
+
+public class JavascriptManager extends AbstractExtension {
+ private Map<String, JavascriptCallback> callbacks = new HashMap<String, JavascriptCallback>();
+
+ // Can not be defined in client package as this JSONArray is not available
+ // in GWT
+ public interface JavascriptCallbackRpc extends ServerRpc {
+ public void call(String name, JSONArray arguments);
+ }
+
+ public JavascriptManager() {
+ registerRpc(new JavascriptCallbackRpc() {
+ public void call(String name, JSONArray arguments) {
+ JavascriptCallback callback = callbacks.get(name);
+ // TODO error handling
+ callback.call(arguments);
+ }
+ });
+ }
+
+ @Override
+ public JavascriptManagerState getState() {
+ return (JavascriptManagerState) super.getState();
+ }
+
+ public void addCallback(String name, JavascriptCallback javascriptCallback) {
+ callbacks.put(name, javascriptCallback);
+ if (getState().getNames().add(name)) {
+ requestRepaint();
+ }
+ }
+
+ public void removeCallback(String name) {
+ callbacks.remove(name);
+ if (getState().getNames().remove(name)) {
+ requestRepaint();
+ }
+ }
+
+}
diff --git a/src/com/vaadin/ui/Root.java b/src/com/vaadin/ui/Root.java
index 8792bf1912..9814084cbc 100644
--- a/src/com/vaadin/ui/Root.java
+++ b/src/com/vaadin/ui/Root.java
@@ -408,6 +408,8 @@ public abstract class Root extends AbstractComponentContainer implements
private DirtyConnectorTracker dirtyConnectorTracker = new DirtyConnectorTracker(
this);
+ private JavascriptManager javascriptManager;
+
private RootServerRpc rpc = new RootServerRpc() {
public void click(MouseEventDetails mouseDetails) {
fireEvent(new ClickEvent(Root.this, mouseDetails));
@@ -1590,4 +1592,14 @@ public abstract class Root extends AbstractComponentContainer implements
return dirtyConnectorTracker;
}
+ public JavascriptManager getJavascriptManager() {
+ if (javascriptManager == null) {
+ // Create and attach on first use
+ javascriptManager = new JavascriptManager();
+ addExtension(javascriptManager);
+ }
+
+ return javascriptManager;
+ }
+
}