import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Style;
+import com.vaadin.client.AnimationUtil.AnimationEndListener;
/**
* Utility methods for working with CSS transitions and animations.
var callbackFunc = $entry(function(e) {
listener.@com.vaadin.client.AnimationUtil.AnimationEndListener::onAnimationEnd(Lcom/google/gwt/dom/client/NativeEvent;)(e);
});
+ callbackFunc.listener = listener;
elem.addEventListener(@com.vaadin.client.AnimationUtil::ANIMATION_END_EVENT_NAME, callbackFunc, false);
elem.removeEventListener(@com.vaadin.client.AnimationUtil::ANIMATION_END_EVENT_NAME, listener, false);
}-*/;
+ /**
+ * Removes the given animation listener.
+ *
+ * @param element
+ * the element which has the listener
+ * @param animationEndListener
+ * the listener to remove
+ * @return <code>true</code> if the listener was removed, <code>false</code>
+ * if the listener was not registered to the given element
+ */
+ public static native boolean removeAnimationEndListener(Element elem,
+ AnimationEndListener animationEndListener)
+ /*-{
+ if(elem._vaadin_animationend_callbacks) {
+ var callbacks = elem._vaadin_animationend_callbacks;
+ for(var i=0; i < callbacks.length; i++) {
+ if (callbacks[i].listener == animationEndListener) {
+ elem.removeEventListener(@com.vaadin.client.AnimationUtil::ANIMATION_END_EVENT_NAME, callbacks[i], false);
+ return true;
+ }
+ }
+ return false;
+ }
+ }-*/;
+
/** For internal use only. May be removed or replaced in the future. */
public static native void removeAllAnimationEndListeners(Element elem)
/*-{
import com.google.gwt.animation.client.Animation;
import com.google.gwt.core.client.GWT;
-import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.IFrameElement;
current = null;
}
- private JavaScriptObject animateInListener;
-
private boolean fitInWindow = false;
private boolean maybeShowWithAnimation() {
if (animationName.contains(ADDITIONAL_CLASSNAME_ANIMATE_IN)) {
// Disable GWT PopupPanel animation if used
setAnimationEnabled(false);
- animateInListener = AnimationUtil.addAnimationEndListener(
- getElement(), new AnimationEndListener() {
+ AnimationUtil.addAnimationEndListener(getElement(),
+ new AnimationEndListener() {
@Override
public void onAnimationEnd(NativeEvent event) {
String animationName = AnimationUtil
.getAnimationName(event);
if (animationName.contains(
ADDITIONAL_CLASSNAME_ANIMATE_IN)) {
- AnimationUtil.removeAnimationEndListener(
- getElement(), animateInListener);
+ boolean removed = AnimationUtil
+ .removeAnimationEndListener(
+ getElement(), this);
+ assert removed : "Animation end listener was not removed";
removeStyleDependentName(
ADDITIONAL_CLASSNAME_ANIMATE_IN);
}
public void onAnimationEnd(NativeEvent event) {
if (AnimationUtil.getAnimationName(event).contains(
ADDITIONAL_CLASSNAME_ANIMATE_IN)) {
+ boolean removed = AnimationUtil
+ .removeAnimationEndListener(
+ getElement(), this);
+ assert removed : "Animation end listener was not removed";
reallyHide(autoClosed);
}
}
.getAnimationName(event);
if (animationName.contains(
ADDITIONAL_CLASSNAME_ANIMATE_OUT)) {
- AnimationUtil
- .removeAllAnimationEndListeners(
- getElement());
- // Remove both animation styles just in
- // case
+ boolean removed = AnimationUtil
+ .removeAnimationEndListener(
+ getElement(), this);
+ assert removed : "Animation end listener was not removed";
+
+ // Remove both animation styles just in case
removeStyleDependentName(
ADDITIONAL_CLASSNAME_ANIMATE_IN);
removeStyleDependentName(
--- /dev/null
+/*
+ * 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.tests.components.combobox;
+
+import com.vaadin.annotations.Theme;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.v7.ui.ComboBox;
+
+@Theme("valo")
+public class ComboBoxValoDoubleClick extends AbstractTestUI {
+
+ // Quite impossible to autotest reliably as there must be a click to open
+ // the popup and another click during the opening animation to reproduce the
+ // bug. Manually a double click is just about the right timing.
+ @Override
+ protected void setup(VaadinRequest request) {
+ ComboBox cb = new ComboBox("Double-click Me");
+ for (int i = 0; i < 100; i++) {
+ cb.addItem("Item-" + i);
+ }
+ addComponent(cb);
+ }
+
+ @Override
+ public String getTestDescription() {
+ return "ComboBox should remain usable even after double-clicking (affects only Valo theme with $v-overlay-animate-in).";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 17903;
+ }
+
+}