]> source.dussan.org Git - vaadin-framework.git/commitdiff
Merged ComboBox related changes from 6.5
authorHenri Sara <henri.sara@itmill.com>
Wed, 16 Mar 2011 08:49:34 +0000 (08:49 +0000)
committerHenri Sara <henri.sara@itmill.com>
Wed, 16 Mar 2011 08:49:34 +0000 (08:49 +0000)
svn changeset:17801/svn branch:6.6

src/com/vaadin/terminal/gwt/client/Util.java
src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java
tests/src/com/vaadin/tests/components/combobox/ComboFocusBlurEvents.html [new file with mode: 0644]
tests/src/com/vaadin/tests/components/combobox/ComboFocusBlurEvents.java [new file with mode: 0644]
tests/src/com/vaadin/tests/components/combobox/Comboboxes.html

index 2cd999fe194417670e7fe0f0d41b185cff202ab1..a451af90e7e826930aeed127150c7a9651ee9712 100644 (file)
@@ -1188,4 +1188,18 @@ public class Util {
 
     }
 
+    /**
+     * Gets the currently focused element for Internet Explorer.
+     * 
+     * @return The currently focused element
+     */
+    public native static Element getIEFocusedElement()
+    /*-{
+       if ($wnd.document.activeElement) {
+           return $wnd.document.activeElement;
+       }
+       
+       return null;
+     }-*/
+    ;
 }
index 5dd06b75a6a5b3d4dd9ced88984bbaddaefdbfa7..ce96e44eb6e1a736b52a954303ae994e771faba4 100644 (file)
@@ -48,6 +48,7 @@ import com.vaadin.terminal.gwt.client.Focusable;
 import com.vaadin.terminal.gwt.client.Paintable;
 import com.vaadin.terminal.gwt.client.UIDL;
 import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VConsole;
 import com.vaadin.terminal.gwt.client.VTooltip;
 
 /**
@@ -175,7 +176,7 @@ public class VFilterSelect extends Composite implements Paintable, Field,
             DOM.appendChild(root, down);
             DOM.appendChild(root, status);
             DOM.setElementProperty(status, "className", CLASSNAME + "-status");
-
+            DOM.sinkEvents(root, Event.ONMOUSEDOWN);
             addCloseHandler(this);
         }
 
@@ -326,15 +327,20 @@ public class VFilterSelect extends Composite implements Paintable, Field,
          */
         @Override
         public void onBrowserEvent(Event event) {
-            final Element target = DOM.eventGetTarget(event);
-            if (DOM.compare(target, up)
-                    || DOM.compare(target, DOM.getChild(up, 0))) {
-                filterOptions(currentPage - 1, lastFilter);
-            } else if (DOM.compare(target, down)
-                    || DOM.compare(target, DOM.getChild(down, 0))) {
-                filterOptions(currentPage + 1, lastFilter);
+            if (event.getTypeInt() == Event.ONCLICK) {
+                final Element target = DOM.eventGetTarget(event);
+                if (target == up || target == DOM.getChild(up, 0)) {
+                    filterOptions(currentPage - 1, lastFilter);
+                } else if (target == down || target == DOM.getChild(down, 0)) {
+                    filterOptions(currentPage + 1, lastFilter);
+                }
             }
-            tb.setFocus(true);
+
+            /*
+             * Prevent the keyboard focus from leaving the textfield by
+             * preventing the default behaviour of the browser. Fixes #4285.
+             */
+            handleMouseDownEvent(event);
         }
 
         /**
@@ -442,7 +448,6 @@ public class VFilterSelect extends Composite implements Paintable, Field,
                 left = getPopupLeft();
             }
             setPopupPosition(left, top);
-
         }
 
         /**
@@ -727,6 +732,7 @@ public class VFilterSelect extends Composite implements Paintable, Field,
      * Used when measuring the width of the popup
      */
     private final HTML popupOpener = new HTML("") {
+
         /*
          * (non-Javadoc)
          * 
@@ -740,6 +746,12 @@ public class VFilterSelect extends Composite implements Paintable, Field,
             if (client != null) {
                 client.handleTooltipEvent(event, VFilterSelect.this);
             }
+
+            /*
+             * Prevent the keyboard focus from leaving the textfield by
+             * preventing the default behaviour of the browser. Fixes #4285.
+             */
+            handleMouseDownEvent(event);
         }
     };
 
@@ -829,7 +841,7 @@ public class VFilterSelect extends Composite implements Paintable, Field,
         });
 
         tb.sinkEvents(VTooltip.TOOLTIP_EVENTS);
-        popupOpener.sinkEvents(VTooltip.TOOLTIP_EVENTS);
+        popupOpener.sinkEvents(VTooltip.TOOLTIP_EVENTS | Event.ONMOUSEDOWN);
         panel.add(tb);
         panel.add(popupOpener);
         initWidget(panel);
@@ -1071,6 +1083,12 @@ public class VFilterSelect extends Composite implements Paintable, Field,
             updateRootWidth();
         }
 
