Bug 555840 - Implement datalist element. r=sicking,mrbkap,ehsan sr=smaug a2.0=roc
authorMounir Lamouri <mounir.lamouri@gmail.com>
Fri, 10 Sep 2010 07:16:56 +0200
changeset 52362 43ae28d1240d9adebe0d33f4544c728ee5343432
parent 52361 e5fd1e37beb404f004251821b528da3e53c5dae3
child 52363 2dc709fe2fcf07c214e254f497acffbe036ac8b1
push idunknown
push userunknown
push dateunknown
reviewerssicking, mrbkap, ehsan, smaug
bugs555840
milestone2.0b6pre
Bug 555840 - Implement datalist element. r=sicking,mrbkap,ehsan sr=smaug a2.0=roc
content/base/src/nsGkAtomList.h
content/html/content/src/Makefile.in
content/html/content/src/nsGenericHTMLElement.h
content/html/content/src/nsHTMLDataListElement.cpp
content/html/content/test/Makefile.in
content/html/content/test/test_bug389797.html
content/html/content/test/test_bug555840.html
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/interfaces/html/Makefile.in
dom/interfaces/html/nsIDOMHTMLDataListElement.idl
editor/libeditor/base/nsEditPropertyAtomList.h
editor/libeditor/html/nsHTMLEditUtils.cpp
layout/reftests/datalist/datalist-errors.html
layout/reftests/datalist/datalist-simple.html
layout/reftests/datalist/reftest.list
layout/reftests/reftest.list
layout/style/html.css
parser/htmlparser/public/nsHTMLTagList.h
parser/htmlparser/src/nsElementTable.cpp
parser/htmlparser/src/nsHTMLTags.cpp
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -257,16 +257,17 @@ GK_ATOM(count, "count")
 GK_ATOM(crop, "crop")
 GK_ATOM(curpos, "curpos")
 GK_ATOM(current, "current")
 #ifdef MOZ_MEDIA
 GK_ATOM(currentloop, "currentloop")
 #endif
 GK_ATOM(cycler, "cycler")
 GK_ATOM(data, "data")
+GK_ATOM(datalist, "datalist")
 GK_ATOM(dataType, "data-type")
 GK_ATOM(datasources, "datasources")
 GK_ATOM(datetime, "datetime")
 GK_ATOM(dblclick, "dblclick")
 GK_ATOM(dd, "dd")
 GK_ATOM(debug, "debug")
 GK_ATOM(decimalFormat, "decimal-format")
 GK_ATOM(decimalSeparator, "decimal-separator")
--- a/content/html/content/src/Makefile.in
+++ b/content/html/content/src/Makefile.in
@@ -67,16 +67,17 @@ CPPSRCS		= \
 		nsTextEditorState.cpp \
 		nsHTMLElement.cpp \
 		nsHTMLAnchorElement.cpp \
 		nsHTMLAreaElement.cpp \
 		nsHTMLBRElement.cpp \
 		nsHTMLBodyElement.cpp \
 		nsHTMLButtonElement.cpp \
 		nsHTMLCanvasElement.cpp \
+		nsHTMLDataListElement.cpp \
 		nsHTMLDelElement.cpp \
 		nsHTMLDivElement.cpp \
 		nsHTMLFieldSetElement.cpp \
 		nsHTMLFontElement.cpp \
 		nsHTMLFormElement.cpp \
 		nsHTMLFrameElement.cpp \
 		nsHTMLFrameSetElement.cpp \
 		nsHTMLHRElement.cpp \
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -1400,16 +1400,17 @@ NS_DECLARE_NS_NEW_HTML_ELEMENT(Area)
 #if defined(MOZ_MEDIA)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Audio)
 #endif
 NS_DECLARE_NS_NEW_HTML_ELEMENT(BR)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Body)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Button)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Canvas)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Mod)
+NS_DECLARE_NS_NEW_HTML_ELEMENT(DataList)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Div)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(FieldSet)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Font)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Form)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Frame)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(FrameSet)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(HR)
 NS_DECLARE_NS_NEW_HTML_ELEMENT_AS_SHARED(Head)
