use of com.vaadin.client.flow.StateNode in project flow by vaadin.
the class GwtExecuteJavaScriptElementUtilsTest method gwtSetUp.
@Override
protected void gwtSetUp() throws Exception {
super.gwtSetUp();
initPolymer();
map = new ExistingElementMap();
Registry registry = new Registry() {
{
set(ExistingElementMap.class, map);
}
};
tree = new ExistingElementStateTree(registry);
node = new StateNode(0, tree);
element = Browser.getDocument().createElement("div");
node.setDomNode(element);
}
use of com.vaadin.client.flow.StateNode in project flow by vaadin.
the class SimpleElementBindingStrategy method addChildren.
private void addChildren(int index, BindingContext context, JsArray<?> add) {
NodeList nodeChildren = context.node.getList(NodeFeatures.ELEMENT_CHILDREN);
Node beforeRef;
if (index == 0) {
// Insert at the first position after the client-side-only nodes
beforeRef = getFirstNodeMappedAsStateNode(nodeChildren, context.htmlNode);
} else if (index <= nodeChildren.length() && index > 0) {
StateNode previousSibling = getPreviousSibling(index, context);
// Insert before the next sibling of the current node
beforeRef = previousSibling == null ? null : DomApi.wrap(previousSibling.getDomNode()).getNextSibling();
} else {
// Insert at the end
beforeRef = null;
}
for (int i = 0; i < add.length(); i++) {
Object newChildObject = add.get(i);
StateNode newChild = (StateNode) newChildObject;
ExistingElementMap existingElementMap = newChild.getTree().getRegistry().getExistingElementMap();
Node childNode = existingElementMap.getElement(newChild.getId());
if (childNode != null) {
existingElementMap.remove(newChild.getId());
newChild.setDomNode(childNode);
context.binderContext.createAndBind(newChild);
} else {
childNode = context.binderContext.createAndBind(newChild);
DomApi.wrap(context.htmlNode).insertBefore(childNode, beforeRef);
}
beforeRef = DomApi.wrap(childNode).getNextSibling();
}
}
use of com.vaadin.client.flow.StateNode in project flow by vaadin.
the class ExecuteJavaScriptElementUtils method attachExistingElement.
/**
* Calculate the data required for server side callback to attach existing
* element and send it to the server.
*
* @param parent
* the parent node whose child is requested to attach
* @param previousSibling
* previous sibling element
* @param tagName
* the tag name of the element requested to attach
* @param id
* the identifier of the server side node which is requested to
* be a counterpart of the client side element
*/
public static void attachExistingElement(StateNode parent, Element previousSibling, String tagName, int id) {
Element existingElement = null;
JsArray<Node> childNodes = DomApi.wrap(parent.getDomNode()).getChildNodes();
JsMap<Node, Integer> indices = new JsMap<>();
boolean afterSibling = previousSibling == null;
int elementIndex = -1;
for (int i = 0; i < childNodes.length(); i++) {
Node node = childNodes.get(i);
indices.set(node, i);
if (node.equals(previousSibling)) {
afterSibling = true;
}
if (afterSibling && hasTag(node, tagName)) {
existingElement = (Element) node;
elementIndex = i;
break;
}
}
if (existingElement == null) {
// report an error
parent.getTree().sendExistingElementAttachToServer(parent, id, -1, tagName, -1);
} else {
NodeList list = parent.getList(NodeFeatures.ELEMENT_CHILDREN);
Integer existingId = null;
int childIndex = 0;
for (int i = 0; i < list.length(); i++) {
StateNode stateNode = (StateNode) list.get(i);
Node domNode = stateNode.getDomNode();
Integer index = indices.get(domNode);
if (index != null && index < elementIndex) {
childIndex++;
}
if (domNode.equals(existingElement)) {
existingId = stateNode.getId();
break;
}
}
existingId = getExistingIdOrUpdate(parent, id, existingElement, existingId);
parent.getTree().sendExistingElementAttachToServer(parent, id, existingId, existingElement.getTagName(), childIndex);
}
}
use of com.vaadin.client.flow.StateNode in project flow by vaadin.
the class PolymerUtils method doGetNotificationPath.
private static String doGetNotificationPath(StateNode rootNode, StateNode currentNode, JsArray<String> path) {
StateNode parent = currentNode.getParent();
if (parent.hasFeature(NodeFeatures.ELEMENT_PROPERTIES)) {
String propertyPath = getPropertiesNotificationPath(currentNode);
if (propertyPath == null) {
return null;
}
path.push(propertyPath);
} else if (parent.hasFeature(NodeFeatures.TEMPLATE_MODELLIST)) {
String listPath = getListNotificationPath(currentNode);
if (listPath == null) {
return null;
}
path.push(listPath);
}
if (!parent.equals(rootNode)) {
return doGetNotificationPath(rootNode, parent, path);
}
StringBuilder pathBuilder = new StringBuilder();
String sep = "";
for (int i = path.length() - 1; i >= 0; i--) {
pathBuilder.append(sep).append(path.get(i));
sep = ".";
}
return pathBuilder.toString();
}
use of com.vaadin.client.flow.StateNode in project flow by vaadin.
the class PolymerUtils method doHandleListChange.
private static void doHandleListChange(ListSpliceEvent event, JsonValue value) {
JsArray<?> add = event.getAdd();
int index = event.getIndex();
int remove = event.getRemove().length();
StateNode node = event.getSource().getNode();
StateNode root = getFirstParentWithDomNode(node);
if (root == null) {
Console.warn("Root node for node " + node.getId() + " could not be found");
return;
}
JsArray<Object> array = JsCollections.array();
add.forEach(item -> array.push(createModelTree(item)));
if (isPolymerElement((Element) root.getDomNode())) {
String path = getNotificationPath(root, node, null);
if (path != null) {
splice((Element) root.getDomNode(), path, index, remove, WidgetUtil.crazyJsoCast(array));
return;
}
}
@SuppressWarnings("unchecked") JsArray<Object> payload = (JsArray<Object>) value;
payload.spliceArray(index, remove, array);
}
Aggregations