WebCore: Patch for https://bugs.webkit.org/show_bug.cgi?id=41146
authorweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 30 Jun 2010 23:15:15 +0000 (23:15 +0000)
committerweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 30 Jun 2010 23:15:15 +0000 (23:15 +0000)
<rdar://problem/8126069>
Implement the .dataset DOM property

Reviewed by Dan Bernstein.

Tests: fast/dom/dataset-xhtml.xhtml
       fast/dom/dataset.html

* DerivedSources.cpp:
* DerivedSources.make:
* GNUmakefile.am:
* WebCore.gypi:
* WebCore.pro:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSDOMStringMapCustom.cpp: Added.
(WebCore::JSDOMStringMap::canGetItemsForName):
(WebCore::JSDOMStringMap::nameGetter):
(WebCore::JSDOMStringMap::getOwnPropertyNames):
(WebCore::JSDOMStringMap::deleteProperty):
(WebCore::JSDOMStringMap::putDelegate):
* bindings/js/JSDOMStringMapCustom.h: Added.
* dom/DOMStringMap.cpp: Added.
(WebCore::DOMStringMap::~DOMStringMap):
* dom/DOMStringMap.h: Added.
(WebCore::DOMStringMap::DOMStringMap):
* dom/DOMStringMap.idl: Added.
* dom/DatasetDOMStringMap.cpp: Added.
(WebCore::isValidAttributeName):
(WebCore::convertAttributeNameToPropertyName):
(WebCore::propertyNameMatchesAttributeName):
(WebCore::isValidPropertyName):
(WebCore::convertPropertyNameToAttributeName):
(WebCore::DatasetDOMStringMap::ref):
(WebCore::DatasetDOMStringMap::deref):
(WebCore::DatasetDOMStringMap::getNames):
(WebCore::DatasetDOMStringMap::item):
(WebCore::DatasetDOMStringMap::contains):
(WebCore::DatasetDOMStringMap::setItem):
(WebCore::DatasetDOMStringMap::deleteItem):
* dom/DatasetDOMStringMap.h: Added.
(WebCore::DatasetDOMStringMap::create):
(WebCore::DatasetDOMStringMap::DatasetDOMStringMap):
* dom/Element.cpp:
(WebCore::Element::dataset):
* dom/Element.h:
* dom/Element.idl:
* dom/ElementRareData.h:
* page/DOMWindow.idl:

LayoutTests: Test changes for https://bugs.webkit.org/show_bug.cgi?id=41146
<rdar://problem/8126069>
Implement the .dataset DOM property

Reviewed by Dan Bernstein.

* fast/dom/Window/window-properties-expected.txt:
* fast/dom/Window/window-property-descriptors-expected.txt:
* fast/dom/dataset-expected.txt: Added.
* fast/dom/dataset-xhtml-expected.txt: Added.
* fast/dom/dataset-xhtml.xhtml: Added.
* fast/dom/dataset.html: Added.
* fast/dom/domListEnumeration-expected.txt:
* fast/dom/prototype-inheritance-2-expected.txt:
* fast/dom/prototype-inheritance-expected.txt:
* fast/dom/script-tests/dataset-xhtml.js: Added.
* fast/dom/script-tests/dataset.js: Added.
* fast/dom/script-tests/domListEnumeration.js:
* fast/js/global-constructors-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@62215 268f45cc-cd09-0410-ab3c-d52691b4dbfc

35 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/Window/window-properties-expected.txt
LayoutTests/fast/dom/Window/window-property-descriptors-expected.txt
LayoutTests/fast/dom/dataset-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/dataset-xhtml-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/dataset-xhtml.xhtml [new file with mode: 0644]
LayoutTests/fast/dom/dataset.html [new file with mode: 0644]
LayoutTests/fast/dom/domListEnumeration-expected.txt
LayoutTests/fast/dom/prototype-inheritance-2-expected.txt
LayoutTests/fast/dom/prototype-inheritance-expected.txt
LayoutTests/fast/dom/script-tests/dataset-xhtml.js [new file with mode: 0644]
LayoutTests/fast/dom/script-tests/dataset.js [new file with mode: 0644]
LayoutTests/fast/dom/script-tests/domListEnumeration.js
LayoutTests/fast/js/global-constructors-expected.txt
WebCore/ChangeLog
WebCore/DerivedSources.cpp
WebCore/DerivedSources.make
WebCore/GNUmakefile.am
WebCore/WebCore.gypi
WebCore/WebCore.pri
WebCore/WebCore.pro
WebCore/WebCore.vcproj/WebCore.vcproj
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/bindings/js/JSDOMStringMapCustom.cpp [new file with mode: 0644]
WebCore/bindings/js/JSDOMStringMapCustom.h [new file with mode: 0644]
WebCore/dom/DOMStringMap.cpp [new file with mode: 0644]
WebCore/dom/DOMStringMap.h [new file with mode: 0644]
WebCore/dom/DOMStringMap.idl [new file with mode: 0644]
WebCore/dom/DatasetDOMStringMap.cpp [new file with mode: 0644]
WebCore/dom/DatasetDOMStringMap.h [new file with mode: 0644]
WebCore/dom/Element.cpp
WebCore/dom/Element.h
WebCore/dom/Element.idl
WebCore/dom/ElementRareData.h
WebCore/page/DOMWindow.idl

index d2b294d..f48c400 100644 (file)
@@ -1,3 +1,25 @@
+2010-06-29  Sam Weinig  <sam@webkit.org>
+
+        Reviewed by Dan Bernstein.
+
+        Test changes for https://bugs.webkit.org/show_bug.cgi?id=41146
+        <rdar://problem/8126069>
+        Implement the .dataset DOM property
+
+        * fast/dom/Window/window-properties-expected.txt:
+        * fast/dom/Window/window-property-descriptors-expected.txt:
+        * fast/dom/dataset-expected.txt: Added.
+        * fast/dom/dataset-xhtml-expected.txt: Added.
+        * fast/dom/dataset-xhtml.xhtml: Added.
+        * fast/dom/dataset.html: Added.
+        * fast/dom/domListEnumeration-expected.txt:
+        * fast/dom/prototype-inheritance-2-expected.txt:
+        * fast/dom/prototype-inheritance-expected.txt:
+        * fast/dom/script-tests/dataset-xhtml.js: Added.
+        * fast/dom/script-tests/dataset.js: Added.
+        * fast/dom/script-tests/domListEnumeration.js:
+        * fast/js/global-constructors-expected.txt:
+
 2010-06-30  Albert J. Wong  <ajwong@chromium.org>
 
         Not reviewed. Chromium: Disable flaky test.
 2010-06-30  Albert J. Wong  <ajwong@chromium.org>
 
         Not reviewed. Chromium: Disable flaky test.
index bf70745..e81e505 100644 (file)
@@ -558,6 +558,8 @@ window.DOMStringList [object DOMStringListConstructor]
 window.DOMStringList.prototype [object DOMStringListPrototype]
 window.DOMStringList.prototype.contains [function]
 window.DOMStringList.prototype.item [function]
 window.DOMStringList.prototype [object DOMStringListPrototype]
 window.DOMStringList.prototype.contains [function]
 window.DOMStringList.prototype.item [function]
+window.DOMStringMap [object DOMStringMapConstructor]
+window.DOMStringMap.prototype [object DOMStringMapPrototype]
 window.Document [object DocumentConstructor]
 window.Document.prototype [object DocumentPrototype]
 window.Document.prototype.ATTRIBUTE_NODE [number]
 window.Document [object DocumentConstructor]
 window.Document.prototype [object DocumentPrototype]
 window.Document.prototype.ATTRIBUTE_NODE [number]
index 2d63414..ba5526d 100644 (file)
@@ -39,6 +39,7 @@ PASS typeof Object.getOwnPropertyDescriptor(window, 'DOMException') is 'object'
 PASS typeof Object.getOwnPropertyDescriptor(window, 'DOMImplementation') is 'object'
 PASS typeof Object.getOwnPropertyDescriptor(window, 'DOMParser') is 'object'
 PASS typeof Object.getOwnPropertyDescriptor(window, 'DOMStringList') is 'object'
 PASS typeof Object.getOwnPropertyDescriptor(window, 'DOMImplementation') is 'object'
 PASS typeof Object.getOwnPropertyDescriptor(window, 'DOMParser') is 'object'
 PASS typeof Object.getOwnPropertyDescriptor(window, 'DOMStringList') is 'object'
+PASS typeof Object.getOwnPropertyDescriptor(window, 'DOMStringMap') is 'object'
 PASS typeof Object.getOwnPropertyDescriptor(window, 'Date') is 'object'
 PASS typeof Object.getOwnPropertyDescriptor(window, 'Document') is 'object'
 PASS typeof Object.getOwnPropertyDescriptor(window, 'DocumentFragment') is 'object'
 PASS typeof Object.getOwnPropertyDescriptor(window, 'Date') is 'object'
 PASS typeof Object.getOwnPropertyDescriptor(window, 'Document') is 'object'
 PASS typeof Object.getOwnPropertyDescriptor(window, 'DocumentFragment') is 'object'