+        // Focus dependent style names are lost during the update, so we add
+        // them here back again
+        if (focused) {
+            addStyleDependentName("focus");
+        }
+
         initDone = true;
     }
 
@@ -1370,9 +1388,8 @@ public class VFilterSelect extends Composite implements Paintable, Field,
                 prompting = true;
             }
             DOM.eventPreventDefault(DOM.eventGetCurrentEvent());
-            tb.setFocus(true);
+            focus();
             tb.selectAll();
-
         }
     }
 
@@ -1401,6 +1418,11 @@ public class VFilterSelect extends Composite implements Paintable, Field,
         return w;
     }-*/;
 
+    /**
+     * A flag which prevents a focus event from taking place
+     */
+    boolean iePreventNextFocus = false;
+
     /*
      * (non-Javadoc)
      * 
@@ -1409,6 +1431,17 @@ public class VFilterSelect extends Composite implements Paintable, Field,
      * .dom.client.FocusEvent)
      */
     public void onFocus(FocusEvent event) {
+
+        /*
+         * When we disable a blur event in ie we need to refocus the textfield.
+         * This will cause a focus event we do not want to process, so in that
+         * case we just ignore it.
+         */
+        if (BrowserInfo.get().isIE() && iePreventNextFocus) {
+            iePreventNextFocus = false;
+            return;
+        }
+
         focused = true;
         if (prompting && !readonly) {
             setPromptingOff("");
@@ -1420,6 +1453,12 @@ public class VFilterSelect extends Composite implements Paintable, Field,
         }
     }
 
+    /**
+     * A flag which cancels the blur event and sets the focus back to the
+     * textfield if the Browser is IE
+     */
+    boolean preventNextBlurEventInIE = false;
+
     /*
      * (non-Javadoc)
      * 
@@ -1427,7 +1466,34 @@ public class VFilterSelect extends Composite implements Paintable, Field,
      * com.google.gwt.event.dom.client.BlurHandler#onBlur(com.google.gwt.event
      * .dom.client.BlurEvent)
      */
+
     public void onBlur(BlurEvent event) {
+
+        if (BrowserInfo.get().isIE() && preventNextBlurEventInIE) {
+            /*
+             * Clicking in the suggestion popup or on the popup button in IE
+             * causes a blur event to be sent for the field. In other browsers
+             * this is prevented by canceling/preventing default behavior for
+             * the focus event, in IE we handle it here by refocusing the text
+             * field and ignoring the resulting focus event for the textfield
+             * (in onFocus).
+             */
+            preventNextBlurEventInIE = false;
+
+            Element focusedElement = Util.getIEFocusedElement();
+            if (getElement().isOrHasChild(focusedElement)
+                    || suggestionPopup.getElement()
+                            .isOrHasChild(focusedElement)) {
+
+                // IF the suggestion popup or another part of the VFilterSelect
+                // was focused, move the focus back to the textfield and prevent
+                // the triggered focus event (in onFocus).
+                iePreventNextFocus = true;
+                tb.setFocus(true);
+                return;
+            }
+        }
+
         focused = false;
         if (!readonly) {
             // much of the TAB handling takes place here
@@ -1633,4 +1699,31 @@ public class VFilterSelect extends Composite implements Paintable, Field,
         }
         return componentPadding;
     }
+
+    /**
+     * Handles special behavior of the mouse down event
+     * 
+     * @param event
+     */
+    private void handleMouseDownEvent(Event event) {
+        /*
+         * Prevent the keyboard focus from leaving the textfield by preventing
+         * the default behaviour of the browser. Fixes #4285.
+         */
+        if (event.getTypeInt() == Event.ONMOUSEDOWN) {
+            event.preventDefault();
+            event.stopPropagation();
+
+            /*
+             * In IE the above wont work, the blur event will still trigger. So,
+             * we set a flag here to prevent the next blur event from happening.
+             * This is not needed if do not already have focus, in that case
+             * there will not be any blur event and we should not cancel the
+             * next blur.
+             */
+            if (BrowserInfo.get().isIE() && focused) {
+                preventNextBlurEventInIE = true;
+            }
+        }
+    }
 }
