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());
+  }
 }