import com.google.gwt.user.client.Element;
import com.vaadin.client.ApplicationConnection;
-import com.vaadin.client.BrowserInfo;
/**
* ComponentLocator provides methods for generating a String locator for a given
public class ComponentLocator {
private final List<LocatorStrategy> locatorStrategies;
- private final LegacyLocatorStrategy legacyLocatorStrategy = new LegacyLocatorStrategy(
- this);
/**
* Reference to ApplicationConnection instance.
*/
- private ApplicationConnection client;
+ private final ApplicationConnection client;
/**
* Construct a ComponentLocator for the given ApplicationConnection.
*/
public ComponentLocator(ApplicationConnection client) {
this.client = client;
- locatorStrategies = Arrays.asList(
- new VaadinFinderLocatorStrategy(this), legacyLocatorStrategy);
+ locatorStrategies = Arrays.asList(new VaadinFinderLocatorStrategy(
+ client), new LegacyLocatorStrategy(client));
}
/**
* String locator could not be created.
*/
public String getPathForElement(Element targetElement) {
- // For now, only use the legacy locator to find paths
- return legacyLocatorStrategy
- .getPathForElement(getElement(targetElement));
- }
-
- /**
- * Returns the element passed to the method. Or in case of Firefox 15,
- * returns the real element that is in the DOM instead of the element passed
- * to the method (which is the same element but not ==).
- *
- * @param targetElement
- * the element to return
- * @return the element passed to the method
- */
- private Element getElement(Element targetElement) {
- if (targetElement == null) {
- return null;
- }
-
- if (!BrowserInfo.get().isFirefox()) {
- return targetElement;
- }
-
- if (BrowserInfo.get().getBrowserMajorVersion() != 15) {
- return targetElement;
- }
-
- // Firefox 15, you make me sad
- if (targetElement.getNextSibling() != null) {
- return (Element) targetElement.getNextSibling()
- .getPreviousSibling();
- }
- if (targetElement.getPreviousSibling() != null) {
- return (Element) targetElement.getPreviousSibling()
- .getNextSibling();
+ for (LocatorStrategy strategy : locatorStrategies) {
+ String path = strategy.getPathForElement(targetElement);
+ if (null != path) {
+ return path;
+ }
}
- // No siblings so this is the only child
- return (Element) targetElement.getParentNode().getChild(0);
+ return null;
}
/**
* could not be located.
*/
public Element getElementByPath(String path) {
- // As LegacyLocatorStrategy always is the last item in the list, it is
- // always used as a last resort if no other strategies claim
- // responsibility for the path syntax.
for (LocatorStrategy strategy : locatorStrategies) {
Element element = strategy.getElementByPath(path);
if (null != element) {
* could not be located.
*/
public Element getElementByPathStartingAt(String path, Element root) {
- // As LegacyLocatorStrategy always is the last item in the list, it is
- // always used as a last resort if no other strategies claim
- // responsibility for the path syntax.
for (LocatorStrategy strategy : locatorStrategies) {
Element element = strategy.getElementByPathStartingAt(path, root);
if (null != element) {
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.ComponentConnector;
import com.vaadin.client.ConnectorMap;
import com.vaadin.client.ServerConnector;
* @author Vaadin Ltd
*/
public class LegacyLocatorStrategy implements LocatorStrategy {
- private final ComponentLocator componentLocator;
+
/**
* Separator used in the String locator between a parent and a child widget.
*/
*/
static final String ROOT_ID = "Root";
- public LegacyLocatorStrategy(ComponentLocator componentLocator) {
- this.componentLocator = componentLocator;
+ private final ApplicationConnection client;
+
+ public LegacyLocatorStrategy(ApplicationConnection clientConnection) {
+ client = clientConnection;
}
@Override
public String getPathForElement(Element targetElement) {
- ComponentConnector connector = Util.findPaintable(
- componentLocator.getClient(), targetElement);
+ ComponentConnector connector = Util
+ .findPaintable(client, targetElement);
Widget w = null;
if (connector != null) {
String parts[] = path.split(LegacyLocatorStrategy.SUBPART_SEPARATOR, 2);
String widgetPath = parts[0];
- Widget baseWidget = null;
- if (null != baseElement) {
- // Note that this only works if baseElement can be mapped to a
- // widget to which the path is relative. Otherwise, the current
- // implementation simply interprets the path as if baseElement was
- // null.
- baseWidget = Util.findWidget(baseElement, null);
- }
+ // Note that this only works if baseElement can be mapped to a
+ // widget to which the path is relative. Otherwise, the current
+ // implementation simply interprets the path as if baseElement was
+ // null.
+ Widget baseWidget = Util.findWidget(baseElement, null);
+
Widget w = getWidgetFromPath(widgetPath, baseWidget);
if (w == null || !Util.isAttachedAndDisplayed(w)) {
return null;
// Contains dom reference to a sub element of the widget
String subPath = widgetPath.substring(pos);
- return getElementByDOMPath(baseElement, subPath);
+ return getElementByDOMPath(w.getElement(), subPath);
} else if (parts.length == 2) {
if (w instanceof SubPartAware) {
return ((SubPartAware) w).getSubPartElement(parts[1]);
String parts[] = path.split(PARENTCHILD_SEPARATOR);
Element element = baseElement;
- for (String part : parts) {
+ for (int i = 0, l = parts.length; i < l; ++i) {
+ String part = parts[i];
if (part.startsWith("domChild[")) {
String childIndexString = part.substring("domChild[".length(),
part.length() - 1);
return null;
}
+ } else {
+
+ path = parts[i];
+ for (int j = i + 1; j < l; ++j) {
+ path += PARENTCHILD_SEPARATOR + parts[j];
+ }
+
+ return getElementByPathStartingAt(path, element);
}
}
} else if (w instanceof VUI) {
return "";
} else if (w instanceof VWindow) {
- Connector windowConnector = ConnectorMap.get(
- componentLocator.getClient()).getConnector(w);
- List<WindowConnector> subWindowList = componentLocator.getClient()
- .getUIConnector().getSubWindows();
+ Connector windowConnector = ConnectorMap.get(client)
+ .getConnector(w);
+ List<WindowConnector> subWindowList = client.getUIConnector()
+ .getSubWindows();
int indexOfSubWindow = subWindowList.indexOf(windowConnector);
return PARENTCHILD_SEPARATOR + "VWindow[" + indexOfSubWindow + "]";
} else if (w instanceof RootPanel) {
* @return The Widget identified by the String locator or null if the widget
* could not be identified.
*/
+ @SuppressWarnings("unchecked")
private Widget getWidgetFromPath(String path, Widget baseWidget) {
Widget w = baseWidget;
String parts[] = path.split(PARENTCHILD_SEPARATOR);
if (part.equals(ROOT_ID)) {
w = RootPanel.get();
} else if (part.equals("")) {
- w = componentLocator.getClient().getUIConnector().getWidget();
+ if (w == null) {
+ w = client.getUIConnector().getWidget();
+ }
} else if (w == null) {
String id = part;
// Must be old static pid (PID_S*)
- ServerConnector connector = ConnectorMap.get(
- componentLocator.getClient()).getConnector(id);
+ ServerConnector connector = ConnectorMap.get(client)
+ .getConnector(id);
if (connector == null) {
// Lookup by component id
// TODO Optimize this
- connector = findConnectorById(componentLocator.getClient()
- .getUIConnector(), id.substring(5));
+ connector = findConnectorById(client.getUIConnector(),
+ id.substring(5));
}
if (connector instanceof ComponentConnector) {
if (w instanceof VOverlay
&& "VCalendarPanel".equals(widgetClassName)) {
// Vaadin 7.1 adds a wrapper for datefield popups
- parent = (Iterable<?>) ((Iterable) parent).iterator()
+ parent = (Iterable<?>) ((Iterable<?>) parent).iterator()
.next();
}
/*
* compatibility
*/
if (widgetClassName.equals("VWindow")) {
- List<WindowConnector> windows = componentLocator
- .getClient().getUIConnector().getSubWindows();
+ List<WindowConnector> windows = client.getUIConnector()
+ .getSubWindows();
List<VWindow> windowWidgets = new ArrayList<VWindow>(
windows.size());
for (WindowConnector wc : windows) {
}
iterator = windowWidgets.iterator();
} else if (widgetClassName.equals("VContextMenu")) {
- return componentLocator.getClient().getContextMenu();
+ return client.getContextMenu();
} else {
iterator = (Iterator<? extends Widget>) parent.iterator();
}
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.ComponentConnector;
import com.vaadin.client.Util;
import com.vaadin.client.metadata.NoDataException;
public class VaadinFinderLocatorStrategy implements LocatorStrategy {
public static final String SUBPART_SEPARATOR = "#";
- private ComponentLocator componentLocator;
- public VaadinFinderLocatorStrategy(ComponentLocator componentLocator) {
- this.componentLocator = componentLocator;
+ private final ApplicationConnection client;
+
+ public VaadinFinderLocatorStrategy(ApplicationConnection clientConnection) {
+ client = clientConnection;
}
/**
if (path.startsWith("//VNotification")) {
return findNotificationByPath(path);
}
- return getElementByPathStartingAtConnector(path, componentLocator
- .getClient().getUIConnector());
+ return getElementByPathStartingAtConnector(path,
+ client.getUIConnector());
}
/**
@Override
public Element getElementByPathStartingAt(String path, Element root) {
return getElementByPathStartingAtConnector(path,
- Util.findPaintable(componentLocator.getClient(), root));
+ Util.findPaintable(client, root));
}
/**