From d44e06fc50415d3dcdc93ad8c711a2c4f2664e6e Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Thu, 14 Jun 2012 17:29:49 +0300 Subject: JavascriptManager -> JavaScript and changes based on review (#6730) --- src/com/vaadin/ui/JavaScript.java | 84 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/com/vaadin/ui/JavaScript.java (limited to 'src/com/vaadin/ui/JavaScript.java') diff --git a/src/com/vaadin/ui/JavaScript.java b/src/com/vaadin/ui/JavaScript.java new file mode 100644 index 0000000000..dcd8540947 --- /dev/null +++ b/src/com/vaadin/ui/JavaScript.java @@ -0,0 +1,84 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.ui; + +import java.util.HashMap; +import java.util.Map; + +import com.vaadin.external.json.JSONArray; +import com.vaadin.external.json.JSONException; +import com.vaadin.terminal.AbstractExtension; +import com.vaadin.terminal.Extension; +import com.vaadin.terminal.gwt.client.communication.ServerRpc; +import com.vaadin.terminal.gwt.client.extensions.javascriptmanager.ExecuteJavaScriptRpc; +import com.vaadin.terminal.gwt.client.extensions.javascriptmanager.JavascriptManagerState; + +public class JavaScript extends AbstractExtension { + private Map callbacks = new HashMap(); + + // 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 JavaScript() { + registerRpc(new JavascriptCallbackRpc() { + public void call(String name, JSONArray arguments) { + JavascriptCallback callback = callbacks.get(name); + // TODO handle situation if name is not registered + try { + callback.call(arguments); + } catch (JSONException e) { + throw new IllegalArgumentException(e); + } + } + }); + } + + @Override + public JavascriptManagerState getState() { + return (JavascriptManagerState) super.getState(); + } + + public void addCallback(String name, JavascriptCallback callback) { + callbacks.put(name, callback); + if (getState().getNames().add(name)) { + requestRepaint(); + } + } + + public void removeCallback(String name) { + callbacks.remove(name); + if (getState().getNames().remove(name)) { + requestRepaint(); + } + } + + public void execute(String script) { + getRpcProxy(ExecuteJavaScriptRpc.class).executeJavaScript(script); + } + + public static JavaScript getCurrent() { + return Root.getCurrentRoot().getJavaScript(); + } + + private static JavaScript getJavascript(Root root) { + // TODO Add caching to avoid iterating collection every time + // Caching should use weak references to avoid memory leaks -> cache + // should be transient to avoid serialization problems + for (Extension extension : root.getExtensions()) { + if (extension instanceof JavaScript) { + return (JavaScript) extension; + } + } + + // Extend root if it isn't yet done + JavaScript javascript = new JavaScript(); + javascript.extend(root); + return javascript; + } + +} -- cgit v1.2.3 From 755adc2731383e6e04ddfa5bee04b6ed6feaf243 Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Thu, 14 Jun 2012 17:42:04 +0300 Subject: Rename Javascript -> JavaScript --- WebContent/statictestfiles/jsconnector.js | 4 +- WebContent/statictestfiles/jsextension.js | 6 +- .../terminal/AbstractJavaScriptExtension.java | 21 +++ .../terminal/AbstractJavascriptExtension.java | 20 -- .../vaadin/terminal/JavaScriptCallbackHelper.java | 61 ++++++ src/com/vaadin/terminal/JavascriptRpcHelper.java | 61 ------ .../terminal/gwt/client/ApplicationConnection.java | 6 +- .../gwt/client/JavaScriptConnectorHelper.java | 205 +++++++++++++++++++++ .../terminal/gwt/client/JavaScriptExtension.java | 33 ++++ .../gwt/client/JavascriptConnectorHelper.java | 205 --------------------- .../terminal/gwt/client/JavascriptExtension.java | 33 ---- src/com/vaadin/terminal/gwt/client/WidgetSet.java | 6 +- .../HasJavaScriptConnectorHelper.java | 11 ++ .../HasJavascriptConnectorHelper.java | 11 -- .../gwt/client/communication/RpcManager.java | 4 +- .../JavaScriptManagerConnector.java | 92 +++++++++ .../javascriptmanager/JavaScriptManagerState.java | 22 +++ .../JavascriptManagerConnector.java | 92 --------- .../javascriptmanager/JavascriptManagerState.java | 22 --- .../client/ui/JavaScriptComponentConnector.java | 60 ++++++ .../terminal/gwt/client/ui/JavaScriptWidget.java | 25 +++ .../client/ui/JavascriptComponentConnector.java | 60 ------ .../terminal/gwt/client/ui/JavascriptWidget.java | 25 --- src/com/vaadin/ui/AbstractJavaScriptComponent.java | 20 ++ src/com/vaadin/ui/AbstractJavascriptComponent.java | 19 -- src/com/vaadin/ui/JavaScript.java | 16 +- src/com/vaadin/ui/JavaScriptCallback.java | 14 ++ src/com/vaadin/ui/JavascriptCallback.java | 14 -- .../BasicJavaScriptComponent.java | 73 ++++++++ .../BasicJavascriptComponent.java | 73 -------- .../tests/extensions/JavascriptManagerTest.java | 4 +- .../extensions/SimpleJavaScriptExtensionTest.java | 95 ++++++++++ .../extensions/SimpleJavascriptExtensionTest.java | 95 ---------- 33 files changed, 755 insertions(+), 753 deletions(-) create mode 100644 src/com/vaadin/terminal/AbstractJavaScriptExtension.java delete mode 100644 src/com/vaadin/terminal/AbstractJavascriptExtension.java create mode 100644 src/com/vaadin/terminal/JavaScriptCallbackHelper.java delete mode 100644 src/com/vaadin/terminal/JavascriptRpcHelper.java create mode 100644 src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java create mode 100644 src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java delete mode 100644 src/com/vaadin/terminal/gwt/client/JavascriptConnectorHelper.java delete mode 100644 src/com/vaadin/terminal/gwt/client/JavascriptExtension.java create mode 100644 src/com/vaadin/terminal/gwt/client/communication/HasJavaScriptConnectorHelper.java delete mode 100644 src/com/vaadin/terminal/gwt/client/communication/HasJavascriptConnectorHelper.java create mode 100644 src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerConnector.java create mode 100644 src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerState.java delete mode 100644 src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerConnector.java delete mode 100644 src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerState.java create mode 100644 src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java create mode 100644 src/com/vaadin/terminal/gwt/client/ui/JavaScriptWidget.java delete mode 100644 src/com/vaadin/terminal/gwt/client/ui/JavascriptComponentConnector.java delete mode 100644 src/com/vaadin/terminal/gwt/client/ui/JavascriptWidget.java create mode 100644 src/com/vaadin/ui/AbstractJavaScriptComponent.java delete mode 100644 src/com/vaadin/ui/AbstractJavascriptComponent.java create mode 100644 src/com/vaadin/ui/JavaScriptCallback.java delete mode 100644 src/com/vaadin/ui/JavascriptCallback.java create mode 100644 tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java delete mode 100644 tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavascriptComponent.java create mode 100644 tests/testbench/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java delete mode 100644 tests/testbench/com/vaadin/tests/extensions/SimpleJavascriptExtensionTest.java (limited to 'src/com/vaadin/ui/JavaScript.java') diff --git a/WebContent/statictestfiles/jsconnector.js b/WebContent/statictestfiles/jsconnector.js index db8a065e86..1432c20698 100644 --- a/WebContent/statictestfiles/jsconnector.js +++ b/WebContent/statictestfiles/jsconnector.js @@ -1,10 +1,10 @@ -window.com_vaadin_tests_components_javascriptcomponent_BasicJavascriptComponent_ExampleWidget = function() { +window.com_vaadin_tests_components_javascriptcomponent_BasicJavaScriptComponent_ExampleWidget = function() { var connector = this; var rootElement = connector.getWidgetElement(); rootElement.innerHTML = 'Hello world!'; rootElement.onclick = function() { - connector.getRpcProxyFunction("com.vaadin.tests.components.javascriptcomponent.BasicJavascriptComponent$ExampleClickRpc", "onClick")("message"); + connector.getRpcProxyFunction("com.vaadin.tests.components.javascriptcomponent.BasicJavaScriptComponent$ExampleClickRpc", "onClick")("message"); } connector.onStateChange = function() { console.log('state change:', this.getState()); diff --git a/WebContent/statictestfiles/jsextension.js b/WebContent/statictestfiles/jsextension.js index bdc0460c29..be551746ca 100644 --- a/WebContent/statictestfiles/jsextension.js +++ b/WebContent/statictestfiles/jsextension.js @@ -1,8 +1,8 @@ -window.com_vaadin_tests_extensions_SimpleJavascriptExtensionTest_SimpleJavascriptExtension = function() { +window.com_vaadin_tests_extensions_SimpleJavaScriptExtensionTest_SimpleJavascriptExtension = function() { var state = this.getState(); - var greetBack = this.getRpcProxyFunction('com.vaadin.tests.extensions.SimpleJavascriptExtensionTest$SimpleJavascriptExtensionServerRpc', 'greet'); + var greetBack = this.getRpcProxyFunction('com.vaadin.tests.extensions.SimpleJavaScriptExtensionTest$SimpleJavaScriptExtensionServerRpc', 'greet'); - this.registerRpc("com.vaadin.tests.extensions.SimpleJavascriptExtensionTest.SimpleJavascriptExtensionClientRpc", { + this.registerRpc("com.vaadin.tests.extensions.SimpleJavaScriptExtensionTest.SimpleJavaScriptExtensionClientRpc", { 'greet': function(greeting) { var response = window.prompt(state.prefix + greeting); if (response !== null) { diff --git a/src/com/vaadin/terminal/AbstractJavaScriptExtension.java b/src/com/vaadin/terminal/AbstractJavaScriptExtension.java new file mode 100644 index 0000000000..49f361f343 --- /dev/null +++ b/src/com/vaadin/terminal/AbstractJavaScriptExtension.java @@ -0,0 +1,21 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal; + +import com.vaadin.ui.JavaScriptCallback; + +public class AbstractJavaScriptExtension extends AbstractExtension { + private JavaScriptCallbackHelper callbackHelper = new JavaScriptCallbackHelper( + this); + + protected void registerCallback(String functionName, + JavaScriptCallback javaScriptCallback) { + callbackHelper.registerCallback(functionName, javaScriptCallback); + } + + protected void invokeCallback(String name, Object... arguments) { + callbackHelper.invokeCallback(name, arguments); + } +} diff --git a/src/com/vaadin/terminal/AbstractJavascriptExtension.java b/src/com/vaadin/terminal/AbstractJavascriptExtension.java deleted file mode 100644 index e741e2af1e..0000000000 --- a/src/com/vaadin/terminal/AbstractJavascriptExtension.java +++ /dev/null @@ -1,20 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.terminal; - -import com.vaadin.ui.JavascriptCallback; - -public class AbstractJavascriptExtension extends AbstractExtension { - private JavascriptRpcHelper rpcHelper = new JavascriptRpcHelper(this); - - protected void registerCallback(String functionName, - JavascriptCallback javascriptCallback) { - rpcHelper.registerCallback(functionName, javascriptCallback); - } - - protected void invokeCallback(String name, Object... arguments) { - rpcHelper.invokeCallback(name, arguments); - } -} diff --git a/src/com/vaadin/terminal/JavaScriptCallbackHelper.java b/src/com/vaadin/terminal/JavaScriptCallbackHelper.java new file mode 100644 index 0000000000..5ea5e56255 --- /dev/null +++ b/src/com/vaadin/terminal/JavaScriptCallbackHelper.java @@ -0,0 +1,61 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import com.vaadin.external.json.JSONArray; +import com.vaadin.external.json.JSONException; +import com.vaadin.tools.ReflectTools; +import com.vaadin.ui.JavaScript.JavaScriptCallbackRpc; +import com.vaadin.ui.JavaScriptCallback; + +public class JavaScriptCallbackHelper { + + private static final Method CALL_METHOD = ReflectTools.findMethod( + JavaScriptCallbackRpc.class, "call", String.class, JSONArray.class); + private AbstractClientConnector connector; + + private Map callbacks = new HashMap(); + private JavaScriptCallbackRpc javascriptCallbackRpc; + + public JavaScriptCallbackHelper(AbstractClientConnector connector) { + this.connector = connector; + } + + public void registerCallback(String functionName, + JavaScriptCallback javaScriptCallback) { + callbacks.put(functionName, javaScriptCallback); + ensureRpc(); + } + + private void ensureRpc() { + if (javascriptCallbackRpc == null) { + javascriptCallbackRpc = new JavaScriptCallbackRpc() { + public void call(String name, JSONArray arguments) { + JavaScriptCallback callback = callbacks.get(name); + try { + callback.call(arguments); + } catch (JSONException e) { + throw new IllegalArgumentException(e); + } + } + }; + connector.registerRpc(javascriptCallbackRpc); + } + } + + public void invokeCallback(String name, Object... arguments) { + JSONArray args = new JSONArray(Arrays.asList(arguments)); + connector.addMethodInvocationToQueue( + JavaScriptCallbackRpc.class.getName(), CALL_METHOD, + new Object[] { name, args }); + connector.requestRepaint(); + } + +} diff --git a/src/com/vaadin/terminal/JavascriptRpcHelper.java b/src/com/vaadin/terminal/JavascriptRpcHelper.java deleted file mode 100644 index 937f7e3a54..0000000000 --- a/src/com/vaadin/terminal/JavascriptRpcHelper.java +++ /dev/null @@ -1,61 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.terminal; - -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import com.vaadin.external.json.JSONArray; -import com.vaadin.external.json.JSONException; -import com.vaadin.tools.ReflectTools; -import com.vaadin.ui.JavaScript.JavascriptCallbackRpc; -import com.vaadin.ui.JavascriptCallback; - -public class JavascriptRpcHelper { - - private static final Method CALL_METHOD = ReflectTools.findMethod( - JavascriptCallbackRpc.class, "call", String.class, JSONArray.class); - private AbstractClientConnector connector; - - private Map callbacks = new HashMap(); - private JavascriptCallbackRpc javascriptCallbackRpc; - - public JavascriptRpcHelper(AbstractClientConnector connector) { - this.connector = connector; - } - - public void registerCallback(String functionName, - JavascriptCallback javascriptCallback) { - callbacks.put(functionName, javascriptCallback); - ensureRpc(); - } - - private void ensureRpc() { - if (javascriptCallbackRpc == null) { - javascriptCallbackRpc = new JavascriptCallbackRpc() { - public void call(String name, JSONArray arguments) { - JavascriptCallback callback = callbacks.get(name); - try { - callback.call(arguments); - } catch (JSONException e) { - throw new IllegalArgumentException(e); - } - } - }; - connector.registerRpc(javascriptCallbackRpc); - } - } - - public void invokeCallback(String name, Object... arguments) { - JSONArray args = new JSONArray(Arrays.asList(arguments)); - connector.addMethodInvocationToQueue( - JavascriptCallbackRpc.class.getName(), CALL_METHOD, - new Object[] { name, args }); - connector.requestRepaint(); - } - -} diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index c973fe44d1..1349af465d 100644 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -40,7 +40,7 @@ import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConfiguration.ErrorMessage; -import com.vaadin.terminal.gwt.client.communication.HasJavascriptConnectorHelper; +import com.vaadin.terminal.gwt.client.communication.HasJavaScriptConnectorHelper; import com.vaadin.terminal.gwt.client.communication.JsonDecoder; import com.vaadin.terminal.gwt.client.communication.JsonEncoder; import com.vaadin.terminal.gwt.client.communication.MethodInvocation; @@ -1416,8 +1416,8 @@ public class ApplicationConnection { JSONObject stateJson = new JSONObject( states.getJavaScriptObject(connectorId)); - if (connector instanceof HasJavascriptConnectorHelper) { - ((HasJavascriptConnectorHelper) connector) + if (connector instanceof HasJavaScriptConnectorHelper) { + ((HasJavaScriptConnectorHelper) connector) .getJavascriptConnectorHelper() .setNativeState( stateJson.getJavaScriptObject()); diff --git a/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java b/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java new file mode 100644 index 0000000000..2c7ca22157 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java @@ -0,0 +1,205 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client; + +import java.util.ArrayList; + +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; + +public class JavaScriptConnectorHelper { + + private final ServerConnector connector; + private final JavaScriptObject nativeState = JavaScriptObject + .createObject(); + private final JavaScriptObject rpcMap = JavaScriptObject.createObject(); + + private JavaScriptObject connectorWrapper; + private int tag; + + public JavaScriptConnectorHelper(ServerConnector connector) { + this.connector = connector; + } + + public boolean init() { + ApplicationConfiguration conf = connector.getConnection() + .getConfiguration(); + ArrayList attemptedNames = new ArrayList(); + Integer tag = Integer.valueOf(this.tag); + while (tag != null) { + String serverSideClassName = conf.getServerSideClassNameForTag(tag); + String initFunctionName = serverSideClassName + .replaceAll("\\.", "_"); + if (tryInitJs(initFunctionName, getConnectorWrapper())) { + VConsole.log("JavaScript connector initialized using " + + initFunctionName); + return true; + } else { + VConsole.log("No JavaScript function " + initFunctionName + + " found"); + attemptedNames.add(initFunctionName); + tag = conf.getParentTag(tag.intValue()); + } + } + VConsole.log("No JavaScript init for connector not found"); + showInitProblem(attemptedNames); + return false; + } + + protected void showInitProblem(ArrayList attemptedNames) { + // Default does nothing + } + + private static native boolean tryInitJs(String initFunctionName, + JavaScriptObject connectorWrapper) + /*-{ + if (typeof $wnd[initFunctionName] == 'function') { + $wnd[initFunctionName].apply(connectorWrapper); + return true; + } else { + return false; + } + }-*/; + + private JavaScriptObject getConnectorWrapper() { + if (connectorWrapper == null) { + connectorWrapper = createConnectorWrapper(); + } + + return connectorWrapper; + } + + protected JavaScriptObject createConnectorWrapper() { + return createConnectorWrapper(this, nativeState, rpcMap, + connector.getConnectorId()); + } + + public void fireNativeStateChange() { + fireNativeStateChange(getConnectorWrapper()); + } + + private static native void fireNativeStateChange( + JavaScriptObject connectorWrapper) + /*-{ + if (typeof connectorWrapper.onStateChange == 'function') { + connectorWrapper.onStateChange(); + } + }-*/; + + private static native JavaScriptObject createConnectorWrapper( + JavaScriptConnectorHelper h, JavaScriptObject nativeState, + JavaScriptObject registeredRpc, String connectorId) + /*-{ + return { + 'getConnectorId': function() { + return connectorId; + }, + 'getState': function() { + return nativeState; + }, + 'getRpcProxyFunction': function(iface, method) { + return $entry(function() { + h.@com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper::fireRpc(Ljava/lang/String;Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(iface, method, arguments); + }); + }, + 'getCallback': function(name) { + return $entry(function() { + var args = [name, Array.prototype.slice.call(arguments, 0)]; + var iface = "com.vaadin.ui.JavaScript$JavaScriptCallbackRpc"; + var method = "call"; + h.@com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper::fireRpc(Ljava/lang/String;Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(iface, method, args); + }); + }, + 'registerCallback': function(name, callback) { + //TODO maintain separate map + if (!registeredRpc[name]) { + registeredRpc[name] = []; + } + registeredRpc[name].push(callback); + }, + 'registerRpc': function(iface, rpcHandler) { + if (!registeredRpc[iface]) { + registeredRpc[iface] = []; + } + registeredRpc[iface].push(rpcHandler); + }, + }; + }-*/; + + private void fireRpc(String iface, String method, + JsArray arguments) { + JSONArray argumentsArray = new JSONArray(arguments); + Object[] parameters = new Object[arguments.length()]; + for (int i = 0; i < parameters.length; i++) { + parameters[i] = argumentsArray.get(i); + } + connector.getConnection().addMethodInvocationToQueue( + new MethodInvocation(connector.getConnectorId(), iface, method, + parameters), true); + } + + public void setNativeState(JavaScriptObject state) { + updateNativeState(nativeState, state); + } + + private static native void updateNativeState(JavaScriptObject state, + JavaScriptObject input) + /*-{ + // Copy all fields to existing state object + for(var key in state) { + if (state.hasOwnProperty(key)) { + delete state[key]; + } + } + + for(var key in input) { + if (input.hasOwnProperty(key)) { + state[key] = input[key]; + } + } + }-*/; + + public Object[] decodeRpcParameters(JSONArray parametersJson) { + return new Object[] { parametersJson.getJavaScriptObject() }; + } + + public void setTag(int tag) { + this.tag = tag; + } + + public void invokeJsRpc(MethodInvocation invocation, + JSONArray parametersJson) { + if ("com.vaadin.ui.JavaScript$JavaScriptCallbackRpc".equals(invocation + .getInterfaceName()) + && "call".equals(invocation.getMethodName())) { + invokeJsRpc(rpcMap, parametersJson.get(0).isString().stringValue(), + null, parametersJson.get(1).isArray().getJavaScriptObject()); + } else { + invokeJsRpc(rpcMap, invocation.getInterfaceName(), + invocation.getMethodName(), + parametersJson.getJavaScriptObject()); + } + } + + private static native void invokeJsRpc(JavaScriptObject rpcMap, + String interfaceName, String methodName, JavaScriptObject parameters) + /*-{ + var targets = rpcMap[interfaceName]; + if (!targets) { + return; + } + for(var i = 0; i < targets.length; i++) { + var target = targets[i]; + if (methodName === null && typeof target === 'function') { + target.apply($wnd, parameters); + } else { + target[methodName].apply(target, parameters); + } + } + }-*/; + +} diff --git a/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java b/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java new file mode 100644 index 0000000000..121208d754 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java @@ -0,0 +1,33 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client; + +import com.vaadin.terminal.AbstractJavaScriptExtension; +import com.vaadin.terminal.gwt.client.communication.HasJavaScriptConnectorHelper; +import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; +import com.vaadin.terminal.gwt.client.extensions.AbstractExtensionConnector; +import com.vaadin.terminal.gwt.client.ui.Connect; + +@Connect(AbstractJavaScriptExtension.class) +public class JavaScriptExtension extends AbstractExtensionConnector implements + HasJavaScriptConnectorHelper { + private final JavaScriptConnectorHelper helper = new JavaScriptConnectorHelper( + this); + + @Override + protected void init() { + helper.init(); + } + + @Override + public void onStateChanged(StateChangeEvent stateChangeEvent) { + super.onStateChanged(stateChangeEvent); + helper.fireNativeStateChange(); + } + + public JavaScriptConnectorHelper getJavascriptConnectorHelper() { + return helper; + } +} diff --git a/src/com/vaadin/terminal/gwt/client/JavascriptConnectorHelper.java b/src/com/vaadin/terminal/gwt/client/JavascriptConnectorHelper.java deleted file mode 100644 index 36f7c47959..0000000000 --- a/src/com/vaadin/terminal/gwt/client/JavascriptConnectorHelper.java +++ /dev/null @@ -1,205 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.terminal.gwt.client; - -import java.util.ArrayList; - -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; - -public class JavascriptConnectorHelper { - - private final ServerConnector connector; - private final JavaScriptObject nativeState = JavaScriptObject - .createObject(); - private final JavaScriptObject rpcMap = JavaScriptObject.createObject(); - - private JavaScriptObject connectorWrapper; - private int tag; - - public JavascriptConnectorHelper(ServerConnector connector) { - this.connector = connector; - } - - public boolean init() { - ApplicationConfiguration conf = connector.getConnection() - .getConfiguration(); - ArrayList attemptedNames = new ArrayList(); - Integer tag = Integer.valueOf(this.tag); - while (tag != null) { - String serverSideClassName = conf.getServerSideClassNameForTag(tag); - String initFunctionName = serverSideClassName - .replaceAll("\\.", "_"); - if (tryInitJs(initFunctionName, getConnectorWrapper())) { - VConsole.log("Javascript connector initialized using " - + initFunctionName); - return true; - } else { - VConsole.log("No javascript function " + initFunctionName - + " found"); - attemptedNames.add(initFunctionName); - tag = conf.getParentTag(tag.intValue()); - } - } - VConsole.log("No javascript init for connector not found"); - showInitProblem(attemptedNames); - return false; - } - - protected void showInitProblem(ArrayList attemptedNames) { - // Default does nothing - } - - private static native boolean tryInitJs(String initFunctionName, - JavaScriptObject connectorWrapper) - /*-{ - if (typeof $wnd[initFunctionName] == 'function') { - $wnd[initFunctionName].apply(connectorWrapper); - return true; - } else { - return false; - } - }-*/; - - private JavaScriptObject getConnectorWrapper() { - if (connectorWrapper == null) { - connectorWrapper = createConnectorWrapper(); - } - - return connectorWrapper; - } - - protected JavaScriptObject createConnectorWrapper() { - return createConnectorWrapper(this, nativeState, rpcMap, - connector.getConnectorId()); - } - - public void fireNativeStateChange() { - fireNativeStateChange(getConnectorWrapper()); - } - - private static native void fireNativeStateChange( - JavaScriptObject connectorWrapper) - /*-{ - if (typeof connectorWrapper.onStateChange == 'function') { - connectorWrapper.onStateChange(); - } - }-*/; - - private static native JavaScriptObject createConnectorWrapper( - JavascriptConnectorHelper h, JavaScriptObject nativeState, - JavaScriptObject registeredRpc, String connectorId) - /*-{ - return { - 'getConnectorId': function() { - return connectorId; - }, - 'getState': function() { - return nativeState; - }, - 'getRpcProxyFunction': function(iface, method) { - return $entry(function() { - h.@com.vaadin.terminal.gwt.client.JavascriptConnectorHelper::fireRpc(Ljava/lang/String;Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(iface, method, arguments); - }); - }, - 'getCallback': function(name) { - return $entry(function() { - var args = [name, Array.prototype.slice.call(arguments, 0)]; - var iface = "com.vaadin.ui.JavaScript$JavascriptCallbackRpc"; - var method = "call"; - h.@com.vaadin.terminal.gwt.client.JavascriptConnectorHelper::fireRpc(Ljava/lang/String;Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(iface, method, args); - }); - }, - 'registerCallback': function(name, callback) { - //TODO maintain separate map - if (!registeredRpc[name]) { - registeredRpc[name] = []; - } - registeredRpc[name].push(callback); - }, - 'registerRpc': function(iface, rpcHandler) { - if (!registeredRpc[iface]) { - registeredRpc[iface] = []; - } - registeredRpc[iface].push(rpcHandler); - }, - }; - }-*/; - - private void fireRpc(String iface, String method, - JsArray arguments) { - JSONArray argumentsArray = new JSONArray(arguments); - Object[] parameters = new Object[arguments.length()]; - for (int i = 0; i < parameters.length; i++) { - parameters[i] = argumentsArray.get(i); - } - connector.getConnection().addMethodInvocationToQueue( - new MethodInvocation(connector.getConnectorId(), iface, method, - parameters), true); - } - - public void setNativeState(JavaScriptObject state) { - updateNativeState(nativeState, state); - } - - private static native void updateNativeState(JavaScriptObject state, - JavaScriptObject input) - /*-{ - // Copy all fields to existing state object - for(var key in state) { - if (state.hasOwnProperty(key)) { - delete state[key]; - } - } - - for(var key in input) { - if (input.hasOwnProperty(key)) { - state[key] = input[key]; - } - } - }-*/; - - public Object[] decodeRpcParameters(JSONArray parametersJson) { - return new Object[] { parametersJson.getJavaScriptObject() }; - } - - public void setTag(int tag) { - this.tag = tag; - } - - public void invokeJsRpc(MethodInvocation invocation, - JSONArray parametersJson) { - if ("com.vaadin.ui.JavaScript$JavascriptCallbackRpc".equals(invocation - .getInterfaceName()) - && "call".equals(invocation.getMethodName())) { - invokeJsRpc(rpcMap, parametersJson.get(0).isString().stringValue(), - null, parametersJson.get(1).isArray().getJavaScriptObject()); - } else { - invokeJsRpc(rpcMap, invocation.getInterfaceName(), - invocation.getMethodName(), - parametersJson.getJavaScriptObject()); - } - } - - private static native void invokeJsRpc(JavaScriptObject rpcMap, - String interfaceName, String methodName, JavaScriptObject parameters) - /*-{ - var targets = rpcMap[interfaceName]; - if (!targets) { - return; - } - for(var i = 0; i < targets.length; i++) { - var target = targets[i]; - if (methodName === null && typeof target === 'function') { - target.apply($wnd, parameters); - } else { - target[methodName].apply(target, parameters); - } - } - }-*/; - -} diff --git a/src/com/vaadin/terminal/gwt/client/JavascriptExtension.java b/src/com/vaadin/terminal/gwt/client/JavascriptExtension.java deleted file mode 100644 index 74c3d7da45..0000000000 --- a/src/com/vaadin/terminal/gwt/client/JavascriptExtension.java +++ /dev/null @@ -1,33 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.terminal.gwt.client; - -import com.vaadin.terminal.AbstractJavascriptExtension; -import com.vaadin.terminal.gwt.client.communication.HasJavascriptConnectorHelper; -import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; -import com.vaadin.terminal.gwt.client.extensions.AbstractExtensionConnector; -import com.vaadin.terminal.gwt.client.ui.Connect; - -@Connect(AbstractJavascriptExtension.class) -public class JavascriptExtension extends AbstractExtensionConnector implements - HasJavascriptConnectorHelper { - private final JavascriptConnectorHelper helper = new JavascriptConnectorHelper( - this); - - @Override - protected void init() { - helper.init(); - } - - @Override - public void onStateChanged(StateChangeEvent stateChangeEvent) { - super.onStateChanged(stateChangeEvent); - helper.fireNativeStateChange(); - } - - public JavascriptConnectorHelper getJavascriptConnectorHelper() { - return helper; - } -} diff --git a/src/com/vaadin/terminal/gwt/client/WidgetSet.java b/src/com/vaadin/terminal/gwt/client/WidgetSet.java index ecbfb0ecc9..3d7e838c62 100644 --- a/src/com/vaadin/terminal/gwt/client/WidgetSet.java +++ b/src/com/vaadin/terminal/gwt/client/WidgetSet.java @@ -5,7 +5,7 @@ package com.vaadin.terminal.gwt.client; import com.google.gwt.core.client.GWT; -import com.vaadin.terminal.gwt.client.communication.HasJavascriptConnectorHelper; +import com.vaadin.terminal.gwt.client.communication.HasJavaScriptConnectorHelper; import com.vaadin.terminal.gwt.client.ui.UnknownComponentConnector; public class WidgetSet { @@ -54,8 +54,8 @@ public class WidgetSet { * let the auto generated code instantiate this type */ ServerConnector connector = widgetMap.instantiate(classType); - if (connector instanceof HasJavascriptConnectorHelper) { - ((HasJavascriptConnectorHelper) connector) + if (connector instanceof HasJavaScriptConnectorHelper) { + ((HasJavaScriptConnectorHelper) connector) .getJavascriptConnectorHelper().setTag(tag); } return connector; diff --git a/src/com/vaadin/terminal/gwt/client/communication/HasJavaScriptConnectorHelper.java b/src/com/vaadin/terminal/gwt/client/communication/HasJavaScriptConnectorHelper.java new file mode 100644 index 0000000000..a5191a5fed --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/communication/HasJavaScriptConnectorHelper.java @@ -0,0 +1,11 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client.communication; + +import com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper; + +public interface HasJavaScriptConnectorHelper { + public JavaScriptConnectorHelper getJavascriptConnectorHelper(); +} diff --git a/src/com/vaadin/terminal/gwt/client/communication/HasJavascriptConnectorHelper.java b/src/com/vaadin/terminal/gwt/client/communication/HasJavascriptConnectorHelper.java deleted file mode 100644 index 74bc75da66..0000000000 --- a/src/com/vaadin/terminal/gwt/client/communication/HasJavascriptConnectorHelper.java +++ /dev/null @@ -1,11 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.terminal.gwt.client.communication; - -import com.vaadin.terminal.gwt.client.JavascriptConnectorHelper; - -public interface HasJavascriptConnectorHelper { - public JavascriptConnectorHelper getJavascriptConnectorHelper(); -} diff --git a/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java b/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java index e0ffb40125..07d6292ce2 100644 --- a/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java +++ b/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java @@ -89,8 +89,8 @@ public class RpcManager { MethodInvocation invocation = new MethodInvocation(connectorId, interfaceName, methodName); - if (connector instanceof HasJavascriptConnectorHelper) { - ((HasJavascriptConnectorHelper) connector) + if (connector instanceof HasJavaScriptConnectorHelper) { + ((HasJavaScriptConnectorHelper) connector) .getJavascriptConnectorHelper().invokeJsRpc(invocation, parametersJson); } else { 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..72bd253ecb --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerConnector.java @@ -0,0 +1,92 @@ +/* +@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.extensions.AbstractExtensionConnector; +import com.vaadin.terminal.gwt.client.ui.Connect; +import com.vaadin.ui.JavaScript; + +@Connect(JavaScript.class) +public class JavaScriptManagerConnector extends AbstractExtensionConnector { + private Set currentNames = new HashSet(); + + @Override + protected void init() { + registerRpc(ExecuteJavaScriptRpc.class, new ExecuteJavaScriptRpc() { + public void executeJavaScript(String Script) { + eval(Script); + } + }); + } + + @Override + public void onStateChanged(StateChangeEvent stateChangeEvent) { + super.onStateChanged(stateChangeEvent); + + Set newNames = getState().getNames(); + + // Current names now only contains orphan callbacks + currentNames.removeAll(newNames); + + for (String name : currentNames) { + removeCallback(name); + } + + currentNames = new HashSet(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]; + }-*/; + + private static native void eval(String Script) + /*-{ + if(Script) { + $wnd.eval(Script); + } + }-*/; + + public void sendRpc(String name, JsArray 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.JavaScript$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..fc246aff04 --- /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 names = new HashSet(); + + public Set getNames() { + return names; + } + + public void setNames(Set names) { + this.names = names; + } +} diff --git a/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerConnector.java b/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerConnector.java deleted file mode 100644 index 10c4847bac..0000000000 --- a/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerConnector.java +++ /dev/null @@ -1,92 +0,0 @@ -/* -@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.extensions.AbstractExtensionConnector; -import com.vaadin.terminal.gwt.client.ui.Connect; -import com.vaadin.ui.JavaScript; - -@Connect(JavaScript.class) -public class JavascriptManagerConnector extends AbstractExtensionConnector { - private Set currentNames = new HashSet(); - - @Override - protected void init() { - registerRpc(ExecuteJavaScriptRpc.class, new ExecuteJavaScriptRpc() { - public void executeJavaScript(String script) { - eval(script); - } - }); - } - - @Override - public void onStateChanged(StateChangeEvent stateChangeEvent) { - super.onStateChanged(stateChangeEvent); - - Set newNames = getState().getNames(); - - // Current names now only contains orphan callbacks - currentNames.removeAll(newNames); - - for (String name : currentNames) { - removeCallback(name); - } - - currentNames = new HashSet(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]; - }-*/; - - private static native void eval(String script) - /*-{ - if(script) { - $wnd.eval(script); - } - }-*/; - - public void sendRpc(String name, JsArray 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.JavaScript$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 deleted file mode 100644 index 77794ffdca..0000000000 --- a/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerState.java +++ /dev/null @@ -1,22 +0,0 @@ -/* -@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 names = new HashSet(); - - public Set getNames() { - return names; - } - - public void setNames(Set names) { - this.names = names; - } -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java new file mode 100644 index 0000000000..c8b22a4239 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java @@ -0,0 +1,60 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client.ui; + +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.user.client.Element; +import com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper; +import com.vaadin.terminal.gwt.client.communication.HasJavaScriptConnectorHelper; +import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; +import com.vaadin.ui.AbstractJavaScriptComponent; + +@Connect(AbstractJavaScriptComponent.class) +public class JavaScriptComponentConnector extends AbstractComponentConnector + implements HasJavaScriptConnectorHelper { + + private final JavaScriptConnectorHelper helper = new JavaScriptConnectorHelper( + this) { + @Override + protected void showInitProblem( + java.util.ArrayList attemptedNames) { + getWidget().showNoInitFound(attemptedNames); + } + + @Override + protected JavaScriptObject createConnectorWrapper() { + JavaScriptObject connectorWrapper = super.createConnectorWrapper(); + addGetWidgetElement(connectorWrapper, getWidget().getElement()); + return connectorWrapper; + } + }; + + @Override + protected void init() { + helper.init(); + } + + @Override + public void onStateChanged(StateChangeEvent stateChangeEvent) { + super.onStateChanged(stateChangeEvent); + helper.fireNativeStateChange(); + } + + private static native void addGetWidgetElement( + JavaScriptObject connectorWrapper, Element element) + /*-{ + connectorWrapper.getWidgetElement = function() { + return element; + }; + }-*/; + + @Override + public JavaScriptWidget getWidget() { + return (JavaScriptWidget) super.getWidget(); + } + + public JavaScriptConnectorHelper getJavascriptConnectorHelper() { + return helper; + } +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/JavaScriptWidget.java b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptWidget.java new file mode 100644 index 0000000000..e6c3323893 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptWidget.java @@ -0,0 +1,25 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client.ui; + +import java.util.ArrayList; + +import com.google.gwt.dom.client.Document; +import com.google.gwt.user.client.ui.Widget; + +public class JavaScriptWidget extends Widget { + public JavaScriptWidget() { + setElement(Document.get().createDivElement()); + } + + public void showNoInitFound(ArrayList attemptedNames) { + String message = "Could not initialize JavaScriptConnector because no JavaScript init function was found. Make sure one of these functions are defined:
    "; + for (String name : attemptedNames) { + message += "
  • " + name + "
  • "; + } + message += "
"; + + getElement().setInnerHTML(message); + } +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/JavascriptComponentConnector.java b/src/com/vaadin/terminal/gwt/client/ui/JavascriptComponentConnector.java deleted file mode 100644 index 57e65e91c6..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/JavascriptComponentConnector.java +++ /dev/null @@ -1,60 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.terminal.gwt.client.ui; - -import com.google.gwt.core.client.JavaScriptObject; -import com.google.gwt.user.client.Element; -import com.vaadin.terminal.gwt.client.JavascriptConnectorHelper; -import com.vaadin.terminal.gwt.client.communication.HasJavascriptConnectorHelper; -import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; -import com.vaadin.ui.AbstractJavascriptComponent; - -@Connect(AbstractJavascriptComponent.class) -public class JavascriptComponentConnector extends AbstractComponentConnector - implements HasJavascriptConnectorHelper { - - private final JavascriptConnectorHelper helper = new JavascriptConnectorHelper( - this) { - @Override - protected void showInitProblem( - java.util.ArrayList attemptedNames) { - getWidget().showNoInitFound(attemptedNames); - } - - @Override - protected JavaScriptObject createConnectorWrapper() { - JavaScriptObject connectorWrapper = super.createConnectorWrapper(); - addGetWidgetElement(connectorWrapper, getWidget().getElement()); - return connectorWrapper; - } - }; - - @Override - protected void init() { - helper.init(); - } - - @Override - public void onStateChanged(StateChangeEvent stateChangeEvent) { - super.onStateChanged(stateChangeEvent); - helper.fireNativeStateChange(); - } - - private static native void addGetWidgetElement( - JavaScriptObject connectorWrapper, Element element) - /*-{ - connectorWrapper.getWidgetElement = function() { - return element; - }; - }-*/; - - @Override - public JavascriptWidget getWidget() { - return (JavascriptWidget) super.getWidget(); - } - - public JavascriptConnectorHelper getJavascriptConnectorHelper() { - return helper; - } -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/JavascriptWidget.java b/src/com/vaadin/terminal/gwt/client/ui/JavascriptWidget.java deleted file mode 100644 index 93a4417b1c..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/JavascriptWidget.java +++ /dev/null @@ -1,25 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.terminal.gwt.client.ui; - -import java.util.ArrayList; - -import com.google.gwt.dom.client.Document; -import com.google.gwt.user.client.ui.Widget; - -public class JavascriptWidget extends Widget { - public JavascriptWidget() { - setElement(Document.get().createDivElement()); - } - - public void showNoInitFound(ArrayList attemptedNames) { - String message = "Could not initialize JavascriptConnector because no javascript init function was found. Make sure one of these functions are defined:
    "; - for (String name : attemptedNames) { - message += "
  • " + name + "
  • "; - } - message += "
"; - - getElement().setInnerHTML(message); - } -} diff --git a/src/com/vaadin/ui/AbstractJavaScriptComponent.java b/src/com/vaadin/ui/AbstractJavaScriptComponent.java new file mode 100644 index 0000000000..881ac3f9d9 --- /dev/null +++ b/src/com/vaadin/ui/AbstractJavaScriptComponent.java @@ -0,0 +1,20 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.ui; + +import com.vaadin.terminal.JavaScriptCallbackHelper; + +public class AbstractJavaScriptComponent extends AbstractComponent { + private JavaScriptCallbackHelper callbackHelper = new JavaScriptCallbackHelper( + this); + + protected void registerCallback(String functionName, + JavaScriptCallback javascriptCallback) { + callbackHelper.registerCallback(functionName, javascriptCallback); + } + + protected void invokeCallback(String name, Object... arguments) { + callbackHelper.invokeCallback(name, arguments); + } +} diff --git a/src/com/vaadin/ui/AbstractJavascriptComponent.java b/src/com/vaadin/ui/AbstractJavascriptComponent.java deleted file mode 100644 index 0a26c10239..0000000000 --- a/src/com/vaadin/ui/AbstractJavascriptComponent.java +++ /dev/null @@ -1,19 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.ui; - -import com.vaadin.terminal.JavascriptRpcHelper; - -public class AbstractJavascriptComponent extends AbstractComponent { - private JavascriptRpcHelper rpcHelper = new JavascriptRpcHelper(this); - - protected void registerCallback(String functionName, - JavascriptCallback javascriptCallback) { - rpcHelper.registerCallback(functionName, javascriptCallback); - } - - protected void invokeCallback(String name, Object... arguments) { - rpcHelper.invokeCallback(name, arguments); - } -} diff --git a/src/com/vaadin/ui/JavaScript.java b/src/com/vaadin/ui/JavaScript.java index dcd8540947..fb1dba2f20 100644 --- a/src/com/vaadin/ui/JavaScript.java +++ b/src/com/vaadin/ui/JavaScript.java @@ -13,21 +13,21 @@ import com.vaadin.terminal.AbstractExtension; import com.vaadin.terminal.Extension; import com.vaadin.terminal.gwt.client.communication.ServerRpc; import com.vaadin.terminal.gwt.client.extensions.javascriptmanager.ExecuteJavaScriptRpc; -import com.vaadin.terminal.gwt.client.extensions.javascriptmanager.JavascriptManagerState; +import com.vaadin.terminal.gwt.client.extensions.javascriptmanager.JavaScriptManagerState; public class JavaScript extends AbstractExtension { - private Map callbacks = new HashMap(); + private Map callbacks = new HashMap(); // Can not be defined in client package as this JSONArray is not available // in GWT - public interface JavascriptCallbackRpc extends ServerRpc { + public interface JavaScriptCallbackRpc extends ServerRpc { public void call(String name, JSONArray arguments); } public JavaScript() { - registerRpc(new JavascriptCallbackRpc() { + registerRpc(new JavaScriptCallbackRpc() { public void call(String name, JSONArray arguments) { - JavascriptCallback callback = callbacks.get(name); + JavaScriptCallback callback = callbacks.get(name); // TODO handle situation if name is not registered try { callback.call(arguments); @@ -39,11 +39,11 @@ public class JavaScript extends AbstractExtension { } @Override - public JavascriptManagerState getState() { - return (JavascriptManagerState) super.getState(); + public JavaScriptManagerState getState() { + return (JavaScriptManagerState) super.getState(); } - public void addCallback(String name, JavascriptCallback callback) { + public void addCallback(String name, JavaScriptCallback callback) { callbacks.put(name, callback); if (getState().getNames().add(name)) { requestRepaint(); diff --git a/src/com/vaadin/ui/JavaScriptCallback.java b/src/com/vaadin/ui/JavaScriptCallback.java new file mode 100644 index 0000000000..e6b16010e4 --- /dev/null +++ b/src/com/vaadin/ui/JavaScriptCallback.java @@ -0,0 +1,14 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.ui; + +import java.io.Serializable; + +import com.vaadin.external.json.JSONArray; +import com.vaadin.external.json.JSONException; + +public interface JavaScriptCallback extends Serializable { + public void call(JSONArray arguments) throws JSONException; +} diff --git a/src/com/vaadin/ui/JavascriptCallback.java b/src/com/vaadin/ui/JavascriptCallback.java deleted file mode 100644 index 89700b3faf..0000000000 --- a/src/com/vaadin/ui/JavascriptCallback.java +++ /dev/null @@ -1,14 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import java.io.Serializable; - -import com.vaadin.external.json.JSONArray; -import com.vaadin.external.json.JSONException; - -public interface JavascriptCallback extends Serializable { - public void call(JSONArray arguments) throws JSONException; -} diff --git a/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java b/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java new file mode 100644 index 0000000000..4de80aaf9d --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java @@ -0,0 +1,73 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.tests.components.javascriptcomponent; + +import java.util.Arrays; +import java.util.List; + +import com.vaadin.annotations.LoadScripts; +import com.vaadin.terminal.WrappedRequest; +import com.vaadin.terminal.gwt.client.ComponentState; +import com.vaadin.terminal.gwt.client.communication.ServerRpc; +import com.vaadin.tests.components.AbstractTestRoot; +import com.vaadin.ui.AbstractJavaScriptComponent; +import com.vaadin.ui.Root; + +@LoadScripts({ "/statictestfiles/jsconnector.js" }) +public class BasicJavaScriptComponent extends AbstractTestRoot { + + public interface ExampleClickRpc extends ServerRpc { + public void onClick(String message); + } + + public static class SpecialState extends ComponentState { + private List data; + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + } + + public static class ExampleWidget extends AbstractJavaScriptComponent { + public ExampleWidget() { + registerRpc(new ExampleClickRpc() { + public void onClick(String message) { + Root.getCurrentRoot().showNotification( + "Got a click: " + message); + } + }); + getState().setData(Arrays.asList("a", "b", "c")); + } + + @Override + public SpecialState getState() { + return (SpecialState) super.getState(); + } + } + + @Override + protected void setup(WrappedRequest request) { + ExampleWidget c = new ExampleWidget(); + c.setCaption("test caption"); + c.setDescription("Some description"); + addComponent(c); + } + + @Override + protected String getTestDescription() { + // TODO Auto-generated method stub + return null; + } + + @Override + protected Integer getTicketNumber() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavascriptComponent.java b/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavascriptComponent.java deleted file mode 100644 index 2240fc246b..0000000000 --- a/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavascriptComponent.java +++ /dev/null @@ -1,73 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.tests.components.javascriptcomponent; - -import java.util.Arrays; -import java.util.List; - -import com.vaadin.annotations.LoadScripts; -import com.vaadin.terminal.WrappedRequest; -import com.vaadin.terminal.gwt.client.ComponentState; -import com.vaadin.terminal.gwt.client.communication.ServerRpc; -import com.vaadin.tests.components.AbstractTestRoot; -import com.vaadin.ui.AbstractJavascriptComponent; -import com.vaadin.ui.Root; - -@LoadScripts({ "/statictestfiles/jsconnector.js" }) -public class BasicJavascriptComponent extends AbstractTestRoot { - - public interface ExampleClickRpc extends ServerRpc { - public void onClick(String message); - } - - public static class SpecialState extends ComponentState { - private List data; - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - } - - public static class ExampleWidget extends AbstractJavascriptComponent { - public ExampleWidget() { - registerRpc(new ExampleClickRpc() { - public void onClick(String message) { - Root.getCurrentRoot().showNotification( - "Got a click: " + message); - } - }); - getState().setData(Arrays.asList("a", "b", "c")); - } - - @Override - public SpecialState getState() { - return (SpecialState) super.getState(); - } - } - - @Override - protected void setup(WrappedRequest request) { - ExampleWidget c = new ExampleWidget(); - c.setCaption("test caption"); - c.setDescription("Some description"); - addComponent(c); - } - - @Override - protected String getTestDescription() { - // TODO Auto-generated method stub - return null; - } - - @Override - protected Integer getTicketNumber() { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/tests/testbench/com/vaadin/tests/extensions/JavascriptManagerTest.java b/tests/testbench/com/vaadin/tests/extensions/JavascriptManagerTest.java index 0270f7ed8f..be4675eb2d 100644 --- a/tests/testbench/com/vaadin/tests/extensions/JavascriptManagerTest.java +++ b/tests/testbench/com/vaadin/tests/extensions/JavascriptManagerTest.java @@ -11,7 +11,7 @@ import com.vaadin.terminal.WrappedRequest; import com.vaadin.tests.components.AbstractTestRoot; import com.vaadin.tests.util.Log; import com.vaadin.ui.JavaScript; -import com.vaadin.ui.JavascriptCallback; +import com.vaadin.ui.JavaScriptCallback; public class JavascriptManagerTest extends AbstractTestRoot { @@ -21,7 +21,7 @@ public class JavascriptManagerTest extends AbstractTestRoot { protected void setup(WrappedRequest request) { addComponent(log); JavaScript js = JavaScript.getCurrent(); - js.addCallback("testing", new JavascriptCallback() { + js.addCallback("testing", new JavaScriptCallback() { public void call(JSONArray arguments) throws JSONException { log.log("Got " + arguments.length() + " arguments"); log.log("Argument 1 as a number: " + arguments.getInt(0)); diff --git a/tests/testbench/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java b/tests/testbench/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java new file mode 100644 index 0000000000..983520ee93 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java @@ -0,0 +1,95 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.tests.extensions; + +import com.vaadin.annotations.LoadScripts; +import com.vaadin.terminal.AbstractJavaScriptExtension; +import com.vaadin.terminal.WrappedRequest; +import com.vaadin.terminal.gwt.client.communication.ClientRpc; +import com.vaadin.terminal.gwt.client.communication.ServerRpc; +import com.vaadin.terminal.gwt.client.communication.SharedState; +import com.vaadin.tests.components.AbstractTestRoot; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Root; + +@LoadScripts({ "/statictestfiles/jsextension.js" }) +public class SimpleJavaScriptExtensionTest extends AbstractTestRoot { + + public static class SimpleJavaScriptExtensionState extends SharedState { + private String prefix; + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + public String getPrefix() { + return prefix; + } + } + + public static interface SimpleJavaScriptExtensionClientRpc extends + ClientRpc { + public void greet(String message); + } + + public static interface SimpleJavaScriptExtensionServerRpc extends + ServerRpc { + public void greet(String message); + } + + public static class SimpleJavascriptExtension extends + AbstractJavaScriptExtension { + + public SimpleJavascriptExtension() { + registerRpc(new SimpleJavaScriptExtensionServerRpc() { + public void greet(String message) { + Root.getCurrentRoot().showNotification( + getState().getPrefix() + message); + } + }); + } + + @Override + public SimpleJavaScriptExtensionState getState() { + return (SimpleJavaScriptExtensionState) super.getState(); + } + + public void setPrefix(String prefix) { + getState().setPrefix(prefix); + requestRepaint(); + } + + public void greet(String message) { + getRpcProxy(SimpleJavaScriptExtensionClientRpc.class) + .greet(message); + } + } + + @Override + protected void setup(WrappedRequest request) { + final SimpleJavascriptExtension simpleJavascriptExtension = new SimpleJavascriptExtension(); + simpleJavascriptExtension.setPrefix("Prefix: "); + addExtension(simpleJavascriptExtension); + addComponent(new Button("Send greeting", new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + simpleJavascriptExtension.greet("Greeted by button"); + } + })); + } + + @Override + protected String getTestDescription() { + // TODO Auto-generated method stub + return null; + } + + @Override + protected Integer getTicketNumber() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/tests/testbench/com/vaadin/tests/extensions/SimpleJavascriptExtensionTest.java b/tests/testbench/com/vaadin/tests/extensions/SimpleJavascriptExtensionTest.java deleted file mode 100644 index 92c134efb0..0000000000 --- a/tests/testbench/com/vaadin/tests/extensions/SimpleJavascriptExtensionTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.tests.extensions; - -import com.vaadin.annotations.LoadScripts; -import com.vaadin.terminal.AbstractJavascriptExtension; -import com.vaadin.terminal.WrappedRequest; -import com.vaadin.terminal.gwt.client.communication.ClientRpc; -import com.vaadin.terminal.gwt.client.communication.ServerRpc; -import com.vaadin.terminal.gwt.client.communication.SharedState; -import com.vaadin.tests.components.AbstractTestRoot; -import com.vaadin.ui.Button; -import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.Root; - -@LoadScripts({ "/statictestfiles/jsextension.js" }) -public class SimpleJavascriptExtensionTest extends AbstractTestRoot { - - public static class SimpleJavascriptExtensionState extends SharedState { - private String prefix; - - public void setPrefix(String prefix) { - this.prefix = prefix; - } - - public String getPrefix() { - return prefix; - } - } - - public static interface SimpleJavascriptExtensionClientRpc extends - ClientRpc { - public void greet(String message); - } - - public static interface SimpleJavascriptExtensionServerRpc extends - ServerRpc { - public void greet(String message); - } - - public static class SimpleJavascriptExtension extends - AbstractJavascriptExtension { - - public SimpleJavascriptExtension() { - registerRpc(new SimpleJavascriptExtensionServerRpc() { - public void greet(String message) { - Root.getCurrentRoot().showNotification( - getState().getPrefix() + message); - } - }); - } - - @Override - public SimpleJavascriptExtensionState getState() { - return (SimpleJavascriptExtensionState) super.getState(); - } - - public void setPrefix(String prefix) { - getState().setPrefix(prefix); - requestRepaint(); - } - - public void greet(String message) { - getRpcProxy(SimpleJavascriptExtensionClientRpc.class) - .greet(message); - } - } - - @Override - protected void setup(WrappedRequest request) { - final SimpleJavascriptExtension simpleJavascriptExtension = new SimpleJavascriptExtension(); - simpleJavascriptExtension.setPrefix("Prefix: "); - addExtension(simpleJavascriptExtension); - addComponent(new Button("Send greeting", new Button.ClickListener() { - public void buttonClick(ClickEvent event) { - simpleJavascriptExtension.greet("Greeted by button"); - } - })); - } - - @Override - protected String getTestDescription() { - // TODO Auto-generated method stub - return null; - } - - @Override - protected Integer getTicketNumber() { - // TODO Auto-generated method stub - return null; - } - -} -- cgit v1.2.3 From c93d485613bc17032653f6b938bf43eae4e801dc Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Fri, 15 Jun 2012 14:50:11 +0300 Subject: Remove method accidentally left behind (#6730) --- src/com/vaadin/ui/JavaScript.java | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'src/com/vaadin/ui/JavaScript.java') diff --git a/src/com/vaadin/ui/JavaScript.java b/src/com/vaadin/ui/JavaScript.java index fb1dba2f20..234f37f8a6 100644 --- a/src/com/vaadin/ui/JavaScript.java +++ b/src/com/vaadin/ui/JavaScript.java @@ -10,7 +10,6 @@ import java.util.Map; import com.vaadin.external.json.JSONArray; import com.vaadin.external.json.JSONException; import com.vaadin.terminal.AbstractExtension; -import com.vaadin.terminal.Extension; import com.vaadin.terminal.gwt.client.communication.ServerRpc; import com.vaadin.terminal.gwt.client.extensions.javascriptmanager.ExecuteJavaScriptRpc; import com.vaadin.terminal.gwt.client.extensions.javascriptmanager.JavaScriptManagerState; @@ -65,20 +64,4 @@ public class JavaScript extends AbstractExtension { return Root.getCurrentRoot().getJavaScript(); } - private static JavaScript getJavascript(Root root) { - // TODO Add caching to avoid iterating collection every time - // Caching should use weak references to avoid memory leaks -> cache - // should be transient to avoid serialization problems - for (Extension extension : root.getExtensions()) { - if (extension instanceof JavaScript) { - return (JavaScript) extension; - } - } - - // Extend root if it isn't yet done - JavaScript javascript = new JavaScript(); - javascript.extend(root); - return javascript; - } - } -- cgit v1.2.3 From 26ba3f922fbb01daa35b6f97039335892b896d36 Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Tue, 19 Jun 2012 12:23:33 +0300 Subject: Extract API from Root to Page (#8907) --- src/com/vaadin/navigator/Navigator.java | 25 +- src/com/vaadin/terminal/Page.java | 630 ++++++++++++ .../terminal/gwt/client/ui/root/PageClientRpc.java | 13 + .../terminal/gwt/client/ui/root/RootConnector.java | 10 +- src/com/vaadin/ui/HelloWorldExtension.java | 2 +- src/com/vaadin/ui/JavaScript.java | 7 +- src/com/vaadin/ui/Link.java | 7 +- src/com/vaadin/ui/Notification.java | 115 +++ src/com/vaadin/ui/Root.java | 1046 +++++++------------- .../tests/server/navigator/NavigatorTest.java | 6 +- .../server/navigator/UriFragmentManagerTest.java | 24 +- tests/testbench/com/vaadin/tests/TestBench.java | 6 +- .../vaadin/tests/TestComponentAddAndRecursion.java | 13 +- .../com/vaadin/tests/TestForWindowOpen.java | 6 +- .../com/vaadin/tests/appengine/GAESyncTest.java | 3 +- .../vaadin/tests/components/AbstractTestRoot.java | 2 +- .../vaadin/tests/components/TouchScrollables.java | 3 +- .../components/customfield/AddressFormExample.java | 8 +- .../customfield/BooleanFieldExample.java | 12 +- .../BasicJavaScriptComponent.java | 9 +- .../components/notification/Notifications.java | 4 +- .../notification/NotificationsHtmlAllowed.java | 11 +- .../RichTextAreaWithKeyboardShortcuts.java | 3 +- .../tests/components/root/UriFragmentTest.java | 8 +- .../table/MultiSelectWithNotIdentityEqualIds.java | 4 +- .../tests/components/table/TableContextMenu.java | 3 +- .../table/TableShouldNotEatValueChanges.java | 4 +- .../components/treetable/ProgrammaticCollapse.java | 10 +- .../tests/components/window/LazyWindowResize.java | 4 +- .../window/SubWindowFocusAndBlurListeners.java | 9 +- .../components/window/WindowResizeListener.java | 6 +- .../extensions/SimpleJavaScriptExtensionTest.java | 9 +- .../fieldgroup/AbstractBeanFieldGroupTest.java | 4 +- .../vaadin/tests/fieldgroup/BasicPersonForm.java | 4 +- .../fieldgroup/FieldBinderWithBeanValidation.java | 4 +- .../vaadin/tests/integration/EmbedSizeTest.java | 9 +- .../tests/integration/JSR286PortletRoot.java | 4 +- .../vaadin/tests/integration/LiferayThemeDemo.java | 23 +- .../minitutorials/IntegerTextFieldDataSource.java | 11 +- .../minitutorials/IntegerTextFieldStandalone.java | 12 +- .../tests/minitutorials/StringMyTypeConverter.java | 8 +- .../tests/tickets/Ticket1465ModalNotification.java | 7 +- .../com/vaadin/tests/tickets/Ticket2998.java | 4 +- .../com/vaadin/tests/tickets/Ticket34.java | 8 +- .../testbench/com/vaadin/tests/util/TestUtils.java | 2 +- 45 files changed, 1253 insertions(+), 869 deletions(-) create mode 100644 src/com/vaadin/terminal/Page.java create mode 100644 src/com/vaadin/terminal/gwt/client/ui/root/PageClientRpc.java (limited to 'src/com/vaadin/ui/JavaScript.java') diff --git a/src/com/vaadin/navigator/Navigator.java b/src/com/vaadin/navigator/Navigator.java index 9d9acf9ed3..387f1d4eae 100644 --- a/src/com/vaadin/navigator/Navigator.java +++ b/src/com/vaadin/navigator/Navigator.java @@ -10,12 +10,13 @@ import java.util.LinkedList; import java.util.List; import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; +import com.vaadin.terminal.Page; +import com.vaadin.terminal.Page.FragmentChangedEvent; +import com.vaadin.terminal.Page.FragmentChangedListener; import com.vaadin.ui.Component; import com.vaadin.ui.CssLayout; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.Root; -import com.vaadin.ui.Root.FragmentChangedEvent; -import com.vaadin.ui.Root.FragmentChangedListener; /** * Navigator utility that allows switching of views in a part of an application. @@ -67,7 +68,7 @@ public class Navigator implements Serializable { */ public static class UriFragmentManager implements FragmentManager, FragmentChangedListener { - private final Root root; + private final Page page; private final Navigator navigator; /** @@ -80,20 +81,20 @@ public class Navigator implements Serializable { * {@link Navigator} to notify of fragment changes (using * {@link Navigator#navigateTo(String)} */ - public UriFragmentManager(Root root, Navigator navigator) { - this.root = root; + public UriFragmentManager(Page page, Navigator navigator) { + this.page = page; this.navigator = navigator; - root.addListener(this); + page.addListener(this); } public String getFragment() { - return root.getFragment(); + return page.getFragment(); } public void setFragment(String fragment) { // TODO ", false" ??? - root.setFragment(fragment); + page.setFragment(fragment); } public void fragmentChanged(FragmentChangedEvent event) { @@ -276,9 +277,9 @@ public class Navigator implements Serializable { * @param display * where to display the views */ - public Navigator(Root root, ViewDisplay display) { + public Navigator(Page page, ViewDisplay display) { this.display = display; - fragmentManager = new UriFragmentManager(root, this); + fragmentManager = new UriFragmentManager(page, this); } /** @@ -289,9 +290,9 @@ public class Navigator implements Serializable { * @param root * whose URI fragments are used */ - public Navigator(Root root) { + public Navigator(Page page) { display = new SimpleViewDisplay(); - fragmentManager = new UriFragmentManager(root, this); + fragmentManager = new UriFragmentManager(page, this); } /** diff --git a/src/com/vaadin/terminal/Page.java b/src/com/vaadin/terminal/Page.java new file mode 100644 index 0000000000..65fa500d27 --- /dev/null +++ b/src/com/vaadin/terminal/Page.java @@ -0,0 +1,630 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal; + +import java.io.Serializable; +import java.lang.reflect.Method; +import java.util.EventObject; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import com.vaadin.event.EventRouter; +import com.vaadin.terminal.WrappedRequest.BrowserDetails; +import com.vaadin.terminal.gwt.client.ui.notification.VNotification; +import com.vaadin.terminal.gwt.client.ui.root.PageClientRpc; +import com.vaadin.terminal.gwt.client.ui.root.VRoot; +import com.vaadin.terminal.gwt.server.WebApplicationContext; +import com.vaadin.terminal.gwt.server.WebBrowser; +import com.vaadin.tools.ReflectTools; +import com.vaadin.ui.JavaScript; +import com.vaadin.ui.Notification; +import com.vaadin.ui.Root; + +public class Page implements Serializable { + + /** + * Listener that gets notified when the size of the browser window + * containing the root has changed. + * + * @see Root#addListener(BrowserWindowResizeListener) + */ + public interface BrowserWindowResizeListener extends Serializable { + /** + * Invoked when the browser window containing a Root has been resized. + * + * @param event + * a browser window resize event + */ + public void browserWindowResized(BrowserWindowResizeEvent event); + } + + /** + * Event that is fired when a browser window containing a root is resized. + */ + public class BrowserWindowResizeEvent extends EventObject { + + private final int width; + private final int height; + + /** + * Creates a new event + * + * @param source + * the root for which the browser window has been resized + * @param width + * the new width of the browser window + * @param height + * the new height of the browser window + */ + public BrowserWindowResizeEvent(Page source, int width, int height) { + super(source); + this.width = width; + this.height = height; + } + + @Override + public Page getSource() { + return (Page) super.getSource(); + } + + /** + * Gets the new browser window height + * + * @return an integer with the new pixel height of the browser window + */ + public int getHeight() { + return height; + } + + /** + * Gets the new browser window width + * + * @return an integer with the new pixel width of the browser window + */ + public int getWidth() { + return width; + } + } + + /** + * Private class for storing properties related to opening resources. + */ + private class OpenResource implements Serializable { + + /** + * The resource to open + */ + private final Resource resource; + + /** + * The name of the target window + */ + private final String name; + + /** + * The width of the target window + */ + private final int width; + + /** + * The height of the target window + */ + private final int height; + + /** + * The border style of the target window + */ + private final int border; + + /** + * Creates a new open resource. + * + * @param resource + * The resource to open + * @param name + * The name of the target window + * @param width + * The width of the target window + * @param height + * The height of the target window + * @param border + * The border style of the target window + */ + private OpenResource(Resource resource, String name, int width, + int height, int border) { + this.resource = resource; + this.name = name; + this.width = width; + this.height = height; + this.border = border; + } + + /** + * Paints the open request. Should be painted inside the window. + * + * @param target + * the paint target + * @throws PaintException + * if the paint operation fails + */ + private void paintContent(PaintTarget target) throws PaintException { + target.startTag("open"); + target.addAttribute("src", resource); + if (name != null && name.length() > 0) { + target.addAttribute("name", name); + } + if (width >= 0) { + target.addAttribute("width", width); + } + if (height >= 0) { + target.addAttribute("height", height); + } + switch (border) { + case BORDER_MINIMAL: + target.addAttribute("border", "minimal"); + break; + case BORDER_NONE: + target.addAttribute("border", "none"); + break; + } + + target.endTag("open"); + } + } + + private static final Method BROWSWER_RESIZE_METHOD = ReflectTools + .findMethod(BrowserWindowResizeListener.class, + "browserWindowResized", BrowserWindowResizeEvent.class); + + /** + * A border style used for opening resources in a window without a border. + */ + public static final int BORDER_NONE = 0; + + /** + * A border style used for opening resources in a window with a minimal + * border. + */ + public static final int BORDER_MINIMAL = 1; + + /** + * A border style that indicates that the default border style should be + * used when opening resources. + */ + public static final int BORDER_DEFAULT = 2; + + /** + * Listener that listens changes in URI fragment. + */ + public interface FragmentChangedListener extends Serializable { + public void fragmentChanged(FragmentChangedEvent event); + } + + private static final Method FRAGMENT_CHANGED_METHOD = ReflectTools + .findMethod(Page.FragmentChangedListener.class, "fragmentChanged", + FragmentChangedEvent.class); + + /** + * Resources to be opened automatically on next repaint. The list is + * automatically cleared when it has been sent to the client. + */ + private final LinkedList openList = new LinkedList(); + + /** + * A list of notifications that are waiting to be sent to the client. + * Cleared (set to null) when the notifications have been sent. + */ + private List notifications; + + /** + * Event fired when uri fragment changes. + */ + public class FragmentChangedEvent extends EventObject { + + /** + * The new uri fragment + */ + private final String fragment; + + /** + * Creates a new instance of UriFragmentReader change event. + * + * @param source + * the Source of the event. + */ + public FragmentChangedEvent(Page source, String fragment) { + super(source); + this.fragment = fragment; + } + + /** + * Gets the root in which the fragment has changed. + * + * @return the root in which the fragment has changed + */ + public Page getPage() { + return (Page) getSource(); + } + + /** + * Get the new fragment + * + * @return the new fragment + */ + public String getFragment() { + return fragment; + } + } + + private EventRouter eventRouter; + + /** + * The current URI fragment. + */ + private String fragment; + + private final Root root; + + private int browserWindowWidth = -1; + private int browserWindowHeight = -1; + + private JavaScript javaScript; + + public Page(Root root) { + this.root = root; + } + + private void addListener(Class eventType, Object target, Method method) { + if (eventRouter == null) { + eventRouter = new EventRouter(); + } + eventRouter.addListener(eventType, target, method); + } + + private void removeListener(Class eventType, Object target, Method method) { + if (eventRouter != null) { + eventRouter.removeListener(eventType, target, method); + } + } + + public void addListener(Page.FragmentChangedListener listener) { + addListener(FragmentChangedEvent.class, listener, + FRAGMENT_CHANGED_METHOD); + } + + public void removeListener(Page.FragmentChangedListener listener) { + removeListener(FragmentChangedEvent.class, listener, + FRAGMENT_CHANGED_METHOD); + } + + /** + * Sets URI fragment. Optionally fires a {@link FragmentChangedEvent} + * + * @param newFragment + * id of the new fragment + * @param fireEvent + * true to fire event + * @see FragmentChangedEvent + * @see Page.FragmentChangedListener + */ + public void setFragment(String newFragment, boolean fireEvents) { + if (newFragment == null) { + throw new NullPointerException("The fragment may not be null"); + } + if (!newFragment.equals(fragment)) { + fragment = newFragment; + if (fireEvents) { + fireEvent(new FragmentChangedEvent(this, newFragment)); + } + root.requestRepaint(); + } + } + + private void fireEvent(EventObject event) { + if (eventRouter != null) { + eventRouter.fireEvent(event); + } + } + + /** + * Sets URI fragment. This method fires a {@link FragmentChangedEvent} + * + * @param newFragment + * id of the new fragment + * @see FragmentChangedEvent + * @see Page.FragmentChangedListener + */ + public void setFragment(String newFragment) { + setFragment(newFragment, true); + } + + /** + * Gets currently set URI fragment. + *

+ * To listen changes in fragment, hook a + * {@link Page.FragmentChangedListener}. + * + * @return the current fragment in browser uri or null if not known + */ + public String getFragment() { + return fragment; + } + + public void init(WrappedRequest request) { + BrowserDetails browserDetails = request.getBrowserDetails(); + if (browserDetails != null) { + fragment = browserDetails.getUriFragment(); + } + } + + public WebBrowser getWebBrowser() { + return ((WebApplicationContext) root.getApplication().getContext()) + .getBrowser(); + } + + public void setBrowserWindowSize(Integer width, Integer height) { + boolean fireEvent = false; + + if (width != null) { + int newWidth = width.intValue(); + if (newWidth != browserWindowWidth) { + browserWindowWidth = newWidth; + fireEvent = true; + } + } + + if (height != null) { + int newHeight = height.intValue(); + if (newHeight != browserWindowHeight) { + browserWindowHeight = newHeight; + fireEvent = true; + } + } + + if (fireEvent) { + fireEvent(new BrowserWindowResizeEvent(this, browserWindowWidth, + browserWindowHeight)); + } + + } + + /** + * Adds a new {@link BrowserWindowResizeListener} to this root. The listener + * will be notified whenever the browser window within which this root + * resides is resized. + * + * @param resizeListener + * the listener to add + * + * @see BrowserWindowResizeListener#browserWindowResized(BrowserWindowResizeEvent) + * @see #setResizeLazy(boolean) + */ + public void addListener(BrowserWindowResizeListener resizeListener) { + addListener(BrowserWindowResizeEvent.class, resizeListener, + BROWSWER_RESIZE_METHOD); + } + + /** + * Removes a {@link BrowserWindowResizeListener} from this root. The + * listener will no longer be notified when the browser window is resized. + * + * @param resizeListener + * the listener to remove + */ + public void removeListener(BrowserWindowResizeListener resizeListener) { + removeListener(BrowserWindowResizeEvent.class, resizeListener, + BROWSWER_RESIZE_METHOD); + } + + /** + * Gets the last known height of the browser window in which this root + * resides. + * + * @return the browser window height in pixels + */ + public int getBrowserWindowHeight() { + return browserWindowHeight; + } + + /** + * Gets the last known width of the browser window in which this root + * resides. + * + * @return the browser window width in pixels + */ + public int getBrowserWindowWidth() { + return browserWindowWidth; + } + + public JavaScript getJavaScript() { + if (javaScript == null) { + // Create and attach on first use + javaScript = new JavaScript(); + javaScript.extend(root); + } + + return javaScript; + } + + public void paintContent(PaintTarget target) throws PaintException { + if (!openList.isEmpty()) { + for (final Iterator i = openList.iterator(); i + .hasNext();) { + (i.next()).paintContent(target); + } + openList.clear(); + } + + // Paint notifications + if (notifications != null) { + target.startTag("notifications"); + for (final Iterator it = notifications.iterator(); it + .hasNext();) { + final Notification n = it.next(); + target.startTag("notification"); + if (n.getCaption() != null) { + target.addAttribute( + VNotification.ATTRIBUTE_NOTIFICATION_CAPTION, + n.getCaption()); + } + if (n.getDescription() != null) { + target.addAttribute( + VNotification.ATTRIBUTE_NOTIFICATION_MESSAGE, + n.getDescription()); + } + if (n.getIcon() != null) { + target.addAttribute( + VNotification.ATTRIBUTE_NOTIFICATION_ICON, + n.getIcon()); + } + if (!n.isHtmlContentAllowed()) { + target.addAttribute( + VRoot.NOTIFICATION_HTML_CONTENT_NOT_ALLOWED, true); + } + target.addAttribute( + VNotification.ATTRIBUTE_NOTIFICATION_POSITION, + n.getPosition()); + target.addAttribute(VNotification.ATTRIBUTE_NOTIFICATION_DELAY, + n.getDelayMsec()); + if (n.getStyleName() != null) { + target.addAttribute( + VNotification.ATTRIBUTE_NOTIFICATION_STYLE, + n.getStyleName()); + } + target.endTag("notification"); + } + target.endTag("notifications"); + notifications = null; + } + + if (fragment != null) { + target.addAttribute(VRoot.FRAGMENT_VARIABLE, fragment); + } + + } + + /** + * Opens the given resource in this root. The contents of this Root is + * replaced by the {@code Resource}. + * + * @param resource + * the resource to show in this root + */ + public void open(Resource resource) { + openList.add(new OpenResource(resource, null, -1, -1, BORDER_DEFAULT)); + root.requestRepaint(); + } + + /** + * Opens the given resource in a window with the given name. + *

+ * The supplied {@code windowName} is used as the target name in a + * window.open call in the client. This means that special values such as + * "_blank", "_self", "_top", "_parent" have special meaning. An empty or + * null window name is also a special case. + *

+ *

+ * "", null and "_self" as {@code windowName} all causes the resource to be + * opened in the current window, replacing any old contents. For + * downloadable content you should avoid "_self" as "_self" causes the + * client to skip rendering of any other changes as it considers them + * irrelevant (the page will be replaced by the resource). This can speed up + * the opening of a resource, but it might also put the client side into an + * inconsistent state if the window content is not completely replaced e.g., + * if the resource is downloaded instead of displayed in the browser. + *

+ *

+ * "_blank" as {@code windowName} causes the resource to always be opened in + * a new window or tab (depends on the browser and browser settings). + *

+ *

+ * "_top" and "_parent" as {@code windowName} works as specified by the HTML + * standard. + *

+ *

+ * Any other {@code windowName} will open the resource in a window with that + * name, either by opening a new window/tab in the browser or by replacing + * the contents of an existing window with that name. + *

+ * + * @param resource + * the resource. + * @param windowName + * the name of the window. + */ + public void open(Resource resource, String windowName) { + openList.add(new OpenResource(resource, windowName, -1, -1, + BORDER_DEFAULT)); + root.requestRepaint(); + } + + /** + * Opens the given resource in a window with the given size, border and + * name. For more information on the meaning of {@code windowName}, see + * {@link #open(Resource, String)}. + * + * @param resource + * the resource. + * @param windowName + * the name of the window. + * @param width + * the width of the window in pixels + * @param height + * the height of the window in pixels + * @param border + * the border style of the window. See {@link #BORDER_NONE + * Window.BORDER_* constants} + */ + public void open(Resource resource, String windowName, int width, + int height, int border) { + openList.add(new OpenResource(resource, windowName, width, height, + border)); + root.requestRepaint(); + } + + /** + * Internal helper method to actually add a notification. + * + * @param notification + * the notification to add + */ + private void addNotification(Notification notification) { + if (notifications == null) { + notifications = new LinkedList(); + } + notifications.add(notification); + root.requestRepaint(); + } + + /** + * Shows a notification message. + * + * @see Notification + * @see #showNotification(String) + * @see #showNotification(String, int) + * @see #showNotification(String, String) + * @see #showNotification(String, String, int) + * + * @param notification + * The notification message to show + */ + public void showNotification(Notification notification) { + addNotification(notification); + } + + public static Page getCurrent() { + Root currentRoot = Root.getCurrentRoot(); + if (currentRoot == null) { + return null; + } + return currentRoot.getPage(); + } + + public void setTitle(String title) { + root.getRpcProxy(PageClientRpc.class).setTitle(title); + } + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/root/PageClientRpc.java b/src/com/vaadin/terminal/gwt/client/ui/root/PageClientRpc.java new file mode 100644 index 0000000000..a02ecc8ded --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/root/PageClientRpc.java @@ -0,0 +1,13 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client.ui.root; + +import com.vaadin.terminal.gwt.client.communication.ClientRpc; + +public interface PageClientRpc extends ClientRpc { + + public void setTitle(String title); + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java b/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java index eebbe971a4..5184f38ed9 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java @@ -61,6 +61,11 @@ public class RootConnector extends AbstractComponentContainerConnector @Override protected void init() { super.init(); + registerRpc(PageClientRpc.class, new PageClientRpc() { + public void setTitle(String title) { + com.google.gwt.user.client.Window.setTitle(title); + } + }); } public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) { @@ -95,11 +100,6 @@ public class RootConnector extends AbstractComponentContainerConnector clickEventHandler.handleEventHandlerRegistration(); - if (!getWidget().isEmbedded() && getState().getCaption() != null) { - // only change window title if we're in charge of the whole page - com.google.gwt.user.client.Window.setTitle(getState().getCaption()); - } - // Process children int childIndex = 0; diff --git a/src/com/vaadin/ui/HelloWorldExtension.java b/src/com/vaadin/ui/HelloWorldExtension.java index 6d9ce9bcf1..e705954f2e 100644 --- a/src/com/vaadin/ui/HelloWorldExtension.java +++ b/src/com/vaadin/ui/HelloWorldExtension.java @@ -13,7 +13,7 @@ public class HelloWorldExtension extends AbstractExtension { public HelloWorldExtension() { registerRpc(new HelloWorldRpc() { public void onMessageSent(String message) { - getRoot().showNotification(message); + Notification.show(message); } }); } diff --git a/src/com/vaadin/ui/JavaScript.java b/src/com/vaadin/ui/JavaScript.java index 234f37f8a6..241d477506 100644 --- a/src/com/vaadin/ui/JavaScript.java +++ b/src/com/vaadin/ui/JavaScript.java @@ -10,6 +10,7 @@ import java.util.Map; import com.vaadin.external.json.JSONArray; import com.vaadin.external.json.JSONException; import com.vaadin.terminal.AbstractExtension; +import com.vaadin.terminal.Page; import com.vaadin.terminal.gwt.client.communication.ServerRpc; import com.vaadin.terminal.gwt.client.extensions.javascriptmanager.ExecuteJavaScriptRpc; import com.vaadin.terminal.gwt.client.extensions.javascriptmanager.JavaScriptManagerState; @@ -61,7 +62,11 @@ public class JavaScript extends AbstractExtension { } public static JavaScript getCurrent() { - return Root.getCurrentRoot().getJavaScript(); + Page page = Page.getCurrent(); + if (page == null) { + return null; + } + return page.getJavaScript(); } } diff --git a/src/com/vaadin/ui/Link.java b/src/com/vaadin/ui/Link.java index ed5ffbba3a..db0dc58e6b 100644 --- a/src/com/vaadin/ui/Link.java +++ b/src/com/vaadin/ui/Link.java @@ -6,6 +6,7 @@ package com.vaadin.ui; import java.util.Map; +import com.vaadin.terminal.Page; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; import com.vaadin.terminal.Resource; @@ -23,13 +24,13 @@ import com.vaadin.terminal.Vaadin6Component; public class Link extends AbstractComponent implements Vaadin6Component { /* Target window border type constant: No window border */ - public static final int TARGET_BORDER_NONE = Root.BORDER_NONE; + public static final int TARGET_BORDER_NONE = Page.BORDER_NONE; /* Target window border type constant: Minimal window border */ - public static final int TARGET_BORDER_MINIMAL = Root.BORDER_MINIMAL; + public static final int TARGET_BORDER_MINIMAL = Page.BORDER_MINIMAL; /* Target window border type constant: Default window border */ - public static final int TARGET_BORDER_DEFAULT = Root.BORDER_DEFAULT; + public static final int TARGET_BORDER_DEFAULT = Page.BORDER_DEFAULT; private Resource resource = null; diff --git a/src/com/vaadin/ui/Notification.java b/src/com/vaadin/ui/Notification.java index bb1f874635..075ab50196 100644 --- a/src/com/vaadin/ui/Notification.java +++ b/src/com/vaadin/ui/Notification.java @@ -6,6 +6,7 @@ package com.vaadin.ui; import java.io.Serializable; +import com.vaadin.terminal.Page; import com.vaadin.terminal.Resource; /** @@ -318,4 +319,118 @@ public class Notification implements Serializable { public boolean isHtmlContentAllowed() { return htmlContentAllowed; } + + public void show() { + Page.getCurrent().showNotification(this); + } + + /** + * Shows a notification message on the middle of the current page. The + * message automatically disappears ("humanized message"). + * + * Care should be taken to to avoid XSS vulnerabilities as the caption is + * rendered as html. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The message + */ + public static void show(String caption) { + new Notification(caption).show(); + } + + /** + * Shows a notification message the current page. The position and behavior + * of the message depends on the type, which is one of the basic types + * defined in {@link Notification}, for instance + * Notification.TYPE_WARNING_MESSAGE. + * + * Care should be taken to to avoid XSS vulnerabilities as the caption is + * rendered as html. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The message + * @param type + * The message type + */ + public static void show(String caption, int type) { + new Notification(caption, type).show(); + } + + /** + * Shows a notification consisting of a bigger caption and a smaller + * description on the middle of the current page. The message automatically + * disappears ("humanized message"). + * + * Care should be taken to to avoid XSS vulnerabilities as the caption and + * description are rendered as html. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The caption of the message + * @param description + * The message description + * + */ + public static void show(String caption, String description) { + new Notification(caption, description).show(); + } + + /** + * Shows a notification consisting of a bigger caption and a smaller + * description. The position and behavior of the message depends on the + * type, which is one of the basic types defined in {@link Notification}, + * for instance Notification.TYPE_WARNING_MESSAGE. + * + * Care should be taken to to avoid XSS vulnerabilities as the caption and + * description are rendered as html. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The caption of the message + * @param description + * The message description + * @param type + * The message type + */ + public static void show(String caption, String description, int type) { + + new Notification(caption, description, type).show(); + } + + /** + * Shows a notification consisting of a bigger caption and a smaller + * description. The position and behavior of the message depends on the + * type, which is one of the basic types defined in {@link Notification}, + * for instance Notification.TYPE_WARNING_MESSAGE. + * + * Care should be taken to avoid XSS vulnerabilities if html content is + * allowed. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The message caption + * @param description + * The message description + * @param type + * The type of message + * @param htmlContentAllowed + * Whether html in the caption and description should be + * displayed as html or as plain text + */ + public static void show(String caption, String description, int type, + boolean htmlContentAllowed) { + new Notification(caption, description, type, htmlContentAllowed).show(); + } } \ No newline at end of file diff --git a/src/com/vaadin/ui/Root.java b/src/com/vaadin/ui/Root.java index 60408fe1dc..50ad99571e 100644 --- a/src/com/vaadin/ui/Root.java +++ b/src/com/vaadin/ui/Root.java @@ -4,8 +4,6 @@ package com.vaadin.ui; -import java.io.Serializable; -import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; @@ -13,8 +11,6 @@ import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; import java.util.Map; import com.vaadin.Application; @@ -24,6 +20,9 @@ import com.vaadin.event.Action.Handler; import com.vaadin.event.ActionManager; import com.vaadin.event.MouseEvents.ClickEvent; import com.vaadin.event.MouseEvents.ClickListener; +import com.vaadin.terminal.Page; +import com.vaadin.terminal.Page.BrowserWindowResizeEvent; +import com.vaadin.terminal.Page.BrowserWindowResizeListener; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; import com.vaadin.terminal.Resource; @@ -31,11 +30,9 @@ import com.vaadin.terminal.Vaadin6Component; import com.vaadin.terminal.WrappedRequest; import com.vaadin.terminal.WrappedRequest.BrowserDetails; import com.vaadin.terminal.gwt.client.MouseEventDetails; -import com.vaadin.terminal.gwt.client.ui.notification.VNotification; import com.vaadin.terminal.gwt.client.ui.root.RootServerRpc; import com.vaadin.terminal.gwt.client.ui.root.RootState; import com.vaadin.terminal.gwt.client.ui.root.VRoot; -import com.vaadin.tools.ReflectTools; import com.vaadin.ui.Window.CloseListener; /** @@ -78,121 +75,6 @@ import com.vaadin.ui.Window.CloseListener; public abstract class Root extends AbstractComponentContainer implements Action.Container, Action.Notifier, Vaadin6Component { - /** - * Listener that gets notified when the size of the browser window - * containing the root has changed. - * - * @see Root#addListener(BrowserWindowResizeListener) - */ - public interface BrowserWindowResizeListener extends Serializable { - /** - * Invoked when the browser window containing a Root has been resized. - * - * @param event - * a browser window resize event - */ - public void browserWindowResized(BrowserWindowResizeEvent event); - } - - /** - * Event that is fired when a browser window containing a root is resized. - */ - public class BrowserWindowResizeEvent extends Component.Event { - - private final int width; - private final int height; - - /** - * Creates a new event - * - * @param source - * the root for which the browser window has been resized - * @param width - * the new width of the browser window - * @param height - * the new height of the browser window - */ - public BrowserWindowResizeEvent(Root source, int width, int height) { - super(source); - this.width = width; - this.height = height; - } - - @Override - public Root getSource() { - return (Root) super.getSource(); - } - - /** - * Gets the new browser window height - * - * @return an integer with the new pixel height of the browser window - */ - public int getHeight() { - return height; - } - - /** - * Gets the new browser window width - * - * @return an integer with the new pixel width of the browser window - */ - public int getWidth() { - return width; - } - } - - private static final Method BROWSWER_RESIZE_METHOD = ReflectTools - .findMethod(BrowserWindowResizeListener.class, - "browserWindowResized", BrowserWindowResizeEvent.class); - - /** - * Listener that listens changes in URI fragment. - */ - public interface FragmentChangedListener extends Serializable { - public void fragmentChanged(FragmentChangedEvent event); - } - - /** - * Event fired when uri fragment changes. - */ - public class FragmentChangedEvent extends Component.Event { - - /** - * The new uri fragment - */ - private final String fragment; - - /** - * Creates a new instance of UriFragmentReader change event. - * - * @param source - * the Source of the event. - */ - public FragmentChangedEvent(Root source, String fragment) { - super(source); - this.fragment = fragment; - } - - /** - * Gets the root in which the fragment has changed. - * - * @return the root in which the fragment has changed - */ - public Root getRoot() { - return (Root) getComponent(); - } - - /** - * Get the new fragment - * - * @return the new fragment - */ - public String getFragment() { - return fragment; - } - } - /** * Helper class to emulate the main window from Vaadin 6 using roots. This * class should be used in the same way as Window used as a browser level @@ -312,61 +194,343 @@ public abstract class Root extends AbstractComponentContainer implements "Internal problem getting window URL, please report"); } } - } - private static final Method FRAGMENT_CHANGED_METHOD; - - static { - try { - FRAGMENT_CHANGED_METHOD = FragmentChangedListener.class - .getDeclaredMethod("fragmentChanged", - new Class[] { FragmentChangedEvent.class }); - } catch (final java.lang.NoSuchMethodException e) { - // This should never happen - throw new java.lang.RuntimeException( - "Internal error finding methods in FragmentChangedListener"); + /** + * Opens the given resource in this root. The contents of this Root is + * replaced by the {@code Resource}. + * + * @param resource + * the resource to show in this root + * + * @deprecated As of 7.0, use getPage().open instead + */ + @Deprecated + public void open(Resource resource) { + getPage().open(resource); } - } - /** - * A border style used for opening resources in a window without a border. - */ - public static final int BORDER_NONE = 0; + /* ********************************************************************* */ - /** - * A border style used for opening resources in a window with a minimal - * border. - */ - public static final int BORDER_MINIMAL = 1; + /** + * Opens the given resource in a window with the given name. + *

+ * The supplied {@code windowName} is used as the target name in a + * window.open call in the client. This means that special values such + * as "_blank", "_self", "_top", "_parent" have special meaning. An + * empty or null window name is also a special case. + *

+ *

+ * "", null and "_self" as {@code windowName} all causes the resource to + * be opened in the current window, replacing any old contents. For + * downloadable content you should avoid "_self" as "_self" causes the + * client to skip rendering of any other changes as it considers them + * irrelevant (the page will be replaced by the resource). This can + * speed up the opening of a resource, but it might also put the client + * side into an inconsistent state if the window content is not + * completely replaced e.g., if the resource is downloaded instead of + * displayed in the browser. + *

+ *

+ * "_blank" as {@code windowName} causes the resource to always be + * opened in a new window or tab (depends on the browser and browser + * settings). + *

+ *

+ * "_top" and "_parent" as {@code windowName} works as specified by the + * HTML standard. + *

+ *

+ * Any other {@code windowName} will open the resource in a window with + * that name, either by opening a new window/tab in the browser or by + * replacing the contents of an existing window with that name. + *

+ * + * @param resource + * the resource. + * @param windowName + * the name of the window. + * @deprecated As of 7.0, use getPage().open instead + */ + @Deprecated + public void open(Resource resource, String windowName) { + getPage().open(resource, windowName); + } - /** - * A border style that indicates that the default border style should be - * used when opening resources. - */ - public static final int BORDER_DEFAULT = 2; + /** + * Opens the given resource in a window with the given size, border and + * name. For more information on the meaning of {@code windowName}, see + * {@link #open(Resource, String)}. + * + * @param resource + * the resource. + * @param windowName + * the name of the window. + * @param width + * the width of the window in pixels + * @param height + * the height of the window in pixels + * @param border + * the border style of the window. See {@link #BORDER_NONE + * Window.BORDER_* constants} + * @deprecated As of 7.0, use getPage().open instead + */ + @Deprecated + public void open(Resource resource, String windowName, int width, + int height, int border) { + getPage().open(resource, windowName, width, height, border); + } + + /** + * Adds a new {@link BrowserWindowResizeListener} to this root. The + * listener will be notified whenever the browser window within which + * this root resides is resized. + * + * @param resizeListener + * the listener to add + * + * @see BrowserWindowResizeListener#browserWindowResized(BrowserWindowResizeEvent) + * @see #setResizeLazy(boolean) + * + * @deprecated As of 7.0, use the similarly named api in Page instead + */ + @Deprecated + public void addListener(BrowserWindowResizeListener resizeListener) { + getPage().addListener(resizeListener); + } + + /** + * Removes a {@link BrowserWindowResizeListener} from this root. The + * listener will no longer be notified when the browser window is + * resized. + * + * @param resizeListener + * the listener to remove + * @deprecated As of 7.0, use the similarly named api in Page instead + */ + @Deprecated + public void removeListener(BrowserWindowResizeListener resizeListener) { + getPage().removeListener(resizeListener); + } + + /** + * Gets the last known height of the browser window in which this root + * resides. + * + * @return the browser window height in pixels + * @deprecated As of 7.0, use the similarly named api in Page instead + */ + @Deprecated + public int getBrowserWindowHeight() { + return getPage().getBrowserWindowHeight(); + } + + /** + * Gets the last known width of the browser window in which this root + * resides. + * + * @return the browser window width in pixels + * + * @deprecated As of 7.0, use the similarly named api in Page instead + */ + @Deprecated + public int getBrowserWindowWidth() { + return getPage().getBrowserWindowWidth(); + } + + /** + * Shows a notification message on the middle of the root. The message + * automatically disappears ("humanized message"). + * + * Care should be taken to to avoid XSS vulnerabilities as the caption + * is rendered as html. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The message + * + * @deprecated As of 7.0, use Notification.show instead + */ + @Deprecated + public void showNotification(String caption) { + getPage().showNotification(new Notification(caption)); + } + + /** + * Shows a notification message the root. The position and behavior of + * the message depends on the type, which is one of the basic types + * defined in {@link Notification}, for instance + * Notification.TYPE_WARNING_MESSAGE. + * + * Care should be taken to to avoid XSS vulnerabilities as the caption + * is rendered as html. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The message + * @param type + * The message type + * + * @deprecated As of 7.0, use Notification.show instead + */ + @Deprecated + public void showNotification(String caption, int type) { + getPage().showNotification(new Notification(caption, type)); + } + + /** + * Shows a notification consisting of a bigger caption and a smaller + * description on the middle of the root. The message automatically + * disappears ("humanized message"). + * + * Care should be taken to to avoid XSS vulnerabilities as the caption + * and description are rendered as html. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The caption of the message + * @param description + * The message description + * + * @deprecated As of 7.0, use Notification.show instead + */ + @Deprecated + public void showNotification(String caption, String description) { + getPage().showNotification(new Notification(caption, description)); + } + + /** + * Shows a notification consisting of a bigger caption and a smaller + * description. The position and behavior of the message depends on the + * type, which is one of the basic types defined in {@link Notification} + * , for instance Notification.TYPE_WARNING_MESSAGE. + * + * Care should be taken to to avoid XSS vulnerabilities as the caption + * and description are rendered as html. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The caption of the message + * @param description + * The message description + * @param type + * The message type + * + * @deprecated As of 7.0, use Notification.show instead + */ + @Deprecated + public void showNotification(String caption, String description, + int type) { + getPage().showNotification( + new Notification(caption, description, type)); + } + + /** + * Shows a notification consisting of a bigger caption and a smaller + * description. The position and behavior of the message depends on the + * type, which is one of the basic types defined in {@link Notification} + * , for instance Notification.TYPE_WARNING_MESSAGE. + * + * Care should be taken to avoid XSS vulnerabilities if html content is + * allowed. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The message caption + * @param description + * The message description + * @param type + * The type of message + * @param htmlContentAllowed + * Whether html in the caption and description should be + * displayed as html or as plain text + * + * @deprecated As of 7.0, use Notification.show instead + */ + @Deprecated + public void showNotification(String caption, String description, + int type, boolean htmlContentAllowed) { + getPage().showNotification( + new Notification(caption, description, type, + htmlContentAllowed)); + } + + /** + * Shows a notification message. + * + * @see Notification + * @see #showNotification(String) + * @see #showNotification(String, int) + * @see #showNotification(String, String) + * @see #showNotification(String, String, int) + * + * @param notification + * The notification message to show + * + * @deprecated As of 7.0, use Notification.show instead + */ + @Deprecated + public void showNotification(Notification notification) { + getPage().showNotification(notification); + } + + /** + * Executes JavaScript in this window. + * + *

+ * This method allows one to inject javascript from the server to + * client. A client implementation is not required to implement this + * functionality, but currently all web-based clients do implement this. + *

+ * + *

+ * Executing javascript this way often leads to cross-browser + * compatibility issues and regressions that are hard to resolve. Use of + * this method should be avoided and instead it is recommended to create + * new widgets with GWT. For more info on creating own, reusable + * client-side widgets in Java, read the corresponding chapter in Book + * of Vaadin. + *

+ * + * @param script + * JavaScript snippet that will be executed. + * + * @deprecated as of 7.0, use JavaScript.getCurrent().execute(String) + * instead + */ + @Deprecated + public void executeJavaScript(String script) { + getPage().getJavaScript().execute(script); + } + + @Override + public void setCaption(String caption) { + // Override to provide backwards compatibility + getState().setCaption(caption); + getPage().setTitle(caption); + } + + } /** * The application to which this root belongs */ private Application application; - /** - * A list of notifications that are waiting to be sent to the client. - * Cleared (set to null) when the notifications have been sent. - */ - private List notifications; - /** * List of windows in this root. */ private final LinkedHashSet windows = new LinkedHashSet(); - /** - * Resources to be opened automatically on next repaint. The list is - * automatically cleared when it has been sent to the client. - */ - private final LinkedList openList = new LinkedList(); - /** * The component that should be scrolled into view after the next repaint. * Null if nothing should be scrolled into view. @@ -393,16 +557,13 @@ public abstract class Root extends AbstractComponentContainer implements */ private static final ThreadLocal currentRoot = new ThreadLocal(); - private int browserWindowWidth = -1; - private int browserWindowHeight = -1; - /** Identifies the click event */ private static final String CLICK_EVENT_ID = VRoot.CLICK_EVENT_ID; private DirtyConnectorTracker dirtyConnectorTracker = new DirtyConnectorTracker( this); - private JavaScript javaScript; + private Page page = new Page(this); private RootServerRpc rpc = new RootServerRpc() { public void click(MouseEventDetails mouseDetails) { @@ -498,58 +659,7 @@ public abstract class Root extends AbstractComponentContainer implements } public void paintContent(PaintTarget target) throws PaintException { - // Open requested resource - synchronized (openList) { - if (!openList.isEmpty()) { - for (final Iterator i = openList.iterator(); i - .hasNext();) { - (i.next()).paintContent(target); - } - openList.clear(); - } - } - - // Paint notifications - if (notifications != null) { - target.startTag("notifications"); - for (final Iterator it = notifications.iterator(); it - .hasNext();) { - final Notification n = it.next(); - target.startTag("notification"); - if (n.getCaption() != null) { - target.addAttribute( - VNotification.ATTRIBUTE_NOTIFICATION_CAPTION, - n.getCaption()); - } - if (n.getDescription() != null) { - target.addAttribute( - VNotification.ATTRIBUTE_NOTIFICATION_MESSAGE, - n.getDescription()); - } - if (n.getIcon() != null) { - target.addAttribute( - VNotification.ATTRIBUTE_NOTIFICATION_ICON, - n.getIcon()); - } - if (!n.isHtmlContentAllowed()) { - target.addAttribute( - VRoot.NOTIFICATION_HTML_CONTENT_NOT_ALLOWED, true); - } - target.addAttribute( - VNotification.ATTRIBUTE_NOTIFICATION_POSITION, - n.getPosition()); - target.addAttribute(VNotification.ATTRIBUTE_NOTIFICATION_DELAY, - n.getDelayMsec()); - if (n.getStyleName() != null) { - target.addAttribute( - VNotification.ATTRIBUTE_NOTIFICATION_STYLE, - n.getStyleName()); - } - target.endTag("notification"); - } - target.endTag("notifications"); - notifications = null; - } + page.paintContent(target); if (scrollIntoView != null) { target.addAttribute("scrollTo", scrollIntoView); @@ -570,10 +680,6 @@ public abstract class Root extends AbstractComponentContainer implements actionManager.paintActions(null, target); } - if (fragment != null) { - target.addAttribute(VRoot.FRAGMENT_VARIABLE, fragment); - } - if (isResizeLazy()) { target.addAttribute(VRoot.RESIZE_LAZY, true); } @@ -604,23 +710,14 @@ public abstract class Root extends AbstractComponentContainer implements if (variables.containsKey(VRoot.FRAGMENT_VARIABLE)) { String fragment = (String) variables.get(VRoot.FRAGMENT_VARIABLE); - setFragment(fragment, true); + getPage().setFragment(fragment, true); } - boolean sendResizeEvent = false; - if (variables.containsKey("height")) { - browserWindowHeight = ((Integer) variables.get("height")) - .intValue(); - sendResizeEvent = true; - } - if (variables.containsKey("width")) { - browserWindowWidth = ((Integer) variables.get("width")).intValue(); - sendResizeEvent = true; - } - if (sendResizeEvent) { - fireEvent(new BrowserWindowResizeEvent(this, browserWindowWidth, - browserWindowHeight)); + if (variables.containsKey("height") || variables.containsKey("width")) { + getPage().setBrowserWindowSize((Integer) variables.get("width"), + (Integer) variables.get("height")); } + } /* @@ -801,11 +898,6 @@ public abstract class Root extends AbstractComponentContainer implements */ private Focusable pendingFocus; - /** - * The current URI fragment. - */ - private String fragment; - private boolean resizeLazy = false; /** @@ -826,172 +918,6 @@ public abstract class Root extends AbstractComponentContainer implements requestRepaint(); } - /** - * Shows a notification message on the middle of the root. The message - * automatically disappears ("humanized message"). - * - * Care should be taken to to avoid XSS vulnerabilities as the caption is - * rendered as html. - * - * @see #showNotification(Notification) - * @see Notification - * - * @param caption - * The message - */ - public void showNotification(String caption) { - addNotification(new Notification(caption)); - } - - /** - * Shows a notification message the root. The position and behavior of the - * message depends on the type, which is one of the basic types defined in - * {@link Notification}, for instance Notification.TYPE_WARNING_MESSAGE. - * - * Care should be taken to to avoid XSS vulnerabilities as the caption is - * rendered as html. - * - * @see #showNotification(Notification) - * @see Notification - * - * @param caption - * The message - * @param type - * The message type - */ - public void showNotification(String caption, int type) { - addNotification(new Notification(caption, type)); - } - - /** - * Shows a notification consisting of a bigger caption and a smaller - * description on the middle of the root. The message automatically - * disappears ("humanized message"). - * - * Care should be taken to to avoid XSS vulnerabilities as the caption and - * description are rendered as html. - * - * @see #showNotification(Notification) - * @see Notification - * - * @param caption - * The caption of the message - * @param description - * The message description - * - */ - public void showNotification(String caption, String description) { - addNotification(new Notification(caption, description)); - } - - /** - * Shows a notification consisting of a bigger caption and a smaller - * description. The position and behavior of the message depends on the - * type, which is one of the basic types defined in {@link Notification}, - * for instance Notification.TYPE_WARNING_MESSAGE. - * - * Care should be taken to to avoid XSS vulnerabilities as the caption and - * description are rendered as html. - * - * @see #showNotification(Notification) - * @see Notification - * - * @param caption - * The caption of the message - * @param description - * The message description - * @param type - * The message type - */ - public void showNotification(String caption, String description, int type) { - addNotification(new Notification(caption, description, type)); - } - - /** - * Shows a notification consisting of a bigger caption and a smaller - * description. The position and behavior of the message depends on the - * type, which is one of the basic types defined in {@link Notification}, - * for instance Notification.TYPE_WARNING_MESSAGE. - * - * Care should be taken to avoid XSS vulnerabilities if html content is - * allowed. - * - * @see #showNotification(Notification) - * @see Notification - * - * @param caption - * The message caption - * @param description - * The message description - * @param type - * The type of message - * @param htmlContentAllowed - * Whether html in the caption and description should be - * displayed as html or as plain text - */ - public void showNotification(String caption, String description, int type, - boolean htmlContentAllowed) { - addNotification(new Notification(caption, description, type, - htmlContentAllowed)); - } - - /** - * Shows a notification message. - * - * @see Notification - * @see #showNotification(String) - * @see #showNotification(String, int) - * @see #showNotification(String, String) - * @see #showNotification(String, String, int) - * - * @param notification - * The notification message to show - */ - public void showNotification(Notification notification) { - addNotification(notification); - } - - /** - * Internal helper method to actually add a notification. - * - * @param notification - * the notification to add - */ - private void addNotification(Notification notification) { - if (notifications == null) { - notifications = new LinkedList(); - } - notifications.add(notification); - requestRepaint(); - } - - /** - * Executes JavaScript in this root. - * - *

- * This method allows one to inject javascript from the server to client. A - * client implementation is not required to implement this functionality, - * but currently all web-based clients do implement this. - *

- * - *

- * Executing javascript this way often leads to cross-browser compatibility - * issues and regressions that are hard to resolve. Use of this method - * should be avoided and instead it is recommended to create new widgets - * with GWT. For more info on creating own, reusable client-side widgets in - * Java, read the corresponding chapter in Book of Vaadin. - *

- * - * @param script - * JavaScript snippet that will be executed. - * - * @deprecated as of 7.0, use getJavaScript().execute(String) instead - */ - @Deprecated - public void executeJavaScript(String script) { - getJavaScript().execute(script); - } - /** * Scrolls any component between the component and root to a suitable * position so the component is visible to the user. The given component @@ -1106,10 +1032,7 @@ public abstract class Root extends AbstractComponentContainer implements * the initialization request */ public void doInit(WrappedRequest request) { - BrowserDetails browserDetails = request.getBrowserDetails(); - if (browserDetails != null) { - fragment = browserDetails.getUriFragment(); - } + getPage().init(request); // Call the init overridden by the application developer init(request); @@ -1168,186 +1091,6 @@ public abstract class Root extends AbstractComponentContainer implements return currentRoot.get(); } - /** - * Opens the given resource in this root. The contents of this Root is - * replaced by the {@code Resource}. - * - * @param resource - * the resource to show in this root - */ - public void open(Resource resource) { - synchronized (openList) { - if (!openList.contains(resource)) { - openList.add(new OpenResource(resource, null, -1, -1, - BORDER_DEFAULT)); - } - } - requestRepaint(); - } - - /* ********************************************************************* */ - - /** - * Opens the given resource in a window with the given name. - *

- * The supplied {@code windowName} is used as the target name in a - * window.open call in the client. This means that special values such as - * "_blank", "_self", "_top", "_parent" have special meaning. An empty or - * null window name is also a special case. - *

- *

- * "", null and "_self" as {@code windowName} all causes the resource to be - * opened in the current window, replacing any old contents. For - * downloadable content you should avoid "_self" as "_self" causes the - * client to skip rendering of any other changes as it considers them - * irrelevant (the page will be replaced by the resource). This can speed up - * the opening of a resource, but it might also put the client side into an - * inconsistent state if the window content is not completely replaced e.g., - * if the resource is downloaded instead of displayed in the browser. - *

- *

- * "_blank" as {@code windowName} causes the resource to always be opened in - * a new window or tab (depends on the browser and browser settings). - *

- *

- * "_top" and "_parent" as {@code windowName} works as specified by the HTML - * standard. - *

- *

- * Any other {@code windowName} will open the resource in a window with that - * name, either by opening a new window/tab in the browser or by replacing - * the contents of an existing window with that name. - *

- * - * @param resource - * the resource. - * @param windowName - * the name of the window. - */ - public void open(Resource resource, String windowName) { - synchronized (openList) { - if (!openList.contains(resource)) { - openList.add(new OpenResource(resource, windowName, -1, -1, - BORDER_DEFAULT)); - } - } - requestRepaint(); - } - - /** - * Opens the given resource in a window with the given size, border and - * name. For more information on the meaning of {@code windowName}, see - * {@link #open(Resource, String)}. - * - * @param resource - * the resource. - * @param windowName - * the name of the window. - * @param width - * the width of the window in pixels - * @param height - * the height of the window in pixels - * @param border - * the border style of the window. See {@link #BORDER_NONE - * Window.BORDER_* constants} - */ - public void open(Resource resource, String windowName, int width, - int height, int border) { - synchronized (openList) { - if (!openList.contains(resource)) { - openList.add(new OpenResource(resource, windowName, width, - height, border)); - } - } - requestRepaint(); - } - - /** - * Private class for storing properties related to opening resources. - */ - private class OpenResource implements Serializable { - - /** - * The resource to open - */ - private final Resource resource; - - /** - * The name of the target window - */ - private final String name; - - /** - * The width of the target window - */ - private final int width; - - /** - * The height of the target window - */ - private final int height; - - /** - * The border style of the target window - */ - private final int border; - - /** - * Creates a new open resource. - * - * @param resource - * The resource to open - * @param name - * The name of the target window - * @param width - * The width of the target window - * @param height - * The height of the target window - * @param border - * The border style of the target window - */ - private OpenResource(Resource resource, String name, int width, - int height, int border) { - this.resource = resource; - this.name = name; - this.width = width; - this.height = height; - this.border = border; - } - - /** - * Paints the open request. Should be painted inside the window. - * - * @param target - * the paint target - * @throws PaintException - * if the paint operation fails - */ - private void paintContent(PaintTarget target) throws PaintException { - target.startTag("open"); - target.addAttribute("src", resource); - if (name != null && name.length() > 0) { - target.addAttribute("name", name); - } - if (width >= 0) { - target.addAttribute("width", width); - } - if (height >= 0) { - target.addAttribute("height", height); - } - switch (border) { - case BORDER_MINIMAL: - target.addAttribute("border", "minimal"); - break; - case BORDER_NONE: - target.addAttribute("border", "none"); - break; - } - - target.endTag("open"); - } - } - public void setScrollTop(int scrollTop) { throw new RuntimeException("Not yet implemented"); } @@ -1435,110 +1178,6 @@ public abstract class Root extends AbstractComponentContainer implements removeListener(CLICK_EVENT_ID, ClickEvent.class, listener); } - public void addListener(FragmentChangedListener listener) { - addListener(FragmentChangedEvent.class, listener, - FRAGMENT_CHANGED_METHOD); - } - - public void removeListener(FragmentChangedListener listener) { - removeListener(FragmentChangedEvent.class, listener, - FRAGMENT_CHANGED_METHOD); - } - - /** - * Sets URI fragment. Optionally fires a {@link FragmentChangedEvent} - * - * @param newFragment - * id of the new fragment - * @param fireEvent - * true to fire event - * @see FragmentChangedEvent - * @see FragmentChangedListener - */ - public void setFragment(String newFragment, boolean fireEvents) { - if (newFragment == null) { - throw new NullPointerException("The fragment may not be null"); - } - if (!newFragment.equals(fragment)) { - fragment = newFragment; - if (fireEvents) { - fireEvent(new FragmentChangedEvent(this, newFragment)); - } - requestRepaint(); - } - } - - /** - * Sets URI fragment. This method fires a {@link FragmentChangedEvent} - * - * @param newFragment - * id of the new fragment - * @see FragmentChangedEvent - * @see FragmentChangedListener - */ - public void setFragment(String newFragment) { - setFragment(newFragment, true); - } - - /** - * Gets currently set URI fragment. - *

- * To listen changes in fragment, hook a {@link FragmentChangedListener}. - * - * @return the current fragment in browser uri or null if not known - */ - public String getFragment() { - return fragment; - } - - /** - * Adds a new {@link BrowserWindowResizeListener} to this root. The listener - * will be notified whenever the browser window within which this root - * resides is resized. - * - * @param resizeListener - * the listener to add - * - * @see BrowserWindowResizeListener#browserWindowResized(BrowserWindowResizeEvent) - * @see #setResizeLazy(boolean) - */ - public void addListener(BrowserWindowResizeListener resizeListener) { - addListener(BrowserWindowResizeEvent.class, resizeListener, - BROWSWER_RESIZE_METHOD); - } - - /** - * Removes a {@link BrowserWindowResizeListener} from this root. The - * listener will no longer be notified when the browser window is resized. - * - * @param resizeListener - * the listener to remove - */ - public void removeListener(BrowserWindowResizeListener resizeListener) { - removeListener(BrowserWindowResizeEvent.class, resizeListener, - BROWSWER_RESIZE_METHOD); - } - - /** - * Gets the last known height of the browser window in which this root - * resides. - * - * @return the browser window height in pixels - */ - public int getBrowserWindowHeight() { - return browserWindowHeight; - } - - /** - * Gets the last known width of the browser window in which this root - * resides. - * - * @return the browser window width in pixels - */ - public int getBrowserWindowWidth() { - return browserWindowWidth; - } - /** * Notifies the child components and windows that the root is attached to * the application. @@ -1573,14 +1212,21 @@ public abstract class Root extends AbstractComponentContainer implements return dirtyConnectorTracker; } - public JavaScript getJavaScript() { - if (javaScript == null) { - // Create and attach on first use - javaScript = new JavaScript(); - addExtension(javaScript); - } + public Page getPage() { + return page; + } - return javaScript; + /** + * Setting the caption of a Root is not supported. To set the title of the + * HTML page, use Page.setTitle + * + * @deprecated as of 7.0.0, use {@link Page#setTitle(String)} + */ + @Override + @Deprecated + public void setCaption(String caption) { + throw new IllegalStateException( + "You can not set the title of a Root. To set the title of the HTML page, use Page.setTitle"); } } diff --git a/tests/server-side/com/vaadin/tests/server/navigator/NavigatorTest.java b/tests/server-side/com/vaadin/tests/server/navigator/NavigatorTest.java index ab983b4022..03f49d4ab6 100644 --- a/tests/server-side/com/vaadin/tests/server/navigator/NavigatorTest.java +++ b/tests/server-side/com/vaadin/tests/server/navigator/NavigatorTest.java @@ -19,9 +19,9 @@ import com.vaadin.navigator.ViewChangeListener; import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; import com.vaadin.navigator.ViewDisplay; import com.vaadin.navigator.ViewProvider; +import com.vaadin.terminal.Page; import com.vaadin.tests.server.navigator.ClassBasedViewProviderTest.TestView; import com.vaadin.tests.server.navigator.ClassBasedViewProviderTest.TestView2; -import com.vaadin.ui.Root; public class NavigatorTest extends TestCase { @@ -366,9 +366,9 @@ public class NavigatorTest extends TestCase { public void testDefaultDisplayType() { IMocksControl control = EasyMock.createControl(); - Root root = control.createMock(Root.class); + Page page = control.createMock(Page.class); - Navigator navigator = new Navigator(root); + Navigator navigator = new Navigator(page); assertEquals("Default display should be a SimpleViewDisplay", SimpleViewDisplay.class, navigator.getDisplay().getClass()); diff --git a/tests/server-side/com/vaadin/tests/server/navigator/UriFragmentManagerTest.java b/tests/server-side/com/vaadin/tests/server/navigator/UriFragmentManagerTest.java index cfbf50f256..65294b2913 100644 --- a/tests/server-side/com/vaadin/tests/server/navigator/UriFragmentManagerTest.java +++ b/tests/server-side/com/vaadin/tests/server/navigator/UriFragmentManagerTest.java @@ -11,20 +11,20 @@ import org.easymock.IMocksControl; import com.vaadin.navigator.Navigator; import com.vaadin.navigator.Navigator.UriFragmentManager; -import com.vaadin.ui.Root; -import com.vaadin.ui.Root.FragmentChangedEvent; +import com.vaadin.terminal.Page; +import com.vaadin.terminal.Page.FragmentChangedEvent; public class UriFragmentManagerTest extends TestCase { public void testGetSetFragment() { - Root root = EasyMock.createMock(Root.class); - UriFragmentManager manager = new UriFragmentManager(root, null); + Page page = EasyMock.createMock(Page.class); + UriFragmentManager manager = new UriFragmentManager(page, null); // prepare mock - EasyMock.expect(root.getFragment()).andReturn(""); - root.setFragment("test"); - EasyMock.expect(root.getFragment()).andReturn("test"); - EasyMock.replay(root); + EasyMock.expect(page.getFragment()).andReturn(""); + page.setFragment("test"); + EasyMock.expect(page.getFragment()).andReturn("test"); + EasyMock.replay(page); // test manager using the mock assertEquals("Incorrect fragment value", "", manager.getFragment()); @@ -36,15 +36,15 @@ public class UriFragmentManagerTest extends TestCase { // create mocks IMocksControl control = EasyMock.createControl(); Navigator navigator = control.createMock(Navigator.class); - Root root = control.createMock(Root.class); + Page page = control.createMock(Page.class); - UriFragmentManager manager = new UriFragmentManager(root, navigator); + UriFragmentManager manager = new UriFragmentManager(page, navigator); - EasyMock.expect(root.getFragment()).andReturn("test"); + EasyMock.expect(page.getFragment()).andReturn("test"); navigator.navigateTo("test"); control.replay(); - FragmentChangedEvent event = root.new FragmentChangedEvent(root, + FragmentChangedEvent event = page.new FragmentChangedEvent(page, "oldtest"); manager.fragmentChanged(event); } diff --git a/tests/testbench/com/vaadin/tests/TestBench.java b/tests/testbench/com/vaadin/tests/TestBench.java index c3bb24cbef..1ac497e574 100644 --- a/tests/testbench/com/vaadin/tests/TestBench.java +++ b/tests/testbench/com/vaadin/tests/TestBench.java @@ -16,6 +16,8 @@ import com.vaadin.Application; import com.vaadin.data.Property; import com.vaadin.data.util.HierarchicalContainer; import com.vaadin.terminal.ExternalResource; +import com.vaadin.terminal.Page; +import com.vaadin.terminal.Page.FragmentChangedEvent; import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.HorizontalSplitPanel; @@ -23,8 +25,6 @@ import com.vaadin.ui.Label; import com.vaadin.ui.Layout; import com.vaadin.ui.Link; import com.vaadin.ui.Panel; -import com.vaadin.ui.Root; -import com.vaadin.ui.Root.FragmentChangedEvent; import com.vaadin.ui.Root.LegacyWindow; import com.vaadin.ui.Tree; import com.vaadin.ui.VerticalLayout; @@ -119,7 +119,7 @@ public class TestBench extends com.vaadin.Application.LegacyApplication VerticalLayout lo = new VerticalLayout(); lo.addComponent(menu); - mainWindow.addListener(new Root.FragmentChangedListener() { + mainWindow.getPage().addListener(new Page.FragmentChangedListener() { public void fragmentChanged(FragmentChangedEvent source) { String fragment = source.getFragment(); if (fragment != null && !"".equals(fragment)) { diff --git a/tests/testbench/com/vaadin/tests/TestComponentAddAndRecursion.java b/tests/testbench/com/vaadin/tests/TestComponentAddAndRecursion.java index 48eff0336e..c63c0caf16 100644 --- a/tests/testbench/com/vaadin/tests/TestComponentAddAndRecursion.java +++ b/tests/testbench/com/vaadin/tests/TestComponentAddAndRecursion.java @@ -10,7 +10,6 @@ import com.vaadin.ui.GridLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Notification; import com.vaadin.ui.Panel; -import com.vaadin.ui.Root; import com.vaadin.ui.VerticalLayout; /** @@ -92,12 +91,10 @@ public class TestComponentAddAndRecursion extends CustomComponent { public void buttonClick(ClickEvent event) { try { p3.addComponent(p2); - Root.getCurrentRoot().showNotification("ERROR", - "This should have failed", + Notification.show("ERROR", "This should have failed", Notification.TYPE_ERROR_MESSAGE); } catch (Exception e) { - Root.getCurrentRoot().showNotification("OK", - "threw, as expected", + Notification.show("OK", "threw, as expected", Notification.TYPE_ERROR_MESSAGE); } } @@ -111,12 +108,10 @@ public class TestComponentAddAndRecursion extends CustomComponent { p.addComponent(p2); try { p3.addComponent(p); - Root.getCurrentRoot().showNotification("ERROR", - "This should have failed", + Notification.show("ERROR", "This should have failed", Notification.TYPE_ERROR_MESSAGE); } catch (Exception e) { - Root.getCurrentRoot().showNotification("OK", - "threw, as expected", + Notification.show("OK", "threw, as expected", Notification.TYPE_ERROR_MESSAGE); } } diff --git a/tests/testbench/com/vaadin/tests/TestForWindowOpen.java b/tests/testbench/com/vaadin/tests/TestForWindowOpen.java index c9dbf8dabe..76154f2419 100644 --- a/tests/testbench/com/vaadin/tests/TestForWindowOpen.java +++ b/tests/testbench/com/vaadin/tests/TestForWindowOpen.java @@ -24,7 +24,7 @@ public class TestForWindowOpen extends CustomComponent { public void buttonClick(ClickEvent event) { final ExternalResource r = new ExternalResource( "http://www.google.com"); - Root.getCurrentRoot().open(r); + Root.getCurrentRoot().getPage().open(r); } @@ -36,7 +36,7 @@ public class TestForWindowOpen extends CustomComponent { public void buttonClick(ClickEvent event) { final ExternalResource r = new ExternalResource( "http://www.google.com"); - Root.getCurrentRoot().open(r, "mytarget"); + Root.getCurrentRoot().getPage().open(r, "mytarget"); } @@ -48,7 +48,7 @@ public class TestForWindowOpen extends CustomComponent { public void buttonClick(ClickEvent event) { final ExternalResource r = new ExternalResource( "http://www.google.com"); - Root.getCurrentRoot().open(r, "secondtarget"); + Root.getCurrentRoot().getPage().open(r, "secondtarget"); } diff --git a/tests/testbench/com/vaadin/tests/appengine/GAESyncTest.java b/tests/testbench/com/vaadin/tests/appengine/GAESyncTest.java index 7d5e298286..58faec35f0 100644 --- a/tests/testbench/com/vaadin/tests/appengine/GAESyncTest.java +++ b/tests/testbench/com/vaadin/tests/appengine/GAESyncTest.java @@ -91,7 +91,8 @@ public class GAESyncTest extends Application.LegacyApplication { public void buttonClick(ClickEvent event) { if (getRoot() == getMainWindow()) { - getRoot().showNotification("main"); + getRoot().getPage().showNotification( + new Notification("main")); try { Thread.sleep((5000)); } catch (InterruptedException e) { diff --git a/tests/testbench/com/vaadin/tests/components/AbstractTestRoot.java b/tests/testbench/com/vaadin/tests/components/AbstractTestRoot.java index fd90cf2d6e..72cbcd386e 100644 --- a/tests/testbench/com/vaadin/tests/components/AbstractTestRoot.java +++ b/tests/testbench/com/vaadin/tests/components/AbstractTestRoot.java @@ -15,7 +15,7 @@ public abstract class AbstractTestRoot extends Root { @Override public void init(WrappedRequest request) { - setCaption(getClass().getName()); + getPage().setTitle(getClass().getName()); Label label = new Label(getTestDescription(), ContentMode.XHTML); label.setWidth("100%"); diff --git a/tests/testbench/com/vaadin/tests/components/TouchScrollables.java b/tests/testbench/com/vaadin/tests/components/TouchScrollables.java index 053691e738..8ad12da85f 100644 --- a/tests/testbench/com/vaadin/tests/components/TouchScrollables.java +++ b/tests/testbench/com/vaadin/tests/components/TouchScrollables.java @@ -24,6 +24,7 @@ import com.vaadin.ui.CssLayout; import com.vaadin.ui.HorizontalSplitPanel; import com.vaadin.ui.Label; import com.vaadin.ui.Layout; +import com.vaadin.ui.Notification; import com.vaadin.ui.Panel; import com.vaadin.ui.TabSheet; import com.vaadin.ui.Table; @@ -189,7 +190,7 @@ public class TouchScrollables extends TestBase { } public void handleAction(Action action, Object sender, Object target) { - getLayout().getRoot().showNotification(action.getCaption()); + Notification.show(action.getCaption()); } }); diff --git a/tests/testbench/com/vaadin/tests/components/customfield/AddressFormExample.java b/tests/testbench/com/vaadin/tests/components/customfield/AddressFormExample.java index 55e61e3980..02c080e8fd 100644 --- a/tests/testbench/com/vaadin/tests/components/customfield/AddressFormExample.java +++ b/tests/testbench/com/vaadin/tests/components/customfield/AddressFormExample.java @@ -4,6 +4,7 @@ import com.vaadin.tests.components.TestBase; import com.vaadin.tests.util.Address; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Notification; /** * Demonstrate a custom field which is a form, and contains another custom field @@ -23,10 +24,9 @@ public class AddressFormExample extends TestBase { public void buttonClick(ClickEvent event) { field.commit(); Address address = field.getValue(); - field.getRoot().showNotification( - "Address saved: " + address.getStreetAddress() + ", " - + address.getPostalCode() + ", " - + address.getCity()); + Notification.show("Address saved: " + + address.getStreetAddress() + ", " + + address.getPostalCode() + ", " + address.getCity()); } }); addComponent(commitButton); diff --git a/tests/testbench/com/vaadin/tests/components/customfield/BooleanFieldExample.java b/tests/testbench/com/vaadin/tests/components/customfield/BooleanFieldExample.java index 2f9720a1c1..694c5b54f9 100644 --- a/tests/testbench/com/vaadin/tests/components/customfield/BooleanFieldExample.java +++ b/tests/testbench/com/vaadin/tests/components/customfield/BooleanFieldExample.java @@ -10,6 +10,7 @@ import com.vaadin.ui.Component; import com.vaadin.ui.DefaultFieldFactory; import com.vaadin.ui.Field; import com.vaadin.ui.Form; +import com.vaadin.ui.Notification; import com.vaadin.ui.VerticalLayout; public class BooleanFieldExample extends TestBase { @@ -62,13 +63,10 @@ public class BooleanFieldExample extends TestBase { Button submit = new Button("Submit", new ClickListener() { public void buttonClick(ClickEvent event) { form.commit(); - layout.getRoot() - .showNotification( - "The custom boolean field value is " - + data.isCustom() - + ".
" - + "The checkbox (default boolean field) value is " - + data.isNormal() + "."); + Notification.show("The custom boolean field value is " + + data.isCustom() + ".
" + + "The checkbox (default boolean field) value is " + + data.isNormal() + "."); } }); layout.addComponent(submit); diff --git a/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java b/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java index 6519e4ae74..5f2f945c8b 100644 --- a/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java +++ b/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java @@ -15,7 +15,7 @@ import com.vaadin.terminal.gwt.client.ui.JavaScriptComponentState; import com.vaadin.tests.components.AbstractTestRoot; import com.vaadin.ui.AbstractJavaScriptComponent; import com.vaadin.ui.JavaScriptCallback; -import com.vaadin.ui.Root; +import com.vaadin.ui.Notification; @LoadScripts({ "/statictestfiles/jsconnector.js" }) public class BasicJavaScriptComponent extends AbstractTestRoot { @@ -40,14 +40,13 @@ public class BasicJavaScriptComponent extends AbstractTestRoot { public ExampleWidget() { registerRpc(new ExampleClickRpc() { public void onClick(String message) { - Root.getCurrentRoot().showNotification( - "Got a click: " + message); + Notification.show("Got a click: " + message); } }); registerCallback("onclick", new JavaScriptCallback() { public void call(JSONArray arguments) throws JSONException { - Root.getCurrentRoot().showNotification( - "Got a callback: " + arguments.getString(0)); + Notification.show("Got a callback: " + + arguments.getString(0)); } }); getState().setData(Arrays.asList("a", "b", "c")); diff --git a/tests/testbench/com/vaadin/tests/components/notification/Notifications.java b/tests/testbench/com/vaadin/tests/components/notification/Notifications.java index 27aef918d1..a36fbe3121 100644 --- a/tests/testbench/com/vaadin/tests/components/notification/Notifications.java +++ b/tests/testbench/com/vaadin/tests/components/notification/Notifications.java @@ -6,7 +6,6 @@ import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.NativeSelect; import com.vaadin.ui.Notification; -import com.vaadin.ui.Root; import com.vaadin.ui.TextArea; public class Notifications extends TestBase implements ClickListener { @@ -53,7 +52,6 @@ public class Notifications extends TestBase implements ClickListener { public void buttonClick(ClickEvent event) { Notification n = new Notification(tf.getValue(), (Integer) type.getValue()); - Root.getCurrentRoot().showNotification(n); - + n.show(); } } diff --git a/tests/testbench/com/vaadin/tests/components/notification/NotificationsHtmlAllowed.java b/tests/testbench/com/vaadin/tests/components/notification/NotificationsHtmlAllowed.java index 152688d109..a16b8edcde 100644 --- a/tests/testbench/com/vaadin/tests/components/notification/NotificationsHtmlAllowed.java +++ b/tests/testbench/com/vaadin/tests/components/notification/NotificationsHtmlAllowed.java @@ -6,7 +6,6 @@ import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.CheckBox; import com.vaadin.ui.Notification; -import com.vaadin.ui.Root; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; @@ -46,15 +45,13 @@ public class NotificationsHtmlAllowed extends TestBase implements ClickListener public void buttonClick(ClickEvent event) { Notification n = makeNotification(); - Root.getCurrentRoot().showNotification(n); - + n.show(); } private Notification makeNotification() { - Notification n = new Notification((String) captionField.getValue(), - (String) messageField.getValue(), - Notification.TYPE_HUMANIZED_MESSAGE, - (Boolean) htmlAllowedBox.getValue()); + Notification n = new Notification(captionField.getValue(), + messageField.getValue(), Notification.TYPE_HUMANIZED_MESSAGE, + htmlAllowedBox.getValue()); return n; } } diff --git a/tests/testbench/com/vaadin/tests/components/richtextarea/RichTextAreaWithKeyboardShortcuts.java b/tests/testbench/com/vaadin/tests/components/richtextarea/RichTextAreaWithKeyboardShortcuts.java index 95691ef9d7..98f31cd68c 100644 --- a/tests/testbench/com/vaadin/tests/components/richtextarea/RichTextAreaWithKeyboardShortcuts.java +++ b/tests/testbench/com/vaadin/tests/components/richtextarea/RichTextAreaWithKeyboardShortcuts.java @@ -6,6 +6,7 @@ import com.vaadin.event.ShortcutAction; import com.vaadin.tests.components.TestBase; import com.vaadin.ui.AbstractField; import com.vaadin.ui.Component; +import com.vaadin.ui.Notification; import com.vaadin.ui.Panel; import com.vaadin.ui.RichTextArea; import com.vaadin.ui.Window; @@ -30,7 +31,7 @@ public class RichTextAreaWithKeyboardShortcuts extends TestBase { String string = f.getValue().toString(); msg += " Value: " + string; - f.getRoot().showNotification(msg); + Notification.show(msg); } diff --git a/tests/testbench/com/vaadin/tests/components/root/UriFragmentTest.java b/tests/testbench/com/vaadin/tests/components/root/UriFragmentTest.java index 6078161996..251672fb9a 100644 --- a/tests/testbench/com/vaadin/tests/components/root/UriFragmentTest.java +++ b/tests/testbench/com/vaadin/tests/components/root/UriFragmentTest.java @@ -1,5 +1,7 @@ package com.vaadin.tests.components.root; +import com.vaadin.terminal.Page; +import com.vaadin.terminal.Page.FragmentChangedEvent; import com.vaadin.terminal.WrappedRequest; import com.vaadin.tests.components.AbstractTestRoot; import com.vaadin.ui.Button; @@ -14,7 +16,7 @@ public class UriFragmentTest extends AbstractTestRoot { protected void setup(WrappedRequest request) { addComponent(fragmentLabel); updateLabel(); - addListener(new FragmentChangedListener() { + getPage().addListener(new Page.FragmentChangedListener() { public void fragmentChanged(FragmentChangedEvent event) { updateLabel(); } @@ -22,13 +24,13 @@ public class UriFragmentTest extends AbstractTestRoot { addComponent(new Button("Navigate to #test", new Button.ClickListener() { public void buttonClick(ClickEvent event) { - setFragment("test"); + getPage().setFragment("test"); } })); } private void updateLabel() { - String fragment = getFragment(); + String fragment = getPage().getFragment(); if (fragment == null) { fragmentLabel.setValue("No URI fragment set"); } else { diff --git a/tests/testbench/com/vaadin/tests/components/table/MultiSelectWithNotIdentityEqualIds.java b/tests/testbench/com/vaadin/tests/components/table/MultiSelectWithNotIdentityEqualIds.java index 9178b284f3..6773f0a96c 100644 --- a/tests/testbench/com/vaadin/tests/components/table/MultiSelectWithNotIdentityEqualIds.java +++ b/tests/testbench/com/vaadin/tests/components/table/MultiSelectWithNotIdentityEqualIds.java @@ -5,6 +5,7 @@ import com.vaadin.data.Property; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.util.IndexedContainer; import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Notification; import com.vaadin.ui.Table; @SuppressWarnings("serial") @@ -20,8 +21,7 @@ public class MultiSelectWithNotIdentityEqualIds extends TestBase { t.setImmediate(true); t.addListener(new Property.ValueChangeListener() { public void valueChange(ValueChangeEvent event) { - t.getRoot() - .showNotification("Selected: " + event.getProperty()); + Notification.show("Selected: " + event.getProperty()); } }); diff --git a/tests/testbench/com/vaadin/tests/components/table/TableContextMenu.java b/tests/testbench/com/vaadin/tests/components/table/TableContextMenu.java index 16323e5024..06afd406ef 100644 --- a/tests/testbench/com/vaadin/tests/components/table/TableContextMenu.java +++ b/tests/testbench/com/vaadin/tests/components/table/TableContextMenu.java @@ -2,6 +2,7 @@ package com.vaadin.tests.components.table; import com.vaadin.event.Action; import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Notification; import com.vaadin.ui.Table; public class TableContextMenu extends TestBase { @@ -16,7 +17,7 @@ public class TableContextMenu extends TestBase { table.addActionHandler(new Action.Handler() { public void handleAction(Action action, Object sender, Object target) { - getLayout().getRoot().showNotification("Done that :-)"); + Notification.show("Done that :-)"); } public Action[] getActions(Object target, Object sender) { diff --git a/tests/testbench/com/vaadin/tests/components/table/TableShouldNotEatValueChanges.java b/tests/testbench/com/vaadin/tests/components/table/TableShouldNotEatValueChanges.java index a1686dee3f..d64bc0035d 100644 --- a/tests/testbench/com/vaadin/tests/components/table/TableShouldNotEatValueChanges.java +++ b/tests/testbench/com/vaadin/tests/components/table/TableShouldNotEatValueChanges.java @@ -27,10 +27,8 @@ public class TableShouldNotEatValueChanges extends TestBase { ItemClickListener l = new ItemClickListener() { public void itemClick(ItemClickEvent event) { - tf.getRoot().showNotification( - "TF Value on the server:" + tf.getValue(), + Notification.show("TF Value on the server:" + tf.getValue(), Notification.TYPE_WARNING_MESSAGE); - } }; t.addListener(l); diff --git a/tests/testbench/com/vaadin/tests/components/treetable/ProgrammaticCollapse.java b/tests/testbench/com/vaadin/tests/components/treetable/ProgrammaticCollapse.java index 2f84c8a68d..447ce6c465 100644 --- a/tests/testbench/com/vaadin/tests/components/treetable/ProgrammaticCollapse.java +++ b/tests/testbench/com/vaadin/tests/components/treetable/ProgrammaticCollapse.java @@ -4,6 +4,7 @@ import com.vaadin.tests.components.TestBase; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Notification; import com.vaadin.ui.TreeTable; import com.vaadin.ui.VerticalLayout; @@ -31,8 +32,7 @@ public class ProgrammaticCollapse extends TestBase { new ClickListener() { public void buttonClick(ClickEvent event) { boolean collapsed = !table.isCollapsed(1); - table.getRoot().showNotification( - "set collapsed: " + collapsed); + Notification.show("set collapsed: " + collapsed); table.setCollapsed(1, collapsed); } })); @@ -40,8 +40,7 @@ public class ProgrammaticCollapse extends TestBase { new ClickListener() { public void buttonClick(ClickEvent event) { boolean collapsed = !table.isCollapsed(100); - table.getRoot().showNotification( - "set collapsed: " + collapsed); + Notification.show("set collapsed: " + collapsed); table.setCollapsed(100, collapsed); } })); @@ -51,8 +50,7 @@ public class ProgrammaticCollapse extends TestBase { public void buttonClick(ClickEvent event) { collapsed = !collapsed; - table.getRoot().showNotification( - "set collapsed: " + collapsed); + Notification.show("set collapsed: " + collapsed); for (int i = 0; i < 50; ++i) { table.setCollapsed(i * 2, collapsed); } diff --git a/tests/testbench/com/vaadin/tests/components/window/LazyWindowResize.java b/tests/testbench/com/vaadin/tests/components/window/LazyWindowResize.java index 49da6758ea..9eaabf7340 100644 --- a/tests/testbench/com/vaadin/tests/components/window/LazyWindowResize.java +++ b/tests/testbench/com/vaadin/tests/components/window/LazyWindowResize.java @@ -2,14 +2,14 @@ package com.vaadin.tests.components.window; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.terminal.Page.BrowserWindowResizeEvent; +import com.vaadin.terminal.Page.BrowserWindowResizeListener; import com.vaadin.terminal.gwt.client.ui.label.ContentMode; import com.vaadin.tests.components.AbstractTestCase; import com.vaadin.tests.util.Log; import com.vaadin.tests.util.LoremIpsum; import com.vaadin.ui.CheckBox; import com.vaadin.ui.Label; -import com.vaadin.ui.Root.BrowserWindowResizeEvent; -import com.vaadin.ui.Root.BrowserWindowResizeListener; import com.vaadin.ui.Root.LegacyWindow; import com.vaadin.ui.Window; import com.vaadin.ui.Window.ResizeEvent; diff --git a/tests/testbench/com/vaadin/tests/components/window/SubWindowFocusAndBlurListeners.java b/tests/testbench/com/vaadin/tests/components/window/SubWindowFocusAndBlurListeners.java index 988d47e29f..1e342abe01 100644 --- a/tests/testbench/com/vaadin/tests/components/window/SubWindowFocusAndBlurListeners.java +++ b/tests/testbench/com/vaadin/tests/components/window/SubWindowFocusAndBlurListeners.java @@ -10,6 +10,7 @@ import com.vaadin.event.ShortcutAction; import com.vaadin.tests.components.TestBase; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Notification; import com.vaadin.ui.Root; import com.vaadin.ui.TextField; import com.vaadin.ui.Window; @@ -36,15 +37,13 @@ public class SubWindowFocusAndBlurListeners extends TestBase { window.addComponent(new TextField()); window.addListener(new FocusListener() { public void focus(FocusEvent event) { - event.getComponent().getRoot() - .showNotification("Focused window"); + Notification.show("Focused window"); } }); window.addListener(new BlurListener() { public void blur(BlurEvent event) { - event.getComponent().getRoot() - .showNotification("Blurred window"); + Notification.show("Blurred window"); } }); @@ -57,7 +56,7 @@ public class SubWindowFocusAndBlurListeners extends TestBase { } public void handleAction(Action action, Object sender, Object target) { - window.getRoot().showNotification("Action!"); + Notification.show("Action!"); } }); diff --git a/tests/testbench/com/vaadin/tests/components/window/WindowResizeListener.java b/tests/testbench/com/vaadin/tests/components/window/WindowResizeListener.java index c6563f200f..ac6c313d29 100644 --- a/tests/testbench/com/vaadin/tests/components/window/WindowResizeListener.java +++ b/tests/testbench/com/vaadin/tests/components/window/WindowResizeListener.java @@ -2,13 +2,13 @@ package com.vaadin.tests.components.window; import com.vaadin.data.Property; import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.terminal.Page; +import com.vaadin.terminal.Page.BrowserWindowResizeEvent; import com.vaadin.tests.components.TestBase; import com.vaadin.ui.Button; import com.vaadin.ui.CheckBox; import com.vaadin.ui.Label; import com.vaadin.ui.Layout; -import com.vaadin.ui.Root; -import com.vaadin.ui.Root.BrowserWindowResizeEvent; import com.vaadin.ui.Window; public class WindowResizeListener extends TestBase { @@ -33,7 +33,7 @@ public class WindowResizeListener extends TestBase { final Label l = new Label(); getLayout().addComponent(l); - getMainWindow().addListener(new Root.BrowserWindowResizeListener() { + getMainWindow().addListener(new Page.BrowserWindowResizeListener() { public void browserWindowResized(BrowserWindowResizeEvent event) { l.setValue("Current browser window size: " + getMainWindow().getBrowserWindowWidth() + " x " diff --git a/tests/testbench/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java b/tests/testbench/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java index 8bcf873cd5..bbfe3f0f46 100644 --- a/tests/testbench/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java +++ b/tests/testbench/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java @@ -16,7 +16,7 @@ import com.vaadin.tests.components.AbstractTestRoot; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.JavaScriptCallback; -import com.vaadin.ui.Root; +import com.vaadin.ui.Notification; @LoadScripts({ "/statictestfiles/jsextension.js" }) public class SimpleJavaScriptExtensionTest extends AbstractTestRoot { @@ -50,14 +50,13 @@ public class SimpleJavaScriptExtensionTest extends AbstractTestRoot { public SimpleJavascriptExtension() { registerRpc(new SimpleJavaScriptExtensionServerRpc() { public void greet(String message) { - Root.getCurrentRoot().showNotification( - getState().getPrefix() + message); + Notification.show(getState().getPrefix() + message); } }); registerCallback("greetToServer", new JavaScriptCallback() { public void call(JSONArray arguments) throws JSONException { - Root.getCurrentRoot().showNotification( - getState().getPrefix() + arguments.getString(0)); + Notification.show(getState().getPrefix() + + arguments.getString(0)); } }); } diff --git a/tests/testbench/com/vaadin/tests/fieldgroup/AbstractBeanFieldGroupTest.java b/tests/testbench/com/vaadin/tests/fieldgroup/AbstractBeanFieldGroupTest.java index 584ce0ec36..b73a29efea 100644 --- a/tests/testbench/com/vaadin/tests/fieldgroup/AbstractBeanFieldGroupTest.java +++ b/tests/testbench/com/vaadin/tests/fieldgroup/AbstractBeanFieldGroupTest.java @@ -7,7 +7,7 @@ import com.vaadin.tests.util.Log; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; -import com.vaadin.ui.Root; +import com.vaadin.ui.Notification; public abstract class AbstractBeanFieldGroupTest extends TestBase { @@ -64,7 +64,7 @@ public abstract class AbstractBeanFieldGroupTest extends TestBase { } catch (CommitException e) { msg = "Commit failed: " + e.getMessage(); } - Root.getCurrentRoot().showNotification(msg); + Notification.show(msg); log.log(msg); } diff --git a/tests/testbench/com/vaadin/tests/fieldgroup/BasicPersonForm.java b/tests/testbench/com/vaadin/tests/fieldgroup/BasicPersonForm.java index f95c172348..c86cb6f5e8 100644 --- a/tests/testbench/com/vaadin/tests/fieldgroup/BasicPersonForm.java +++ b/tests/testbench/com/vaadin/tests/fieldgroup/BasicPersonForm.java @@ -18,8 +18,8 @@ import com.vaadin.tests.data.bean.Sex; import com.vaadin.tests.util.Log; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Notification; import com.vaadin.ui.Panel; -import com.vaadin.ui.Root; import com.vaadin.ui.Table; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; @@ -125,7 +125,7 @@ public class BasicPersonForm extends TestBase { } catch (CommitException e) { msg = "Commit failed: " + e.getMessage(); } - Root.getCurrentRoot().showNotification(msg); + Notification.show(msg); log.log(msg); } diff --git a/tests/testbench/com/vaadin/tests/fieldgroup/FieldBinderWithBeanValidation.java b/tests/testbench/com/vaadin/tests/fieldgroup/FieldBinderWithBeanValidation.java index 9ff553ce61..6c6cd8024b 100644 --- a/tests/testbench/com/vaadin/tests/fieldgroup/FieldBinderWithBeanValidation.java +++ b/tests/testbench/com/vaadin/tests/fieldgroup/FieldBinderWithBeanValidation.java @@ -13,7 +13,7 @@ import com.vaadin.tests.data.bean.Sex; import com.vaadin.tests.util.Log; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.Root; +import com.vaadin.ui.Notification; import com.vaadin.ui.Table; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; @@ -52,7 +52,7 @@ public class FieldBinderWithBeanValidation extends TestBase { } catch (CommitException e) { msg = "Commit failed: " + e.getMessage(); } - Root.getCurrentRoot().showNotification(msg); + Notification.show(msg); log.log(msg); } diff --git a/tests/testbench/com/vaadin/tests/integration/EmbedSizeTest.java b/tests/testbench/com/vaadin/tests/integration/EmbedSizeTest.java index eb26faacc0..41225b2571 100644 --- a/tests/testbench/com/vaadin/tests/integration/EmbedSizeTest.java +++ b/tests/testbench/com/vaadin/tests/integration/EmbedSizeTest.java @@ -2,11 +2,12 @@ package com.vaadin.tests.integration; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.terminal.Page; +import com.vaadin.terminal.Page.BrowserWindowResizeEvent; import com.vaadin.tests.components.TestBase; import com.vaadin.tests.util.Log; import com.vaadin.ui.CheckBox; -import com.vaadin.ui.Root; -import com.vaadin.ui.Root.BrowserWindowResizeEvent; +import com.vaadin.ui.Root.LegacyWindow; public class EmbedSizeTest extends TestBase { @@ -14,7 +15,7 @@ public class EmbedSizeTest extends TestBase { @Override protected void setup() { - Root mainWindow = getMainWindow(); + LegacyWindow mainWindow = getMainWindow(); mainWindow.setSizeUndefined(); mainWindow.getContent().setSizeUndefined(); mainWindow.setImmediate(true); @@ -34,7 +35,7 @@ public class EmbedSizeTest extends TestBase { addComponent(lazyCheckBox); addComponent(log); - mainWindow.addListener(new Root.BrowserWindowResizeListener() { + mainWindow.addListener(new Page.BrowserWindowResizeListener() { public void browserWindowResized(BrowserWindowResizeEvent event) { log.log("Resize event: " + event.getWidth() + " x " + event.getHeight()); diff --git a/tests/testbench/com/vaadin/tests/integration/JSR286PortletRoot.java b/tests/testbench/com/vaadin/tests/integration/JSR286PortletRoot.java index e022a8bf30..913ce8f54c 100644 --- a/tests/testbench/com/vaadin/tests/integration/JSR286PortletRoot.java +++ b/tests/testbench/com/vaadin/tests/integration/JSR286PortletRoot.java @@ -86,7 +86,7 @@ public class JSR286PortletRoot extends Root { .getContext(); ctx.addPortletListener(getApplication(), new DemoPortletListener()); } else { - showNotification("Not inited via Portal!", + Notification.show("Not inited via Portal!", Notification.TYPE_ERROR_MESSAGE); } @@ -109,7 +109,7 @@ public class JSR286PortletRoot extends Root { tf.setEnabled((request.getPortletMode() == PortletMode.EDIT)); // Show notification about current mode and state - showNotification( + Notification.show( "Portlet status", "Mode: " + request.getPortletMode() + " State: " + request.getWindowState(), diff --git a/tests/testbench/com/vaadin/tests/integration/LiferayThemeDemo.java b/tests/testbench/com/vaadin/tests/integration/LiferayThemeDemo.java index 0250658bc9..8b7f498b0e 100644 --- a/tests/testbench/com/vaadin/tests/integration/LiferayThemeDemo.java +++ b/tests/testbench/com/vaadin/tests/integration/LiferayThemeDemo.java @@ -595,10 +595,7 @@ public class LiferayThemeDemo extends Application.LegacyApplication { Button show = new Button("Humanized Notification", new Button.ClickListener() { public void buttonClick(ClickEvent event) { - event.getButton() - .getRoot() - .showNotification(title.getValue(), - message.getValue()); + Notification.show(title.getValue(), message.getValue()); } }); @@ -607,10 +604,8 @@ public class LiferayThemeDemo extends Application.LegacyApplication { l.addComponent(new Label("Warning", ContentMode.XHTML)); show = new Button("Warning Notification", new Button.ClickListener() { public void buttonClick(ClickEvent event) { - event.getButton() - .getRoot() - .showNotification(title.getValue(), message.getValue(), - Notification.TYPE_WARNING_MESSAGE); + Notification.show(title.getValue(), message.getValue(), + Notification.TYPE_WARNING_MESSAGE); } }); @@ -619,10 +614,8 @@ public class LiferayThemeDemo extends Application.LegacyApplication { l.addComponent(new Label("Error", ContentMode.XHTML)); show = new Button("Error Notification", new Button.ClickListener() { public void buttonClick(ClickEvent event) { - event.getButton() - .getRoot() - .showNotification(title.getValue(), message.getValue(), - Notification.TYPE_ERROR_MESSAGE); + Notification.show(title.getValue(), message.getValue(), + Notification.TYPE_ERROR_MESSAGE); } }); @@ -631,10 +624,8 @@ public class LiferayThemeDemo extends Application.LegacyApplication { l.addComponent(new Label("Tray", ContentMode.XHTML)); show = new Button("Tray Notification", new Button.ClickListener() { public void buttonClick(ClickEvent event) { - event.getButton() - .getRoot() - .showNotification(title.getValue(), message.getValue(), - Notification.TYPE_TRAY_NOTIFICATION); + Notification.show(title.getValue(), message.getValue(), + Notification.TYPE_TRAY_NOTIFICATION); } }); diff --git a/tests/testbench/com/vaadin/tests/minitutorials/IntegerTextFieldDataSource.java b/tests/testbench/com/vaadin/tests/minitutorials/IntegerTextFieldDataSource.java index 5c0efea3ea..96b10d0415 100644 --- a/tests/testbench/com/vaadin/tests/minitutorials/IntegerTextFieldDataSource.java +++ b/tests/testbench/com/vaadin/tests/minitutorials/IntegerTextFieldDataSource.java @@ -8,7 +8,7 @@ import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.Label; -import com.vaadin.ui.Root; +import com.vaadin.ui.Notification; import com.vaadin.ui.TextField; public class IntegerTextFieldDataSource extends AbstractTestRoot { @@ -40,12 +40,9 @@ public class IntegerTextFieldDataSource extends AbstractTestRoot { Integer propertyValue = integerProperty.getValue(); int dataModelValue = myBean.getValue(); - Root.getCurrentRoot().showNotification( - "UI value (String): " + uiValue - + "
Property value (Integer): " - + propertyValue - + "
Data model value (int): " - + dataModelValue); + Notification.show("UI value (String): " + uiValue + + "
Property value (Integer): " + propertyValue + + "
Data model value (int): " + dataModelValue); } }); diff --git a/tests/testbench/com/vaadin/tests/minitutorials/IntegerTextFieldStandalone.java b/tests/testbench/com/vaadin/tests/minitutorials/IntegerTextFieldStandalone.java index 45bc49ba72..5a47bd7fb8 100644 --- a/tests/testbench/com/vaadin/tests/minitutorials/IntegerTextFieldStandalone.java +++ b/tests/testbench/com/vaadin/tests/minitutorials/IntegerTextFieldStandalone.java @@ -8,7 +8,7 @@ import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.Label; -import com.vaadin.ui.Root; +import com.vaadin.ui.Notification; import com.vaadin.ui.TextField; public class IntegerTextFieldStandalone extends AbstractTestRoot { @@ -24,14 +24,12 @@ public class IntegerTextFieldStandalone extends AbstractTestRoot { try { Integer convertedValue = (Integer) textField .getConvertedValue(); - Root.getCurrentRoot().showNotification( - "UI value (String): " + uiValue - + "
Converted value (Integer): " - + convertedValue); + Notification.show("UI value (String): " + uiValue + + "
Converted value (Integer): " + + convertedValue); } catch (ConversionException e) { e.printStackTrace(); - Root.getCurrentRoot().showNotification( - "Could not convert value: " + uiValue); + Notification.show("Could not convert value: " + uiValue); } } }); diff --git a/tests/testbench/com/vaadin/tests/minitutorials/StringMyTypeConverter.java b/tests/testbench/com/vaadin/tests/minitutorials/StringMyTypeConverter.java index e28788f743..33602ce4d5 100644 --- a/tests/testbench/com/vaadin/tests/minitutorials/StringMyTypeConverter.java +++ b/tests/testbench/com/vaadin/tests/minitutorials/StringMyTypeConverter.java @@ -9,6 +9,7 @@ import com.vaadin.tests.components.AbstractTestRoot; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Notification; import com.vaadin.ui.TextField; public class StringMyTypeConverter extends AbstractTestRoot { @@ -26,12 +27,11 @@ public class StringMyTypeConverter extends AbstractTestRoot { public void buttonClick(ClickEvent event) { try { Name name = (Name) textField.getConvertedValue(); - getRoot().showNotification( - "First name: " + name.getFirstName() - + "
Last name: " + name.getLastName()); + Notification.show("First name: " + name.getFirstName() + + "
Last name: " + name.getLastName()); } catch (ConversionException e) { e.printStackTrace(); - getRoot().showNotification(e.getCause().getMessage()); + Notification.show(e.getCause().getMessage()); } } })); diff --git a/tests/testbench/com/vaadin/tests/tickets/Ticket1465ModalNotification.java b/tests/testbench/com/vaadin/tests/tickets/Ticket1465ModalNotification.java index 9459c7cc85..9a777d655c 100644 --- a/tests/testbench/com/vaadin/tests/tickets/Ticket1465ModalNotification.java +++ b/tests/testbench/com/vaadin/tests/tickets/Ticket1465ModalNotification.java @@ -5,7 +5,6 @@ import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Label; import com.vaadin.ui.Notification; -import com.vaadin.ui.Root; import com.vaadin.ui.Root.LegacyWindow; import com.vaadin.ui.Window; @@ -25,7 +24,7 @@ public class Ticket1465ModalNotification extends Application.LegacyApplication { new Button.ClickListener() { public void buttonClick(ClickEvent event) { - Root.getCurrentRoot().showNotification( + Notification.show( "Try clicking the button in main window!", Notification.TYPE_ERROR_MESSAGE); @@ -37,7 +36,7 @@ public class Ticket1465ModalNotification extends Application.LegacyApplication { new Button.ClickListener() { public void buttonClick(ClickEvent event) { - Root.getCurrentRoot().showNotification( + Notification.show( "Try clicking the button in main window!", Notification.TYPE_WARNING_MESSAGE); } @@ -48,7 +47,7 @@ public class Ticket1465ModalNotification extends Application.LegacyApplication { new Button.ClickListener() { public void buttonClick(ClickEvent event) { - Root.getCurrentRoot().showNotification( + Notification.show( "Try clicking the button in main window!", Notification.TYPE_HUMANIZED_MESSAGE); } diff --git a/tests/testbench/com/vaadin/tests/tickets/Ticket2998.java b/tests/testbench/com/vaadin/tests/tickets/Ticket2998.java index 6cf5c8f754..a3ff6808dc 100644 --- a/tests/testbench/com/vaadin/tests/tickets/Ticket2998.java +++ b/tests/testbench/com/vaadin/tests/tickets/Ticket2998.java @@ -20,6 +20,7 @@ import com.vaadin.ui.Field; import com.vaadin.ui.FormLayout; import com.vaadin.ui.Layout; import com.vaadin.ui.ListSelect; +import com.vaadin.ui.Notification; import com.vaadin.ui.Panel; import com.vaadin.ui.Root.LegacyWindow; import com.vaadin.ui.Table; @@ -181,8 +182,7 @@ public class Ticket2998 extends Application.LegacyApplication { @SuppressWarnings("unused") float f = Float.parseFloat((String) value); } catch (Exception e) { - f.getRoot() - .showNotification("Bad number value"); + Notification.show("Bad number value"); f.setValue(0); } } diff --git a/tests/testbench/com/vaadin/tests/tickets/Ticket34.java b/tests/testbench/com/vaadin/tests/tickets/Ticket34.java index 1c55bcbe7d..f6fbe05e38 100644 --- a/tests/testbench/com/vaadin/tests/tickets/Ticket34.java +++ b/tests/testbench/com/vaadin/tests/tickets/Ticket34.java @@ -4,13 +4,13 @@ import java.util.HashMap; import java.util.Map; import com.vaadin.Application; +import com.vaadin.terminal.Page; +import com.vaadin.terminal.Page.FragmentChangedEvent; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Component; import com.vaadin.ui.Label; import com.vaadin.ui.Panel; -import com.vaadin.ui.Root; -import com.vaadin.ui.Root.FragmentChangedEvent; import com.vaadin.ui.Root.LegacyWindow; import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; @@ -32,7 +32,7 @@ public class Ticket34 extends Application.LegacyApplication { "Test app for URI fragment management/reading", mainLayout); setMainWindow(mainWin); - mainWin.addListener(new Root.FragmentChangedListener() { + mainWin.getPage().addListener(new Page.FragmentChangedListener() { public void fragmentChanged(FragmentChangedEvent event) { getMainWindow().showNotification( @@ -93,7 +93,7 @@ public class Ticket34 extends Application.LegacyApplication { public void buttonClick(ClickEvent event) { String viewName = tf.getValue().toString(); // fragmentChangedListener will change the view if possible - event.getButton().getRoot().setFragment(viewName); + event.getButton().getRoot().getPage().setFragment(viewName); } }); diff --git a/tests/testbench/com/vaadin/tests/util/TestUtils.java b/tests/testbench/com/vaadin/tests/util/TestUtils.java index 551e7a7ed8..a9e1518c54 100644 --- a/tests/testbench/com/vaadin/tests/util/TestUtils.java +++ b/tests/testbench/com/vaadin/tests/util/TestUtils.java @@ -112,7 +112,7 @@ public class TestUtils { + "document.body.style.WebkitAppearance=='string') /* webkit only */ ? 'innerText' " + ": 'innerHTML'] = '" + cssString + "';}"; - w.executeJavaScript(script); + w.getPage().getJavaScript().execute(script); } public static IndexedContainer getISO3166Container() { -- cgit v1.2.3 From f505d99754fa0139fbbe1b52236ad622c8c3246d Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Wed, 20 Jun 2012 14:36:21 +0300 Subject: Javadocs and minor tweaks for extensions, JavaScript and js wrappers --- .../vaadin/terminal/AbstractClientConnector.java | 31 ++++- src/com/vaadin/terminal/AbstractExtension.java | 42 ++++++- .../terminal/AbstractJavaScriptExtension.java | 130 +++++++++++++++++++- src/com/vaadin/terminal/Extension.java | 18 ++- .../vaadin/terminal/JavaScriptCallbackHelper.java | 14 +++ .../terminal/gwt/client/JavaScriptExtension.java | 4 +- .../client/ui/JavaScriptComponentConnector.java | 4 +- .../terminal/gwt/server/ClientConnector.java | 56 ++++----- src/com/vaadin/ui/AbstractJavaScriptComponent.java | 136 ++++++++++++++++++++- src/com/vaadin/ui/JavaScript.java | 74 +++++++++++ src/com/vaadin/ui/JavaScriptCallback.java | 27 ++++ 11 files changed, 488 insertions(+), 48 deletions(-) (limited to 'src/com/vaadin/ui/JavaScript.java') diff --git a/src/com/vaadin/terminal/AbstractClientConnector.java b/src/com/vaadin/terminal/AbstractClientConnector.java index ee1a2ab981..6a87f58c71 100644 --- a/src/com/vaadin/terminal/AbstractClientConnector.java +++ b/src/com/vaadin/terminal/AbstractClientConnector.java @@ -31,7 +31,12 @@ import com.vaadin.ui.HasComponents; import com.vaadin.ui.Root; /** - * + * An abstract base class for ClientConnector implementations. This class + * provides all the basic functionality required for connectors. + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 */ public abstract class AbstractClientConnector implements ClientConnector { /** @@ -115,6 +120,7 @@ public abstract class AbstractClientConnector implements ClientConnector { throw new RuntimeException( "Use registerRpc(T implementation, Class rpcInterfaceType) if the Rpc implementation implements more than one interface"); } + @SuppressWarnings("unchecked") Class type = (Class) interfaces[0]; registerRpc(implementation, type); } @@ -371,6 +377,14 @@ public abstract class AbstractClientConnector implements ClientConnector { } } + /** + * Get an Iterable for iterating over all child connectors, including both + * extensions and child components. + * + * @param connector + * the connector to get children for + * @return an Iterable giving all child connectors. + */ public static Iterable getAllChildrenIterable( final ClientConnector connector) { return new AllChildrenIterable(connector); @@ -380,6 +394,13 @@ public abstract class AbstractClientConnector implements ClientConnector { return Collections.unmodifiableCollection(extensions); } + /** + * Add an extension to this connector. This method is protected to allow + * extensions to select which targets they can extend. + * + * @param extension + * the extension to add + */ protected void addExtension(Extension extension) { ClientConnector previousParent = extension.getParent(); if (previousParent == this) { @@ -439,6 +460,14 @@ public abstract class AbstractClientConnector implements ClientConnector { } } + /** + * {@inheritDoc} + * + *

+ * The {@link #getApplication()} and {@link #getRoot()} methods might return + * null after this method is called. + *

+ */ public void detach() { for (ClientConnector connector : getAllChildrenIterable(this)) { connector.detach(); diff --git a/src/com/vaadin/terminal/AbstractExtension.java b/src/com/vaadin/terminal/AbstractExtension.java index 6753d6f929..33a60e39ef 100644 --- a/src/com/vaadin/terminal/AbstractExtension.java +++ b/src/com/vaadin/terminal/AbstractExtension.java @@ -6,19 +6,51 @@ package com.vaadin.terminal; import com.vaadin.terminal.gwt.server.ClientConnector; +/** + * An extension is an entity that is attached to a Component or another + * Extension and independently communicates between client and server. + *

+ * Extensions can use shared state and RPC in the same way as components. + *

+ * AbstractExtension adds a mechanism for adding the extension to any Connector + * (extend). To let the Extension determine what kind target it can be added to, + * the extend method is declared as protected. + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ public abstract class AbstractExtension extends AbstractClientConnector implements Extension { private boolean previouslyAttached = false; - protected Class getAcceptedParentType() { + /** + * Gets a type that the parent must be an instance of. Override this if the + * extension only support certain targets, e.g. if only TextFields can be + * extended. + * + * @return a type that the parent must be an instance of + */ + protected Class getSupportedParentType() { return ClientConnector.class; } + /** + * Add this extension to the target connector. This method is protected to + * allow subclasses to require a more specific type of target. + * + * @param target + * the connector to attach this extension to + */ protected void extend(AbstractClientConnector target) { target.addExtension(this); } - protected void removeFromTarget() { + /** + * Remove this extension from its target. After an extension has been + * removed, it can not be attached again. + */ + public void removeFromTarget() { getParent().removeExtension(this); } @@ -29,14 +61,14 @@ public abstract class AbstractExtension extends AbstractClientConnector "An extension can not be set to extend a new target after getting detached from the previous."); } - Class acceptedParentType = getAcceptedParentType(); - if (parent == null || acceptedParentType.isInstance(parent)) { + Class supportedParentType = getSupportedParentType(); + if (parent == null || supportedParentType.isInstance(parent)) { super.setParent(parent); previouslyAttached = true; } else { throw new IllegalArgumentException(getClass().getName() + " can only be attached to targets of type " - + acceptedParentType.getName() + " but attach to " + + supportedParentType.getName() + " but attach to " + parent.getClass().getName() + " was attempted."); } } diff --git a/src/com/vaadin/terminal/AbstractJavaScriptExtension.java b/src/com/vaadin/terminal/AbstractJavaScriptExtension.java index a2f8019858..bdcd948c74 100644 --- a/src/com/vaadin/terminal/AbstractJavaScriptExtension.java +++ b/src/com/vaadin/terminal/AbstractJavaScriptExtension.java @@ -7,22 +7,146 @@ package com.vaadin.terminal; import com.vaadin.terminal.gwt.client.JavaScriptExtensionState; import com.vaadin.ui.JavaScriptCallback; -public class AbstractJavaScriptExtension extends AbstractExtension { +/** + * Base class for Extensions with all client-side logic implemented using + * JavaScript. + *

+ * When a new JavaScript extension is initialized in the browser, the framework + * will look for a globally defined JavaScript function that will initialize the + * extension. The name of the initialization function is formed by replacing . + * with _ in the name of the server-side class. If no such function is defined, + * each super class is used in turn until a match is found. The framework will + * thus first attempt with com_example_MyExtension for the + * server-side + * com.example.MyExtension extends AbstractJavaScriptExtension + * class. If MyExtension instead extends com.example.SuperExtension + * , then com_example_SuperExtension will also be attempted if + * com_example_MyExtension has not been defined. + *

+ * + * The initialization function will be called with this pointing to + * a connector wrapper object providing integration to Vaadin with the following + * functions: + *

    + *
  • getConnectorId() - returns a string with the id of the + * connector.
  • + *
  • getParentId([connectorId]) - returns a string with the id of + * the connector's parent. If connectorId is provided, the id of + * the parent of the corresponding connector with the passed id is returned + * instead.
  • + *
  • getWidgetElement([connectorId]) - returns the DOM Element + * that is the root of a connector's widget. null is returned if + * the connector can not be found or if the connector doesn't have a widget. If + * connectorId is not provided, the connector id of the current + * connector will be used.
  • + *
  • getState() - returns an object corresponding to the shared + * state defined on the server. The scheme for conversion between Java and + * JavaScript types is described bellow.
  • + *
  • registerRpc([name, ] rpcObject) - registers the + * rpcObject as a RPC handler. rpcObject should be an + * object with field containing functions for all eligible RPC functions. If + * name is provided, the RPC handler will only used for RPC calls + * for the RPC interface with the same fully qualified Java name. If no + * name is provided, the RPC handler will be used for all incoming + * RPC invocations where the RPC method name is defined as a function field in + * the handler. The scheme for conversion between Java types in the RPC + * interface definition and the JavaScript values passed as arguments to the + * handler functions is described bellow.
  • + *
  • getRpcProxy([name]) - returns an RPC proxy object. If + * name is provided, the proxy object will contain functions for + * all methods in the RPC interface with the same fully qualified name, provided + * a RPC handler has been registered by the server-side code. If no + * name is provided, the returned RPC proxy object will contain + * functions for all methods in all RPC interfaces registered for the connector + * on the server. If the same method name is present in multiple registered RPC + * interfaces, the corresponding function in the RPC proxy object will throw an + * exception when called. The scheme for conversion between Java types in the + * RPC interface and the JavaScript values that should be passed to the + * functions is described bellow.
  • + *
+ * The connector wrapper also supports these special functions: + *
    + *
  • onStateChange - If the JavaScript code assigns a function to + * the field, that function is called whenever the contents of the shared state + * is changed.
  • + *
  • Any field name corresponding to a call to + * {@link #registerCallback(String, JavaScriptCallback)} on the server will + * automatically be present as a function that triggers the registered callback + * on the server.
  • + *
  • Any field name referred to using + * {@link #invokeCallback(String, Object...)} on the server will be called if a + * function has been assigned to the field.
  • + *
+ *

+ * + * Values in the Shared State and in RPC calls are converted between Java and + * JavaScript using the following conventions: + *

    + *
  • Primitive Java numbers (byte, char, int, long, float, double) and their + * boxed types (Byte, Character, Integer, Long, Float, Double) are represented + * by JavaScript numbers.
  • + *
  • The primitive Java boolean and the boxed Boolean are represented by + * JavaScript booleans.
  • + *
  • Java Strings are represented by JavaScript strings.
  • + *
  • List, Set and all arrays in Java are represented by JavaScript arrays.
  • + *
  • Map in Java is represented by JavaScript object with fields + * corresponding to the map keys.
  • + *
  • Any other Java Map is represented by a JavaScript array containing two + * arrays, the first contains the keys and the second contains the values in the + * same order.
  • + *
  • A Java Bean is represented by a JavaScript object with fields + * corresponding to the bean's properties.
  • + *
  • A Java Connector is represented by a JavaScript string containing the + * connector's id.
  • + *
  • A pluggable serialization mechanism is provided for types not described + * here. Please refer to the documentation for specific types for serialization + * information.
  • + *
+ * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ +public abstract class AbstractJavaScriptExtension extends AbstractExtension { private JavaScriptCallbackHelper callbackHelper = new JavaScriptCallbackHelper( this); @Override - protected void registerRpc(T implementation, - java.lang.Class rpcInterfaceType) { + protected void registerRpc(T implementation, Class rpcInterfaceType) { super.registerRpc(implementation, rpcInterfaceType); callbackHelper.registerRpc(rpcInterfaceType); } + /** + * Register a {@link JavaScriptCallback} that can be called from the + * JavaScript using the provided name. A JavaScript function with the + * provided name will be added to the connector wrapper object (initially + * available as this). Calling that JavaScript function will + * cause the call method in the registered {@link JavaScriptCallback} to be + * invoked with the same arguments. + * + * @param functionName + * the name that should be used for client-side callback + * @param javaScriptCallback + * the callback object that will be invoked when the JavaScript + * function is called + */ protected void registerCallback(String functionName, JavaScriptCallback javaScriptCallback) { callbackHelper.registerCallback(functionName, javaScriptCallback); } + /** + * Invoke a named function that the connector JavaScript has added to the + * JavaScript connector wrapper object. The arguments should only contain + * data types that can be represented in JavaScript, including primitive + * boxing types, arrays, String, List, Set, Map, Connector and JavaBeans. + * + * @param name + * the name of the function + * @param arguments + * function arguments + */ protected void invokeCallback(String name, Object... arguments) { callbackHelper.invokeCallback(name, arguments); } diff --git a/src/com/vaadin/terminal/Extension.java b/src/com/vaadin/terminal/Extension.java index 7769423f0d..ef5bb4cf8d 100644 --- a/src/com/vaadin/terminal/Extension.java +++ b/src/com/vaadin/terminal/Extension.java @@ -6,6 +6,22 @@ package com.vaadin.terminal; import com.vaadin.terminal.gwt.server.ClientConnector; +/** + * An extension is an entity that is attached to a Component or another + * Extension and independently communicates between client and server. + *

+ * An extension can only be attached once. It is not supported to move an + * extension from one target to another. + *

+ * Extensions can use shared state and RPC in the same way as components. + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ public interface Extension extends ClientConnector { - + /* + * Currently just an empty marker interface to distinguish between + * extensions and other connectors, e.g. components + */ } diff --git a/src/com/vaadin/terminal/JavaScriptCallbackHelper.java b/src/com/vaadin/terminal/JavaScriptCallbackHelper.java index 2da64d7b10..01db0267d9 100644 --- a/src/com/vaadin/terminal/JavaScriptCallbackHelper.java +++ b/src/com/vaadin/terminal/JavaScriptCallbackHelper.java @@ -14,11 +14,25 @@ import java.util.Set; import com.vaadin.external.json.JSONArray; import com.vaadin.external.json.JSONException; +import com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper; import com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper.JavaScriptConnectorState; import com.vaadin.tools.ReflectTools; +import com.vaadin.ui.AbstractJavaScriptComponent; import com.vaadin.ui.JavaScript.JavaScriptCallbackRpc; import com.vaadin.ui.JavaScriptCallback; +/** + * Internal helper class used to implement functionality common to + * {@link AbstractJavaScriptComponent} and {@link AbstractJavaScriptExtension}. + * Corresponding support in client-side code is in + * {@link JavaScriptConnectorHelper}. + *

+ * You should most likely no use this class directly. + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ public class JavaScriptCallbackHelper implements Serializable { private static final Method CALL_METHOD = ReflectTools.findMethod( diff --git a/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java b/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java index 61c50dbcb4..2a97e4a770 100644 --- a/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java +++ b/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java @@ -10,8 +10,8 @@ import com.vaadin.terminal.gwt.client.extensions.AbstractExtensionConnector; import com.vaadin.terminal.gwt.client.ui.Connect; @Connect(AbstractJavaScriptExtension.class) -public class JavaScriptExtension extends AbstractExtensionConnector implements - HasJavaScriptConnectorHelper { +public final class JavaScriptExtension extends AbstractExtensionConnector + implements HasJavaScriptConnectorHelper { private final JavaScriptConnectorHelper helper = new JavaScriptConnectorHelper( this); diff --git a/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java index ab5280fee9..bb062a6677 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java @@ -8,8 +8,8 @@ import com.vaadin.terminal.gwt.client.communication.HasJavaScriptConnectorHelper import com.vaadin.ui.AbstractJavaScriptComponent; @Connect(AbstractJavaScriptComponent.class) -public class JavaScriptComponentConnector extends AbstractComponentConnector - implements HasJavaScriptConnectorHelper { +public final class JavaScriptComponentConnector extends + AbstractComponentConnector implements HasJavaScriptConnectorHelper { private final JavaScriptConnectorHelper helper = new JavaScriptConnectorHelper( this) { diff --git a/src/com/vaadin/terminal/gwt/server/ClientConnector.java b/src/com/vaadin/terminal/gwt/server/ClientConnector.java index 860627a352..dfdd58879d 100644 --- a/src/com/vaadin/terminal/gwt/server/ClientConnector.java +++ b/src/com/vaadin/terminal/gwt/server/ClientConnector.java @@ -12,7 +12,6 @@ import com.vaadin.terminal.gwt.client.Connector; import com.vaadin.terminal.gwt.client.communication.SharedState; import com.vaadin.ui.Component; import com.vaadin.ui.ComponentContainer; -import com.vaadin.ui.Root; /** * Interface implemented by all connectors that are capable of communicating @@ -30,8 +29,6 @@ public interface ClientConnector extends Connector, RpcTarget { * * @return an unmodifiable ordered list of pending server to client method * calls (not null) - * - * @since 7.0 */ public List retrievePendingRpcCalls(); @@ -61,7 +58,7 @@ public interface ClientConnector extends Connector, RpcTarget { * Causes a repaint of this connector, and all connectors below it. * * This should only be used in special cases, e.g when the state of a - * descendant depends on the state of a ancestor. + * descendant depends on the state of an ancestor. */ public void requestRepaintAll(); @@ -69,18 +66,18 @@ public interface ClientConnector extends Connector, RpcTarget { * Sets the parent connector of the connector. * *

- * This method automatically calls {@link #attach()} if the parent becomes - * attached to the application, regardless of whether it was attached - * previously. Conversely, if the parent is {@code null} and the connector - * is attached to the application, {@link #detach()} is called for the - * connector. + * This method automatically calls {@link #attach()} if the connector + * becomes attached to the application, regardless of whether it was + * attached previously. Conversely, if the parent is {@code null} and the + * connector is attached to the application, {@link #detach()} is called for + * the connector. *

*

* This method is rarely called directly. One of the * {@link ComponentContainer#addComponent(Component)} or - * {@link AbstractClientConnector#addFeature(Feature)} methods is normally - * used for adding connectors to a container and it will call this method - * implicitly. + * {@link AbstractClientConnector#addExtension(Extension)} methods are + * normally used for adding connectors to a parent and they will call this + * method implicitly. *

* *

@@ -103,15 +100,13 @@ public interface ClientConnector extends Connector, RpcTarget { * The caller of this method is {@link #setParent(ClientConnector)} if the * parent is itself already attached to the application. If not, the parent * will call the {@link #attach()} for all its children when it is attached - * to the application. This method is always called before the connector is - * painted for the first time. + * to the application. This method is always called before the connector's + * data is sent to the client-side for the first time. *

* *

* The attachment logic is implemented in {@link AbstractClientConnector}. *

- * - * @see #getApplication() */ public void attach(); @@ -119,25 +114,26 @@ public interface ClientConnector extends Connector, RpcTarget { * Notifies the component that it is detached from the application. * *

- * The {@link #getApplication()} and {@link #getRoot()} methods might return - * null after this method is called. - *

- * - *

- * This method must call {@link Root#componentDetached(Component)} to let - * the Root know that a new Component has been attached. - *

- * * - *

- * The caller of this method is {@link #setParent(Component)} if the parent - * is in the application. When the parent is detached from the application - * it is its response to call {@link #detach()} for all the children and to - * detach itself from the terminal. + * The caller of this method is {@link #setParent(ClientConnector)} if the + * parent is in the application. When the parent is detached from the + * application it is its response to call {@link #detach()} for all the + * children and to detach itself from the terminal. *

*/ public void detach(); + /** + * Get a read-only collection of all extensions attached to this connector. + * + * @return a collection of extensions + */ public Collection getExtensions(); + /** + * Remove an extension from this connector. + * + * @param extension + * the extension to remove. + */ public void removeExtension(Extension extension); } diff --git a/src/com/vaadin/ui/AbstractJavaScriptComponent.java b/src/com/vaadin/ui/AbstractJavaScriptComponent.java index 343caf4abb..95c45f55f9 100644 --- a/src/com/vaadin/ui/AbstractJavaScriptComponent.java +++ b/src/com/vaadin/ui/AbstractJavaScriptComponent.java @@ -5,23 +5,151 @@ package com.vaadin.ui; import com.vaadin.terminal.JavaScriptCallbackHelper; import com.vaadin.terminal.gwt.client.ui.JavaScriptComponentState; +import com.vaadin.terminal.gwt.client.ui.JavaScriptWidget; +/** + * Base class for Components with all client-side logic implemented using + * JavaScript. + *

+ * When a new JavaScript component is initialized in the browser, the framework + * will look for a globally defined JavaScript function that will initialize the + * component. The name of the initialization function is formed by replacing . + * with _ in the name of the server-side class. If no such function is defined, + * each super class is used in turn until a match is found. The framework will + * thus first attempt with com_example_MyComponent for the + * server-side + * com.example.MyComponent extends AbstractJavaScriptComponent + * class. If MyComponent instead extends com.example.SuperComponent + * , then com_example_SuperComponent will also be attempted if + * com_example_MyComponent has not been defined. + *

+ * JavaScript components have a very simple GWT widget ({@link JavaScriptWidget} + * ) just consisting of a div element to which the JavaScript code + * should initialize its own user interface. + *

+ * The initialization function will be called with this pointing to + * a connector wrapper object providing integration to Vaadin with the following + * functions: + *

    + *
  • getConnectorId() - returns a string with the id of the + * connector.
  • + *
  • getParentId([connectorId]) - returns a string with the id of + * the connector's parent. If connectorId is provided, the id of + * the parent of the corresponding connector with the passed id is returned + * instead.
  • + *
  • getWidgetElement([connectorId]) - returns the DOM Element + * that is the root of a connector's widget. null is returned if + * the connector can not be found or if the connector doesn't have a widget. If + * connectorId is not provided, the connector id of the current + * connector will be used.
  • + *
  • getState() - returns an object corresponding to the shared + * state defined on the server. The scheme for conversion between Java and + * JavaScript types is described bellow.
  • + *
  • registerRpc([name, ] rpcObject) - registers the + * rpcObject as a RPC handler. rpcObject should be an + * object with field containing functions for all eligible RPC functions. If + * name is provided, the RPC handler will only used for RPC calls + * for the RPC interface with the same fully qualified Java name. If no + * name is provided, the RPC handler will be used for all incoming + * RPC invocations where the RPC method name is defined as a function field in + * the handler. The scheme for conversion between Java types in the RPC + * interface definition and the JavaScript values passed as arguments to the + * handler functions is described bellow.
  • + *
  • getRpcProxy([name]) - returns an RPC proxy object. If + * name is provided, the proxy object will contain functions for + * all methods in the RPC interface with the same fully qualified name, provided + * a RPC handler has been registered by the server-side code. If no + * name is provided, the returned RPC proxy object will contain + * functions for all methods in all RPC interfaces registered for the connector + * on the server. If the same method name is present in multiple registered RPC + * interfaces, the corresponding function in the RPC proxy object will throw an + * exception when called. The scheme for conversion between Java types in the + * RPC interface and the JavaScript values that should be passed to the + * functions is described bellow.
  • + *
+ * The connector wrapper also supports these special functions: + *
    + *
  • onStateChange - If the JavaScript code assigns a function to + * the field, that function is called whenever the contents of the shared state + * is changed.
  • + *
  • Any field name corresponding to a call to + * {@link #registerCallback(String, JavaScriptCallback)} on the server will + * automatically be present as a function that triggers the registered callback + * on the server.
  • + *
  • Any field name referred to using + * {@link #invokeCallback(String, Object...)} on the server will be called if a + * function has been assigned to the field.
  • + *
+ *

+ * + * Values in the Shared State and in RPC calls are converted between Java and + * JavaScript using the following conventions: + *

    + *
  • Primitive Java numbers (byte, char, int, long, float, double) and their + * boxed types (Byte, Character, Integer, Long, Float, Double) are represented + * by JavaScript numbers.
  • + *
  • The primitive Java boolean and the boxed Boolean are represented by + * JavaScript booleans.
  • + *
  • Java Strings are represented by JavaScript strings.
  • + *
  • List, Set and all arrays in Java are represented by JavaScript arrays.
  • + *
  • Map in Java is represented by JavaScript object with fields + * corresponding to the map keys.
  • + *
  • Any other Java Map is represented by a JavaScript array containing two + * arrays, the first contains the keys and the second contains the values in the + * same order.
  • + *
  • A Java Bean is represented by a JavaScript object with fields + * corresponding to the bean's properties.
  • + *
  • A Java Connector is represented by a JavaScript string containing the + * connector's id.
  • + *
  • A pluggable serialization mechanism is provided for types not described + * here. Please refer to the documentation for specific types for serialization + * information.
  • + *
+ * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ public class AbstractJavaScriptComponent extends AbstractComponent { private JavaScriptCallbackHelper callbackHelper = new JavaScriptCallbackHelper( this); @Override - protected void registerRpc(T implementation, - java.lang.Class rpcInterfaceType) { + protected void registerRpc(T implementation, Class rpcInterfaceType) { super.registerRpc(implementation, rpcInterfaceType); callbackHelper.registerRpc(rpcInterfaceType); } + /** + * Register a {@link JavaScriptCallback} that can be called from the + * JavaScript using the provided name. A JavaScript function with the + * provided name will be added to the connector wrapper object (initially + * available as this). Calling that JavaScript function will + * cause the call method in the registered {@link JavaScriptCallback} to be + * invoked with the same arguments. + * + * @param functionName + * the name that should be used for client-side callback + * @param javaScriptCallback + * the callback object that will be invoked when the JavaScript + * function is called + */ protected void registerCallback(String functionName, - JavaScriptCallback javascriptCallback) { - callbackHelper.registerCallback(functionName, javascriptCallback); + JavaScriptCallback javaScriptCallback) { + callbackHelper.registerCallback(functionName, javaScriptCallback); } + /** + * Invoke a named function that the connector JavaScript has added to the + * JavaScript connector wrapper object. The arguments should only contain + * data types that can be represented in JavaScript, including primitive + * boxing types, arrays, String, List, Set, Map, Connector and JavaBeans. + * + * @param name + * the name of the function + * @param arguments + * function arguments + */ protected void invokeCallback(String name, Object... arguments) { callbackHelper.invokeCallback(name, arguments); } diff --git a/src/com/vaadin/ui/JavaScript.java b/src/com/vaadin/ui/JavaScript.java index 241d477506..d256717711 100644 --- a/src/com/vaadin/ui/JavaScript.java +++ b/src/com/vaadin/ui/JavaScript.java @@ -15,6 +15,16 @@ import com.vaadin.terminal.gwt.client.communication.ServerRpc; import com.vaadin.terminal.gwt.client.extensions.javascriptmanager.ExecuteJavaScriptRpc; import com.vaadin.terminal.gwt.client.extensions.javascriptmanager.JavaScriptManagerState; +/** + * Provides access to JavaScript functionality in the web browser. To get an + * instance of JavaScript, either use Page.getJavaScript() or + * JavaScript.getCurrent() as a shorthand for getting the JavaScript object + * corresponding to the current Page. + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ public class JavaScript extends AbstractExtension { private Map callbacks = new HashMap(); @@ -24,6 +34,11 @@ public class JavaScript extends AbstractExtension { public void call(String name, JSONArray arguments); } + /** + * Creates a new JavaScript object. You should typically not this, but + * instead use the JavaScript object already associated with your Page + * object. + */ public JavaScript() { registerRpc(new JavaScriptCallbackRpc() { public void call(String name, JSONArray arguments) { @@ -43,6 +58,27 @@ public class JavaScript extends AbstractExtension { return (JavaScriptManagerState) super.getState(); } + /** + * Add a new function to the global JavaScript namespace (i.e. the window + * object). The call method in the passed + * {@link JavaScriptCallback} object will be invoked with the same + * parameters whenever the JavaScript function is called in the browser. + * + * A callback added with the name "myCallback" can thus be + * invoked with the following JavaScript code: + * window.myCallback(argument1, argument2). + * + * If the name parameter contains dots, simple objects are created on demand + * to allow calling the function using the same name (e.g. + * window.myObject.myFunction). + * + * @param name + * the name that the callback function should get in the global + * JavaScript namespace. + * @param callback + * the JavaScriptCallback that will be invoked if the JavaScript + * function is called. + */ public void addCallback(String name, JavaScriptCallback callback) { callbacks.put(name, callback); if (getState().getNames().add(name)) { @@ -50,6 +86,17 @@ public class JavaScript extends AbstractExtension { } } + /** + * Removes a JavaScripCallback from the browser's global JavaScript + * namespace. + * + * If the name contains dots and intermediate were created by + * {@link #addCallback(String, JavaScriptCallback)}addCallback, these + * objects will not be removed when the callback is removed. + * + * @param name + * the name of the callback to remove + */ public void removeCallback(String name) { callbacks.remove(name); if (getState().getNames().remove(name)) { @@ -57,10 +104,25 @@ public class JavaScript extends AbstractExtension { } } + /** + * Executes the given JavaScript code in the browser. + * + * @param script + * The JavaScript code to run. + */ public void execute(String script) { getRpcProxy(ExecuteJavaScriptRpc.class).executeJavaScript(script); } + /** + * Get the JavaScript object for the current Page, or null if there is no + * current page. + * + * @see Page#getCurrent() + * + * @return the JavaScript object corresponding to the current Page, or + * null if there is no current page. + */ public static JavaScript getCurrent() { Page page = Page.getCurrent(); if (page == null) { @@ -69,4 +131,16 @@ public class JavaScript extends AbstractExtension { return page.getJavaScript(); } + /** + * JavaScript is not designed to be removed. + * + * @throws UnsupportedOperationException + * when invoked + */ + @Override + public void removeFromTarget() { + throw new UnsupportedOperationException( + "JavaScript is not designed to be removed."); + } + } diff --git a/src/com/vaadin/ui/JavaScriptCallback.java b/src/com/vaadin/ui/JavaScriptCallback.java index e6b16010e4..49f7695e89 100644 --- a/src/com/vaadin/ui/JavaScriptCallback.java +++ b/src/com/vaadin/ui/JavaScriptCallback.java @@ -8,7 +8,34 @@ import java.io.Serializable; import com.vaadin.external.json.JSONArray; import com.vaadin.external.json.JSONException; +import com.vaadin.terminal.AbstractJavaScriptExtension; +/** + * Defines a method that is called by a client-side JavaScript function. When + * the corresponding JavaScript function is called, the {@link #call(JSONArray)} + * method is invoked. + * + * @see JavaScript#addCallback(String, JavaScriptCallback) + * @see AbstractJavaScriptComponent#registerCallback(String, JavaScriptCallback) + * @see AbstractJavaScriptExtension#registerCallback(String, JavaScriptCallback) + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ public interface JavaScriptCallback extends Serializable { + /** + * Invoked whenever the corresponding JavaScript function is called in the + * browser. + *

+ * Because of the asynchronous nature of the communication between client + * and server, no return value can be sent back to the browser. + * + * @param arguments + * an array with JSON representations of the arguments with which + * the JavaScript function was called. + * @throws JSONException + * if the arguments can not be interpreted + */ public void call(JSONArray arguments) throws JSONException; } -- cgit v1.2.3