diff --git a/LayoutTests/fast/dom/dataset-expected.txt b/LayoutTests/fast/dom/dataset-expected.txt
new file mode 100644 (file)
index 0000000..1ef6859
--- /dev/null
@@ -0,0 +1,46 @@
+This tests element.dataset.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS testGet('data-foo', 'foo') is true
+PASS testGet('data-foo-bar', 'fooBar') is true
+PASS testGet('data--', '-') is true
+PASS testGet('data--foo', 'Foo') is true
+PASS testGet('data---foo', '-Foo') is true
+PASS testGet('data-Foo', 'foo') is true
+PASS testGet('data-', '') is true
+PASS testGet('data-à', 'à') is true
+
+PASS matchesNothingInDataset('dataFoo') is true
+
+PASS testSet('foo', 'data-foo') is true
+PASS testSet('fooBar', 'data-foo-bar') is true
+PASS testSet('-', 'data--') is true
+PASS testSet('Foo', 'data--foo') is true
+PASS testSet('-Foo', 'data---foo') is true
+PASS testSet('', 'data-') is true
+PASS testSet('à', 'data-à') is true
+
+PASS testSet('-foo', 'dummy') threw exception Error: SYNTAX_ERR: DOM Exception 12.
+PASS testSet('foo ', 'dummy') threw exception Error: INVALID_CHARACTER_ERR: DOM Exception 5.
+PASS testSet('foo豈', 'dummy') threw exception Error: INVALID_CHARACTER_ERR: DOM Exception 5.
+
+PASS testDelete('data-foo', 'foo') is true
+PASS testDelete('data-foo-bar', 'fooBar') is true
+PASS testDelete('data--', '-') is true
+PASS testDelete('data--foo', 'Foo') is true
+PASS testDelete('data---foo', '-Foo') is true
+PASS testDelete('data-', '') is true
+PASS testDelete('data-à', 'à') is true
+
+PASS testDelete('dummy', '-foo') threw exception Error: SYNTAX_ERR: DOM Exception 12.
+
+PASS testForIn(['data-foo', 'data-bar', 'data-baz']) is 3
+PASS testForIn(['data-foo', 'data-bar', 'dataFoo']) is 2
+PASS testForIn(['data-foo', 'data-bar', 'style']) is 2
+PASS testForIn(['data-foo', 'data-bar', 'data-']) is 3
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/dataset-xhtml-expected.txt b/LayoutTests/fast/dom/dataset-xhtml-expected.txt
new file mode 100644 (file)
index 0000000..93ff7d2
--- /dev/null
@@ -0,0 +1,46 @@
+This tests element.dataset for XHTML.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS testGet('data-foo', 'foo') is true
+PASS testGet('data-foo-bar', 'fooBar') is true
+PASS testGet('data--', '-') is true
+PASS testGet('data--foo', 'Foo') is true
+PASS testGet('data---foo', '-Foo') is true
+PASS testGet('data-', '') is true
+PASS testGet('data-à', 'à') is true
+
+PASS matchesNothingInDataset('dataFoo') is true
+PASS matchesNothingInDataset('data-Foo') is true
+
+PASS testSet('foo', 'data-foo') is true
+PASS testSet('fooBar', 'data-foo-bar') is true
+PASS testSet('-', 'data--') is true
+PASS testSet('Foo', 'data--foo') is true
+PASS testSet('-Foo', 'data---foo') is true
+PASS testSet('', 'data-') is true
+PASS testSet('à', 'data-à') is true
+
+PASS testSet('-foo', 'dummy') threw exception Error: SYNTAX_ERR: DOM Exception 12.
+PASS testSet('foo ', 'dummy') threw exception Error: INVALID_CHARACTER_ERR: DOM Exception 5.
+PASS testSet('foo豈', 'dummy') threw exception Error: INVALID_CHARACTER_ERR: DOM Exception 5.
+
+PASS testDelete('data-foo', 'foo') is true
+PASS testDelete('data-foo-bar', 'fooBar') is true
+PASS testDelete('data--', '-') is true
+PASS testDelete('data--foo', 'Foo') is true
+PASS testDelete('data---foo', '-Foo') is true
+PASS testDelete('data-', '') is true
+PASS testDelete('data-à', 'à') is true
+
+PASS testDelete('dummy', '-foo') threw exception Error: SYNTAX_ERR: DOM Exception 12.
+
+PASS testForIn(['data-foo', 'data-bar', 'data-baz']) is 3
+PASS testForIn(['data-foo', 'data-bar', 'dataFoo']) is 2
+PASS testForIn(['data-foo', 'data-bar', 'style']) is 2
+PASS testForIn(['data-foo', 'data-bar', 'data-']) is 3
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/dataset-xhtml.xhtml b/LayoutTests/fast/dom/dataset-xhtml.xhtml
new file mode 100644 (file)
index 0000000..1da3ca2
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css"></link>
+<script src="../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/dataset-xhtml.js"></script>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/dom/dataset.html b/LayoutTests/fast/dom/dataset.html
new file mode 100644 (file)
index 0000000..1c9f094
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/dataset.js"></script>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
index 6611cd4..ea4524f 100644 (file)
@@ -32,7 +32,7 @@ PASS resultArray[2].i is '2'
 PASS resultArray[2].item is namedNodeMap.item(2)
 
 [object HTMLFormElement]
 PASS resultArray[2].item is namedNodeMap.item(2)
 
 [object HTMLFormElement]
-PASS resultArray.length is 135
+PASS resultArray.length is 136
 PASS resultArray[0].i is '0'
 PASS resultArray[0].item is document.getElementsByTagName('select')[0]
 PASS resultArray[1].i is '1'
 PASS resultArray[0].i is '0'
 PASS resultArray[0].item is document.getElementsByTagName('select')[0]
 PASS resultArray[1].i is '1'
@@ -41,7 +41,7 @@ PASS resultArray[2].i is '2'
 PASS resultArray[2].item is document.getElementsByTagName('select')[2]
 
 [object HTMLSelectElement]
 PASS resultArray[2].item is document.getElementsByTagName('select')[2]
 
 [object HTMLSelectElement]
-PASS resultArray.length is 143
+PASS resultArray.length is 144
 PASS resultArray[0].i is '0'
 PASS resultArray[0].item is document.getElementsByTagName('option')[0]
 PASS resultArray[1].i is '1'
 PASS resultArray[0].i is '0'
 PASS resultArray[0].item is document.getElementsByTagName('option')[0]
 PASS resultArray[1].i is '1'
index 62dea8e..53a359e 100644 (file)
@@ -74,6 +74,9 @@ PASS DOMApplicationCachePrototype from inner.document.forms.testForm.0.ownerDocu
 PASS DOMImplementation from inner.document.forms.testForm.0.ownerDocument.implementation
 PASS DOMImplementationConstructor from inner.document.forms.testForm.0.ownerDocument.implementation.constructor
 PASS DOMImplementationPrototype from inner.document.forms.testForm.0.ownerDocument.implementation.__proto__
 PASS DOMImplementation from inner.document.forms.testForm.0.ownerDocument.implementation
 PASS DOMImplementationConstructor from inner.document.forms.testForm.0.ownerDocument.implementation.constructor
 PASS DOMImplementationPrototype from inner.document.forms.testForm.0.ownerDocument.implementation.__proto__
+PASS DOMStringMap from inner.document.forms.testForm.0.dataset
+PASS DOMStringMapConstructor from inner.document.forms.testForm.0.dataset.constructor
+PASS DOMStringMapPrototype from inner.document.forms.testForm.0.dataset.__proto__
 PASS DOMWindow from inner
 PASS DOMWindowPrototype from inner.document.forms.testForm.0.ownerDocument.defaultView.__proto__
 PASS DocumentPrototype from inner.document.forms.testForm.0.ownerDocument.__proto__.__proto__
 PASS DOMWindow from inner
 PASS DOMWindowPrototype from inner.document.forms.testForm.0.ownerDocument.defaultView.__proto__
 PASS DocumentPrototype from inner.document.forms.testForm.0.ownerDocument.__proto__.__proto__
index 1747137..e90175a 100644 (file)
@@ -71,6 +71,8 @@ PASS inner.DOMParser.isInner is true
 PASS inner.DOMParser.constructor.isInner is true
 PASS inner.DOMStringList.isInner is true
 PASS inner.DOMStringList.constructor.isInner is true
 PASS inner.DOMParser.constructor.isInner is true
 PASS inner.DOMStringList.isInner is true
 PASS inner.DOMStringList.constructor.isInner is true
