Changeset 196115 in webkit


Ignore:
Timestamp:
Feb 4, 2016 2:39:37 AM (8 years ago)
Author:
youenn.fablet@crf.canon.fr
Message:

[Fetch API] Add support for iterating over Headers
https://bugs.webkit.org/show_bug.cgi?id=153787

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

  • 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: fixed typo in test.

Source/WebCore:

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/JSDOMBinding.h:

(WebCore::jsPair):

  • bindings/js/JSBindingsAllInOne.cpp:
  • 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::JSKeyValueIteratorPrototypeFuncNext):

Location:
trunk
Files:
1 added
15 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r196091 r196115  
     12016-02-04  Youenn Fablet  <youenn.fablet@crf.canon.fr>
     2
     3        [Fetch API] Add support for iterating over Headers
     4        https://bugs.webkit.org/show_bug.cgi?id=153787
     5
     6        Reviewed by Darin Adler.
     7
     8        * web-platform-tests/fetch/api/headers/headers-basic-expected.txt:
     9        * web-platform-tests/fetch/api/headers/headers-basic.html:
     10        * web-platform-tests/fetch/api/headers/headers-structure-expected.txt:
     11        * web-platform-tests/fetch/api/request/request-clone.sub-expected.txt:
     12        * web-platform-tests/fetch/api/request/request-init-003.sub-expected.txt:
     13        * web-platform-tests/fetch/api/resources/utils.js: fixed typo in test.
     14
    1152016-02-03  Chris Dumez  <cdumez@apple.com>
    216
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/headers/headers-basic-expected.txt

    r195530 r196115  
    1313PASS Check delete method
    1414PASS Check get method
     15PASS Check keys method
     16PASS Check values method
     17PASS Check entries method
    1518
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/headers/headers-basic.html

    r195954 r196115  
    112112        assert_equals(headers.get("nameNotInHeaders"), null, "header: nameNotInHeaders has no value");
    113113      }, "Check get method");
    114     </script>
     114
     115      var headerEntriesDict = {"name1": "value1",
     116                               "Name2": "value2",
     117                               "name": "value3",
     118                               "content-Type": "value4",
     119                               "Content-Typ": "value5",
     120                               "Content-Types": "value6"
     121      };
     122      var sortedHeaderDict = {};
     123      var sortedHeaderKeys = Object.keys(headerEntriesDict).map(function(value) {
     124        sortedHeaderDict[value.toLowerCase()] = headerEntriesDict[value];
     125        return value.toLowerCase();
     126      }).sort();
     127
     128      test(function() {
     129        var headers = new Headers(headerEntriesDict);
     130        var actual = headers.keys();
     131        sortedHeaderKeys.forEach(function(key) {
     132            entry = actual.next();
     133            assert_false(entry.done);
     134            assert_equals(entry.value, key);
     135        });
     136        assert_true(actual.next().done);
     137        assert_true(actual.next().done);
     138      }, "Check keys method");
     139
     140      test(function() {
     141        var headers = new Headers(headerEntriesDict);
     142        var actual = headers.values();
     143
     144        sortedHeaderKeys.forEach(function(key) {
     145            entry = actual.next();
     146            assert_false(entry.done);
     147            assert_equals(entry.value, sortedHeaderDict[key]);
     148        });
     149        assert_true(actual.next().done);
     150        assert_true(actual.next().done);
     151      }, "Check values method");
     152
     153      test(function() {
     154        var headers = new Headers(headerEntriesDict);
     155        var actual = headers.entries();
     156
     157        sortedHeaderKeys.forEach(function(key) {
     158            entry = actual.next();
     159            assert_false(entry.done);
     160            assert_equals(entry.value[0], key);
     161            assert_equals(entry.value[1], sortedHeaderDict[key]);
     162        });
     163        assert_true(actual.next().done);
     164        assert_true(actual.next().done);
     165      }, "Check entries method");
     166   </script>
    115167  </body>
    116168</html>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/headers/headers-structure-expected.txt

    r195530 r196115  
    55PASS Headers has has method
    66PASS Headers has set method
    7 FAIL Headers has entries method assert_true: headers has entries method expected true got false
    8 FAIL Headers has keys method assert_true: headers has keys method expected true got false
    9 FAIL Headers has values method assert_true: headers has values method expected true got false
     7PASS Headers has entries method
     8PASS Headers has keys method
     9PASS Headers has values method
    1010
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-clone.sub-expected.txt

    r195954 r196115  
    11
    2 FAIL Check cloning a request ExpectedValuesDict["headers"].keys is not a function. (In 'ExpectedValuesDict["headers"].keys()', 'ExpectedValuesDict["headers"].keys' is undefined)
     2PASS Check cloning a request
    33PASS Check cloning a request copies the headers
    44
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-init-003.sub-expected.txt

    r195954 r196115  
    11
    2 FAIL Check request values when initialized from Request ExpectedValuesDict["headers"].keys is not a function. (In 'ExpectedValuesDict["headers"].keys()', 'ExpectedValuesDict["headers"].keys' is undefined)
    3 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)
     2PASS Check request values when initialized from Request
     3PASS Check request values when initialized from Request and init values
    44FAIL 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"
    5 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)
     5FAIL 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"
    66
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/resources/utils.js

    r195954 r196115  
    1616    switch(attribute) {
    1717      case "headers":
    18           for (var key of ExpectedValuesDict["headers"].keys())
     18          for (var key in ExpectedValuesDict["headers"].keys())
    1919            assert_equals(request["headers"].get(key), ExpectedValuesDict["headers"].get(key),
    2020              "Check headers attribute has " + key + ":" + ExpectedValuesDict["headers"].get(key));
  • trunk/Source/WebCore/CMakeLists.txt

    r196031 r196115  
    11651165    bindings/js/JSEventTargetCustom.cpp
    11661166    bindings/js/JSExceptionBase.cpp
     1167    bindings/js/JSFetchHeadersCustom.cpp
    11671168    bindings/js/JSFileReaderCustom.cpp
    11681169    bindings/js/JSGeolocationCustom.cpp
  • trunk/Source/WebCore/ChangeLog

    r196112 r196115  
     12016-02-04  Youenn Fablet  <youenn.fablet@crf.canon.fr>
     2
     3        [Fetch API] Add support for iterating over Headers
     4        https://bugs.webkit.org/show_bug.cgi?id=153787
     5
     6        Reviewed by Darin Adler.
     7
     8        Covered by updated tests.
     9        Introducing template class (JSKeyValueIterator) to support key-value iterators in DOM classes.
     10        Using JSKeyValueIterator to implement Headers entries(), keys() and values() as custom methods.
     11        Binding generator should be updated to generate directly these custom methods and handle iterator Symbol.
     12
     13        * CMakeLists.txt:
     14        * Modules/fetch/FetchHeaders.cpp:
     15        (WebCore::FetchHeaders::Iterator::next):
     16        (WebCore::FetchHeaders::Iterator::Iterator):
     17        * Modules/fetch/FetchHeaders.h:
     18        (WebCore::FetchHeaders::createIterator):
     19        * Modules/fetch/FetchHeaders.idl:
     20        * WebCore.xcodeproj/project.pbxproj:
     21        * bindings/js/JSDOMBinding.h:
     22        (WebCore::jsPair):
     23        * bindings/js/JSBindingsAllInOne.cpp:
     24        * bindings/js/JSFetchHeadersCustom.cpp: Added.
     25        (WebCore::JSFetchHeaders::entries):
     26        (WebCore::JSFetchHeaders::keys):
     27        (WebCore::JSFetchHeaders::values):
     28        * bindings/js/JSKeyValueIterator.h: Added.
     29        (WebCore::JSKeyValueIteratorPrototype::create):
     30        (WebCore::JSKeyValueIteratorPrototype::createStructure):
     31        (WebCore::JSKeyValueIteratorPrototype::JSKeyValueIteratorPrototype):
     32        (WebCore::JSKeyValueIteratorPrototypeFuncNext):
     33
    1342016-02-03  Carlos Garcia Campos  <cgarcia@igalia.com>
    235
  • trunk/Source/WebCore/Modules/fetch/FetchHeaders.cpp

    r195954 r196115  
    180180}
    181181
     182bool FetchHeaders::Iterator::next(String& nextKey, String& nextValue)
     183{
     184    while (m_currentIndex < m_keys.size()) {
     185        auto& key = m_keys[m_currentIndex++];
     186        String value = m_headers->m_headers.get(key);
     187        if (!value.isNull()) {
     188            nextKey = key;
     189            nextValue = WTFMove(value);
     190            return false;
     191        }
     192    }
     193    m_keys.clear();
     194    return true;
     195}
     196
     197FetchHeaders::Iterator::Iterator(FetchHeaders& headers)
     198    : m_headers(headers)
     199{
     200    m_keys.reserveInitialCapacity(headers.m_headers.size());
     201    for (auto& header : headers.m_headers)
     202        m_keys.uncheckedAppend(header.key.convertToASCIILowercase());
     203
     204    std::sort(m_keys.begin(), m_keys.end(), WTF::codePointCompareLessThan);
     205}
     206
    182207} // namespace WebCore
    183208
  • trunk/Source/WebCore/Modules/fetch/FetchHeaders.h

    r195954 r196115  
    6363    void fastSet(HTTPHeaderName name, const String& value) { m_headers.set(name, value); }
    6464
     65    class Iterator {
     66    public:
     67        explicit Iterator(FetchHeaders&);
     68
     69        // FIXME: Binding generator should be able to generate iterator key and value types.
     70        using Key = String;
     71        using Value = String;
     72
     73        bool next(String& nextKey, String& nextValue);
     74
     75    private:
     76        Ref<FetchHeaders> m_headers;
     77        size_t m_currentIndex = 0;
     78        Vector<String> m_keys;
     79    };
     80    Iterator createIterator() { return Iterator(*this); }
     81
    6582private:
    6683    FetchHeaders(Guard guard) : m_guard(guard) { }
  • trunk/Source/WebCore/Modules/fetch/FetchHeaders.idl

    r195530 r196115  
    4141    [RaisesException] void set(DOMString name, DOMString value);
    4242
    43     // FIXME: Support iterable.
     43    // FIXME: Support iterable within binding generator.
    4444    //iterable<DOMString, DOMString>;
     45    [Custom] any entries();
     46    [Custom] any keys();
     47    [Custom] any values();
    4548
    4649    [Private, RaisesException, ImplementedAs=append] void appendFromJS(DOMString name, DOMString value);
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r196082 r196115  
    15421542                41E1B1D00FF5986900576B3B /* AbstractWorker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41E1B1CA0FF5986900576B3B /* AbstractWorker.cpp */; };
    15431543                41E1B1D10FF5986900576B3B /* AbstractWorker.h in Headers */ = {isa = PBXBuildFile; fileRef = 41E1B1CB0FF5986900576B3B /* AbstractWorker.h */; };
     1544                41E910A71C60FD6C007A453F /* JSFetchHeadersCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41E910A61C60FD6C007A453F /* JSFetchHeadersCustom.cpp */; };
    15441545                41F062140F5F192600A07EAC /* InspectorDatabaseResource.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F062120F5F192600A07EAC /* InspectorDatabaseResource.h */; };
    15451546                41F062150F5F192600A07EAC /* InspectorDatabaseResource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41F062130F5F192600A07EAC /* InspectorDatabaseResource.cpp */; };
     
    89688969                41E1B1CB0FF5986900576B3B /* AbstractWorker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractWorker.h; sourceTree = "<group>"; };
    89698970                41E1B1CC0FF5986900576B3B /* AbstractWorker.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AbstractWorker.idl; sourceTree = "<group>"; };
     8971                41E910A61C60FD6C007A453F /* JSFetchHeadersCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFetchHeadersCustom.cpp; sourceTree = "<group>"; };
    89708972                41F062120F5F192600A07EAC /* InspectorDatabaseResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorDatabaseResource.h; sourceTree = "<group>"; };
    89718973                41F062130F5F192600A07EAC /* InspectorDatabaseResource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorDatabaseResource.cpp; sourceTree = "<group>"; };
     
    2230122303                                ADEC78F718EE5308001315C2 /* JSElementCustom.h */,
    2230222304                                BCEFAF4D0C317E6900FA81F6 /* JSEventCustom.cpp */,
     22305                                41E910A61C60FD6C007A453F /* JSFetchHeadersCustom.cpp */,
    2230322306                                2E7582ED12764F260062628B /* JSFileReaderCustom.cpp */,
    2230422307                                FE80D7A60E9C1ED2000D6F75 /* JSGeolocationCustom.cpp */,
     
    2938429387                                97D2AD0314B823A60093DF32 /* DOMWindowProperty.cpp in Sources */,
    2938529388                                AA2A5AD716A4861A00975A25 /* DOMWindowSpeechSynthesis.cpp in Sources */,
     29389                                41E910A71C60FD6C007A453F /* JSFetchHeadersCustom.cpp in Sources */,
    2938629390                                A8CCBB48151F831600AB7CE9 /* DOMWindowWebDatabase.cpp in Sources */,
    2938729391                                BC53DA481143134D000D817E /* DOMWrapperWorld.cpp in Sources */,
  • trunk/Source/WebCore/bindings/js/JSBindingsAllInOne.cpp

    r195520 r196115  
    7878#include "JSEventTargetCustom.cpp"
    7979#include "JSExceptionBase.cpp"
     80#include "JSFetchHeaderCustom.cpp"
    8081#include "JSFileReaderCustom.cpp"
    8182#include "JSGeolocationCustom.cpp"
  • trunk/Source/WebCore/bindings/js/JSDOMBinding.h

    r194625 r196115  
    515515}
    516516
     517template<typename Value1, typename Value2> inline JSC::JSValue jsPair(JSC::ExecState& state, JSDOMGlobalObject* globalObject, const Value1& value1, const Value2& value2)
     518{
     519    JSC::MarkedArgumentBuffer args;
     520    args.append(toJS(&state, globalObject, value1));
     521    args.append(toJS(&state, globalObject, value2));
     522    return constructArray(&state, 0, globalObject, args);
     523}
     524
    517525WEBCORE_EXPORT JSC::JSValue jsArray(JSC::ExecState*, JSDOMGlobalObject*, PassRefPtr<DOMStringList>);
    518526
  • trunk/Source/WebCore/bindings/js/JSFetchHeadersCustom.cpp

    r196114 r196115  
    2727 */
    2828
    29 [
    30     Conditional=FETCH_API,
    31     GlobalContext=DOMWindow&WorkerGlobalScope,
    32     ImplementationLacksVTable,
    33     InterfaceName=Headers,
    34     JSBuiltinConstructor
    35 ]
    36 interface FetchHeaders {
    37     [RaisesException] void append(DOMString name, DOMString value);
    38     [RaisesException, ImplementedAs=remove] void delete(DOMString name);
    39     [RaisesException, TreatReturnedNullStringAs=Null] DOMString get(DOMString name);
    40     [RaisesException] boolean has(DOMString name);
    41     [RaisesException] void set(DOMString name, DOMString value);
     29#include "config.h"
     30#include "JSFetchHeaders.h"
    4231
    43     // FIXME: Support iterable.
    44     //iterable<DOMString, DOMString>;
     32#include "JSKeyValueIterator.h"
    4533
    46     [Private, RaisesException, ImplementedAs=append] void appendFromJS(DOMString name, DOMString value);
    47     [Private, RaisesException] void initializeWith(FetchHeaders headers);
    48 };
     34namespace WebCore {
     35
     36// FIXME: Move that code to JSFetchHeaders.
     37using FetchHeadersIterator = JSKeyValueIterator<JSFetchHeaders, FetchHeaders>;
     38using FetchHeadersIteratorPrototype = JSKeyValueIteratorPrototype<JSFetchHeaders, FetchHeaders>;
     39
     40template<>
     41const JSC::ClassInfo FetchHeadersIterator::s_info = { "Headers Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(FetchHeadersIterator) };
     42
     43template<>
     44const JSC::ClassInfo FetchHeadersIteratorPrototype::s_info = { "Headers Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(FetchHeadersIteratorPrototype) };
     45
     46JSC::JSValue JSFetchHeaders::entries(JSC::ExecState&)
     47{
     48    return createIterator<JSFetchHeaders, FetchHeaders>(*globalObject(), *this, IterationKind::KeyValue);
     49}
     50
     51JSC::JSValue JSFetchHeaders::keys(JSC::ExecState&)
     52{
     53    return createIterator<JSFetchHeaders, FetchHeaders>(*globalObject(), *this, IterationKind::Key);
     54}
     55
     56JSC::JSValue JSFetchHeaders::values(JSC::ExecState&)
     57{
     58    return createIterator<JSFetchHeaders, FetchHeaders>(*globalObject(), *this, IterationKind::Value);
     59}
     60
     61}
Note: See TracChangeset for help on using the changeset viewer.