Diff
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (196127 => 196128)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2016-02-04 17:39:11 UTC (rev 196127)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2016-02-04 17:43:05 UTC (rev 196128)
@@ -1,3 +1,21 @@
+2016-02-04 Youenn Fablet <youenn.fab...@crf.canon.fr>
+
+ [Fetch API] Add support for iterating over Headers
+ https://bugs.webkit.org/show_bug.cgi?id=153787
+
+ Reviewed by Darin Adler.
+
+ Relanding.
+
+ * web-platform-tests/fetch/api/headers/headers-basic-expected.txt:
+ * web-platform-tests/fetch/api/headers/headers-basic.html:
+ * web-platform-tests/fetch/api/headers/headers-structure-expected.txt:
+ * web-platform-tests/fetch/api/request/request-clone.sub-expected.txt:
+ * web-platform-tests/fetch/api/request/request-init-003.sub-expected.txt:
+ * web-platform-tests/fetch/api/resources/utils.js:
+ (checkRequest):
+ (readTextStream):
+
2016-02-04 Chris Dumez <cdu...@apple.com>
Merge DOMTokenList and DOMSettableTokenList
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/headers/headers-basic-expected.txt (196127 => 196128)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/headers/headers-basic-expected.txt 2016-02-04 17:39:11 UTC (rev 196127)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/headers/headers-basic-expected.txt 2016-02-04 17:43:05 UTC (rev 196128)
@@ -12,4 +12,7 @@
PASS Check has method
PASS Check delete method
PASS Check get method
+PASS Check keys method
+PASS Check values method
+PASS Check entries method
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/headers/headers-basic.html (196127 => 196128)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/headers/headers-basic.html 2016-02-04 17:39:11 UTC (rev 196127)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/headers/headers-basic.html 2016-02-04 17:43:05 UTC (rev 196128)
@@ -111,6 +111,58 @@
assert_equals(headers.get("nameNotInHeaders"), null, "header: nameNotInHeaders has no value");
}, "Check get method");
- </script>
+
+ var headerEntriesDict = {"name1": "value1",
+ "Name2": "value2",
+ "name": "value3",
+ "content-Type": "value4",
+ "Content-Typ": "value5",
+ "Content-Types": "value6"
+ };
+ var sortedHeaderDict = {};
+ var sortedHeaderKeys = Object.keys(headerEntriesDict).map(function(value) {
+ sortedHeaderDict[value.toLowerCase()] = headerEntriesDict[value];
+ return value.toLowerCase();
+ }).sort();
+
+ test(function() {
+ var headers = new Headers(headerEntriesDict);
+ var actual = headers.keys();
+ sortedHeaderKeys.forEach(function(key) {
+ entry = actual.next();
+ assert_false(entry.done);
+ assert_equals(entry.value, key);
+ });
+ assert_true(actual.next().done);
+ assert_true(actual.next().done);
+ }, "Check keys method");
+
+ test(function() {
+ var headers = new Headers(headerEntriesDict);
+ var actual = headers.values();
+
+ sortedHeaderKeys.forEach(function(key) {
+ entry = actual.next();
+ assert_false(entry.done);
+ assert_equals(entry.value, sortedHeaderDict[key]);
+ });
+ assert_true(actual.next().done);
+ assert_true(actual.next().done);
+ }, "Check values method");
+
+ test(function() {
+ var headers = new Headers(headerEntriesDict);
+ var actual = headers.entries();
+
+ sortedHeaderKeys.forEach(function(key) {
+ entry = actual.next();
+ assert_false(entry.done);
+ assert_equals(entry.value[0], key);
+ assert_equals(entry.value[1], sortedHeaderDict[key]);
+ });
+ assert_true(actual.next().done);
+ assert_true(actual.next().done);
+ }, "Check entries method");
+ </script>
</body>
</html>
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/headers/headers-structure-expected.txt (196127 => 196128)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/headers/headers-structure-expected.txt 2016-02-04 17:39:11 UTC (rev 196127)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/headers/headers-structure-expected.txt 2016-02-04 17:43:05 UTC (rev 196128)
@@ -4,7 +4,7 @@
PASS Headers has get method
PASS Headers has has method
PASS Headers has set method
-FAIL Headers has entries method assert_true: headers has entries method expected true got false
-FAIL Headers has keys method assert_true: headers has keys method expected true got false
-FAIL Headers has values method assert_true: headers has values method expected true got false
+PASS Headers has entries method
+PASS Headers has keys method
+PASS Headers has values method
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-clone.sub-expected.txt (196127 => 196128)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-clone.sub-expected.txt 2016-02-04 17:39:11 UTC (rev 196127)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-clone.sub-expected.txt 2016-02-04 17:43:05 UTC (rev 196128)
@@ -1,4 +1,4 @@
-FAIL Check cloning a request ExpectedValuesDict["headers"].keys is not a function. (In 'ExpectedValuesDict["headers"].keys()', 'ExpectedValuesDict["headers"].keys' is undefined)
+PASS Check cloning a request
PASS Check cloning a request copies the headers
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-init-003.sub-expected.txt (196127 => 196128)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-init-003.sub-expected.txt 2016-02-04 17:39:11 UTC (rev 196127)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-init-003.sub-expected.txt 2016-02-04 17:43:05 UTC (rev 196128)
@@ -1,6 +1,6 @@
-FAIL Check request values when initialized from Request ExpectedValuesDict["headers"].keys is not a function. (In 'ExpectedValuesDict["headers"].keys()', 'ExpectedValuesDict["headers"].keys' is undefined)
-FAIL Check request values when initialized from Request and init values ExpectedValuesDict["headers"].keys is not a function. (In 'ExpectedValuesDict["headers"].keys()', 'ExpectedValuesDict["headers"].keys' is undefined)
+PASS Check request values when initialized from Request
+PASS Check request values when initialized from Request and init values
FAIL Check request values when initialized from url string assert_equals: Check url attribute expected "http://url.test:1234/path/subpath?query=true" but got "http://url.test:1234/path/subpath?query=true#fragment"
-FAIL Check request values when initialized from url and init values ExpectedValuesDict["headers"].keys is not a function. (In 'ExpectedValuesDict["headers"].keys()', 'ExpectedValuesDict["headers"].keys' is undefined)
+FAIL Check request values when initialized from url and init values assert_equals: Check url attribute expected "http://url.test:1234/path/subpath?query=true" but got "http://url.test:1234/path/subpath?query=true#fragment"
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/resources/utils.js (196127 => 196128)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/resources/utils.js 2016-02-04 17:39:11 UTC (rev 196127)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/resources/utils.js 2016-02-04 17:43:05 UTC (rev 196128)
@@ -15,7 +15,7 @@
for (var attribute in ExpectedValuesDict) {
switch(attribute) {
case "headers":
- for (var key of ExpectedValuesDict["headers"].keys())
+ for (var key in ExpectedValuesDict["headers"].keys())
assert_equals(request["headers"].get(key), ExpectedValuesDict["headers"].get(key),
"Check headers attribute has " + key + ":" + ExpectedValuesDict["headers"].get(key));
break;
@@ -63,4 +63,4 @@
asyncTest.done();
});
});
-}
\ No newline at end of file
+}
Modified: trunk/Source/WebCore/CMakeLists.txt (196127 => 196128)
--- trunk/Source/WebCore/CMakeLists.txt 2016-02-04 17:39:11 UTC (rev 196127)
+++ trunk/Source/WebCore/CMakeLists.txt 2016-02-04 17:43:05 UTC (rev 196128)
@@ -1164,6 +1164,7 @@
bindings/js/JSEventListener.cpp
bindings/js/JSEventTargetCustom.cpp
bindings/js/JSExceptionBase.cpp
+ bindings/js/JSFetchHeadersCustom.cpp
bindings/js/JSFileReaderCustom.cpp
bindings/js/JSGeolocationCustom.cpp
bindings/js/JSHTMLAllCollectionCustom.cpp
Modified: trunk/Source/WebCore/ChangeLog (196127 => 196128)
--- trunk/Source/WebCore/ChangeLog 2016-02-04 17:39:11 UTC (rev 196127)
+++ trunk/Source/WebCore/ChangeLog 2016-02-04 17:43:05 UTC (rev 196128)
@@ -1,3 +1,41 @@
+2016-02-04 Youenn Fablet <youenn.fab...@crf.canon.fr>
+
+ [Fetch API] Add support for iterating over Headers
+ https://bugs.webkit.org/show_bug.cgi?id=153787
+
+ Reviewed by Darin Adler.
+
+ Relanding, updating bindings/js/JSKeyValueIterator.h for Windows bots.
+
+ Covered by updated tests.
+ Introducing template class (JSKeyValueIterator) to support key-value iterators in DOM classes.
+ Using JSKeyValueIterator to implement Headers entries(), keys() and values() as custom methods.
+ Binding generator should be updated to generate directly these custom methods and handle iterator Symbol.
+
+ * CMakeLists.txt:
+ * Modules/fetch/FetchHeaders.cpp:
+ (WebCore::FetchHeaders::Iterator::next):
+ (WebCore::FetchHeaders::Iterator::Iterator):
+ * Modules/fetch/FetchHeaders.h:
+ (WebCore::FetchHeaders::createIterator):
+ * Modules/fetch/FetchHeaders.idl:
+ * WebCore.xcodeproj/project.pbxproj:
+ * bindings/js/JSBindingsAllInOne.cpp:
+ * bindings/js/JSDOMBinding.h:
+ (WebCore::jsPair):
+ * bindings/js/JSFetchHeadersCustom.cpp: Added.
+ (WebCore::JSFetchHeaders::entries):
+ (WebCore::JSFetchHeaders::keys):
+ (WebCore::JSFetchHeaders::values):
+ * bindings/js/JSKeyValueIterator.h: Added.
+ (WebCore::JSKeyValueIteratorPrototype::create):
+ (WebCore::JSKeyValueIteratorPrototype::createStructure):
+ (WebCore::JSKeyValueIteratorPrototype::JSKeyValueIteratorPrototype):
+ (WebCore::createIterator):
+ (WebCore::DOMWrapped>::destroy):
+ (WebCore::DOMWrapped>::next):
+ (WebCore::DOMWrapped>::finishCreation):
+
2016-02-04 Chris Dumez <cdu...@apple.com>
Merge DOMTokenList and DOMSettableTokenList
Modified: trunk/Source/WebCore/Modules/fetch/FetchHeaders.cpp (196127 => 196128)
--- trunk/Source/WebCore/Modules/fetch/FetchHeaders.cpp 2016-02-04 17:39:11 UTC (rev 196127)
+++ trunk/Source/WebCore/Modules/fetch/FetchHeaders.cpp 2016-02-04 17:43:05 UTC (rev 196128)
@@ -179,6 +179,31 @@
}
}
+bool FetchHeaders::Iterator::next(String& nextKey, String& nextValue)
+{
+ while (m_currentIndex < m_keys.size()) {
+ auto& key = m_keys[m_currentIndex++];
+ String value = m_headers->m_headers.get(key);
+ if (!value.isNull()) {
+ nextKey = key;
+ nextValue = WTFMove(value);
+ return false;
+ }
+ }
+ m_keys.clear();
+ return true;
+}
+
+FetchHeaders::Iterator::Iterator(FetchHeaders& headers)
+ : m_headers(headers)
+{
+ m_keys.reserveInitialCapacity(headers.m_headers.size());
+ for (auto& header : headers.m_headers)
+ m_keys.uncheckedAppend(header.key.convertToASCIILowercase());
+
+ std::sort(m_keys.begin(), m_keys.end(), WTF::codePointCompareLessThan);
+}
+
} // namespace WebCore
#endif // ENABLE(FETCH_API)
Modified: trunk/Source/WebCore/Modules/fetch/FetchHeaders.h (196127 => 196128)
--- trunk/Source/WebCore/Modules/fetch/FetchHeaders.h 2016-02-04 17:39:11 UTC (rev 196127)
+++ trunk/Source/WebCore/Modules/fetch/FetchHeaders.h 2016-02-04 17:43:05 UTC (rev 196128)
@@ -62,6 +62,23 @@
String fastGet(HTTPHeaderName name) const { return m_headers.get(name); }
void fastSet(HTTPHeaderName name, const String& value) { m_headers.set(name, value); }
+ class Iterator {
+ public:
+ explicit Iterator(FetchHeaders&);
+
+ // FIXME: Binding generator should be able to generate iterator key and value types.
+ using Key = String;
+ using Value = String;
+
+ bool next(String& nextKey, String& nextValue);
+
+ private:
+ Ref<FetchHeaders> m_headers;
+ size_t m_currentIndex = 0;
+ Vector<String> m_keys;
+ };
+ Iterator createIterator() { return Iterator(*this); }
+
private:
FetchHeaders(Guard guard) : m_guard(guard) { }
FetchHeaders(Guard guard, const HTTPHeaderMap& headers) : m_guard(guard), m_headers(headers) { }
Modified: trunk/Source/WebCore/Modules/fetch/FetchHeaders.idl (196127 => 196128)
--- trunk/Source/WebCore/Modules/fetch/FetchHeaders.idl 2016-02-04 17:39:11 UTC (rev 196127)
+++ trunk/Source/WebCore/Modules/fetch/FetchHeaders.idl 2016-02-04 17:43:05 UTC (rev 196128)
@@ -40,8 +40,11 @@
[RaisesException] boolean has(DOMString name);
[RaisesException] void set(DOMString name, DOMString value);
- // FIXME: Support iterable.
+ // FIXME: Support iterable within binding generator.
//iterable<DOMString, DOMString>;
+ [Custom] any entries();
+ [Custom] any keys();
+ [Custom] any values();
[Private, RaisesException, ImplementedAs=append] void appendFromJS(DOMString name, DOMString value);
[Private, RaisesException] void initializeWith(FetchHeaders headers);
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (196127 => 196128)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2016-02-04 17:39:11 UTC (rev 196127)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2016-02-04 17:43:05 UTC (rev 196128)
@@ -1541,6 +1541,7 @@
41D015CB0F4B5C71004A662F /* ContentType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41D015C90F4B5C71004A662F /* ContentType.cpp */; };
41E1B1D00FF5986900576B3B /* AbstractWorker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41E1B1CA0FF5986900576B3B /* AbstractWorker.cpp */; };
41E1B1D10FF5986900576B3B /* AbstractWorker.h in Headers */ = {isa = PBXBuildFile; fileRef = 41E1B1CB0FF5986900576B3B /* AbstractWorker.h */; };
+ 41E910A71C60FD6C007A453F /* JSFetchHeadersCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41E910A61C60FD6C007A453F /* JSFetchHeadersCustom.cpp */; };
41F062140F5F192600A07EAC /* InspectorDatabaseResource.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F062120F5F192600A07EAC /* InspectorDatabaseResource.h */; };
41F062150F5F192600A07EAC /* InspectorDatabaseResource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41F062130F5F192600A07EAC /* InspectorDatabaseResource.cpp */; };
41F066E40F64BCF600A07EAC /* ScriptGlobalObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F066E20F64BCF600A07EAC /* ScriptGlobalObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -8964,6 +8965,7 @@
41E1B1CA0FF5986900576B3B /* AbstractWorker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AbstractWorker.cpp; sourceTree = "<group>"; };
41E1B1CB0FF5986900576B3B /* AbstractWorker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractWorker.h; sourceTree = "<group>"; };
41E1B1CC0FF5986900576B3B /* AbstractWorker.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AbstractWorker.idl; sourceTree = "<group>"; };
+ 41E910A61C60FD6C007A453F /* JSFetchHeadersCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFetchHeadersCustom.cpp; sourceTree = "<group>"; };
41F062120F5F192600A07EAC /* InspectorDatabaseResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorDatabaseResource.h; sourceTree = "<group>"; };
41F062130F5F192600A07EAC /* InspectorDatabaseResource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorDatabaseResource.cpp; sourceTree = "<group>"; };
41F066E20F64BCF600A07EAC /* ScriptGlobalObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptGlobalObject.h; sourceTree = "<group>"; };
@@ -22291,6 +22293,7 @@
BC2ED5540C6B9BD300920BFF /* JSElementCustom.cpp */,
ADEC78F718EE5308001315C2 /* JSElementCustom.h */,
BCEFAF4D0C317E6900FA81F6 /* JSEventCustom.cpp */,
+ 41E910A61C60FD6C007A453F /* JSFetchHeadersCustom.cpp */,
2E7582ED12764F260062628B /* JSFileReaderCustom.cpp */,
FE80D7A60E9C1ED2000D6F75 /* JSGeolocationCustom.cpp */,
BCE7B1920D4E86960075A539 /* JSHistoryCustom.cpp */,
@@ -29372,6 +29375,7 @@
97B38E28151C4273004622E9 /* DOMWindowNotifications.cpp in Sources */,
97D2AD0314B823A60093DF32 /* DOMWindowProperty.cpp in Sources */,
AA2A5AD716A4861A00975A25 /* DOMWindowSpeechSynthesis.cpp in Sources */,
+ 41E910A71C60FD6C007A453F /* JSFetchHeadersCustom.cpp in Sources */,
A8CCBB48151F831600AB7CE9 /* DOMWindowWebDatabase.cpp in Sources */,
BC53DA481143134D000D817E /* DOMWrapperWorld.cpp in Sources */,
1A1D13810A5325520064BF5F /* DOMXPath.mm in Sources */,
Modified: trunk/Source/WebCore/bindings/js/JSBindingsAllInOne.cpp (196127 => 196128)
--- trunk/Source/WebCore/bindings/js/JSBindingsAllInOne.cpp 2016-02-04 17:39:11 UTC (rev 196127)
+++ trunk/Source/WebCore/bindings/js/JSBindingsAllInOne.cpp 2016-02-04 17:43:05 UTC (rev 196128)
@@ -77,6 +77,7 @@
#include "JSEventListener.cpp"
#include "JSEventTargetCustom.cpp"
#include "JSExceptionBase.cpp"
+#include "JSFetchHeadersCustom.cpp"
#include "JSFileReaderCustom.cpp"
#include "JSGeolocationCustom.cpp"
#include "JSHTMLAllCollectionCustom.cpp"
Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.h (196127 => 196128)
--- trunk/Source/WebCore/bindings/js/JSDOMBinding.h 2016-02-04 17:39:11 UTC (rev 196127)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.h 2016-02-04 17:43:05 UTC (rev 196128)
@@ -514,6 +514,14 @@
return jsArray(exec, globalObject, *vector);
}
+template<typename Value1, typename Value2> inline JSC::JSValue jsPair(JSC::ExecState& state, JSDOMGlobalObject* globalObject, const Value1& value1, const Value2& value2)
+{
+ JSC::MarkedArgumentBuffer args;
+ args.append(toJS(&state, globalObject, value1));
+ args.append(toJS(&state, globalObject, value2));
+ return constructArray(&state, 0, globalObject, args);
+}
+
WEBCORE_EXPORT JSC::JSValue jsArray(JSC::ExecState*, JSDOMGlobalObject*, PassRefPtr<DOMStringList>);
inline PassRefPtr<JSC::ArrayBufferView> toArrayBufferView(JSC::JSValue value)
Copied: trunk/Source/WebCore/bindings/js/JSFetchHeadersCustom.cpp (from rev 196126, trunk/Source/WebCore/Modules/fetch/FetchHeaders.idl) (0 => 196128)
--- trunk/Source/WebCore/bindings/js/JSFetchHeadersCustom.cpp (rev 0)
+++ trunk/Source/WebCore/bindings/js/JSFetchHeadersCustom.cpp 2016-02-04 17:43:05 UTC (rev 196128)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2016 Canon Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted, provided that the following conditions
+ * are required to be 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.
+ * 3. Neither the name of Canon Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CANON 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 CANON INC. AND 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 "JSFetchHeaders.h"
+
+#if ENABLE(FETCH_API)
+
+#include "JSKeyValueIterator.h"
+
+namespace WebCore {
+
+// FIXME: Move this code to JSFetchHeaders.
+using FetchHeadersIterator = JSKeyValueIterator<JSFetchHeaders, FetchHeaders>;
+using FetchHeadersIteratorPrototype = JSKeyValueIteratorPrototype<JSFetchHeaders, FetchHeaders>;
+
+template<>
+const JSC::ClassInfo FetchHeadersIterator::s_info = { "Headers Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(FetchHeadersIterator) };
+
+template<>
+const JSC::ClassInfo FetchHeadersIteratorPrototype::s_info = { "Headers Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(FetchHeadersIteratorPrototype) };
+
+JSC::JSValue JSFetchHeaders::entries(JSC::ExecState&)
+{
+ return createIterator<JSFetchHeaders, FetchHeaders>(*globalObject(), *this, IterationKind::KeyValue);
+}
+
+JSC::JSValue JSFetchHeaders::keys(JSC::ExecState&)
+{
+ return createIterator<JSFetchHeaders, FetchHeaders>(*globalObject(), *this, IterationKind::Key);
+}
+
+JSC::JSValue JSFetchHeaders::values(JSC::ExecState&)
+{
+ return createIterator<JSFetchHeaders, FetchHeaders>(*globalObject(), *this, IterationKind::Value);
+}
+
+}
+
+#endif
Added: trunk/Source/WebCore/bindings/js/JSKeyValueIterator.h (0 => 196128)
--- trunk/Source/WebCore/bindings/js/JSKeyValueIterator.h (rev 0)
+++ trunk/Source/WebCore/bindings/js/JSKeyValueIterator.h 2016-02-04 17:43:05 UTC (rev 196128)
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2016 Canon, 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 CANON INC. ``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 CANON INC. OR
+ * 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 JSKeyValueIterator_h
+#define JSKeyValueIterator_h
+
+#include "JSDOMBinding.h"
+#include <runtime/JSDestructibleObject.h>
+
+namespace WebCore {
+
+// FIXME: Update binding generator to allow getting DOMWrapped from JSWrapper.
+template<typename JSWrapper, typename DOMWrapped>
+class JSKeyValueIteratorPrototype : public JSC::JSNonFinalObject {
+public:
+ typedef JSC::JSNonFinalObject Base;
+
+ static JSKeyValueIteratorPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
+ {
+ JSKeyValueIteratorPrototype* prototype = new (NotNull, JSC::allocateCell<JSKeyValueIteratorPrototype>(vm.heap)) JSKeyValueIteratorPrototype(vm, structure);
+ prototype->finishCreation(vm, globalObject);
+ return prototype;
+ }
+
+ DECLARE_INFO;
+
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+ }
+
+ static JSC::EncodedJSValue JSC_HOST_CALL next(JSC::ExecState*);
+
+private:
+ JSKeyValueIteratorPrototype(JSC::VM& vm, JSC::Structure* structure) : Base(vm, structure) { }
+
+ void finishCreation(JSC::VM&, JSC::JSGlobalObject*);
+};
+
+enum class IterationKind { Key, Value, KeyValue };
+
+template<typename JSWrapper, typename DOMWrapped>
+class JSKeyValueIterator: public JSDOMObject {
+public:
+ typedef JSDOMObject Base;
+
+ DECLARE_INFO;
+
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+ }
+
+ static JSKeyValueIterator* create(JSC::VM& vm, JSC::Structure* structure, JSWrapper& iteratedObject, IterationKind kind)
+ {
+ JSKeyValueIterator* instance = new (NotNull, JSC::allocateCell<JSKeyValueIterator>(vm.heap)) JSKeyValueIterator(structure, iteratedObject, kind);
+ instance->finishCreation(vm);
+ return instance;
+ }
+
+ static JSKeyValueIteratorPrototype<JSWrapper, DOMWrapped>* createPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
+ {
+ return JSKeyValueIteratorPrototype<JSWrapper, DOMWrapped>::create(vm, globalObject,
+ JSKeyValueIteratorPrototype<JSWrapper, DOMWrapped>::createStructure(vm, globalObject, globalObject->objectPrototype()));
+ }
+
+ bool next(JSC::ExecState&, JSC::JSValue&);
+
+private:
+ JSKeyValueIterator(JSC::Structure* structure, JSWrapper& iteratedObject, IterationKind kind)
+ : Base(structure, *iteratedObject.globalObject())
+ , m_iterator(iteratedObject.wrapped().createIterator())
+ , m_kind(kind)
+ {
+ }
+
+ static void destroy(JSC::JSCell*);
+
+ typename DOMWrapped::Iterator m_iterator;
+ IterationKind m_kind;
+};
+
+template<typename JSWrapper, typename DOMWrapped>
+JSKeyValueIterator<JSWrapper, DOMWrapped>* createIterator(JSDOMGlobalObject& globalObject, JSWrapper& wrapper, IterationKind kind)
+{
+ return JSKeyValueIterator<JSWrapper, DOMWrapped>::create(globalObject.vm(), getDOMStructure<JSKeyValueIterator<JSWrapper, DOMWrapped>>(globalObject.vm(), globalObject), wrapper, kind);
+}
+
+template<typename JSWrapper, typename DOMWrapped>
+void JSKeyValueIterator<JSWrapper, DOMWrapped>::destroy(JSCell* cell)
+{
+ JSKeyValueIterator<JSWrapper, DOMWrapped>* thisObject = JSC::jsCast<JSKeyValueIterator<JSWrapper, DOMWrapped>*>(cell);
+ thisObject->JSKeyValueIterator<JSWrapper, DOMWrapped>::~JSKeyValueIterator();
+}
+
+template<typename JSWrapper, typename DOMWrapped>
+bool JSKeyValueIterator<JSWrapper, DOMWrapped>::next(JSC::ExecState& state, JSC::JSValue& value)
+{
+ typename DOMWrapped::Iterator::Key nextKey;
+ typename DOMWrapped::Iterator::Value nextValue;
+ if (m_iterator.next(nextKey, nextValue)) {
+ value = JSC::jsUndefined();
+ return true;
+ }
+ if (m_kind == IterationKind::Value)
+ value = toJS(&state, globalObject(), nextValue);
+ else if (m_kind == IterationKind::Key)
+ value = toJS(&state, globalObject(), nextKey);
+ else
+ value = jsPair(state, globalObject(), nextKey, nextValue);
+ return false;
+}
+
+template<typename JSWrapper, typename DOMWrapped>
+JSC::EncodedJSValue JSC_HOST_CALL JSKeyValueIteratorPrototype<JSWrapper, DOMWrapped>::next(JSC::ExecState* state)
+{
+ JSKeyValueIterator<JSWrapper, DOMWrapped>* iterator = JSC::jsDynamicCast<JSKeyValueIterator<JSWrapper, DOMWrapped>*>(state->thisValue());
+ if (!iterator)
+ return JSC::JSValue::encode(throwTypeError(state, ASCIILiteral("Cannot call next() on a non-Iterator object")));
+
+ JSC::JSValue result;
+ bool isDone = iterator->next(*state, result);
+ return JSC::JSValue::encode(createIteratorResultObject(state, result, isDone));
+}
+
+template<typename JSWrapper, typename DOMWrapped>
+void JSKeyValueIteratorPrototype<JSWrapper, DOMWrapped>::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
+{
+ Base::finishCreation(vm);
+ ASSERT(inherits(info()));
+
+ JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->next, next, JSC::DontEnum, 0, JSC::NoIntrinsic);
+}
+
+}
+
+#endif // !defined(JSKeyValueIterator_h)