+PASS inner.DOMStringMap.isInner is true
+PASS inner.DOMStringMap.constructor.isInner is true
 PASS inner.Document.isInner is true
 PASS inner.Document.constructor.isInner is true
 PASS inner.DocumentFragment.isInner is true
 PASS inner.Document.isInner is true
 PASS inner.Document.constructor.isInner is true
 PASS inner.DocumentFragment.isInner is true
diff --git a/LayoutTests/fast/dom/script-tests/dataset-xhtml.js b/LayoutTests/fast/dom/script-tests/dataset-xhtml.js
new file mode 100644 (file)
index 0000000..01110a0
--- /dev/null
@@ -0,0 +1,94 @@
+description("This tests element.dataset for XHTML.");
+
+function testGet(attr, expected)
+{
+    var d = document.createElement("div");
+    d.setAttribute(attr, "value");
+    return d.dataset[expected] == "value";
+}
+
+shouldBeTrue("testGet('data-foo', 'foo')");
+shouldBeTrue("testGet('data-foo-bar', 'fooBar')");
+shouldBeTrue("testGet('data--', '-')");
+shouldBeTrue("testGet('data--foo', 'Foo')");
+shouldBeTrue("testGet('data---foo', '-Foo')");
+shouldBeTrue("testGet('data-', '')");
+shouldBeTrue("testGet('data-\xE0', '\xE0')");
+debug("");
+
+function matchesNothingInDataset(attr)
+{
+    var d = document.createElement("div");
+    d.setAttribute(attr, "value");
+
+    var count = 0;
+    for (var item in d.dataset)
+        count++;
+    return count == 0;
+}
+
+shouldBeTrue("matchesNothingInDataset('dataFoo')");
+shouldBeTrue("matchesNothingInDataset('data-Foo')");
+debug("");
+
+function testSet(prop, expected)
+{
+    var d = document.createElement("div");
+    d.dataset[prop] = "value";
+    return d.getAttribute(expected) == "value";
+}
+
+shouldBeTrue("testSet('foo', 'data-foo')");
+shouldBeTrue("testSet('fooBar', 'data-foo-bar')");
+shouldBeTrue("testSet('-', 'data--')");
+shouldBeTrue("testSet('Foo', 'data--foo')");
+shouldBeTrue("testSet('-Foo', 'data---foo')");
+shouldBeTrue("testSet('', 'data-')");
+shouldBeTrue("testSet('\xE0', 'data-\xE0')");
+debug("");
+
+shouldThrow("testSet('-foo', 'dummy')", "'Error: SYNTAX_ERR: DOM Exception 12'");
+shouldThrow("testSet('foo\x20', 'dummy')", "'Error: INVALID_CHARACTER_ERR: DOM Exception 5'");
+shouldThrow("testSet('foo\uF900', 'dummy')", "'Error: INVALID_CHARACTER_ERR: DOM Exception 5'");
+debug("");
+
+function testDelete(attr, prop)
+{
+    var d = document.createElement("div");
+    d.setAttribute(attr, "value");
+    delete d.dataset[prop];
+    return d.getAttribute(attr) != "value";
+}
+
+shouldBeTrue("testDelete('data-foo', 'foo')");
+shouldBeTrue("testDelete('data-foo-bar', 'fooBar')");
+shouldBeTrue("testDelete('data--', '-')");
+shouldBeTrue("testDelete('data--foo', 'Foo')");
+shouldBeTrue("testDelete('data---foo', '-Foo')");
+shouldBeTrue("testDelete('data-', '')");
+shouldBeTrue("testDelete('data-\xE0', '\xE0')");
+debug("");
+
+shouldThrow("testDelete('dummy', '-foo')", "'Error: SYNTAX_ERR: DOM Exception 12'");
+debug("");
+
+function testForIn(array)
+{
+    var d = document.createElement("div");
+    for (var i = 0; i < array.length; ++i) {
+        d.setAttribute(array[i], "value");
+    }
+
+    var count = 0;
+    for (var item in d.dataset)
+        count++;
+
+    return count;
+}
+
+shouldBe("testForIn(['data-foo', 'data-bar', 'data-baz'])", "3");
+shouldBe("testForIn(['data-foo', 'data-bar', 'dataFoo'])", "2");
+shouldBe("testForIn(['data-foo', 'data-bar', 'style'])", "2");
+shouldBe("testForIn(['data-foo', 'data-bar', 'data-'])", "3");
+
+var successfullyParsed = true;
diff --git a/LayoutTests/fast/dom/script-tests/dataset.js b/LayoutTests/fast/dom/script-tests/dataset.js
new file mode 100644 (file)
index 0000000..6aaa14a
--- /dev/null
@@ -0,0 +1,94 @@
+description("This tests element.dataset.");
+
+function testGet(attr, expected)
+{
+    var d = document.createElement("div");
+    d.setAttribute(attr, "value");
+    return d.dataset[expected] == "value";
+}
+
+shouldBeTrue("testGet('data-foo', 'foo')");
+shouldBeTrue("testGet('data-foo-bar', 'fooBar')");
+shouldBeTrue("testGet('data--', '-')");
+shouldBeTrue("testGet('data--foo', 'Foo')");
+shouldBeTrue("testGet('data---foo', '-Foo')");
+shouldBeTrue("testGet('data-Foo', 'foo')"); // HTML lowercases all attributes.
+shouldBeTrue("testGet('data-', '')");
+shouldBeTrue("testGet('data-\xE0', '\xE0')");
+debug("");
+
+function matchesNothingInDataset(attr)
+{
+    var d = document.createElement("div");
+    d.setAttribute(attr, "value");
+
+    var count = 0;
+    for (var item in d.dataset)
+        count++;
+    return count == 0;
+}
+
+shouldBeTrue("matchesNothingInDataset('dataFoo')");
+debug("");
+
+function testSet(prop, expected)
+{
+    var d = document.createElement("div");
+    d.dataset[prop] = "value";
+    return d.getAttribute(expected) == "value";
+}
+
+shouldBeTrue("testSet('foo', 'data-foo')");
+shouldBeTrue("testSet('fooBar', 'data-foo-bar')");
+shouldBeTrue("testSet('-', 'data--')");
+shouldBeTrue("testSet('Foo', 'data--foo')");
+shouldBeTrue("testSet('-Foo', 'data---foo')");
+shouldBeTrue("testSet('', 'data-')");
+shouldBeTrue("testSet('\xE0', 'data-\xE0')");
+debug("");
+
+shouldThrow("testSet('-foo', 'dummy')", "'Error: SYNTAX_ERR: DOM Exception 12'");
+shouldThrow("testSet('foo\x20', 'dummy')", "'Error: INVALID_CHARACTER_ERR: DOM Exception 5'");
+shouldThrow("testSet('foo\uF900', 'dummy')", "'Error: INVALID_CHARACTER_ERR: DOM Exception 5'");
+debug("");
+
+function testDelete(attr, prop)
+{
+    var d = document.createElement("div");
+    d.setAttribute(attr, "value");
+    delete d.dataset[prop];
+    return d.getAttribute(attr) != "value";
+}
+
+shouldBeTrue("testDelete('data-foo', 'foo')");
+shouldBeTrue("testDelete('data-foo-bar', 'fooBar')");
+shouldBeTrue("testDelete('data--', '-')");
+shouldBeTrue("testDelete('data--foo', 'Foo')");
+shouldBeTrue("testDelete('data---foo', '-Foo')");
+shouldBeTrue("testDelete('data-', '')");
+shouldBeTrue("testDelete('data-\xE0', '\xE0')");
+debug("");
+
+shouldThrow("testDelete('dummy', '-foo')", "'Error: SYNTAX_ERR: DOM Exception 12'");
+debug("");
+
+function testForIn(array)
+{
+    var d = document.createElement("div");
+    for (var i = 0; i < array.length; ++i) {
+        d.setAttribute(array[i], "value");
+    }
+
+    var count = 0;
+    for (var item in d.dataset)
+        count++;
+
+    return count;
+}
+
+shouldBe("testForIn(['data-foo', 'data-bar', 'data-baz'])", "3");
+shouldBe("testForIn(['data-foo', 'data-bar', 'dataFoo'])", "2");
+shouldBe("testForIn(['data-foo', 'data-bar', 'style'])", "2");
+shouldBe("testForIn(['data-foo', 'data-bar', 'data-'])", "3");
+
+var successfullyParsed = true;
index 0f9ed33..b8d31ed 100644 (file)
@@ -130,7 +130,7 @@ shouldBe("resultArray[2].item", "namedNodeMap.item(2)");
 // HTMLFormElement
 var htmlFormElement = document.getElementsByTagName('form')[0];
 resultArray = iterateList(htmlFormElement);
 // HTMLFormElement
 var htmlFormElement = document.getElementsByTagName('form')[0];
 resultArray = iterateList(htmlFormElement);
