Changeset 196128 in webkit


Ignore:
Timestamp:
Feb 4, 2016 9:43:05 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:

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):

Source/WebCore:

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):

Location:
trunk
Files:
1 added
15 edited
1 copied

Legend:

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

    r196123 r196128  
     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        Relanding.
     9
     10        * web-platform-tests/fetch/api/headers/headers-basic-expected.txt:
     11        * web-platform-tests/fetch/api/headers/headers-basic.html:
     12        * web-platform-tests/fetch/api/headers/headers-structure-expected.txt:
     13        * web-platform-tests/fetch/api/request/request-clone.sub-expected.txt:
     14        * web-platform-tests/fetch/api/request/request-init-003.sub-expected.txt:
     15        * web-platform-tests/fetch/api/resources/utils.js:
     16        (checkRequest):
     17        (readTextStream):
     18
    1192016-02-04  Chris Dumez  <cdumez@apple.com>
    220
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/headers/headers-basic-expected.txt

    r196118 r196128  
    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

    r196118 r196128  
    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

    r196118 r196128  
    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

    r196118 r196128  
    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

    r196118 r196128  
    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

    r196118 r196128  
    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

    r196123 r196128  
    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

    r196123 r196128  
     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        Relanding, updating bindings/js/JSKeyValueIterator.h for Windows bots.
     9
     10        Covered by updated tests.
     11        Introducing template class (JSKeyValueIterator) to support key-value iterators in DOM classes.
     12        Using JSKeyValueIterator to implement Headers entries(), keys() and values() as custom methods.
     13        Binding generator should be updated to generate directly these custom methods and handle iterator Symbol.
     14
     15        * CMakeLists.txt:
     16        * Modules/fetch/FetchHeaders.cpp:
     17        (WebCore::FetchHeaders::Iterator::next):
     18        (WebCore::FetchHeaders::Iterator::Iterator):
     19        * Modules/fetch/FetchHeaders.h:
     20        (WebCore::FetchHeaders::createIterator):
     21        * Modules/fetch/FetchHeaders.idl:
     22        * WebCore.xcodeproj/project.pbxproj:
     23        * bindings/js/JSBindingsAllInOne.cpp:
     24        * bindings/js/JSDOMBinding.h:
     25        (WebCore::jsPair):
     26        * bindings/js/JSFetchHeadersCustom.cpp: Added.
     27        (WebCore::JSFetchHeaders::entries):
     28        (WebCore::JSFetchHeaders::keys):
     29        (WebCore::JSFetchHeaders::values):
     30        * bindings/js/JSKeyValueIterator.h: Added.
     31        (WebCore::JSKeyValueIteratorPrototype::create):
     32        (WebCore::JSKeyValueIteratorPrototype::createStructure):
     33        (WebCore::JSKeyValueIteratorPrototype::JSKeyValueIteratorPrototype):
     34        (WebCore::createIterator):
     35        (WebCore::DOMWrapped>::destroy):
     36        (WebCore::DOMWrapped>::next):
     37        (WebCore::DOMWrapped>::finishCreation):
     38
    1392016-02-04  Chris Dumez  <cdumez@apple.com>
    240
  • trunk/Source/WebCore/Modules/fetch/FetchHeaders.cpp

    r196118 r196128  
    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

    r196118 r196128  
    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

    r196118 r196128  
    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

    r196123 r196128  
    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 */; };
     
    89658966                41E1B1CB0FF5986900576B3B /* AbstractWorker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractWorker.h; sourceTree = "<group>"; };
    89668967                41E1B1CC0FF5986900576B3B /* AbstractWorker.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AbstractWorker.idl; sourceTree = "<group>"; };
     8968                41E910A61C60FD6C007A453F /* JSFetchHeadersCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFetchHeadersCustom.cpp; sourceTree = "<group>"; };
    89678969                41F062120F5F192600A07EAC /* InspectorDatabaseResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorDatabaseResource.h; sourceTree = "<group>"; };
    89688970                41F062130F5F192600A07EAC /* InspectorDatabaseResource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorDatabaseResource.cpp; sourceTree = "<group>"; };
     
    2229222294                                ADEC78F718EE5308001315C2 /* JSElementCustom.h */,
    2229322295                                BCEFAF4D0C317E6900FA81F6 /* JSEventCustom.cpp */,
     22296                                41E910A61C60FD6C007A453F /* JSFetchHeadersCustom.cpp */,
    2229422297                                2E7582ED12764F260062628B /* JSFileReaderCustom.cpp */,
    2229522298                                FE80D7A60E9C1ED2000D6F75 /* JSGeolocationCustom.cpp */,
     
    2937329376                                97D2AD0314B823A60093DF32 /* DOMWindowProperty.cpp in Sources */,
    2937429377                                AA2A5AD716A4861A00975A25 /* DOMWindowSpeechSynthesis.cpp in Sources */,
     29378                                41E910A71C60FD6C007A453F /* JSFetchHeadersCustom.cpp in Sources */,
    2937529379                                A8CCBB48151F831600AB7CE9 /* DOMWindowWebDatabase.cpp in Sources */,
    2937629380                                BC53DA481143134D000D817E /* DOMWrapperWorld.cpp in Sources */,
  • trunk/Source/WebCore/bindings/js/JSBindingsAllInOne.cpp

    r196118 r196128  
    7878#include "JSEventTargetCustom.cpp"
    7979#include "JSExceptionBase.cpp"
     80#include "JSFetchHeadersCustom.cpp"
    8081#include "JSFileReaderCustom.cpp"
    8182#include "JSGeolocationCustom.cpp"
  • trunk/Source/WebCore/bindings/js/JSDOMBinding.h

    r196118 r196128  
    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

    r196126 r196128  
    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#if ENABLE(FETCH_API)
    4533
    46     [Private, RaisesException, ImplementedAs=append] void appendFromJS(DOMString name, DOMString value);
    47     [Private, RaisesException] void initializeWith(FetchHeaders headers);
    48 };
     34#include "JSKeyValueIterator.h"
     35
     36namespace WebCore {
     37
     38// FIXME: Move this code to JSFetchHeaders.
     39using FetchHeadersIterator = JSKeyValueIterator<JSFetchHeaders, FetchHeaders>;
     40using FetchHeadersIteratorPrototype = JSKeyValueIteratorPrototype<JSFetchHeaders, FetchHeaders>;
     41
     42template<>
     43const JSC::ClassInfo FetchHeadersIterator::s_info = { "Headers Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(FetchHeadersIterator) };
     44
     45template<>
     46const JSC::ClassInfo FetchHeadersIteratorPrototype::s_info = { "Headers Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(FetchHeadersIteratorPrototype) };
     47
     48JSC::JSValue JSFetchHeaders::entries(JSC::ExecState&)
     49{
     50    return createIterator<JSFetchHeaders, FetchHeaders>(*globalObject(), *this, IterationKind::KeyValue);
     51}
     52
     53JSC::JSValue JSFetchHeaders::keys(JSC::ExecState&)
     54{
     55    return createIterator<JSFetchHeaders, FetchHeaders>(*globalObject(), *this, IterationKind::Key);
     56}
     57
     58JSC::JSValue JSFetchHeaders::values(JSC::ExecState&)
     59{
     60    return createIterator<JSFetchHeaders, FetchHeaders>(*globalObject(), *this, IterationKind::Value);
     61}
     62
     63}
     64
     65#endif
Note: See TracChangeset for help on using the changeset viewer.