new file mode 100644
--- /dev/null
+++ b/content/html/content/src/nsHTMLDataListElement.cpp
@@ -0,0 +1,141 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Mounir Lamouri <mounir.lamouri@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * 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 ***** */
+
+#include "nsIDOMHTMLDataListElement.h"
+#include "nsGenericHTMLElement.h"
+#include "nsIDOMEventTarget.h"
+#include "nsGkAtoms.h"
+#include "nsIDOMHTMLOptionElement.h"
+
+
+class nsHTMLDataListElement : public nsGenericHTMLElement,
+                              public nsIDOMHTMLDataListElement
+{
+public:
+  nsHTMLDataListElement(already_AddRefed<nsINodeInfo> aNodeInfo);
+  virtual ~nsHTMLDataListElement();
+
+  // nsISupports
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+
+  // nsIDOMNode
+  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+
+  // nsIDOMElement
+  NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
+
+  // nsIDOMHTMLElement
+  NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
+
+  // nsIDOMHTMLDataListElement
+  NS_DECL_NSIDOMHTMLDATALISTELEMENT
+
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+
+  // This function is used to generate the nsContentList (option elements).
+  static PRBool MatchOptions(nsIContent* aContent, PRInt32 aNamespaceID,
+                             nsIAtom* aAtom, void* aData);
+
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLDataListElement,
+                                           nsGenericHTMLElement)
+
+  virtual nsXPCClassInfo* GetClassInfo();
+
+protected:
+
+  // <option>'s list inside the datalist element.
+  nsRefPtr<nsContentList> mOptions;
+};
+
+
+NS_IMPL_NS_NEW_HTML_ELEMENT(DataList)
+
+
+nsHTMLDataListElement::nsHTMLDataListElement(already_AddRefed<nsINodeInfo> aNodeInfo)
+  : nsGenericHTMLElement(aNodeInfo)
+{
+}
+
+nsHTMLDataListElement::~nsHTMLDataListElement()
+{
+}
+
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsHTMLDataListElement)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOptions)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLDataListElement)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLDataListElement,
+                                                  nsGenericHTMLElement)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mOptions, nsIDOMNodeList)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_ADDREF_INHERITED(nsHTMLDataListElement, nsGenericElement)
+NS_IMPL_RELEASE_INHERITED(nsHTMLDataListElement, nsGenericElement)
+
+DOMCI_NODE_DATA(HTMLDataListElement, nsHTMLDataListElement)
+
+NS_INTERFACE_TABLE_HEAD(nsHTMLDataListElement)
+  NS_HTML_CONTENT_INTERFACE_TABLE1(nsHTMLDataListElement, nsIDOMHTMLDataListElement)
+  NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLDataListElement,
+                                               nsGenericHTMLElement)
+NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLDataListElement)
+
+
+NS_IMPL_ELEMENT_CLONE(nsHTMLDataListElement)
+
+PRBool
+nsHTMLDataListElement::MatchOptions(nsIContent* aContent, PRInt32 aNamespaceID,
+                                    nsIAtom* aAtom, void* aData)
+{
+  return aContent->NodeInfo()->Equals(nsGkAtoms::option, kNameSpaceID_XHTML) &&
+         !aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
+}
+
+NS_IMETHODIMP
+nsHTMLDataListElement::GetOptions(nsIDOMHTMLCollection** aOptions)
+{
+  if (!mOptions) {
+    mOptions = new nsContentList(this, MatchOptions, nsnull, nsnull, PR_FALSE);
+  }
+
+  NS_ADDREF(*aOptions = mOptions);
+
+  return NS_OK;
+}
+
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -212,12 +212,13 @@ include $(topsrcdir)/config/rules.mk
 		test_bug590353-1.html \
 		test_bug590353-2.html \
 		test_bug593689.html \
 		test_bug583288-1.html \
 		test_bug583288-2.html \
 		test_bug583288-3.html \
 		583288_submit_server.sjs \
 		583288_redirect_server.sjs \
+		test_bug555840.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
--- a/content/html/content/test/test_bug389797.html
+++ b/content/html/content/test/test_bug389797.html
@@ -131,16 +131,17 @@ HTML_TAG("br", "BR");
 HTML_TAG("button", "Button");
 HTML_TAG("canvas", "Canvas");
 HTML_TAG("caption", "TableCaption");
 HTML_TAG("center", ""); // HTMLElement
 HTML_TAG("cite", ""); // HTMLElement
 HTML_TAG("code", ""); // HTMLElement
 HTML_TAG("col", "TableCol");
 HTML_TAG("colgroup", "TableCol");