-shouldBe("resultArray.length", "135");
+shouldBe("resultArray.length", "136");
 shouldBe("resultArray[0].i", "'0'");
 shouldBe("resultArray[0].item", "document.getElementsByTagName('select')[0]");
 shouldBe("resultArray[1].i", "'1'");
 shouldBe("resultArray[0].i", "'0'");
 shouldBe("resultArray[0].item", "document.getElementsByTagName('select')[0]");
 shouldBe("resultArray[1].i", "'1'");
@@ -141,7 +141,7 @@ shouldBe("resultArray[2].item", "document.getElementsByTagName('select')[2]");
 // HTMLSelectElement
 var htmlSelectElement = document.getElementsByTagName('select')[0];
 resultArray = iterateList(htmlSelectElement);
 // HTMLSelectElement
 var htmlSelectElement = document.getElementsByTagName('select')[0];
 resultArray = iterateList(htmlSelectElement);
-shouldBe("resultArray.length", "143");
+shouldBe("resultArray.length", "144");
 shouldBe("resultArray[0].i", "'0'");
 shouldBe("resultArray[0].item", "document.getElementsByTagName('option')[0]");
 shouldBe("resultArray[1].i", "'1'");
 shouldBe("resultArray[0].i", "'0'");
 shouldBe("resultArray[0].item", "document.getElementsByTagName('option')[0]");
 shouldBe("resultArray[1].i", "'1'");
index 4cecefe..211ccb2 100644 (file)
@@ -37,6 +37,7 @@ PASS DOMException.toString() is '[object DOMExceptionConstructor]'
 PASS DOMImplementation.toString() is '[object DOMImplementationConstructor]'
 PASS DOMParser.toString() is '[object DOMParserConstructor]'
 PASS DOMStringList.toString() is '[object DOMStringListConstructor]'
 PASS DOMImplementation.toString() is '[object DOMImplementationConstructor]'
 PASS DOMParser.toString() is '[object DOMParserConstructor]'
 PASS DOMStringList.toString() is '[object DOMStringListConstructor]'
+PASS DOMStringMap.toString() is '[object DOMStringMapConstructor]'
 PASS Document.toString() is '[object DocumentConstructor]'
 PASS DocumentFragment.toString() is '[object DocumentFragmentConstructor]'
 PASS DocumentType.toString() is '[object DocumentTypeConstructor]'
 PASS Document.toString() is '[object DocumentConstructor]'
 PASS DocumentFragment.toString() is '[object DocumentFragmentConstructor]'
 PASS DocumentType.toString() is '[object DocumentTypeConstructor]'
index 7a3580c..0f3d568 100644 (file)
@@ -1,3 +1,56 @@
+2010-06-29  Sam Weinig  <sam@webkit.org>
+
+        Reviewed by Dan Bernstein.
+
+        Patch for https://bugs.webkit.org/show_bug.cgi?id=41146
+        <rdar://problem/8126069>
+        Implement the .dataset DOM property
+
+        Tests: fast/dom/dataset-xhtml.xhtml
+               fast/dom/dataset.html
+
+        * DerivedSources.cpp:
+        * DerivedSources.make:
+        * GNUmakefile.am:
+        * WebCore.gypi:
+        * WebCore.pro:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/JSDOMStringMapCustom.cpp: Added.
+        (WebCore::JSDOMStringMap::canGetItemsForName):
+        (WebCore::JSDOMStringMap::nameGetter):
+        (WebCore::JSDOMStringMap::getOwnPropertyNames):
+        (WebCore::JSDOMStringMap::deleteProperty):
+        (WebCore::JSDOMStringMap::putDelegate):
+        * bindings/js/JSDOMStringMapCustom.h: Added.
+        * dom/DOMStringMap.cpp: Added.
+        (WebCore::DOMStringMap::~DOMStringMap):
+        * dom/DOMStringMap.h: Added.
+        (WebCore::DOMStringMap::DOMStringMap):
+        * dom/DOMStringMap.idl: Added.
+        * dom/DatasetDOMStringMap.cpp: Added.
+        (WebCore::isValidAttributeName):
+        (WebCore::convertAttributeNameToPropertyName):
+        (WebCore::propertyNameMatchesAttributeName):
+        (WebCore::isValidPropertyName):
+        (WebCore::convertPropertyNameToAttributeName):
+        (WebCore::DatasetDOMStringMap::ref):
+        (WebCore::DatasetDOMStringMap::deref):
+        (WebCore::DatasetDOMStringMap::getNames):
+        (WebCore::DatasetDOMStringMap::item):
+        (WebCore::DatasetDOMStringMap::contains):
+        (WebCore::DatasetDOMStringMap::setItem):
+        (WebCore::DatasetDOMStringMap::deleteItem):
+        * dom/DatasetDOMStringMap.h: Added.
+        (WebCore::DatasetDOMStringMap::create):
+        (WebCore::DatasetDOMStringMap::DatasetDOMStringMap):
+        * dom/Element.cpp:
+        (WebCore::Element::dataset):
+        * dom/Element.h:
+        * dom/Element.idl:
+        * dom/ElementRareData.h:
+        * page/DOMWindow.idl:
+
 2010-06-30  Darin Adler  <darin@apple.com>
 
         More Qt build fix.
 2010-06-30  Darin Adler  <darin@apple.com>
 
         More Qt build fix.
index ccf97b1..77a737b 100644 (file)
@@ -82,6 +82,7 @@
 #include "JSDOMParser.cpp"
 #include "JSDOMSelection.cpp"
 #include "JSDOMStringList.cpp"
 #include "JSDOMParser.cpp"
 #include "JSDOMSelection.cpp"
 #include "JSDOMStringList.cpp"
+#include "JSDOMStringMap.cpp"
 #include "JSDOMWindow.cpp"
 #include "JSElement.cpp"
 #include "JSEntity.cpp"
 #include "JSDOMWindow.cpp"
 #include "JSElement.cpp"
 #include "JSEntity.cpp"
index 5a106ed..2d0b2e5 100644 (file)
@@ -116,6 +116,7 @@ DOM_CLASSES = \
     DOMParser \
     DOMSelection \
     DOMStringList \
     DOMParser \
     DOMSelection \
     DOMStringList \
+    DOMStringMap \
     DOMWindow \
     Database \
     DatabaseCallback \
     DOMWindow \
     Database \
     DatabaseCallback \
index a8e1dae..b5f4e24 100644 (file)
@@ -426,6 +426,8 @@ webcore_sources += \
        WebCore/bindings/js/JSDOMFormDataCustom.cpp \
        WebCore/bindings/js/JSDOMGlobalObject.cpp \
        WebCore/bindings/js/JSDOMGlobalObject.h \
        WebCore/bindings/js/JSDOMFormDataCustom.cpp \
        WebCore/bindings/js/JSDOMGlobalObject.cpp \
        WebCore/bindings/js/JSDOMGlobalObject.h \
+       WebCore/bindings/js/JSDOMStringMapCustom.cpp \
+       WebCore/bindings/js/JSDOMStringMapCustom.h \
        WebCore/bindings/js/JSDOMWindowBase.cpp \
        WebCore/bindings/js/JSDOMWindowBase.h \
        WebCore/bindings/js/JSDOMWindowCustom.cpp \
        WebCore/bindings/js/JSDOMWindowBase.cpp \
        WebCore/bindings/js/JSDOMWindowBase.h \
        WebCore/bindings/js/JSDOMWindowCustom.cpp \
@@ -778,6 +780,10 @@ webcore_sources += \
        WebCore/dom/DOMImplementation.h \
        WebCore/dom/DOMStringList.cpp \
        WebCore/dom/DOMStringList.h \
        WebCore/dom/DOMImplementation.h \
        WebCore/dom/DOMStringList.cpp \
        WebCore/dom/DOMStringList.h \
+       WebCore/dom/DOMStringMap.cpp \
+       WebCore/dom/DOMStringMap.h \
+       WebCore/dom/DatasetDOMStringMap.cpp \
+       WebCore/dom/DatasetDOMStringMap.h \
        WebCore/dom/DecodedDataDocumentParser.cpp \
        WebCore/dom/DecodedDataDocumentParser.h \
        WebCore/dom/DeviceOrientation.cpp \
        WebCore/dom/DecodedDataDocumentParser.cpp \
        WebCore/dom/DecodedDataDocumentParser.h \
        WebCore/dom/DeviceOrientation.cpp \
@@ -4056,6 +4062,7 @@ IDL_BINDINGS_GDOM += \
        WebCore/dom/DocumentType.idl \
        WebCore/dom/DOMImplementation.idl \
        WebCore/dom/DOMStringList.idl \
        WebCore/dom/DocumentType.idl \
        WebCore/dom/DOMImplementation.idl \
        WebCore/dom/DOMStringList.idl \
+       WebCore/dom/DOMStringMap.idl \
        WebCore/dom/Element.idl \
        WebCore/dom/EntityReference.idl \
        WebCore/dom/Event.idl \
        WebCore/dom/Element.idl \
        WebCore/dom/EntityReference.idl \
        WebCore/dom/Event.idl \
