Bug 567663. Implement 'hidden' attribute. r=sicking
authorMs2ger <Ms2ger@gmail.com>
Mon, 02 Aug 2010 15:07:07 +1200
changeset 48696 b1d534754b62
parent 48695 21e82bbf63d2
child 48698 3abcda8e8ca5
push id14768
push userrocallahan@mozilla.com
push dateMon, 02 Aug 2010 03:08:16 +0000
treeherdermozilla-central@b1d534754b62 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking
bugs567663
milestone2.0b3pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 567663. Implement 'hidden' attribute. r=sicking
content/html/content/reftests/hidden-1-ref.html
content/html/content/reftests/hidden-1a.html
content/html/content/reftests/hidden-1b.html
content/html/content/reftests/hidden-1c.html
content/html/content/reftests/hidden-1d.html
content/html/content/reftests/hidden-1e.html
content/html/content/reftests/hidden-1f.html
content/html/content/reftests/hidden-1g.html
content/html/content/reftests/hidden-2-ref.svg
content/html/content/reftests/hidden-2.svg
content/html/content/reftests/reftest.list
content/html/content/src/nsGenericHTMLElement.cpp
content/html/content/src/nsGenericHTMLElement.h
content/html/content/test/Makefile.in
content/html/content/test/test_hidden.html
dom/interfaces/html/nsIDOMNSHTMLElement.idl
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/hidden-1-ref.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<title>The hidden attribute</title>
+<link rel=author title=Ms2ger href=ms2ger@gmail.com>
+<link rel=help href=http://www.whatwg.org/html5/#the-hidden-attribute>
+<p>This line should be visible.
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/hidden-1a.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<title>The hidden attribute</title>
+<link rel=author title=Ms2ger href=ms2ger@gmail.com>
+<link rel=help href=http://www.whatwg.org/html5/#the-hidden-attribute>
+<p>This line should be visible.
+<p hidden>This line should not be visible.
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/hidden-1b.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<title>The hidden attribute</title>
+<link rel=author title=Ms2ger href=ms2ger@gmail.com>
+<link rel=help href=http://www.whatwg.org/html5/#the-hidden-attribute>
+<style>
+p { display: none; }
+[hidden] { display: block; }
+</style>
+<p hidden>This line should be visible.
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/hidden-1c.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>The hidden attribute</title>
+<link rel=author title=Ms2ger href=ms2ger@gmail.com>
+<link rel=help href=http://www.whatwg.org/html5/#the-hidden-attribute>
+<p hidden>This line should be visible.
+<p>This line should not be visible.
+<script>
+document.getElementsByTagName("p")[0].hidden = false;
+document.getElementsByTagName("p")[1].hidden = true;
+</script>
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/hidden-1d.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>The hidden attribute</title>
+<link rel=author title=Ms2ger href=ms2ger@gmail.com>
+<link rel=help href=http://www.whatwg.org/html5/#the-hidden-attribute>
+<p hidden>This line should be visible.
+<p>This line should not be visible.
+<script>
+document.getElementsByTagName("p")[0].removeAttribute("hidden");
+document.getElementsByTagName("p")[1].setAttribute("hidden", "");
+</script>
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/hidden-1e.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<title>The hidden attribute</title>
+<link rel=author title=Ms2ger href=ms2ger@gmail.com>
+<link rel=help href=http://www.whatwg.org/html5/#the-hidden-attribute>
+<style>
+p { display: block; }
+</style>
+<p hidden>This line should be visible.
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/hidden-1f.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<title>The hidden attribute</title>
+<link rel=author title=Ms2ger href=ms2ger@gmail.com>
+<link rel=help href=http://www.whatwg.org/html5/#the-hidden-attribute>
+<style>
+p { display: block !important; }
+</style>
+<p hidden>This line should be visible.
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/hidden-1g.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<title>The hidden attribute</title>
+<link rel=author title=Ms2ger href=ms2ger@gmail.com>
+<link rel=help href=http://www.whatwg.org/html5/#the-hidden-attribute>
+<p>This line should be visible.
+<p hidden=hidden>This line should not be visible.
+<p hidden=blue>This line should not be visible.
+<p hidden=true>This line should not be visible.
+<p hidden=false>This line should not be visible.
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/hidden-2-ref.svg
@@ -0,0 +1,9 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20">
+<metadata>
+  <link xmlns="http://www.w3.org/1999/xhtml" rel="author" title="Ms2ger"
+        href="ms2ger@gmail.com"/>
+  <link xmlns="http://www.w3.org/1999/xhtml" rel="help"
+        href="http://www.whatwg.org/html5/#the-hidden-attribute"/>
+</metadata>
+<rect height="20" width="20"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/hidden-2.svg
@@ -0,0 +1,9 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20">
+<metadata>
+  <link xmlns="http://www.w3.org/1999/xhtml" rel="author" title="Ms2ger"
+        href="ms2ger@gmail.com"/>
+  <link xmlns="http://www.w3.org/1999/xhtml" rel="help"
+        href="http://www.whatwg.org/html5/#the-hidden-attribute"/>
+</metadata>
+<rect hidden="" height="20" width="20"/>
+</svg>
--- a/content/html/content/reftests/reftest.list
+++ b/content/html/content/reftests/reftest.list
@@ -8,10 +8,18 @@
 == 468263-2.html 468263-2-ref.html
 == 468263-2.html 468263-2-alternate-ref.html
 == 484200-1.html 484200-1-ref.html
 == 485377.html 485377-ref.html
 == 557840.html 557840-ref.html
 == 560059-video-dimensions.html 560059-video-dimensions-ref.html
 == 573322-quirks.html 573322-quirks-ref.html
 == 573322-no-quirks.html 573322-no-quirks-ref.html