+HTML_TAG("datalist", "DataList");
 HTML_TAG("dd", ""); // HTMLElement
 HTML_TAG("del", "Del", [ "nsIDOMHTMLModElement" ]);
 HTML_TAG("dfn", ""); // HTMLElement
 HTML_TAG("dir", "Directory");
 HTML_TAG("div", "Div");
 HTML_TAG("dl", "DList");
 HTML_TAG("dt", ""); // HTMLElement
 HTML_TAG("em", ""); // HTMLElement
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_bug555840.html
@@ -0,0 +1,87 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=555840
+-->
+<head>
+  <title>Test for Bug 555840</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=555840">Mozilla Bug 555840</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  <datalist>
+  </datalist>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 555840 **/
+
+function checkClassesAndAttributes()
+{
+  var d = document.getElementsByTagName('datalist');
+  is(d.length, 1, "One datalist has been found");
+
+  d = d[0];
+  ok(d instanceof HTMLDataListElement,
+     "The datalist should be instance of HTMLDataListElement");
+
+  ok('options' in d, "datalist has an options IDL attribute");
+
+  ok(d.options, "options IDL attribute is not null");
+  ok(!d.getAttribute('options'), "datalist has no options content attribute");
+
+  ok(d.options instanceof HTMLCollection,
+     "options IDL attribute should be instance of HTMLCollection");
+}
+
+function checkOptions()
+{
+  var testData = [
+    /* [ Child list, Function modifying children, Recognized options ] */
+    [['option'], null, 1],
+    [['option', 'option', 'option', 'option'], null, 4],
+    /* Disabled options are not valid. */
+    [['option'], function(d) { d.childNodes[0].disabled = true; }, 0],
+    [['option', 'option'], function(d) { d.childNodes[0].disabled = true; }, 1],
+    /* Non-option elements are not recognized. */
+    [['input'], null, 0],
+    [['input', 'option'], null, 1],
+    [['input', 'textarea'], null, 0],
+    /* .value and .label are not needed to be valid options. */
+    [['option', 'option'], function(d) { d.childNodes[0].value = 'value'; }, 2],
+    [['option', 'option'], function(d) { d.childNodes[0].label = 'label'; }, 2],
+    [['option', 'option'], function(d) { d.childNodes[0].value = 'value'; d.childNodes[0].label = 'label'; }, 2],
+  ];
+
+  var d = document.getElementsByTagName('datalist')[0];
+
+  for each (data in testData) {
+    for each (e in data[0]) {
+      d.appendChild(document.createElement(e));
+    }
+
+    /* Modify children. */
+    if (data[1]) {
+      data[1](d);
+    }
+
+    is(d.options.length, data[2],
+       "The number of recognized options should be " + data[2])
+
+    /* Cleaning-up. */
+    for (; d.firstChild; d.removeChild(d.firstChild));
+  }
+}
+
+checkClassesAndAttributes();
+checkOptions();
+
+</script>
+</pre>
+</body>
+</html>
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -256,16 +256,17 @@
 #include "nsIDOMHTMLAnchorElement.h"
 #include "nsIDOMHTMLAppletElement.h"
 #include "nsIDOMHTMLAreaElement.h"
 #include "nsIDOMHTMLBRElement.h"
 #include "nsIDOMHTMLBaseElement.h"
 #include "nsIDOMHTMLBodyElement.h"
 #include "nsIDOMHTMLButtonElement.h"
 #include "nsIDOMHTMLCanvasElement.h"
+#include "nsIDOMHTMLDataListElement.h"
 #include "nsIDOMHTMLDListElement.h"
 #include "nsIDOMHTMLDirectoryElement.h"
 #include "nsIDOMHTMLDivElement.h"
 #include "nsIDOMHTMLEmbedElement.h"
 #include "nsIDOMHTMLFieldSetElement.h"
 #include "nsIDOMHTMLFontElement.h"
 #include "nsIDOMNSHTMLFormElement.h"
 #include "nsIDOMHTMLFrameElement.h"