index 43a99d2..18d34b9 100644 (file)
@@ -42,6 +42,7 @@
             'dom/DOMCoreException.idl',
             'dom/DOMImplementation.idl',
             'dom/DOMStringList.idl',
             'dom/DOMCoreException.idl',
             'dom/DOMImplementation.idl',
             'dom/DOMStringList.idl',
+            'dom/DOMStringMap.idl',
             'dom/DeviceOrientationEvent.idl',
             'dom/Document.idl',
             'dom/DocumentFragment.idl',
             'dom/DeviceOrientationEvent.idl',
             'dom/Document.idl',
             'dom/DocumentFragment.idl',
             'bindings/js/JSDOMBinding.h',
             'bindings/js/JSDOMGlobalObject.cpp',
             'bindings/js/JSDOMGlobalObject.h',
             'bindings/js/JSDOMBinding.h',
             'bindings/js/JSDOMGlobalObject.cpp',
             'bindings/js/JSDOMGlobalObject.h',
+            'bindings/js/JSDOMStringMapCustom.cpp',
+            'bindings/js/JSDOMStringMapCustom.h',
             'bindings/js/JSDOMWindowBase.cpp',
             'bindings/js/JSDOMWindowBase.h',
             'bindings/js/JSDOMWindowCustom.cpp',
             'bindings/js/JSDOMWindowBase.cpp',
             'bindings/js/JSDOMWindowBase.h',
             'bindings/js/JSDOMWindowCustom.cpp',
             'dom/DOMImplementation.h',
             'dom/DOMStringList.cpp',
             'dom/DOMStringList.h',
             'dom/DOMImplementation.h',
             'dom/DOMStringList.cpp',
             'dom/DOMStringList.h',
+            'dom/DOMStringMap.cpp',
+            'dom/DOMStringMap.h',
+            'dom/DatasetDOMStringMap.cpp',
+            'dom/DatasetDOMStringMap.h',
             'dom/DecodedDataDocumentParser.cpp',
             'dom/DecodedDataDocumentParser.h',
             'dom/DeviceOrientation.cpp',
             'dom/DecodedDataDocumentParser.cpp',
             'dom/DecodedDataDocumentParser.h',
             'dom/DeviceOrientation.cpp',
index bd0c87a..2762206 100644 (file)
@@ -288,6 +288,7 @@ IDL_BINDINGS += \
     dom/DOMCoreException.idl \
     dom/DOMImplementation.idl \
     dom/DOMStringList.idl \
     dom/DOMCoreException.idl \
     dom/DOMImplementation.idl \
     dom/DOMStringList.idl \
+    dom/DOMStringMap.idl \
     dom/Element.idl \
     dom/Entity.idl \
     dom/EntityReference.idl \
     dom/Element.idl \
     dom/Entity.idl \
     dom/EntityReference.idl \
index a6b2191..4f0bef9 100644 (file)
@@ -301,6 +301,7 @@ SOURCES += \
     bindings/js/JSDocumentCustom.cpp \
     bindings/js/JSDOMFormDataCustom.cpp \
     bindings/js/JSDOMGlobalObject.cpp \
     bindings/js/JSDocumentCustom.cpp \
     bindings/js/JSDOMFormDataCustom.cpp \
     bindings/js/JSDOMGlobalObject.cpp \
+    bindings/js/JSDOMStringMapCustom.cpp \
     bindings/js/JSDOMWindowBase.cpp \
     bindings/js/JSDOMWindowCustom.cpp \
     bindings/js/JSDOMWindowShell.cpp \
     bindings/js/JSDOMWindowBase.cpp \
     bindings/js/JSDOMWindowCustom.cpp \
     bindings/js/JSDOMWindowShell.cpp \
@@ -483,6 +484,8 @@ SOURCES += \
     dom/DocumentType.cpp \
     dom/DOMImplementation.cpp \
     dom/DOMStringList.cpp \
     dom/DocumentType.cpp \
     dom/DOMImplementation.cpp \
     dom/DOMStringList.cpp \
+    dom/DOMStringMap.cpp \
+    dom/DatasetDOMStringMap.cpp \
     dom/DynamicNodeList.cpp \
     dom/EditingText.cpp \
     dom/Element.cpp \
     dom/DynamicNodeList.cpp \
     dom/EditingText.cpp \
     dom/Element.cpp \
@@ -1080,7 +1083,7 @@ HEADERS += \
     bindings/js/JSDebugWrapperSet.h \
     bindings/js/JSDOMBinding.h \
     bindings/js/JSDOMGlobalObject.h \
     bindings/js/JSDebugWrapperSet.h \
     bindings/js/JSDOMBinding.h \
     bindings/js/JSDOMGlobalObject.h \
-    bindings/js/JSDOMWindowBase.h \
+    bindings/js/JSDOMStringMapCustom.h \
     bindings/js/JSDOMWindowBase.h \
     bindings/js/JSDOMWindowCustom.h \
     bindings/js/JSDOMWindowShell.h \
     bindings/js/JSDOMWindowBase.h \
     bindings/js/JSDOMWindowCustom.h \
     bindings/js/JSDOMWindowShell.h \
@@ -1232,6 +1235,8 @@ HEADERS += \
     dom/DocumentType.h \
     dom/DOMImplementation.h \
     dom/DOMStringList.h \
     dom/DocumentType.h \
     dom/DOMImplementation.h \
     dom/DOMStringList.h \
+    dom/DOMStringMap.h \
+    dom/DatasetDOMStringMap.h \
     dom/DynamicNodeList.h \
     dom/EditingText.h \
     dom/Element.h \
     dom/DynamicNodeList.h \
     dom/EditingText.h \
     dom/Element.h \
index 6b70dc6..3a1143c 100644 (file)
                                >\r
                        </File>\r
                        <File\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSDOMStringMap.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Debug_Internal|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Debug_Cairo|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release_Cairo|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Debug_All|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSDOMStringMap.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSDOMWindow.cpp"\r
                                >\r
                                <FileConfiguration\r
                                RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSDOMWindow.cpp"\r
                                >\r
                                <FileConfiguration\r
                                >\r
                        </File>\r
                        <File\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath="..\dom\DatasetDOMStringMap.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\dom\DatasetDOMStringMap.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="..\dom\Document.cpp"\r
                                >\r
                        </File>\r
                                RelativePath="..\dom\Document.cpp"\r
                                >\r
                        </File>\r
                                >\r
                        </File>\r
                        <File\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath="..\dom\DOMStringMap.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\dom\DOMStringMap.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="..\dom\DynamicNodeList.cpp"\r
                                >\r
                        </File>\r
                                RelativePath="..\dom\DynamicNodeList.cpp"\r
                                >\r
                        </File>\r
                                        >\r
                                </File>\r
                                <File\r
                                        >\r
                                </File>\r
                                <File\r
+                                       RelativePath="..\bindings\js\JSDOMStringMapCustom.cpp"\r
+                                       >\r
+                                       <FileConfiguration\r
+                                               Name="Debug|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Debug_Internal|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Debug_Cairo|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Release_Cairo|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                                       <FileConfiguration\r
+                                               Name="Debug_All|Win32"\r
+                                               ExcludedFromBuild="true"\r
+                                               >\r
+                                               <Tool\r
+                                                       Name="VCCLCompilerTool"\r
+                                               />\r
+                                       </FileConfiguration>\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\bindings\js\JSDOMStringMapCustom.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
                                        RelativePath="..\bindings\js\JSDOMWindowBase.cpp"\r
                                        >\r
                                        <FileConfiguration\r
                                        RelativePath="..\bindings\js\JSDOMWindowBase.cpp"\r
                                        >\r
                                        <FileConfiguration\r
index fd99009..7ba99ee 100644 (file)
                BC60DB490D2A3D1E00B9918F /* JSXPathException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC60DB470D2A3D1E00B9918F /* JSXPathException.cpp */; };
                BC60DB4A0D2A3D1E00B9918F /* JSXPathException.h in Headers */ = {isa = PBXBuildFile; fileRef = BC60DB480D2A3D1E00B9918F /* JSXPathException.h */; };
                BC60EFB70F33A0E700812A93 /* RenderObjectChildList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC60EFB60F33A0E700812A93 /* RenderObjectChildList.cpp */; };
                BC60DB490D2A3D1E00B9918F /* JSXPathException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC60DB470D2A3D1E00B9918F /* JSXPathException.cpp */; };
                BC60DB4A0D2A3D1E00B9918F /* JSXPathException.h in Headers */ = {isa = PBXBuildFile; fileRef = BC60DB480D2A3D1E00B9918F /* JSXPathException.h */; };
                BC60EFB70F33A0E700812A93 /* RenderObjectChildList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC60EFB60F33A0E700812A93 /* RenderObjectChildList.cpp */; };
