summaryrefslogtreecommitdiffstats
path: root/client/src
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2014-11-17 08:14:10 +0200
committerVaadin Code Review <review@vaadin.com>2015-01-13 20:30:45 +0000
commit5102cc98c295a49487fcf90cc6ac7980d166eb40 (patch)
tree59b27fb5a7b41053c7239603052e17793f1aaa3a /client/src
parent30f0e91195447140190f4c4feb232e9c13d02453 (diff)
downloadvaadin-framework-5102cc98c295a49487fcf90cc6ac7980d166eb40.tar.gz
vaadin-framework-5102cc98c295a49487fcf90cc6ac7980d166eb40.zip
Implement JavaScript renderer support (#15485)
Change-Id: Ifeac12d4124a4a7e5d0c143ff5c0590a2c98509d
Diffstat (limited to 'client/src')
-rw-r--r--client/src/com/vaadin/client/JavaScriptConnectorHelper.java13
-rw-r--r--client/src/com/vaadin/client/connectors/JavaScriptRendererConnector.java278
-rw-r--r--client/src/com/vaadin/client/widget/grid/RendererCellReference.java2
3 files changed, 287 insertions, 6 deletions
diff --git a/client/src/com/vaadin/client/JavaScriptConnectorHelper.java b/client/src/com/vaadin/client/JavaScriptConnectorHelper.java
index 11511f9c36..3a9a6198d3 100644
--- a/client/src/com/vaadin/client/JavaScriptConnectorHelper.java
+++ b/client/src/com/vaadin/client/JavaScriptConnectorHelper.java
@@ -50,7 +50,7 @@ public class JavaScriptConnectorHelper {
private JavaScriptObject connectorWrapper;
private int tag;
- private boolean inited = false;
+ private String initFunctionName;
public JavaScriptConnectorHelper(ServerConnector connector) {
this.connector = connector;
@@ -96,9 +96,8 @@ public class JavaScriptConnectorHelper {
}
// Init after setting up callbacks & rpc
- if (!inited) {
+ if (initFunctionName == null) {
initJavaScript();
- inited = true;
}
invokeIfPresent(wrapper, "onStateChange");
@@ -120,7 +119,7 @@ public class JavaScriptConnectorHelper {
return object;
}
- private boolean initJavaScript() {
+ protected boolean initJavaScript() {
ApplicationConfiguration conf = connector.getConnection()
.getConfiguration();
ArrayList<String> attemptedNames = new ArrayList<String>();
@@ -132,6 +131,7 @@ public class JavaScriptConnectorHelper {
if (tryInitJs(initFunctionName, getConnectorWrapper())) {
VConsole.log("JavaScript connector initialized using "
+ initFunctionName);
+ this.initFunctionName = initFunctionName;
return true;
} else {
VConsole.log("No JavaScript function " + initFunctionName
@@ -160,7 +160,7 @@ public class JavaScriptConnectorHelper {
}
}-*/;
- private JavaScriptObject getConnectorWrapper() {
+ public JavaScriptObject getConnectorWrapper() {
if (connectorWrapper == null) {
connectorWrapper = createConnectorWrapper(this,
connector.getConnection(), nativeState, rpcMap,
@@ -465,4 +465,7 @@ public class JavaScriptConnectorHelper {
}
}-*/;
+ public String getInitFunctionName() {
+ return initFunctionName;
+ }
}
diff --git a/client/src/com/vaadin/client/connectors/JavaScriptRendererConnector.java b/client/src/com/vaadin/client/connectors/JavaScriptRendererConnector.java
new file mode 100644
index 0000000000..82d863ce0c
--- /dev/null
+++ b/client/src/com/vaadin/client/connectors/JavaScriptRendererConnector.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.client.connectors;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.core.client.JsArrayString;
+import com.google.gwt.dom.client.NativeEvent;
+import com.vaadin.client.BrowserInfo;
+import com.vaadin.client.JavaScriptConnectorHelper;
+import com.vaadin.client.Util;
+import com.vaadin.client.communication.HasJavaScriptConnectorHelper;
+import com.vaadin.client.renderers.ComplexRenderer;
+import com.vaadin.client.renderers.Renderer;
+import com.vaadin.client.widget.grid.CellReference;
+import com.vaadin.client.widget.grid.RendererCellReference;
+import com.vaadin.shared.JavaScriptExtensionState;
+import com.vaadin.shared.ui.Connect;
+import com.vaadin.ui.renderer.AbstractJavaScriptRenderer;
+
+import elemental.json.JsonObject;
+import elemental.json.JsonValue;
+
+/**
+ * Connector for server-side renderer implemented using JavaScript.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+@Connect(AbstractJavaScriptRenderer.class)
+public class JavaScriptRendererConnector extends
+ AbstractRendererConnector<JsonValue> implements
+ HasJavaScriptConnectorHelper {
+ private final JavaScriptConnectorHelper helper = new JavaScriptConnectorHelper(
+ this);
+
+ private final JavaScriptObject cellReferenceWrapper = createCellReferenceWrapper(BrowserInfo
+ .get().isIE8());
+
+ @Override
+ protected void init() {
+ super.init();
+ helper.init();
+
+ addGetRowKey(helper.getConnectorWrapper());
+ }
+
+ private static native JavaScriptObject createCellReferenceWrapper(
+ boolean isIE8)
+ /*-{
+ var reference = {};
+ if (isIE8) {
+ // IE8 only supports defineProperty for DOM objects
+ reference = $doc.createElement('div');
+ }
+
+ var setProperty = function(name, getter, setter) {
+ var descriptor = {
+ get: getter
+ }
+ if (setter) {
+ descriptor.set = setter;
+ }
+ Object.defineProperty(reference, name, descriptor);
+ };
+
+ setProperty("element", function() {
+ return reference.target.@CellReference::getElement()();
+ }, null);
+
+ setProperty("rowIndex", function() {
+ return reference.target.@CellReference::getRowIndex()();
+ }, null);
+
+ setProperty("columnIndex", function() {
+ return reference.target.@CellReference::getColumnIndex()();
+ }, null);
+
+ setProperty("colSpan", function() {
+ return reference.target.@RendererCellReference::getColSpan()();
+ }, function(colSpan) {
+ reference.target.@RendererCellReference::setColSpan(*)(colSpan);
+ });
+
+ return reference;
+ }-*/;
+
+ @Override
+ public JavaScriptExtensionState getState() {
+ return (JavaScriptExtensionState) super.getState();
+ }
+
+ private native void addGetRowKey(JavaScriptObject wrapper)
+ /*-{
+ var self = this;
+ wrapper.getRowKey = $entry(function(rowIndex) {
+ return @JavaScriptRendererConnector::findRowKey(*)(self, rowIndex);
+ });
+ }-*/;
+
+ private static String findRowKey(JavaScriptRendererConnector connector,
+ int rowIndex) {
+ GridConnector gc = (GridConnector) connector.getParent();
+ JsonObject row = gc.getWidget().getDataSource().getRow(rowIndex);
+ return connector.getRowKey(row);
+ }
+
+ private boolean hasFunction(String name) {
+ return hasFunction(helper.getConnectorWrapper(), name);
+ }
+
+ private static native boolean hasFunction(JavaScriptObject wrapper,
+ String name)
+ /*-{
+ return typeof wrapper[name] === 'function';
+ }-*/;
+
+ @Override
+ protected Renderer<JsonValue> createRenderer() {
+ if (!hasFunction("render")) {
+ throw new RuntimeException("JavaScriptRenderer "
+ + helper.getInitFunctionName()
+ + " must have a function named 'render'");
+ }
+
+ final boolean hasInit = hasFunction("init");
+ final boolean hasDestroy = hasFunction("destroy");
+ final boolean hasOnActivate = hasFunction("onActivate");
+ final boolean hasGetConsumedEvents = hasFunction("getConsumedEvents");
+ final boolean hasOnBrowserEvent = hasFunction("onBrowserEvent");
+
+ return new ComplexRenderer<JsonValue>() {
+ @Override
+ public void render(RendererCellReference cell, JsonValue data) {
+ render(helper.getConnectorWrapper(), getJsCell(cell),
+ Util.json2jso(data));
+ }
+
+ private JavaScriptObject getJsCell(CellReference<?> cell) {
+ updateCellReference(cellReferenceWrapper, cell);
+ return cellReferenceWrapper;
+ }
+
+ public native void render(JavaScriptObject wrapper,
+ JavaScriptObject cell, JavaScriptObject data)
+ /*-{
+ wrapper.render(cell, data);
+ }-*/;
+
+ @Override
+ public void init(RendererCellReference cell) {
+ if (hasInit) {
+ init(helper.getConnectorWrapper(), getJsCell(cell));
+ }
+ }
+
+ private native void init(JavaScriptObject wrapper,
+ JavaScriptObject cell)
+ /*-{
+ wrapper.init(cell);
+ }-*/;
+
+ private native void updateCellReference(
+ JavaScriptObject cellWrapper, CellReference<?> target)
+ /*-{
+ cellWrapper.target = target;
+ }-*/;
+
+ @Override
+ public void destroy(RendererCellReference cell) {
+ if (hasDestroy) {
+ destory(helper.getConnectorWrapper(), getJsCell(cell));
+ } else {
+ super.destroy(cell);
+ }
+ }
+
+ private native void destory(JavaScriptObject wrapper,
+ JavaScriptObject cell)
+ /*-{
+ wrapper.destory(cell);
+ }-*/;
+
+ @Override
+ public boolean onActivate(CellReference<?> cell) {
+ if (hasOnActivate) {
+ return onActivate(helper.getConnectorWrapper(),
+ getJsCell(cell));
+ } else {
+ return super.onActivate(cell);
+ }
+ }
+
+ private native boolean onActivate(JavaScriptObject wrapper,
+ JavaScriptObject cell)
+ /*-{
+ return !!wrapper.onActivate(cell);
+ }-*/;
+
+ @Override
+ public Collection<String> getConsumedEvents() {
+ if (hasGetConsumedEvents) {
+ JsArrayString events = getConsumedEvents(helper
+ .getConnectorWrapper());
+
+ ArrayList<String> list = new ArrayList<String>(
+ events.length());
+ for (int i = 0; i < events.length(); i++) {
+ list.add(events.get(i));
+ }
+ return list;
+ } else {
+ return super.getConsumedEvents();
+ }
+ }
+
+ private native JsArrayString getConsumedEvents(
+ JavaScriptObject wrapper)
+ /*-{
+ var rawEvents = wrapper.getConsumedEvents();
+ var events = [];
+ for(var i = 0; i < rawEvents.length; i++) {
+ events[i] = ""+rawEvents[i];
+ }
+ return events;
+ }-*/;
+
+ @Override
+ public boolean onBrowserEvent(CellReference<?> cell,
+ NativeEvent event) {
+ if (hasOnBrowserEvent) {
+ return onBrowserEvent(helper.getConnectorWrapper(),
+ getJsCell(cell), event);
+ } else {
+ return super.onBrowserEvent(cell, event);
+ }
+ }
+
+ private native boolean onBrowserEvent(JavaScriptObject wrapper,
+ JavaScriptObject cell, NativeEvent event)
+ /*-{
+ return !!wrapper.onBrowserEvent(cell, event);
+ }-*/;
+ };
+ }
+
+ @Override
+ public JsonValue decode(JsonValue value) {
+ // Let the js logic decode the raw json that the server sent
+ return value;
+ }
+
+ @Override
+ public void onUnregister() {
+ super.onUnregister();
+ helper.onUnregister();
+ }
+
+ @Override
+ public JavaScriptConnectorHelper getJavascriptConnectorHelper() {
+ return helper;
+ }
+}
diff --git a/client/src/com/vaadin/client/widget/grid/RendererCellReference.java b/client/src/com/vaadin/client/widget/grid/RendererCellReference.java
index 07ca462293..533eafded6 100644
--- a/client/src/com/vaadin/client/widget/grid/RendererCellReference.java
+++ b/client/src/com/vaadin/client/widget/grid/RendererCellReference.java
@@ -83,7 +83,7 @@ public class RendererCellReference extends CellReference<Object> {
*
* @return the number of columns that the cell should span
*/
- public int getColspan() {
+ public int getColSpan() {
return cell.getColSpan();
}
}