+== hidden-1a.html hidden-1-ref.html
+== hidden-1b.html hidden-1-ref.html
+== hidden-1c.html hidden-1-ref.html
+== hidden-1d.html hidden-1-ref.html
+== hidden-1e.html hidden-1-ref.html
+== hidden-1f.html hidden-1-ref.html
+== hidden-1g.html hidden-1-ref.html
+== hidden-2.svg hidden-2-ref.svg
 == href-attr-change-restyles.html href-attr-change-restyles-ref.html
 == figure.html figure-ref.html
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -252,16 +252,17 @@ NS_INTERFACE_TABLE_HEAD(nsGenericHTMLEle
   NS_INTERFACE_TABLE_INHERITED2(nsGenericHTMLElementTearoff,
                                 nsIDOMNSHTMLElement,
                                 nsIDOMElementCSSInlineStyle)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsGenericHTMLElementTearoff)
 NS_INTERFACE_MAP_END_AGGREGATED(mElement)
 
 
 NS_IMPL_INT_ATTR(nsGenericHTMLElement, TabIndex, tabindex)
+NS_IMPL_BOOL_ATTR(nsGenericHTMLElement, Hidden, hidden)
 
 nsresult
 nsGenericHTMLElement::DOMQueryInterface(nsIDOMHTMLElement *aElement,
                                         REFNSIID aIID, void **aInstancePtr)
 {
   NS_PRECONDITION(aInstancePtr, "null out param");
 
   nsresult rv = NS_ERROR_FAILURE;
@@ -274,17 +275,17 @@ nsGenericHTMLElement::DOMQueryInterface(
 
   NS_INTERFACE_TABLE_TO_MAP_SEGUE
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMNSHTMLElement,
                                  new nsGenericHTMLElementTearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMElementCSSInlineStyle,
                                  new nsGenericHTMLElementTearoff(this))
   NS_INTERFACE_MAP_END
 
-// No closing bracket, becuase NS_INTERFACE_MAP_END does that for us.
+// No closing bracket, because NS_INTERFACE_MAP_END does that for us.
     
 nsresult
 nsGenericHTMLElement::CopyInnerTo(nsGenericElement* aDst) const
 {
   nsresult rv;
   PRInt32 i, count = GetAttrCount();
   for (i = 0; i < count; ++i) {
     const nsAttrName *name = mAttrsAndChildren.AttrNameAt(i);
@@ -1627,23 +1628,33 @@ nsGenericHTMLElement::MapCommonAttribute
         }
         else if (value->Equals(nsGkAtoms::_false, eIgnoreCase)) {
             ui->mUserModify.SetIntValue(NS_STYLE_USER_MODIFY_READ_ONLY,
                                         eCSSUnit_Enumerated);
         }
       }
     }
   }
