summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorTeemu Suo-Anttila <teemusa@vaadin.com>2014-01-13 17:03:01 +0200
committerVaadin Code Review <review@vaadin.com>2014-01-16 11:14:29 +0000
commit168788959373f561b8862128fa6aedc20a5591c2 (patch)
tree58029d9784218cd3c0dcf30a72366b4fe45d5cdd /client
parentb9a6a48ab6ce9e3c7d8d025520e866643d19c004 (diff)
downloadvaadin-framework-168788959373f561b8862128fa6aedc20a5591c2.tar.gz
vaadin-framework-168788959373f561b8862128fa6aedc20a5591c2.zip
Retain focus while changing DOM in OrderedLayout (#12967)
Change-Id: Id25177a2dfecc2d0d3b8bb5803656a39bec9c5d6
Diffstat (limited to 'client')
-rw-r--r--client/src/com/vaadin/client/ui/orderedlayout/Slot.java51
1 files changed, 51 insertions, 0 deletions
diff --git a/client/src/com/vaadin/client/ui/orderedlayout/Slot.java b/client/src/com/vaadin/client/ui/orderedlayout/Slot.java
index 49b3661431..37a97f3399 100644
--- a/client/src/com/vaadin/client/ui/orderedlayout/Slot.java
+++ b/client/src/com/vaadin/client/ui/orderedlayout/Slot.java
@@ -19,9 +19,11 @@ package com.vaadin.client.ui.orderedlayout;
import java.util.List;
import com.google.gwt.aria.client.Roles;
+import com.google.gwt.dom.client.Document;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;
@@ -456,6 +458,9 @@ public final class Slot extends SimplePanel {
// Caption wrappers
Widget widget = getWidget();
+ final Element focusedElement = Util.getFocusedElement();
+ // By default focus will not be lost
+ boolean focusLost = false;
if (captionText != null || iconUrl != null || error != null || required) {
if (caption == null) {
caption = DOM.createDiv();
@@ -466,6 +471,10 @@ public final class Slot extends SimplePanel {
orphan(widget);
captionWrap.appendChild(widget.getElement());
adopt(widget);
+
+ // Made changes to DOM. Focus can be lost if it was in the
+ // widget.
+ focusLost = widget.getElement().isOrHasChild(focusedElement);
}
} else if (caption != null) {
orphan(widget);
@@ -474,6 +483,9 @@ public final class Slot extends SimplePanel {
captionWrap.removeFromParent();
caption = null;
captionWrap = null;
+
+ // Made changes to DOM. Focus can be lost if it was in the widget.
+ focusLost = widget.getElement().isOrHasChild(focusedElement);
}
// Caption text
@@ -560,6 +572,45 @@ public final class Slot extends SimplePanel {
setCaptionPosition(CaptionPosition.RIGHT);
}
}
+
+ if (focusLost) {
+ // Find out what element is currently focused.
+ Element currentFocus = Util.getFocusedElement();
+ if (currentFocus != null
+ && currentFocus.equals(Document.get().getBody())) {
+ // Focus has moved to BodyElement and should be moved back to
+ // original location. This happened because of adding or
+ // removing the captionWrap
+ focusedElement.focus();
+ } else if (currentFocus != focusedElement) {
+ // Focus is either moved somewhere else on purpose or IE has
+ // lost it. Investigate further.
+ Timer focusTimer = new Timer() {
+
+ @Override
+ public void run() {
+ if (Util.getFocusedElement() == null) {
+ // This should never become an infinite loop and
+ // even if it does it will be stopped once something
+ // is done with the browser.
+ schedule(25);
+ } else if (Util.getFocusedElement().equals(
+ Document.get().getBody())) {
+ // Focus found it's way to BodyElement. Now it can
+ // be restored
+ focusedElement.focus();
+ }
+ }
+ };
+ if (BrowserInfo.get().isIE8()) {
+ // IE8 can't fix the focus immediately. It will fail.
+ focusTimer.schedule(25);
+ } else {
+ // Newer IE versions can handle things immediately.
+ focusTimer.run();
+ }
+ }
+ }
}
/**