Browse Source

Only add tooltip listeners when needed (#11051)

Change-Id: I2b097ed67d59260390cd939b2f2d844548b5fced
tags/7.0.1
Leif Åstrand 11 years ago
parent
commit
f759408c0f

+ 16
- 0
client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java View File

@@ -334,6 +334,22 @@ public class ConnectorBundleLoaderFactory extends Generator {
writeGetters(logger, w, bundle);
writeSerializers(logger, w, bundle);
writeDelegateToWidget(logger, w, bundle);
writeHasGetTooltip(logger, w, bundle);
}

/**
* @deprecated As of 7.0.1. This is just a hack to avoid breaking backwards
* compatibility and will be removed in Vaadin 7.1
*/
@Deprecated
private void writeHasGetTooltip(TreeLogger logger, SplittingSourceWriter w,
ConnectorBundle bundle) {
Set<JClassType> types = bundle.getHasGetTooltip();
for (JClassType type : types) {
w.println("store.setHasGetTooltipInfo(%s);",
getClassLiteralString(type));
w.splitIfNeeded();
}
}

private void writeDelegateToWidget(TreeLogger logger,

+ 35
- 0
client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java View File

@@ -63,6 +63,7 @@ public class ConnectorBundle {
private final Set<JClassType> needsGwtConstructor = new HashSet<JClassType>();
private final Set<JClassType> visitedTypes = new HashSet<JClassType>();
private final Set<JClassType> needsProxySupport = new HashSet<JClassType>();
private final Set<JClassType> hasGetTooltip = new HashSet<JClassType>();

private final Map<JClassType, Set<String>> identifiers = new HashMap<JClassType, Set<String>>();
private final Map<JClassType, Set<JMethod>> needsReturnType = new HashMap<JClassType, Set<JMethod>>();
@@ -618,4 +619,38 @@ public class ConnectorBundle {
public Set<Property> getNeedsDelegateToWidget() {
return Collections.unmodifiableSet(needsDelegateToWidget);
}

/**
* @deprecated As of 7.0.1. This is just a hack to avoid breaking backwards
* compatibility and will be removed in Vaadin 7.1
*/
@Deprecated
public Set<JClassType> getHasGetTooltip() {
return Collections.unmodifiableSet(hasGetTooltip);
}

/**
* @deprecated As of 7.0.1. This is just a hack to avoid breaking backwards
* compatibility and will be removed in Vaadin 7.1
*/
@Deprecated
public void setHasGetTooltip(JClassType type) {
if (!isHasGetTooltip(type)) {
hasGetTooltip.add(type);
}
}

/**
* @deprecated As of 7.0.1. This is just a hack to avoid breaking backwards
* compatibility and will be removed in Vaadin 7.1
*/
@Deprecated
private boolean isHasGetTooltip(JClassType type) {
if (hasGetTooltip.contains(type)) {
return true;
} else {
return previousBundle != null
&& previousBundle.isHasGetTooltip(type);
}
}
}

+ 19
- 0
client-compiler/src/com/vaadin/server/widgetsetutils/metadata/WidgetInitVisitor.java View File

@@ -47,6 +47,25 @@ public class WidgetInitVisitor extends TypeVisitor {
bundle.setNeedsReturnType(type, getWidget);
}

// Hack to detect when getTooltipInfo has a custom implementation
// #11051
JClassType getTooltipParamType = type.getOracle().findType(
"com.google.gwt.dom.client.Element");
JMethod getTooltipInfoMethod = findInheritedMethod(type,
"getTooltipInfo", getTooltipParamType);
if (getTooltipInfoMethod == null) {
logger.log(Type.ERROR, "Could not find getTooltipInfo in "
+ type.getQualifiedSourceName());
throw new UnableToCompleteException();
}
JClassType enclosingType = getTooltipInfoMethod.getEnclosingType();
if (!enclosingType.getQualifiedSourceName().equals(
AbstractComponentConnector.class.getCanonicalName())) {
logger.log(Type.WARN, type.getQualifiedSourceName()
+ " has overridden getTooltipInfo");
bundle.setHasGetTooltip(type);
}

// Check state properties for @DelegateToWidget
JMethod getState = findInheritedMethod(type, "getState");
JClassType stateType = getState.getReturnType().isClass();

+ 19
- 0
client/src/com/vaadin/client/metadata/TypeDataStore.java View File

@@ -38,6 +38,7 @@ public class TypeDataStore {

private final FastStringSet delayedMethods = FastStringSet.create();
private final FastStringSet lastOnlyMethods = FastStringSet.create();
private final FastStringSet hasGetTooltipInfo = FastStringSet.create();

private final FastStringMap<Type> returnTypes = FastStringMap.create();
private final FastStringMap<Invoker> invokers = FastStringMap.create();
@@ -276,4 +277,22 @@ public class TypeDataStore {
public static boolean hasProperties(Type type) {
return get().properties.containsKey(type.getSignature());
}

/**
* @deprecated As of 7.0.1. This is just a hack to avoid breaking backwards
* compatibility and will be removed in Vaadin 7.1
*/
@Deprecated
public void setHasGetTooltipInfo(Class<?> clazz) {
hasGetTooltipInfo.add(getType(clazz).getSignature());
}

/**
* @deprecated As of 7.0.1. This is just a hack to avoid breaking backwards
* compatibility and will be removed in Vaadin 7.1
*/
@Deprecated
public static boolean getHasGetTooltipInfo(Class clazz) {
return get().hasGetTooltipInfo.contains(getType(clazz).getSignature());
}
}

+ 52
- 15
client/src/com/vaadin/client/ui/AbstractComponentConnector.java View File

@@ -15,9 +15,6 @@
*/
package com.vaadin.client.ui;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.ui.Focusable;
@@ -38,6 +35,7 @@ import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.metadata.NoDataException;
import com.vaadin.client.metadata.Type;
import com.vaadin.client.metadata.TypeData;
import com.vaadin.client.metadata.TypeDataStore;
import com.vaadin.client.ui.datefield.PopupDateFieldConnector;
import com.vaadin.client.ui.ui.UIConnector;
import com.vaadin.shared.AbstractComponentState;
@@ -56,6 +54,8 @@ public abstract class AbstractComponentConnector extends AbstractConnector

private boolean initialStateEvent = true;

private boolean tooltipListenersAttached = false;

/**
* The style names from getState().getStyles() which are currently applied
* to the widget.
@@ -68,14 +68,6 @@ public abstract class AbstractComponentConnector extends AbstractConnector
public AbstractComponentConnector() {
}

@Override
protected void init() {
super.init();

getConnection().getVTooltip().connectHandlersToWidget(getWidget());

}

/**
* Creates and returns the widget for this VPaintableWidget. This method
* should only be called once when initializing the paintable.
@@ -164,6 +156,17 @@ public abstract class AbstractComponentConnector extends AbstractConnector

updateComponentSize();

Profiler.enter("AbstractComponentContainer.onStateChanged check tooltip");
if (!tooltipListenersAttached && hasTooltip()) {
/*
* Add event handlers for tooltips if they are needed but have not
* yet been added.
*/
tooltipListenersAttached = true;
getConnection().getVTooltip().connectHandlersToWidget(getWidget());
}
Profiler.leave("AbstractComponentContainer.onStateChanged check tooltip");

initialStateEvent = false;

Profiler.leave("AbstractComponentConnector.onStateChanged");
@@ -415,17 +418,51 @@ public abstract class AbstractComponentConnector extends AbstractConnector
}
}

/*
* (non-Javadoc)
/**
* {@inheritDoc}
*
* @see com.vaadin.client.ComponentConnector#getTooltipInfo(com.
* google.gwt.dom.client.Element)
* <p>
* When overriding this method, {@link #hasTooltip()} should also be
* overridden to return true in all situations where this method might
* return a non-empty result.
* </p>
*
* @see ComponentConnector#getTooltipInfo(Element)
*/
@Override
public TooltipInfo getTooltipInfo(Element element) {
return new TooltipInfo(getState().description, getState().errorMessage);
}

/**
* Check whether there might be a tooltip for this component. The framework
* will only add event listeners for automatically handling tooltips (using
* {@link #getTooltipInfo(Element)}) if this method returns true.
*
* @return <code>true</code> if some part of the component might have a
* tooltip, otherwise <code>false</code>
*/
private boolean hasTooltip() {
/*
* Hack to avoid breaking backwards compatibility - use a generator to
* know whether there's a custom implementation of getTooltipInfo, and
* in that case always assume that there might be tooltip.
*/
if (TypeDataStore.getHasGetTooltipInfo(getClass())) {
return true;
}

// Normally, there is a tooltip if description or errorMessage is set
AbstractComponentState state = getState();
if (state.description != null && !state.description.equals("")) {
return true;
} else if (state.errorMessage != null && !state.errorMessage.equals("")) {
return true;
} else {
return false;
}
}

/**
* Gets the icon set for this component.
*

Loading…
Cancel
Save