+
   if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Visibility)) {
     const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::lang);
     if (value && value->Type() == nsAttrValue::eString) {
       aData->mDisplayData->mLang.SetStringValue(value->GetStringValue(),
                                                 eCSSUnit_Ident);
     }
   }
+
+  if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Display)) {
+    nsRuleDataDisplay* disp = aData->mDisplayData;
+    if (disp->mDisplay.GetUnit() == eCSSUnit_Null) {
+      if (aAttributes->IndexOfAttr(nsGkAtoms::hidden, kNameSpaceID_None) >= 0) {
+        disp->mDisplay.SetIntValue(NS_STYLE_DISPLAY_NONE, eCSSUnit_Enumerated);
+      }
+    }
+  }
 }
 
 void
 nsGenericHTMLFormElement::UpdateEditableFormControlState()
 {
   // nsCSSFrameConstructor::MaybeConstructLazily is based on the logic of this
   // function, so should be kept in sync with that.
 
@@ -1673,16 +1684,17 @@ nsGenericHTMLFormElement::UpdateEditable
   SetEditableFlag(!roState);
 }
 
 
 /* static */ const nsGenericHTMLElement::MappedAttributeEntry
 nsGenericHTMLElement::sCommonAttributeMap[] = {
   { &nsGkAtoms::contenteditable },
   { &nsGkAtoms::lang },
+  { &nsGkAtoms::hidden },
   { nsnull }
 };
 
 /* static */ const nsGenericElement::MappedAttributeEntry
 nsGenericHTMLElement::sImageMarginSizeAttributeMap[] = {
   { &nsGkAtoms::width },
   { &nsGkAtoms::height },
   { &nsGkAtoms::hspace },
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -136,23 +136,25 @@ public:
   nsresult GetOffsetTop(PRInt32* aOffsetTop);
   nsresult GetOffsetLeft(PRInt32* aOffsetLeft);
   nsresult GetOffsetWidth(PRInt32* aOffsetWidth);
   nsresult GetOffsetHeight(PRInt32* aOffsetHeight);
   nsresult GetOffsetParent(nsIDOMElement** aOffsetParent);
   virtual nsresult GetInnerHTML(nsAString& aInnerHTML);
   virtual nsresult SetInnerHTML(const nsAString& aInnerHTML);
   nsresult ScrollIntoView(PRBool aTop, PRUint8 optional_argc);
-  // Declare Focus(), Blur(), GetTabIndex(), SetTabIndex(), GetSpellcheck(),
-  // SetSpellcheck(), and GetDraggable() such that classes that inherit interfaces
-  // with those methods properly override them
+  // Declare Focus(), Blur(), GetTabIndex(), SetTabIndex(), GetHidden(),
+  // SetHidden(), GetSpellcheck(), SetSpellcheck(), and GetDraggable() such that
+  // classes that inherit interfaces with those methods properly override them.
   NS_IMETHOD Focus();
   NS_IMETHOD Blur();
   NS_IMETHOD GetTabIndex(PRInt32 *aTabIndex);
   NS_IMETHOD SetTabIndex(PRInt32 aTabIndex);
+  NS_IMETHOD GetHidden(PRBool* aHidden);
+  NS_IMETHOD SetHidden(PRBool aHidden);
   NS_IMETHOD GetSpellcheck(PRBool* aSpellcheck);
   NS_IMETHOD SetSpellcheck(PRBool aSpellcheck);
   NS_IMETHOD GetDraggable(PRBool* aDraggable);
   NS_IMETHOD SetDraggable(PRBool aDraggable);
   nsresult GetContentEditable(nsAString &aContentEditable);
   nsresult GetIsContentEditable(PRBool* aContentEditable);
   nsresult SetContentEditable(const nsAString &aContentEditable);
 
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -30,26 +30,28 @@
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
-DEPTH		= ../../../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-relativesrcdir  = content/html/content/test
+DEPTH          = ../../../..
+topsrcdir      = @top_srcdir@
+srcdir         = @srcdir@
+VPATH          = @srcdir@
+relativesrcdir = content/html/content/test
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
-_TEST_FILES = 	test_bug589.html \
+_TEST_FILES = \
+		test_hidden.html \
+		test_bug589.html \
 		test_bug691.html \
 		nnc_lockup.gif \
 		test_bug694.html \
 		test_bug696.html \
 		test_bug1297.html \
 		test_bug1366.html \
 		test_bug1400.html \
 		test_bug2082.html \
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_hidden.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=567663
+-->
+<head>
+  <title>Test for Bug 567663</title>
+  <script src="/MochiKit/packed.js"></script>
+  <script src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=567663">Mozilla Bug 567663</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  <p></p>
+  <p hidden></p>
+</div>
+<pre id="test">
+<script>
+/** Test for Bug 567663 **/
+var ps = document.getElementById("content").getElementsByTagName("p");
+is(ps[0].hidden, false, "First p's IDL attribute was wrong.");
+is(ps[0].hasAttribute("hidden"), false, "First p had a content attribute.");
+is(ps[1].hidden, true, "Second p's IDL attribute was wrong.");
+is(ps[1].hasAttribute("hidden"), true,
+   "Second p didn't have a content attribute.");
+is(ps[1].getAttribute("hidden"), "",
+   "Second p's content attribute was wrong.");
+
+ps[0].hidden = true;
+is(ps[0].getAttribute("hidden"), "",
+   "Content attribute was set to an incorrect value.");
+ps[1].hidden = false;
+is(ps[1].hasAttribute("hidden"), false,
+   "Second p still had a content attribute.");
+
+ps[0].setAttribute("hidden", "banana");
+is(ps[0].hidden, true, "p's IDL attribute was wrong after setting.");
+is(ps[0].getAttribute("hidden"), "banana", "Content attribute changed.");
+
+ps[0].setAttribute("hidden", "false");
+is(ps[0].hidden, true, "p's IDL attribute was wrong after setting.");
+is(ps[0].getAttribute("hidden"), "false", "Content attribute changed.");
+
+ps[0].removeAttribute("hidden");
+is(ps[0].hidden, false,
+   "p's IDL attribute was wrong after removing the content attribute.");
+is(ps[0].hasAttribute("hidden"), false);
+</script>
+</pre>
+</body>
+</html>
--- a/dom/interfaces/html/nsIDOMNSHTMLElement.idl
+++ b/dom/interfaces/html/nsIDOMNSHTMLElement.idl
@@ -33,26 +33,33 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "domstubs.idl"
 
-[scriptable, uuid(2eeec2e5-a48f-4251-b2e2-adfb87929d18)]
+[scriptable, uuid(f0ffe1d2-9615-492b-aae1-05428ebc2a70)]
 interface nsIDOMNSHTMLElement : nsISupports
 {
   readonly attribute long             offsetTop;
   readonly attribute long             offsetLeft;
   readonly attribute long             offsetWidth;
   readonly attribute long             offsetHeight;
   readonly attribute nsIDOMElement    offsetParent;
            attribute DOMString        innerHTML;
 
+  /**
+   * Indicates that the element is not yet, or is no longer, relevant.
+   *
+   * See <http://www.whatwg.org/html5/#the-hidden-attribute>.
+   */
+           attribute boolean          hidden;
+
            attribute long             tabIndex;
 
            attribute DOMString        contentEditable;
   readonly attribute boolean          isContentEditable;
 
            // for WHAT-WG drag and drop
            attribute boolean          draggable;