Adds support for aria-hidden to UIObject.setVisible().

Review at http://gwt-code-reviews.appspot.com/1671803

Review by: jlabanca@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10924 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/ui/UIObject.java b/user/src/com/google/gwt/user/client/ui/UIObject.java
index 0aa817c..f5e3b36 100644
--- a/user/src/com/google/gwt/user/client/ui/UIObject.java
+++ b/user/src/com/google/gwt/user/client/ui/UIObject.java
@@ -221,12 +221,34 @@
     ensureDebugId(elem, "", id);
   }
 
+  /**
+   * Returns whether the given element is visible in a way consistent with
+   * {@link #setVisible(Element, boolean)}.
+   *
+   * <p>
+   * Warning: implemented with a heuristic. The value returned takes into
+   * account only the "display" style, ignoring CSS and Aria roles, thus may not
+   * accurately reflect whether the element is actually visible in the browser.
+   * </p>
+   */
   public static native boolean isVisible(Element elem) /*-{
     return (elem.style.display != 'none');
   }-*/;
 
+  /**
+   * Shows or hides the given element. Also updates the "aria-hidden" attribute.
+   *
+   * <p>
+   * Warning: implemented with a heuristic based on the "display" style:
+   * clears the "display" style to its default value if {@code visible} is true,
+   * else forces the style to "none". If the "display" style is set to "none"
+   * via CSS style sheets, the element remains invisible after a call to
+   * {@code setVisible(elem, true)}.
+   * </p>
+   */
   public static native void setVisible(Element elem, boolean visible) /*-{
     elem.style.display = visible ? '' : 'none';
+    elem.setAttribute('aria-hidden', String(!visible));
   }-*/;
 
   /**
diff --git a/user/test/com/google/gwt/user/client/ui/UIObjectTest.java b/user/test/com/google/gwt/user/client/ui/UIObjectTest.java
index 19a4b65..3603b09 100644
--- a/user/test/com/google/gwt/user/client/ui/UIObjectTest.java
+++ b/user/test/com/google/gwt/user/client/ui/UIObjectTest.java
@@ -15,9 +15,11 @@
  */
 package com.google.gwt.user.client.ui;
 
+import com.google.gwt.aria.client.State;
 import com.google.gwt.debug.client.DebugInfo;
 import com.google.gwt.dom.client.Document;
 import com.google.gwt.dom.client.SpanElement;
+import com.google.gwt.dom.client.Style;
 import com.google.gwt.junit.client.GWTTestCase;
 import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.Element;
@@ -212,6 +214,48 @@
     DebugInfo.setDebugIdPrefix(oldPrefix);
   }
 
+  public void testIsVisible_defaultDisplay() {
+    Element elem = DOM.createDiv();
+    assertTrue(UIObject.isVisible(elem));
+  }
+
+  public void testIsVisible_customDisplay() {
+    Element elem = DOM.createDiv();
+    elem.getStyle().setDisplay(Style.Display.INLINE_BLOCK);
+    assertTrue(UIObject.isVisible(elem));
+  }
+
+  public void testIsVisible_hidden() {
+    Element elem = DOM.createDiv();
+    elem.getStyle().setDisplay(Style.Display.NONE);
+    assertFalse(UIObject.isVisible(elem));
+  }
+
+  public void testIsVisible_ignoresAria() {
+    Element elem = DOM.createDiv();
+    State.HIDDEN.set(elem, true);
+    assertTrue(UIObject.isVisible(elem));
+  }
+
+  public void testSetVisible() {
+    // Initial state: visible
+    Element elem = DOM.createDiv();
+    assertTrue(UIObject.isVisible(elem));
+    assertFalse(Boolean.valueOf(State.HIDDEN.get(elem)));
+
+    // Hide
+    UIObject.setVisible(elem, false);
+    assertFalse(UIObject.isVisible(elem));
+    assertEquals(Style.Display.NONE.getCssName(), elem.getStyle().getDisplay());
+    assertTrue(Boolean.valueOf(State.HIDDEN.get(elem)));
+
+    // Show again
+    UIObject.setVisible(elem, true);
+    assertTrue(UIObject.isVisible(elem));
+    assertEquals("", elem.getStyle().getDisplay());
+    assertFalse(Boolean.valueOf(State.HIDDEN.get(elem)));
+  }
+
   public void testNormal() {
     // Test the basic set/get case.
     MyObject o = new MyObject();