diff --git a/tests/src/com/vaadin/tests/components/combobox/ComboFocusBlurEvents.html b/tests/src/com/vaadin/tests/components/combobox/ComboFocusBlurEvents.html
new file mode 100644 (file)
index 0000000..4d91ce7
--- /dev/null
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>ComboFocusBlurEvents</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">ComboFocusBlurEvents</td></tr>
+</thead><tbody>
+<tr>
+       <td>open</td>
+       <td>/run/com.vaadin.tests.components.combobox.ComboFocusBlurEvents?restartApplication</td>
+       <td></td>
+</tr>
+<!--Testing selecting several items, the focus should stay on the combo and only one focus event should trigger-->
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[1]</td>
+       <td>9,14</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::Root/VFilterSelect$SuggestionPopup[0]/VFilterSelect$SuggestionMenu[0]#item4</td>
+       <td>142,2</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[1]</td>
+       <td>17,12</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::Root/VFilterSelect$SuggestionPopup[0]/VFilterSelect$SuggestionMenu[0]#item7</td>
+       <td>143,6</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[1]</td>
+       <td>13,9</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::Root/VFilterSelect$SuggestionPopup[0]/VFilterSelect$SuggestionMenu[0]#item3</td>
+       <td>147,11</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[1]</td>
+       <td>16,11</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::Root/VFilterSelect$SuggestionPopup[0]/VFilterSelect$SuggestionMenu[0]#item5</td>
+       <td>146,4</td>
+</tr>
+<tr>
+       <td>assertText</td>
+       <td>vaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VLabel[0]</td>
+       <td>exact:0: Focus event!</td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>OneFocusEvent</td>
+</tr>
+<!--Test ended.-->
+<!--Testing keyboard navigation-->
+<tr>
+       <td>pressSpecialKey</td>
+       <td>vaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[0]</td>
+       <td>down</td>
+</tr>
+<tr>
+       <td>pressSpecialKey</td>
+       <td>vaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[0]</td>
+       <td>down</td>
+</tr>
+<tr>
+       <td>pressSpecialKey</td>
+       <td>vaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[0]</td>
+       <td>down</td>
+</tr>
+<tr>
+       <td>pressSpecialKey</td>
+       <td>vaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[0]</td>
+       <td>down</td>
+</tr>
+<tr>
+       <td>pressSpecialKey</td>
+       <td>vaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[0]</td>
+       <td>down</td>
+</tr>
+<tr>
+       <td>pressSpecialKey</td>
+       <td>vaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[0]</td>
+       <td>enter</td>
+</tr>
+<tr>
+       <td>assertText</td>
+       <td>vaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VLabel[0]</td>
+       <td>exact:0: Focus event!</td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>StillOneFocusEvent</td>
+</tr>
+<!--Test ended.-->
+<!--Move focus out with mouse-->
+<tr>
+       <td>focus</td>
+       <td>vaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VTextField[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>assertText</td>
+       <td>vaadin=runcomvaadintestscomponentscomboboxComboFocusBlurEvents::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VLabel[0]</td>
+       <td>0: Focus event!<br />1: Blur event!</td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>OneFocusOneBlur</td>
+</tr>
+<!--End test.-->
+
+</tbody></table>
+</body>
+</html>
diff --git a/tests/src/com/vaadin/tests/components/combobox/ComboFocusBlurEvents.java b/tests/src/com/vaadin/tests/components/combobox/ComboFocusBlurEvents.java
new file mode 100644 (file)
index 0000000..6681342
--- /dev/null
@@ -0,0 +1,74 @@
+package com.vaadin.tests.components.combobox;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.event.FieldEvents;
+import com.vaadin.event.FieldEvents.BlurEvent;
+import com.vaadin.event.FieldEvents.FocusEvent;
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TextField;
+
+public class ComboFocusBlurEvents extends TestBase {
+
+    private int counter = 0;
+
+    @Override
+    protected void setup() {
+        
+        List<String> list = new ArrayList<String>();
+        for (int i = 0; i < 100; i++) {
+            list.add("Item " + i);
+        }
+        
+        ComboBox cb = new ComboBox("Combobox", list);
+        cb.setImmediate(true);
+        cb.setInputPrompt("Enter text");
+        cb.setDescription("Some Combobox");
+        addComponent(cb);
+                        
+        final ObjectProperty<String> log = new ObjectProperty<String>("");
+
+        cb.addListener(new FieldEvents.FocusListener() {
+            public void focus(FocusEvent event) {
+                log.setValue(log.getValue().toString() + "<br>" + counter
+                        + ": Focus event!");
+                counter++;
+            }
+        });
+
+        cb.addListener(new FieldEvents.BlurListener() {
+            public void blur(BlurEvent event) {
+                log.setValue(log.getValue().toString() + "<br>" + counter
+                        + ": Blur event!");
+                counter++;
+            }
+        });
+        
+        TextField field = new TextField("Some textfield");
+        field.setImmediate(true);
+        addComponent(field);
+
+        Label output = new Label(log);
+        output.setCaption("Events:");
+
+        output.setContentMode(Label.CONTENT_XHTML);
+        addComponent(output);
+
+    }
+
+    @Override
+    protected String getDescription() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 6536;
+    }
+
+}
index d639bbf3e49fc37dee5ff5843e09bdd6524c3dc7..1affc9a8a98445d5e14069c23d4d7e41dc965610 100644 (file)
@@ -4,12 +4,12 @@
 <head profile="http://selenium-ide.openqa.org/profiles/test-case">
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 <link rel="selenium.base" href="" />
-<title>New Test</title>
+<title>Comboboxes</title>
 </head>
 <body>
 <table cellpadding="1" cellspacing="1" border="1">
 <thead>
-<tr><td rowspan="1" colspan="3">New Test</td></tr>
+<tr><td rowspan="1" colspan="3">Comboboxes</td></tr>
 </thead><tbody>
 <tr>
        <td>setSpeed</td>
        <td></td>
        <td></td>
 </tr>
+
 </tbody></table>
 </body>
 </html>