Skip to content

Commit

Permalink
The client side code corrections: javadocs are updated/added, unit te…
Browse files Browse the repository at this point in the history
…sts.
  • Loading branch information
Denis Anisimov committed Dec 6, 2017
1 parent fcefbdc commit 8b3ea20
Show file tree
Hide file tree
Showing 7 changed files with 256 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@
*/
package com.vaadin.client;


import com.google.gwt.core.client.Scheduler;


import com.vaadin.client.flow.ExecuteJavaScriptProcessor;
import com.vaadin.client.flow.StateNode;
import com.vaadin.client.flow.collection.JsArray;
Expand Down
101 changes: 82 additions & 19 deletions flow-client/src/main/java/com/vaadin/client/PolymerUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -219,17 +219,47 @@ public static native Node getElementInShadowRootById(ShadowRoot shadowRoot,
return shadowRoot.getElementById(id);
}-*/;

/**
* Find the DOM element inside shadow root of the {@code shadowRootParent}.
*
* @param shadowRootParent
* the parent whose shadow root contains the element with the
* {@code id}
* @param id
* the identifier of the element to search for
* @return the element with the given {@code id} inside the shadow root of
* the parent
*/
public static native Element getDomElementById(Node shadowRootParent,
String id)
/*-{
return shadowRootParent.$[id];
}-*/;

/**
* Checks whether the {@code node} has required {@code tag}.
*
* @param node
* the node to check
* @param tag
* the required tag name
* @return {@code true} if the node has required tag name
*/
public static boolean hasTag(Node node, String tag) {
return node instanceof Element
&& tag.equalsIgnoreCase(((Element) node).getTagName());
}

/**
* Gets the custom element using {@code path} of indices starting from the
* {@code root}.
*
* @param root
* the root element to start from
* @param path
* the indices path identifying the custom element.
* @return the element inside the {@code root} by the path of indices
*/
public static Element getCustomElement(Node root, JsonArray path) {
Node current = root;
for (int i = 0; i < path.length(); i++) {
Expand All @@ -248,30 +278,27 @@ public static Element getCustomElement(Node root, JsonArray path) {
return null;
}

public static Node getChildIgnoringStyles(Node parent, int index) {
HTMLCollection children = DomApi.wrap(parent).getChildren();
int filteredIndex = -1;
for (int i = 0; i < children.getLength(); i++) {
Node next = children.item(i);
assert next instanceof Element : "Unexpected element type in the collection of children. "
+ "DomElement::getChildren is supposed to return Element chidren only, but got "
+ next.getClass();
Element element = (Element) next;
if (!"style".equalsIgnoreCase(element.getTagName())) {
filteredIndex++;
}
if (filteredIndex == index) {
return next;
}
}
return null;
}

/**
* Returns the shadow root of the {@code templateElement}.
*
* @param templateElement
* the owner of the shadow root
* @return the shadow root of the element
*/
public static native Element getDomRoot(Node templateElement)
/*-{
return templateElement.root;
}-*/;

/**
* Invokes the {@code runnable} when the custom element with the given
* {@code tagName} is initialized (its DOM structure becomes available).
*
* @param tagName
* the name of the custom element
* @param runnable
* the command to run when the element if initialized
*/
public static native void invokeWhenDefined(String tagName,
Runnable runnable)
/*-{
Expand All @@ -281,12 +308,48 @@ public static native void invokeWhenDefined(String tagName,
});
}-*/;

/**
* Invokes the {@code runnable} when the custom element with the tag name of
* the {@code node} is initialized (its DOM structure becomes available).
*
* @param node
* the node whose tag name is awaiting for
* @param runnable
* the command to run when the element if initialized
*/
public static void invokeWhenDefined(Node node, Runnable runnable) {
invokeWhenDefined(node.getLocalName(), runnable);
}

/**
* Gets the tag name of the {@code node}.
*
* @param node
* the node to get the tag name from
* @return the tag name of the node
*/
public static String getTag(StateNode node) {
return (String) node.getMap(NodeFeatures.ELEMENT_DATA)
.getProperty(NodeProperties.TAG).getValue();
}

private static Node getChildIgnoringStyles(Node parent, int index) {
HTMLCollection children = DomApi.wrap(parent).getChildren();
int filteredIndex = -1;
for (int i = 0; i < children.getLength(); i++) {
Node next = children.item(i);
assert next instanceof Element : "Unexpected element type in the collection of children. "
+ "DomElement::getChildren is supposed to return Element chidren only, but got "
+ next.getClass();
Element element = (Element) next;
if (!"style".equalsIgnoreCase(element.getTagName())) {
filteredIndex++;
}
if (filteredIndex == index) {
return next;
}
}
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,6 @@ public void sendExistingElementAttachToServer(StateNode parent,
* @param assignedId
* identifier which should be used on the server side for the
* element (instead of requestedId)
* @param tagName
* the requested tagName
* @param id
* id of requested element
*/
Expand Down
11 changes: 11 additions & 0 deletions flow-client/src/main/java/com/vaadin/client/flow/StateNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,17 @@ public void setDomNode(Node node) {
});
}

/**
* Adds a listener to get a notification when the DOM Node is set for this
* {@link StateNode}.
* <p>
* The listener return value is used to decide whether the listener should
* be removed immediately if it returns {@code true}.
*
* @param listener
* listener to add
* @return an event remover that can be used for removing the added listener
*/
public EventRemover addDomNodeSetListener(
Function<StateNode, Boolean> listener) {
domNodeSetListeners.add(listener);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.google.gwt.core.client.JavaScriptObject;
import com.vaadin.client.Command;
import com.vaadin.client.Console;
import com.vaadin.client.ExistingElementMap;
import com.vaadin.client.PolymerUtils;
import com.vaadin.client.WidgetUtil;
import com.vaadin.client.flow.ConstantPool;
Expand Down Expand Up @@ -545,8 +546,17 @@ private EventRemover bindChildren(BindingContext context) {
for (int i = 0; i < children.length(); i++) {
StateNode childNode = (StateNode) children.get(i);

Node child = context.binderContext.createAndBind(childNode);
DomApi.wrap(context.htmlNode).appendChild(child);
ExistingElementMap existingElementMap = childNode.getTree()
.getRegistry().getExistingElementMap();
Node child = existingElementMap.getElement(childNode.getId());
if (child != null) {
existingElementMap.remove(childNode.getId());
childNode.setDomNode(child);
context.binderContext.createAndBind(childNode);
} else {
child = context.binderContext.createAndBind(childNode);
DomApi.wrap(context.htmlNode).appendChild(child);
}
}

return children.addSpliceListener(e -> {
Expand Down Expand Up @@ -811,9 +821,19 @@ private void addChildren(int index, BindingContext context,
Object newChildObject = add.get(i);
StateNode newChild = (StateNode) newChildObject;

Node childNode = context.binderContext.createAndBind(newChild);
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);
DomApi.wrap(context.htmlNode).insertBefore(childNode,
beforeRef);
}

beforeRef = DomApi.wrap(childNode).getNextSibling();
}
Expand Down
Loading

0 comments on commit 8b3ea20

Please sign in to comment.