You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

JavaScriptManagerConnector.java 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*
  2. @VaadinApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.terminal.gwt.client.extensions.javascriptmanager;
  5. import java.util.HashSet;
  6. import java.util.Set;
  7. import com.google.gwt.core.client.JavaScriptObject;
  8. import com.google.gwt.core.client.JsArray;
  9. import com.google.gwt.json.client.JSONArray;
  10. import com.vaadin.shared.communication.MethodInvocation;
  11. import com.vaadin.shared.extension.javascriptmanager.ExecuteJavaScriptRpc;
  12. import com.vaadin.shared.extension.javascriptmanager.JavaScriptManagerState;
  13. import com.vaadin.shared.ui.Connect;
  14. import com.vaadin.terminal.gwt.client.communication.StateChangeEvent;
  15. import com.vaadin.terminal.gwt.client.extensions.AbstractExtensionConnector;
  16. import com.vaadin.ui.JavaScript;
  17. @Connect(JavaScript.class)
  18. public class JavaScriptManagerConnector extends AbstractExtensionConnector {
  19. private Set<String> currentNames = new HashSet<String>();
  20. @Override
  21. protected void init() {
  22. registerRpc(ExecuteJavaScriptRpc.class, new ExecuteJavaScriptRpc() {
  23. @Override
  24. public void executeJavaScript(String Script) {
  25. eval(Script);
  26. }
  27. });
  28. }
  29. @Override
  30. public void onStateChanged(StateChangeEvent stateChangeEvent) {
  31. super.onStateChanged(stateChangeEvent);
  32. Set<String> newNames = getState().getNames();
  33. // Current names now only contains orphan callbacks
  34. currentNames.removeAll(newNames);
  35. for (String name : currentNames) {
  36. removeCallback(name);
  37. }
  38. currentNames = new HashSet<String>(newNames);
  39. for (String name : newNames) {
  40. addCallback(name);
  41. }
  42. }
  43. // TODO Ensure we don't overwrite anything (important) in $wnd
  44. private native void addCallback(String name)
  45. /*-{
  46. var m = this;
  47. var target = $wnd;
  48. var parts = name.split('.');
  49. for(var i = 0; i < parts.length - 1; i++) {
  50. var part = parts[i];
  51. if (target[part] === undefined) {
  52. target[part] = {};
  53. }
  54. target = target[part];
  55. }
  56. target[parts[parts.length - 1]] = $entry(function() {
  57. //Must make a copy because arguments is an array-like object (not instanceof Array), causing suboptimal JSON encoding
  58. var args = Array.prototype.slice.call(arguments, 0);
  59. m.@com.vaadin.terminal.gwt.client.extensions.javascriptmanager.JavaScriptManagerConnector::sendRpc(Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(name, args);
  60. });
  61. }-*/;
  62. // TODO only remove what we actually added
  63. // TODO We might leave empty objects behind, but there's no good way of
  64. // knowing whether they are unused
  65. private native void removeCallback(String name)
  66. /*-{
  67. var target = $wnd;
  68. var parts = name.split('.');
  69. for(var i = 0; i < parts.length - 1; i++) {
  70. var part = parts[i];
  71. if (target[part] === undefined) {
  72. $wnd.console.log(part,'not defined in',target);
  73. // No longer attached -> nothing more to do
  74. return;
  75. }
  76. target = target[part];
  77. }
  78. $wnd.console.log('removing',parts[parts.length - 1],'from',target);
  79. delete target[parts[parts.length - 1]];
  80. }-*/;
  81. private static native void eval(String script)
  82. /*-{
  83. if(script) {
  84. (new $wnd.Function(script)).apply($wnd);
  85. }
  86. }-*/;
  87. public void sendRpc(String name, JsArray<JavaScriptObject> arguments) {
  88. Object[] parameters = new Object[] { name, new JSONArray(arguments) };
  89. /*
  90. * Must invoke manually as the RPC interface can't be used in GWT
  91. * because of the JSONArray parameter
  92. */
  93. getConnection().addMethodInvocationToQueue(
  94. new MethodInvocation(getConnectorId(),
  95. "com.vaadin.ui.JavaScript$JavaScriptCallbackRpc",
  96. "call", parameters), true);
  97. }
  98. @Override
  99. public JavaScriptManagerState getState() {
  100. return (JavaScriptManagerState) super.getState();
  101. }
  102. }