@@ -759,16 +760,18 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(HTMLBRElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLBaseElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLBodyElement, nsHTMLBodyElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLButtonElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(HTMLDataListElement, nsElementSH,
+                           ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLDListElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLDelElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLDirectoryElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLDivElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
@@ -2523,16 +2526,21 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLButtonElement, nsIDOMHTMLButtonElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLButtonElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(HTMLDataListElement, nsIDOMHTMLDataListElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLDataListElement)
+    DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
+  DOM_CLASSINFO_MAP_END
+
   DOM_CLASSINFO_MAP_BEGIN(HTMLDListElement, nsIDOMHTMLDListElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLDListElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(HTMLDelElement, nsIDOMHTMLElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLModElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -88,16 +88,17 @@ DOMCI_CLASS(HTMLCollection)
 DOMCI_CLASS(HTMLElement)
 DOMCI_CLASS(HTMLAnchorElement)
 DOMCI_CLASS(HTMLAppletElement)
 DOMCI_CLASS(HTMLAreaElement)
 DOMCI_CLASS(HTMLBRElement)
 DOMCI_CLASS(HTMLBaseElement)
 DOMCI_CLASS(HTMLBodyElement)
 DOMCI_CLASS(HTMLButtonElement)
+DOMCI_CLASS(HTMLDataListElement)
 DOMCI_CLASS(HTMLDListElement)
 DOMCI_CLASS(HTMLDelElement)
 DOMCI_CLASS(HTMLDirectoryElement)
 DOMCI_CLASS(HTMLDivElement)
 DOMCI_CLASS(HTMLEmbedElement)
 DOMCI_CLASS(HTMLFieldSetElement)
 DOMCI_CLASS(HTMLFontElement)
 DOMCI_CLASS(HTMLFormElement)
--- a/dom/interfaces/html/Makefile.in
+++ b/dom/interfaces/html/Makefile.in
@@ -50,16 +50,17 @@ SDK_XPIDLSRCS =					\
 	nsIDOMHTMLAnchorElement.idl		\
 	nsIDOMHTMLAppletElement.idl		\
 	nsIDOMHTMLAreaElement.idl		\
 	nsIDOMHTMLBRElement.idl			\
 	nsIDOMHTMLBaseElement.idl		\
 	nsIDOMHTMLBodyElement.idl		\
 	nsIDOMHTMLButtonElement.idl		\
 	nsIDOMHTMLCollection.idl		\
+	nsIDOMHTMLDataListElement.idl		\
 	nsIDOMHTMLDListElement.idl		\
 	nsIDOMHTMLDirectoryElement.idl		\
 	nsIDOMHTMLDivElement.idl		\
 	nsIDOMHTMLDocument.idl			\
 	nsIDOMHTMLElement.idl			\
 	nsIDOMHTMLEmbedElement.idl		\
 	nsIDOMHTMLFieldSetElement.idl		\
 	nsIDOMHTMLFontElement.idl		\
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/html/nsIDOMHTMLDataListElement.idl
@@ -0,0 +1,57 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Mounir Lamouri <mounir.lamouri@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * 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 ***** */
+
+#include "nsIDOMHTMLElement.idl"
+
+/**
+ * The nsIDOMHTMLDataListElement interface is the interface to a HTML
+ * <datalist> element.
+ *
+ * For more information on this interface, please see
+ * http://dev.w3.org/html5/spec/forms.html#the-datalist-element
+ *
+ * @status UNDER_DEVELOPMENT
+ */
+
+interface nsIDOMHTMLCollection;
+
+[scriptable, uuid(ec66a63e-8a23-4a85-bd53-050b49a2b048)]
+interface nsIDOMHTMLDataListElement : nsIDOMHTMLElement
+{
+  readonly attribute nsIDOMHTMLCollection options;
+};
+
--- a/editor/libeditor/base/nsEditPropertyAtomList.h
+++ b/editor/libeditor/base/nsEditPropertyAtomList.h
@@ -110,16 +110,17 @@ EDITOR_ATOM(cssPxUnit, "px")
 EDITOR_ATOM(cssRight, "right")
 EDITOR_ATOM(cssTextAlign, "text-align")
 EDITOR_ATOM(cssTextDecoration, "text-decoration")
 EDITOR_ATOM(cssTop, "top")
 EDITOR_ATOM(cssVerticalAlign, "vertical-align")
 EDITOR_ATOM(cssWhitespace, "white-space")
 EDITOR_ATOM(cssWidth, "width")
 EDITOR_ATOM(cssZIndex, "z-index")
+EDITOR_ATOM(datalist, "datalist")
 EDITOR_ATOM(dd, "dd")
 EDITOR_ATOM(dfn, "dfn")
 EDITOR_ATOM(div, "div")
 EDITOR_ATOM(dl, "dl")
 EDITOR_ATOM(dt, "dt")
 EDITOR_ATOM(em, "em")
 EDITOR_ATOM(face, "face")
 EDITOR_ATOM(fieldset, "fieldset")
--- a/editor/libeditor/html/nsHTMLEditUtils.cpp
+++ b/editor/libeditor/html/nsHTMLEditUtils.cpp
@@ -474,17 +474,18 @@ nsHTMLEditUtils::SupportsAlignAttr(nsIDO
 #define GROUP_TOPLEVEL         (1 << 1)  
 
 // base, isindex, link, meta, script, style, title
 #define GROUP_HEAD_CONTENT     (1 << 2)
 
 // b, big, i, s, small, strike, tt, u
 #define GROUP_FONTSTYLE        (1 << 3)
 
-// abbr, acronym, cite, code, del, dfn, em, ins, kbd, mark, samp, strong, var
+// abbr, acronym, cite, code, datalist, del, dfn, em, ins, kbd, mark, samp,
+// strong, var
 #define GROUP_PHRASE           (1 << 4)
 
 // a, applet, basefont, bdo, br, font, iframe, img, map, object, output, q,
 // script, span, sub, sup
 #define GROUP_SPECIAL          (1 << 5)
 
 // button, form, input, label, select, textarea
 #define GROUP_FORMCONTROL      (1 << 6)
@@ -518,17 +519,17 @@ nsHTMLEditUtils::SupportsAlignAttr(nsIDO
 
 // area
 #define GROUP_MAP_CONTENT      (1 << 15)
 
 // optgroup, option
 #define GROUP_SELECT_CONTENT   (1 << 16)
 
 // option
-#define GROUP_OPTGROUP_CONTENT (1 << 17)
+#define GROUP_OPTIONS          (1 << 17)
 
 // dd, dt
 #define GROUP_DL_CONTENT       (1 << 18)
 
 // p
 #define GROUP_P                (1 << 19)
 
 // text, whitespace, newline, comment
@@ -598,16 +599,18 @@ static const nsElementInfo kElements[eHT
   ELEM(canvas, PR_FALSE, PR_FALSE, GROUP_NONE, GROUP_NONE),
   ELEM(caption, PR_TRUE, PR_TRUE, GROUP_NONE, GROUP_INLINE_ELEMENT),
   ELEM(center, PR_TRUE, PR_TRUE, GROUP_BLOCK, GROUP_FLOW_ELEMENT),
   ELEM(cite, PR_TRUE, PR_TRUE, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
   ELEM(code, PR_TRUE, PR_TRUE, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
   ELEM(col, PR_FALSE, PR_FALSE, GROUP_TABLE_CONTENT | GROUP_COLGROUP_CONTENT,
        GROUP_NONE),
   ELEM(colgroup, PR_TRUE, PR_FALSE, GROUP_NONE, GROUP_COLGROUP_CONTENT),
+  ELEM(datalist, PR_TRUE, PR_FALSE, GROUP_PHRASE,
+       GROUP_OPTIONS | GROUP_INLINE_ELEMENT),
   ELEM(dd, PR_TRUE, PR_FALSE, GROUP_DL_CONTENT, GROUP_FLOW_ELEMENT),
   ELEM(del, PR_TRUE, PR_TRUE, GROUP_PHRASE | GROUP_BLOCK, GROUP_FLOW_ELEMENT),
   ELEM(dfn, PR_TRUE, PR_TRUE, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
   ELEM(dir, PR_TRUE, PR_FALSE, GROUP_BLOCK, GROUP_LI),
   ELEM(div, PR_TRUE, PR_TRUE, GROUP_BLOCK, GROUP_FLOW_ELEMENT),
   ELEM(dl, PR_TRUE, PR_FALSE, GROUP_BLOCK, GROUP_DL_CONTENT),
   ELEM(dt, PR_TRUE, PR_TRUE, GROUP_DL_CONTENT, GROUP_INLINE_ELEMENT),
   ELEM(em, PR_TRUE, PR_TRUE, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
@@ -666,19 +669,19 @@ static const nsElementInfo kElements[eHT
   ELEM(noframes, PR_TRUE, PR_TRUE, GROUP_BLOCK, GROUP_FLOW_ELEMENT),
   ELEM(noscript, PR_TRUE, PR_TRUE, GROUP_BLOCK, GROUP_FLOW_ELEMENT),
   ELEM(object, PR_TRUE, PR_TRUE, GROUP_SPECIAL | GROUP_BLOCK,
        GROUP_FLOW_ELEMENT | GROUP_OBJECT_CONTENT),
   // XXX Can contain self and ul because editor does sublists illegally.
   ELEM(ol, PR_TRUE, PR_TRUE, GROUP_BLOCK | GROUP_OL_UL,
        GROUP_LI | GROUP_OL_UL),
   ELEM(optgroup, PR_TRUE, PR_FALSE, GROUP_SELECT_CONTENT,
-       GROUP_OPTGROUP_CONTENT),
+       GROUP_OPTIONS),
   ELEM(option, PR_TRUE, PR_FALSE,
-       GROUP_SELECT_CONTENT | GROUP_OPTGROUP_CONTENT, GROUP_LEAF),
+       GROUP_SELECT_CONTENT | GROUP_OPTIONS, GROUP_LEAF),
   ELEM(output, PR_TRUE, PR_TRUE, GROUP_SPECIAL, GROUP_INLINE_ELEMENT),
   ELEM(p, PR_TRUE, PR_FALSE, GROUP_BLOCK | GROUP_P, GROUP_INLINE_ELEMENT),
   ELEM(param, PR_FALSE, PR_FALSE, GROUP_OBJECT_CONTENT, GROUP_NONE),
   ELEM(plaintext, PR_FALSE, PR_FALSE, GROUP_NONE, GROUP_NONE),
   ELEM(pre, PR_TRUE, PR_TRUE, GROUP_BLOCK, GROUP_INLINE_ELEMENT),
   ELEM(q, PR_TRUE, PR_TRUE, GROUP_SPECIAL, GROUP_INLINE_ELEMENT),
   ELEM(s, PR_TRUE, PR_TRUE, GROUP_FONTSTYLE, GROUP_INLINE_ELEMENT),
   ELEM(samp, PR_TRUE, PR_TRUE, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
new file mode 100644
--- /dev/null
+++ b/layout/reftests/datalist/datalist-errors.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+  <!-- Test: a datalist element should not be visible
+             even if it contains non-option elements -->
+  <body>
+    <datalist>
+      <option>foo</option>
+      <option>bar</option>
+      <input type='text'>
+    </datalist>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/datalist/datalist-simple.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+  <!-- Test: a datalist element should not be visible -->
+  <body>
+    <datalist>
+      <option>foo</option>
+      <option>bar</option>
+    </datalist>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/datalist/reftest.list
@@ -0,0 +1,2 @@
+== datalist-simple.html about:blank
+== datalist-errors.html about:blank
--- a/layout/reftests/reftest.list
+++ b/layout/reftests/reftest.list
@@ -97,16 +97,19 @@ include css-valuesandunits/reftest.list
 include columns/reftest.list
 
 # content/
 include ../../content/test/reftest/reftest.list
 
 # counters/
 include counters/reftest.list
 
+# datalist
+include datalist/reftest.list
+
 # dom/
 include dom/reftest.list
 
 # editor/
 include editor/reftest.list
 
 # generated-content/
 include generated-content/reftest.list
--- a/layout/style/html.css
+++ b/layout/style/html.css
@@ -686,17 +686,17 @@ table:-moz-focusring, tbody:-moz-focusri
 tfoot:-moz-focusring, th:-moz-focusring, thead:-moz-focusring, 
 tr:-moz-focusring, tt:-moz-focusring, u:-moz-focusring,
 ul:-moz-focusring, var:-moz-focusring {
   /* Don't specify the outline-color, we should always use initial value. */
    outline: 1px dotted;
 }
 
 /* hidden elements */
-base, basefont, head, meta, script, style, title,
+base, basefont, datalist, head, meta, script, style, title,
 noembed, param {
    display: none;
 }
 
 area {
   /* Don't give it frames other than its imageframe */
   display: none ! important;
 }
--- a/parser/htmlparser/public/nsHTMLTagList.h
+++ b/parser/htmlparser/public/nsHTMLTagList.h
@@ -89,16 +89,17 @@ HTML_TAG(br, BR)
 HTML_TAG(button, Button)
 HTML_TAG(canvas, Canvas)
 HTML_TAG(caption, TableCaption)
 HTML_HTMLELEMENT_TAG(center)
 HTML_HTMLELEMENT_TAG(cite)
 HTML_HTMLELEMENT_TAG(code)
 HTML_TAG(col, TableCol)
 HTML_TAG(colgroup, TableCol)
+HTML_TAG(datalist, DataList)
 HTML_HTMLELEMENT_TAG(dd)
 HTML_TAG(del, Mod)
 HTML_HTMLELEMENT_TAG(dfn)
 HTML_TAG(dir, Shared)
 HTML_TAG(div, Div)
 HTML_TAG(dl, SharedList)
 HTML_HTMLELEMENT_TAG(dt)
 HTML_HTMLELEMENT_TAG(em)
--- a/parser/htmlparser/src/nsElementTable.cpp
+++ b/parser/htmlparser/src/nsElementTable.cpp
@@ -437,16 +437,25 @@ const nsHTMLElement gHTMLElements[] = {
     /*req-parent excl-parent*/          eHTMLTag_table,eHTMLTag_unknown,
     /*rootnodes,endrootnodes*/          &gInTable,&gInTable,
     /*autoclose starttags and endtags*/ 0,0,0,0,
     /*parent,incl,exclgroups*/          kNone, kNone, kNone,
     /*special props, prop-range*/       kNoPropagate,kDefaultPropRange,
     /*special parents,kids*/            &gInTable,&gColgroupKids,
   },
   {
+    /*tag*/                             eHTMLTag_datalist,
+    /*requiredAncestor*/                eHTMLTag_unknown, eHTMLTag_unknown,
+    /*rootnodes,endrootnodes*/          &gRootTags,&gRootTags,
+    /*autoclose starttags and endtags*/ 0,0,0,0,
+    /*parent,incl,exclgroups*/          kSpecial, (kInlineEntity|kSelf|kFlowEntity), kNone,
+    /*special props, prop-range*/       0,kDefaultPropRange,
+    /*special parents,kids*/            0,0,
+  },
+  {
     /*tag*/                             eHTMLTag_dd,
     /*req-parent excl-parent*/          eHTMLTag_unknown,eHTMLTag_unknown,
     /*rootnodes,endrootnodes*/          &gRootTags,&gRootTags,
     /*autoclose starttags and endtags*/ &gDTCloseTags,0,&gDLKids,0,
     /*parent,incl,exclgroups*/          kInlineEntity, kFlowEntity, kNone,
     /*special props, prop-range*/       kNoPropagate|kMustCloseSelf|kVerifyHierarchy|kRequiresBody,kDefaultPropRange,
     /*special parents,kids*/            &gInDL,0,
   },
--- a/parser/htmlparser/src/nsHTMLTags.cpp
+++ b/parser/htmlparser/src/nsHTMLTags.cpp
@@ -98,16 +98,18 @@ static const PRUnichar sHTMLTagUnicodeNa
 static const PRUnichar sHTMLTagUnicodeName_code[] =
   {'c', 'o', 'd', 'e', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_col[] =
   {'c', 'o', 'l', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_colgroup[] =
   {'c', 'o', 'l', 'g', 'r', 'o', 'u', 'p', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_counter[] =
   {'c', 'o', 'u', 'n', 't', 'e', 'r', '\0'};
+static const PRUnichar sHTMLTagUnicodeName_datalist[] =
+  {'d', 'a', 't', 'a', 'l', 'i', 's', 't', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_dd[] =
   {'d', 'd', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_del[] =
   {'d', 'e', 'l', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_dfn[] =
   {'d', 'f', 'n', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_dir[] =
   {'d', 'i', 'r', '\0'};