+               BC64640911D7F304006455B0 /* DOMStringMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC64640711D7F304006455B0 /* DOMStringMap.cpp */; };
+               BC64640A11D7F304006455B0 /* DOMStringMap.h in Headers */ = {isa = PBXBuildFile; fileRef = BC64640811D7F304006455B0 /* DOMStringMap.h */; };
+               BC64641C11D7F416006455B0 /* DatasetDOMStringMap.h in Headers */ = {isa = PBXBuildFile; fileRef = BC64641A11D7F416006455B0 /* DatasetDOMStringMap.h */; };
+               BC64641D11D7F416006455B0 /* DatasetDOMStringMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC64641B11D7F416006455B0 /* DatasetDOMStringMap.cpp */; };
+               BC64649711D82349006455B0 /* JSDOMStringMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC64649511D82349006455B0 /* JSDOMStringMap.cpp */; };
+               BC64649811D82349006455B0 /* JSDOMStringMap.h in Headers */ = {isa = PBXBuildFile; fileRef = BC64649611D82349006455B0 /* JSDOMStringMap.h */; };
+               BC64649C11D8238C006455B0 /* JSDOMStringMapCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC64649B11D8238C006455B0 /* JSDOMStringMapCustom.cpp */; };
                BC64B4CB0CB4295D005F2B62 /* CachedFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC64B4C90CB4295D005F2B62 /* CachedFont.cpp */; };
                BC64B4CC0CB4295D005F2B62 /* CachedFont.h in Headers */ = {isa = PBXBuildFile; fileRef = BC64B4CA0CB4295D005F2B62 /* CachedFont.h */; };
                BC64B4D50CB4298A005F2B62 /* CSSFontFace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC64B4CD0CB4298A005F2B62 /* CSSFontFace.cpp */; };
                BC64B4CB0CB4295D005F2B62 /* CachedFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC64B4C90CB4295D005F2B62 /* CachedFont.cpp */; };
                BC64B4CC0CB4295D005F2B62 /* CachedFont.h in Headers */ = {isa = PBXBuildFile; fileRef = BC64B4CA0CB4295D005F2B62 /* CachedFont.h */; };
                BC64B4D50CB4298A005F2B62 /* CSSFontFace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC64B4CD0CB4298A005F2B62 /* CSSFontFace.cpp */; };
                BC60DB470D2A3D1E00B9918F /* JSXPathException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSXPathException.cpp; sourceTree = "<group>"; };
                BC60DB480D2A3D1E00B9918F /* JSXPathException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSXPathException.h; sourceTree = "<group>"; };
                BC60EFB60F33A0E700812A93 /* RenderObjectChildList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderObjectChildList.cpp; sourceTree = "<group>"; };
                BC60DB470D2A3D1E00B9918F /* JSXPathException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSXPathException.cpp; sourceTree = "<group>"; };
                BC60DB480D2A3D1E00B9918F /* JSXPathException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSXPathException.h; sourceTree = "<group>"; };
                BC60EFB60F33A0E700812A93 /* RenderObjectChildList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderObjectChildList.cpp; sourceTree = "<group>"; };
+               BC64640711D7F304006455B0 /* DOMStringMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMStringMap.cpp; sourceTree = "<group>"; };
+               BC64640811D7F304006455B0 /* DOMStringMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMStringMap.h; sourceTree = "<group>"; };
+               BC64641A11D7F416006455B0 /* DatasetDOMStringMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatasetDOMStringMap.h; sourceTree = "<group>"; };
+               BC64641B11D7F416006455B0 /* DatasetDOMStringMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatasetDOMStringMap.cpp; sourceTree = "<group>"; };
+               BC64647911D800CD006455B0 /* DOMStringMap.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DOMStringMap.idl; sourceTree = "<group>"; };
+               BC64649511D82349006455B0 /* JSDOMStringMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMStringMap.cpp; sourceTree = "<group>"; };
+               BC64649611D82349006455B0 /* JSDOMStringMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMStringMap.h; sourceTree = "<group>"; };
+               BC64649B11D8238C006455B0 /* JSDOMStringMapCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMStringMapCustom.cpp; sourceTree = "<group>"; };
                BC64B4C90CB4295D005F2B62 /* CachedFont.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CachedFont.cpp; sourceTree = "<group>"; };
                BC64B4CA0CB4295D005F2B62 /* CachedFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedFont.h; sourceTree = "<group>"; };
                BC64B4CD0CB4298A005F2B62 /* CSSFontFace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSFontFace.cpp; sourceTree = "<group>"; };
                BC64B4C90CB4295D005F2B62 /* CachedFont.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CachedFont.cpp; sourceTree = "<group>"; };
                BC64B4CA0CB4295D005F2B62 /* CachedFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedFont.h; sourceTree = "<group>"; };
                BC64B4CD0CB4298A005F2B62 /* CSSFontFace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSFontFace.cpp; sourceTree = "<group>"; };
                                65DF31E409D1CC60000BE325 /* JSDOMImplementation.h */,
                                C5137CF011A58378004ADB99 /* JSDOMStringList.cpp */,
                                C5137CF111A58378004ADB99 /* JSDOMStringList.h */,
                                65DF31E409D1CC60000BE325 /* JSDOMImplementation.h */,
                                C5137CF011A58378004ADB99 /* JSDOMStringList.cpp */,
                                C5137CF111A58378004ADB99 /* JSDOMStringList.h */,
+                               BC64649511D82349006455B0 /* JSDOMStringMap.cpp */,
+                               BC64649611D82349006455B0 /* JSDOMStringMap.h */,
                                65DF31E509D1CC60000BE325 /* JSElement.cpp */,
                                65DF31E609D1CC60000BE325 /* JSElement.h */,
                                65DF322D09D1DDBC000BE325 /* JSEntity.cpp */,
                                65DF31E509D1CC60000BE325 /* JSElement.cpp */,
                                65DF31E609D1CC60000BE325 /* JSElement.h */,
                                65DF322D09D1DDBC000BE325 /* JSEntity.cpp */,
                                49C7BA8C1042F5B10009D447 /* JSDocumentCustom.cpp */,
                                1AC226160DB69F740089B669 /* JSDOMApplicationCacheCustom.cpp */,
                                2E0888E5114884E200AF4265 /* JSDOMFormDataCustom.cpp */,
                                49C7BA8C1042F5B10009D447 /* JSDocumentCustom.cpp */,
                                1AC226160DB69F740089B669 /* JSDOMApplicationCacheCustom.cpp */,
                                2E0888E5114884E200AF4265 /* JSDOMFormDataCustom.cpp */,
+                               BC64649B11D8238C006455B0 /* JSDOMStringMapCustom.cpp */,
                                BCD9C25E0C17AA67005C90A2 /* JSDOMWindowCustom.cpp */,
                                652FBBBB0DE27CB60001D386 /* JSDOMWindowCustom.h */,
                                BC2ED5540C6B9BD300920BFF /* JSElementCustom.cpp */,
                                BCD9C25E0C17AA67005C90A2 /* JSDOMWindowCustom.cpp */,
                                652FBBBB0DE27CB60001D386 /* JSDOMWindowCustom.h */,
                                BC2ED5540C6B9BD300920BFF /* JSElementCustom.cpp */,
                                C55610F011A704EB00B82D27 /* DOMStringList.cpp */,
                                C544274911A57E7A0063A749 /* DOMStringList.h */,
                                C544274A11A57E7A0063A749 /* DOMStringList.idl */,
                                C55610F011A704EB00B82D27 /* DOMStringList.cpp */,
                                C544274911A57E7A0063A749 /* DOMStringList.h */,
                                C544274A11A57E7A0063A749 /* DOMStringList.idl */,
+                               BC64640711D7F304006455B0 /* DOMStringMap.cpp */,
+                               BC64640811D7F304006455B0 /* DOMStringMap.h */,
+                               BC64647911D800CD006455B0 /* DOMStringMap.idl */,
+                               BC64641B11D7F416006455B0 /* DatasetDOMStringMap.cpp */,
+                               BC64641A11D7F416006455B0 /* DatasetDOMStringMap.h */,
                                BC7FA61E0D1F0CBD00DB22A9 /* DynamicNodeList.cpp */,
                                BC7FA61F0D1F0CBD00DB22A9 /* DynamicNodeList.h */,
                                6550B699099DF0270090D781 /* EditingText.cpp */,
                                BC7FA61E0D1F0CBD00DB22A9 /* DynamicNodeList.cpp */,
                                BC7FA61F0D1F0CBD00DB22A9 /* DynamicNodeList.h */,
                                6550B699099DF0270090D781 /* EditingText.cpp */,
                                E1BE512E0CF6C512002EA959 /* XSLTUnicodeSort.h in Headers */,
                                97DD4D870FDF4D6E00ECF9A4 /* XSSAuditor.h in Headers */,
                                CE172E011136E8CE0062A533 /* ZoomMode.h in Headers */,
                                E1BE512E0CF6C512002EA959 /* XSLTUnicodeSort.h in Headers */,
                                97DD4D870FDF4D6E00ECF9A4 /* XSSAuditor.h in Headers */,
                                CE172E011136E8CE0062A533 /* ZoomMode.h in Headers */,
