Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

JavaScriptRendererConnector.java 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /*
  2. * Copyright 2000-2016 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.v7.client.connectors;
  17. import java.util.ArrayList;
  18. import java.util.Collection;
  19. import com.google.gwt.core.client.JavaScriptObject;
  20. import com.google.gwt.core.client.JsArrayString;
  21. import com.google.gwt.dom.client.NativeEvent;
  22. import com.vaadin.client.JavaScriptConnectorHelper;
  23. import com.vaadin.client.Util;
  24. import com.vaadin.client.communication.HasJavaScriptConnectorHelper;
  25. import com.vaadin.shared.JavaScriptExtensionState;
  26. import com.vaadin.shared.ui.Connect;
  27. import com.vaadin.v7.client.renderers.ComplexRenderer;
  28. import com.vaadin.v7.client.renderers.Renderer;
  29. import com.vaadin.v7.client.widget.grid.CellReference;
  30. import com.vaadin.v7.client.widget.grid.RendererCellReference;
  31. import com.vaadin.v7.ui.renderers.AbstractJavaScriptRenderer;
  32. import elemental.json.JsonObject;
  33. import elemental.json.JsonValue;
  34. /**
  35. * Connector for server-side renderer implemented using JavaScript.
  36. *
  37. * @since 7.4
  38. * @author Vaadin Ltd
  39. */
  40. // This is really typed to <JsonValue>, but because of the way native strings
  41. // are not always instanceof JsonValue, we need to accept Object
  42. @Connect(AbstractJavaScriptRenderer.class)
  43. public class JavaScriptRendererConnector
  44. extends AbstractGridRendererConnector<Object>
  45. implements HasJavaScriptConnectorHelper {
  46. private final JavaScriptConnectorHelper helper = new JavaScriptConnectorHelper(
  47. this);
  48. private final JavaScriptObject cellReferenceWrapper = createCellReferenceWrapper();
  49. @Override
  50. protected void init() {
  51. super.init();
  52. helper.init();
  53. addGetRowKey(helper.getConnectorWrapper());
  54. }
  55. private static native JavaScriptObject createCellReferenceWrapper()
  56. /*-{
  57. var reference = {};
  58. var setProperty = function(name, getter, setter) {
  59. var descriptor = {
  60. get: getter
  61. }
  62. if (setter) {
  63. descriptor.set = setter;
  64. }
  65. Object.defineProperty(reference, name, descriptor);
  66. };
  67. setProperty("element", function() {
  68. return reference.target.@CellReference::getElement()();
  69. }, null);
  70. setProperty("rowIndex", function() {
  71. return reference.target.@CellReference::getRowIndex()();
  72. }, null);
  73. setProperty("columnIndex", function() {
  74. return reference.target.@CellReference::getColumnIndex()();
  75. }, null);
  76. setProperty("colSpan", function() {
  77. return reference.target.@RendererCellReference::getColSpan()();
  78. }, function(colSpan) {
  79. reference.target.@RendererCellReference::setColSpan(*)(colSpan);
  80. });
  81. return reference;
  82. }-*/;
  83. @Override
  84. public JavaScriptExtensionState getState() {
  85. return (JavaScriptExtensionState) super.getState();
  86. }
  87. private native void addGetRowKey(JavaScriptObject wrapper)
  88. /*-{
  89. var self = this;
  90. wrapper.getRowKey = $entry(function(rowIndex) {
  91. return @JavaScriptRendererConnector::findRowKey(*)(self, rowIndex);
  92. });
  93. }-*/;
  94. private static String findRowKey(JavaScriptRendererConnector connector,
  95. int rowIndex) {
  96. GridConnector gc = (GridConnector) connector.getParent();
  97. JsonObject row = gc.getWidget().getDataSource().getRow(rowIndex);
  98. return connector.getRowKey(row);
  99. }
  100. private boolean hasFunction(String name) {
  101. return hasFunction(helper.getConnectorWrapper(), name);
  102. }
  103. private static native boolean hasFunction(JavaScriptObject wrapper,
  104. String name)
  105. /*-{
  106. return typeof wrapper[name] === 'function';
  107. }-*/;
  108. @Override
  109. protected Renderer<Object> createRenderer() {
  110. helper.ensureJavascriptInited();
  111. if (!hasFunction("render")) {
  112. throw new RuntimeException(
  113. "JavaScriptRenderer " + helper.getInitFunctionName()
  114. + " must have a function named 'render'");
  115. }
  116. final boolean hasInit = hasFunction("init");
  117. final boolean hasDestroy = hasFunction("destroy");
  118. final boolean hasOnActivate = hasFunction("onActivate");
  119. final boolean hasGetConsumedEvents = hasFunction("getConsumedEvents");
  120. final boolean hasOnBrowserEvent = hasFunction("onBrowserEvent");
  121. return new ComplexRenderer<Object>() {
  122. @Override
  123. public void render(RendererCellReference cell, Object data) {
  124. if (data instanceof JsonValue) {
  125. data = Util.json2jso((JsonValue) data);
  126. }
  127. render(helper.getConnectorWrapper(), getJsCell(cell), data);
  128. }
  129. private JavaScriptObject getJsCell(CellReference<?> cell) {
  130. updateCellReference(cellReferenceWrapper, cell);
  131. return cellReferenceWrapper;
  132. }
  133. public native void render(JavaScriptObject wrapper,
  134. JavaScriptObject cell, Object data)
  135. /*-{
  136. wrapper.render(cell, data);
  137. }-*/;
  138. @Override
  139. public void init(RendererCellReference cell) {
  140. if (hasInit) {
  141. init(helper.getConnectorWrapper(), getJsCell(cell));
  142. }
  143. }
  144. private native void init(JavaScriptObject wrapper,
  145. JavaScriptObject cell)
  146. /*-{
  147. wrapper.init(cell);
  148. }-*/;
  149. private native void updateCellReference(
  150. JavaScriptObject cellWrapper, CellReference<?> target)
  151. /*-{
  152. cellWrapper.target = target;
  153. }-*/;
  154. @Override
  155. public void destroy(RendererCellReference cell) {
  156. if (hasDestroy) {
  157. destory(helper.getConnectorWrapper(), getJsCell(cell));
  158. } else {
  159. super.destroy(cell);
  160. }
  161. }
  162. private native void destory(JavaScriptObject wrapper,
  163. JavaScriptObject cell)
  164. /*-{
  165. wrapper.destory(cell);
  166. }-*/;
  167. @Override
  168. public boolean onActivate(CellReference<?> cell) {
  169. if (hasOnActivate) {
  170. return onActivate(helper.getConnectorWrapper(),
  171. getJsCell(cell));
  172. } else {
  173. return super.onActivate(cell);
  174. }
  175. }
  176. private native boolean onActivate(JavaScriptObject wrapper,
  177. JavaScriptObject cell)
  178. /*-{
  179. return !!wrapper.onActivate(cell);
  180. }-*/;
  181. @Override
  182. public Collection<String> getConsumedEvents() {
  183. if (hasGetConsumedEvents) {
  184. JsArrayString events = getConsumedEvents(
  185. helper.getConnectorWrapper());
  186. ArrayList<String> list = new ArrayList<String>(
  187. events.length());
  188. for (int i = 0; i < events.length(); i++) {
  189. list.add(events.get(i));
  190. }
  191. return list;
  192. } else {
  193. return super.getConsumedEvents();
  194. }
  195. }
  196. private native JsArrayString getConsumedEvents(
  197. JavaScriptObject wrapper)
  198. /*-{
  199. var rawEvents = wrapper.getConsumedEvents();
  200. var events = [];
  201. for(var i = 0; i < rawEvents.length; i++) {
  202. events[i] = ""+rawEvents[i];
  203. }
  204. return events;
  205. }-*/;
  206. @Override
  207. public boolean onBrowserEvent(CellReference<?> cell,
  208. NativeEvent event) {
  209. if (hasOnBrowserEvent) {
  210. return onBrowserEvent(helper.getConnectorWrapper(),
  211. getJsCell(cell), event);
  212. } else {
  213. return super.onBrowserEvent(cell, event);
  214. }
  215. }
  216. private native boolean onBrowserEvent(JavaScriptObject wrapper,
  217. JavaScriptObject cell, NativeEvent event)
  218. /*-{
  219. return !!wrapper.onBrowserEvent(cell, event);
  220. }-*/;
  221. };
  222. }
  223. @Override
  224. public Object decode(JsonValue value) {
  225. // Let the js logic decode the raw json that the server sent
  226. return value;
  227. }
  228. @Override
  229. public void onUnregister() {
  230. super.onUnregister();
  231. helper.onUnregister();
  232. }
  233. @Override
  234. public JavaScriptConnectorHelper getJavascriptConnectorHelper() {
  235. return helper;
  236. }
  237. }