Lazily initialize FocusImplStandard.focusHandler to avoid clinits.
http://gwt-code-reviews.appspot.com/154808/show
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7641 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/ui/impl/FocusImplStandard.java b/user/src/com/google/gwt/user/client/ui/impl/FocusImplStandard.java
index 4a8a61b..74ca355 100644
--- a/user/src/com/google/gwt/user/client/ui/impl/FocusImplStandard.java
+++ b/user/src/com/google/gwt/user/client/ui/impl/FocusImplStandard.java
@@ -25,14 +25,12 @@
*/
public class FocusImplStandard extends FocusImpl {
- /*
- * Use isolated method calls to create all of the handlers to avoid creating
- * memory leaks via handler-closures-element.
+ /**
+ * Single focusHandler shared by all focusable.
*/
- JavaScriptObject focusHandler = createFocusHandler();
+ static JavaScriptObject focusHandler;
- @Override
- public native Element createFocusable() /*-{
+ private static native Element createFocusable0(JavaScriptObject focusHandler) /*-{
// Divs are focusable in all browsers, but only IE supports the accessKey
// property on divs. We use the infamous 'hidden input' trick to add an
// accessKey to the focusable div. Note that the input is only used to
@@ -44,31 +42,38 @@
var input = $doc.createElement('input');
input.type = 'text';
input.tabIndex = -1;
- input.style.opacity = 0;
- input.style.height = '1px';
- input.style.width = '1px';
- input.style.zIndex = -1;
- input.style.overflow = 'hidden';
- input.style.position = 'absolute';
+ var style = input.style;
+ style.opacity = 0;
+ style.height = '1px';
+ style.width = '1px';
+ style.zIndex = -1;
+ style.overflow = 'hidden';
+ style.position = 'absolute';
// Note that we're using isolated lambda methods as the event listeners
// to avoid creating a memory leaks. (Lambdas here would create cycles
// involving the div and input). This also allows us to share a single
// set of handlers among every focusable item.
- input.addEventListener(
- 'focus',
- this.@com.google.gwt.user.client.ui.impl.FocusImplStandard::focusHandler,
- false);
+ input.addEventListener('focus', focusHandler, false);
div.appendChild(input);
return div;
}-*/;
@Override
+ public Element createFocusable() {
+ return createFocusable0(ensureFocusHandler());
+ }
+
+ @Override
public native void setAccessKey(Element elem, char key) /*-{
elem.firstChild.accessKey = String.fromCharCode(key);
}-*/;
+ /**
+ * Use an isolated method call to create the handler to avoid creating memory
+ * leaks via handler-closures-element.
+ */
private native JavaScriptObject createFocusHandler() /*-{
return function(evt) {
// This function is called directly as an event handler, so 'this' is
@@ -83,4 +88,8 @@
}
};
}-*/;
+
+ private JavaScriptObject ensureFocusHandler() {
+ return focusHandler != null ? focusHandler : (focusHandler = createFocusHandler());
+ }
}