+                               BC64640A11D7F304006455B0 /* DOMStringMap.h in Headers */,
+                               BC64641C11D7F416006455B0 /* DatasetDOMStringMap.h in Headers */,
+                               BC64649811D82349006455B0 /* JSDOMStringMap.h in Headers */,
                                A8A563B411DB3D10003AC2F0 /* HTMLElementStack.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                                A8A563B411DB3D10003AC2F0 /* HTMLElementStack.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                                93F19B0508245E59001E9ABC /* XSLTProcessorLibxslt.cpp in Sources */,
                                E1BE512D0CF6C512002EA959 /* XSLTUnicodeSort.cpp in Sources */,
                                97DD4D860FDF4D6E00ECF9A4 /* XSSAuditor.cpp in Sources */,
                                93F19B0508245E59001E9ABC /* XSLTProcessorLibxslt.cpp in Sources */,
                                E1BE512D0CF6C512002EA959 /* XSLTUnicodeSort.cpp in Sources */,
                                97DD4D860FDF4D6E00ECF9A4 /* XSSAuditor.cpp in Sources */,
+                               BC64640911D7F304006455B0 /* DOMStringMap.cpp in Sources */,
+                               BC64641D11D7F416006455B0 /* DatasetDOMStringMap.cpp in Sources */,
+                               BC64649711D82349006455B0 /* JSDOMStringMap.cpp in Sources */,
+                               BC64649C11D8238C006455B0 /* JSDOMStringMapCustom.cpp in Sources */,
                                A8A563B511DB3D10003AC2F0 /* HTMLElementStack.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                                A8A563B511DB3D10003AC2F0 /* HTMLElementStack.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
diff --git a/WebCore/bindings/js/JSDOMStringMapCustom.cpp b/WebCore/bindings/js/JSDOMStringMapCustom.cpp
new file mode 100644 (file)
index 0000000..455c7b1
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSDOMStringMap.h"
+
+#include "AtomicString.h"
+#include "DOMStringMap.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+bool JSDOMStringMap::canGetItemsForName(ExecState*, DOMStringMap* impl, const Identifier& propertyName)
+{
+    return impl->contains(identifierToAtomicString(propertyName));
+}
+
+JSValue JSDOMStringMap::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
+{
+    JSDOMStringMap* thisObj = static_cast<JSDOMStringMap*>(asObject(slotBase));
+    return jsString(exec, thisObj->impl()->item(identifierToAtomicString(propertyName)));
+}
+
+void JSDOMStringMap::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+    Vector<String> names;
+    m_impl->getNames(names);
+    size_t length = names.size();
+    for (size_t i = 0; i < length; ++i)
+        propertyNames.add(Identifier(exec, stringToUString(names[i])));
+
+    Base::getOwnPropertyNames(exec, propertyNames, mode);
+}
+
+bool JSDOMStringMap::deleteProperty(ExecState* exec, const Identifier& propertyName)
+{
+    // Only perform the custom delete if the object doesn't have a native property by this name.
+    // Since hasProperty() would end up calling canGetItemsForName() and be fooled, we need to check
+    // the native property slots manually.
+    PropertySlot slot;
+    if (getStaticValueSlot<JSDOMStringMap, Base>(exec, s_info.propHashTable(exec), this, propertyName, slot))
+        return false;
+        
+    JSValue prototype = this->prototype();
+    if (prototype.isObject() && asObject(prototype)->hasProperty(exec, propertyName))
+        return false;
+
+    ExceptionCode ec = 0;
+    m_impl->deleteItem(identifierToString(propertyName), ec);
+    setDOMException(exec, ec);
+
+    return true;
+}
+
+bool JSDOMStringMap::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot&)
+{
+    // Only perform the custom put if the object doesn't have a native property by this name.
+    // Since hasProperty() would end up calling canGetItemsForName() and be fooled, we need to check
+    // the native property slots manually.
+    PropertySlot slot;
+    if (getStaticValueSlot<JSDOMStringMap, Base>(exec, s_info.propHashTable(exec), this, propertyName, slot))
+        return false;
+        
+    JSValue prototype = this->prototype();
+    if (prototype.isObject() && asObject(prototype)->hasProperty(exec, propertyName))
+        return false;
+    
+    String stringValue = ustringToString(value.toString(exec));
+    if (exec->hadException())
+        return true;
+    
+    ExceptionCode ec = 0;
+    impl()->setItem(identifierToString(propertyName), stringValue, ec);
+    setDOMException(exec, ec);
+
+    return true;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/js/JSDOMStringMapCustom.h b/WebCore/bindings/js/JSDOMStringMapCustom.h
new file mode 100644 (file)
index 0000000..095fd21
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSDOMStringMapCustom_h
+#define JSDOMStringMapCustom_h
+
+#include "JSDOMStringMap.h"
+
+#endif // JSDOMStringMapCustom_h
diff --git a/WebCore/dom/DOMStringMap.cpp b/WebCore/dom/DOMStringMap.cpp
new file mode 100644 (file)
index 0000000..e63dabe
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DOMStringMap.h"
+
+namespace WebCore {
+
+DOMStringMap::~DOMStringMap()
+{
+}
+
+} // namespace WebCore
diff --git a/WebCore/dom/DOMStringMap.h b/WebCore/dom/DOMStringMap.h
new file mode 100644 (file)
index 0000000..c0bc07d
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DOMStringMap_h
+#define DOMStringMap_h
+
+#include "PlatformString.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+typedef int ExceptionCode;
+
+class DOMStringMap : public Noncopyable {
+public:
+    virtual ~DOMStringMap();
+
+    virtual void ref() = 0;
+    virtual void deref() = 0;
+
+    virtual void getNames(Vector<String>&) = 0;
+    virtual String item(const String& name) = 0;
+    virtual bool contains(const String& name) = 0;
+    virtual void setItem(const String& name, const String& value, ExceptionCode&) = 0;
+    virtual void deleteItem(const String& name, ExceptionCode&) = 0;
+
+protected:
+    DOMStringMap()
+    {
+    }
+};
+
+} // namespace WebCore
+
+#endif // DOMStringMap_h
diff --git a/WebCore/dom/DOMStringMap.idl b/WebCore/dom/DOMStringMap.idl
new file mode 100644 (file)
index 0000000..0320b3b
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module core {
+
+    interface [
+        HasNameGetter,
+        CustomDeleteProperty,
+        CustomGetPropertyNames,
+        DelegatingPutFunction,
+    ] DOMStringMap {
+    };
+
+}
diff --git a/WebCore/dom/DatasetDOMStringMap.cpp b/WebCore/dom/DatasetDOMStringMap.cpp
new file mode 100644 (file)
index 0000000..6359d55
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DatasetDOMStringMap.h"
+
+#include "Attribute.h"
+#include "Element.h"
+#include "ExceptionCode.h"
+#include "NamedNodeMap.h"
+#include <wtf/ASCIICType.h>
+
+namespace WebCore {
+
+static bool isValidAttributeName(const String& name)
+{
+    if (!name.startsWith("data-"))
+        return false;
+
+    const UChar* characters = name.characters();
+    unsigned length = name.length();
+    for (unsigned i = 5; i < length; ++i) {
+        if (isASCIIUpper(characters[i]))
+            return false;
+    }
+
+    return true;
+}
+
+static String convertAttributeNameToPropertyName(const String& name)
+{
+    Vector<UChar> newStringBuffer;
+
+    const UChar* characters = name.characters();
+    unsigned length = name.length();
+    for (unsigned i = 5; i < length; ++i) {
+        if (characters[i] != '-')
+            newStringBuffer.append(characters[i]);
+        else {
+            if ((i + 1 < length) && isASCIILower(characters[i + 1])) {
+                newStringBuffer.append(toASCIIUpper(characters[i + 1]));
+                ++i;
+            } else
+                newStringBuffer.append(characters[i]);
+        }
+    }
+
+    return String::adopt(newStringBuffer);
+}
+
+static bool propertyNameMatchesAttributeName(const String& propertyName, const String& attributeName)
+{
+    // FIXME: This should be able to match without creating a new string.
+
+    if (!isValidAttributeName(attributeName))
+        return false;
+
+    String convertedName = convertAttributeNameToPropertyName(attributeName);
+    return (convertedName == propertyName);
+}
+
+static bool isValidPropertyName(const String& name)
+{
+    const UChar* characters = name.characters();
+    unsigned length = name.length();
+    for (unsigned i = 0; i < length; ++i) {
+        if (characters[i] == '-' && (i + 1 < length) && isASCIILower(characters[i + 1]))
+            return false;
+    }
+    return true;
+}
+
+static String convertPropertyNameToAttributeName(const String& name)
+{
+    Vector<UChar> newStringBuffer;
+
+    newStringBuffer.append('d');
+    newStringBuffer.append('a');
+    newStringBuffer.append('t');
+    newStringBuffer.append('a');
+    newStringBuffer.append('-');
+
+    const UChar* characters = name.characters();
+    unsigned length = name.length();
+    for (unsigned i = 0; i < length; ++i) {
+        if (isASCIIUpper(characters[i])) {
+            newStringBuffer.append('-');
+            newStringBuffer.append(toASCIILower(characters[i]));
+        } else
+            newStringBuffer.append(characters[i]);
+    }
+
+    return String::adopt(newStringBuffer);
+}
+
+
+void DatasetDOMStringMap::ref()
+{
+    m_element->ref();
+}
+
+void DatasetDOMStringMap::deref()
+{
+    m_element->deref();
+}
+
+void DatasetDOMStringMap::getNames(Vector<String>& names)
+{
+    NamedNodeMap* attributeMap = m_element->attributes(true);
+    if (attributeMap) {
+        unsigned length = attributeMap->length();
+        for (unsigned i = 0; i < length; i++) {
+            Attribute* attribute = attributeMap->attributeItem(i);
+            if (isValidAttributeName(attribute->localName()))
+                names.append(convertAttributeNameToPropertyName(attribute->localName()));
+        }
+    }
+}
+
+String DatasetDOMStringMap::item(const String& name)
+{
+    NamedNodeMap* attributeMap = m_element->attributes(true);
+    if (attributeMap) {
+        unsigned length = attributeMap->length();
+        for (unsigned i = 0; i < length; i++) {
+            Attribute* attribute = attributeMap->attributeItem(i);
+            if (propertyNameMatchesAttributeName(name, attribute->localName()))
+                return attribute->value();
+        }
+    }
+
+    return String();
+}
+
+bool DatasetDOMStringMap::contains(const String& name)
+{
+    NamedNodeMap* attributeMap = m_element->attributes(true);
+    if (attributeMap) {
+        unsigned length = attributeMap->length();
+        for (unsigned i = 0; i < length; i++) {
+            Attribute* attribute = attributeMap->attributeItem(i);
+            if (propertyNameMatchesAttributeName(name, attribute->localName()))
+                return true;
+        }
+    }
+    return false;
+}
+
+void DatasetDOMStringMap::setItem(const String& name, const String& value, ExceptionCode& ec)
+{
+    if (!isValidPropertyName(name)) {
+        ec = SYNTAX_ERR;
+        return;
+    }
+
+    m_element->setAttribute(convertPropertyNameToAttributeName(name), value, ec);
+}
+
+void DatasetDOMStringMap::deleteItem(const String& name, ExceptionCode& ec)
+{
+    if (!isValidPropertyName(name)) {
+        ec = SYNTAX_ERR;
+        return;
+    }
+
+    ExceptionCode dummy;
+    m_element->removeAttribute(convertPropertyNameToAttributeName(name), dummy);
+}
+
+} // namespace WebCore
diff --git a/WebCore/dom/DatasetDOMStringMap.h b/WebCore/dom/DatasetDOMStringMap.h
new file mode 100644 (file)
index 0000000..f82eaa5
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DatasetDOMStringMap_h
+#define DatasetDOMStringMap_h
+
+#include "DOMStringMap.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class Element;
+
+class DatasetDOMStringMap : public DOMStringMap {
+public:
+    static PassOwnPtr<DatasetDOMStringMap> create(Element* element)
+    {
+        return new DatasetDOMStringMap(element);
+    }
+
+    virtual void ref();
+    virtual void deref();
+
+    virtual void getNames(Vector<String>&);
+    virtual String item(const String& name);
+    virtual bool contains(const String& name);
+    virtual void setItem(const String& name, const String& value, ExceptionCode&);
+    virtual void deleteItem(const String& name, ExceptionCode&);
+
+private:
+    DatasetDOMStringMap(Element* element)
+        : m_element(element)
+    {
+    }
+
+    Element* m_element;
+};
+
+} // namespace WebCore
+
+#endif // DatasetDOMStringMap_h
index adbb720..4566251 100644 (file)
@@ -33,6 +33,7 @@
 #include "CSSStyleSelector.h"
 #include "ClientRect.h"
 #include "ClientRectList.h"
 #include "CSSStyleSelector.h"
 #include "ClientRect.h"
 #include "ClientRectList.h"
+#include "DatasetDOMStringMap.h"
 #include "Document.h"
 #include "DocumentFragment.h"
 #include "ElementRareData.h"
 #include "Document.h"
 #include "DocumentFragment.h"
 #include "ElementRareData.h"
@@ -1520,6 +1521,14 @@ bool Element::webkitMatchesSelector(const String& selector, ExceptionCode& ec)
     return false;
 }
 
     return false;
 }
 
+DOMStringMap* Element::dataset()
+{
+    ElementRareData* data = ensureRareData();
+    if (!data->m_datasetDOMStringMap)
+        data->m_datasetDOMStringMap = DatasetDOMStringMap::create(this);
+    return data->m_datasetDOMStringMap.get();
+}
+
 KURL Element::getURLAttribute(const QualifiedName& name) const
 {
 #if !ASSERT_DISABLED
 KURL Element::getURLAttribute(const QualifiedName& name) const
 {
 #if !ASSERT_DISABLED
index a0cf7b1..7dd7d80 100644 (file)
@@ -35,6 +35,7 @@ namespace WebCore {
 class Attribute;
 class ClientRect;
 class ClientRectList;
 class Attribute;
 class ClientRect;
 class ClientRectList;
+class DOMStringMap;
 class ElementRareData;
 class IntSize;
 
 class ElementRareData;
 class IntSize;
 
@@ -262,6 +263,8 @@ public:
 
     bool webkitMatchesSelector(const String& selectors, ExceptionCode&);
 
 
     bool webkitMatchesSelector(const String& selectors, ExceptionCode&);
 
+    DOMStringMap* dataset();
+
     virtual bool isFormControlElement() const { return false; }
     virtual bool isEnabledFormControl() const { return true; }
     virtual bool isReadOnlyFormControl() const { return false; }
     virtual bool isFormControlElement() const { return false; }
     virtual bool isEnabledFormControl() const { return true; }
     virtual bool isReadOnlyFormControl() const { return false; }
index 6bb0687..0ad3184 100644 (file)
@@ -99,6 +99,12 @@ module core {
         // HTML 5
         NodeList getElementsByClassName(in DOMString name);
 
         // HTML 5
         NodeList getElementsByClassName(in DOMString name);
 
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+#if !defined(V8_BINDING) || !V8_BINDING
+        readonly attribute DOMStringMap dataset;
+#endif
+#endif
+
         // NodeSelector - Selector API
         Element querySelector(in DOMString selectors)
             raises(DOMException);
         // NodeSelector - Selector API
         Element querySelector(in DOMString selectors)
             raises(DOMException);
index b444d99..8e338ab 100644 (file)
 #ifndef ElementRareData_h
 #define ElementRareData_h
 
 #ifndef ElementRareData_h
 #define ElementRareData_h
 
+#include "DatasetDOMStringMap.h"
 #include "Element.h"
 #include "NodeRareData.h"
 #include "Element.h"
 #include "NodeRareData.h"
+#include <wtf/OwnPtr.h>
 
 namespace WebCore {
 
 
 namespace WebCore {
 
@@ -38,6 +40,8 @@ public:
 
     IntSize m_minimumSizeForResizing;
     RefPtr<RenderStyle> m_computedStyle;
 
     IntSize m_minimumSizeForResizing;
     RefPtr<RenderStyle> m_computedStyle;
+
+    OwnPtr<DatasetDOMStringMap> m_datasetDOMStringMap;
 };
 
 inline IntSize defaultMinimumSizeForResizing()
 };
 
 inline IntSize defaultMinimumSizeForResizing()
index a96c71a..935bdf8 100644 (file)
@@ -459,6 +459,8 @@ module window {
         attribute [Conditional=3D_CANVAS,EnabledAtRuntime] WebGLRenderingContextConstructor WebGLRenderingContext;
         attribute TextMetricsConstructor TextMetrics;
 
         attribute [Conditional=3D_CANVAS,EnabledAtRuntime] WebGLRenderingContextConstructor WebGLRenderingContext;
         attribute TextMetricsConstructor TextMetrics;
 
+        attribute DOMStringMapConstructor DOMStringMap;
+
         attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] ArrayBufferConstructor ArrayBuffer; // Usable with new operator
         attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] Int8ArrayConstructor Int8Array; // Usable with new operator
         attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] Uint8ArrayConstructor Uint8Array; // Usable with new operator
         attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] ArrayBufferConstructor ArrayBuffer; // Usable with new operator
         attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] Int8ArrayConstructor Int8Array; // Usable with new operator
         attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] Uint8ArrayConstructor Uint8Array; // Usable with new operator