Changeset 200619 in webkit
- Timestamp:
- May 10, 2016 2:47:44 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r200618 r200619 1 2016-05-10 Youenn Fablet <youenn.fablet@crf.canon.fr> 2 3 NodeList should be iterable 4 https://bugs.webkit.org/show_bug.cgi?id=131443 5 <rdar://problem/25731519> 6 7 Reviewed by Darin Adler. 8 9 * fast/dom/domListEnumeration-expected.txt: 10 * fast/dom/nodeListIterator-expected.txt: Added. 11 * fast/dom/nodeListIterator.html: Added. 12 * fast/dom/script-tests/domListEnumeration.js: 13 * fast/text/font-face-set-javascript-expected.txt: 14 * fast/text/font-face-set-javascript.html: 15 1 16 2016-05-09 Sergio Villar Senin <svillar@igalia.com> 2 17 -
trunk/LayoutTests/fast/dom/domListEnumeration-expected.txt
r188809 r200619 6 6 7 7 [object NodeList] 8 PASS resultArray.length is 1 18 PASS resultArray.length is 15 9 9 PASS resultArray[0].i is '0' 10 10 PASS resultArray[0].item is nodeList.item(0) -
trunk/LayoutTests/fast/dom/script-tests/domListEnumeration.js
r188809 r200619 98 98 resultArray = iterateList(nodeList); 99 99 100 shouldBe("resultArray.length", "1 1");100 shouldBe("resultArray.length", "15"); 101 101 shouldBe("resultArray[0].i", "'0'"); 102 102 shouldBe("resultArray[0].item", "nodeList.item(0)"); -
trunk/LayoutTests/fast/text/font-face-set-javascript-expected.txt
r200583 r200619 4 4 PASS fontFaceSet.status is "loaded" 5 5 PASS item.done is false 6 PASS item.value is [fontFace1, fontFace1] 6 PASS item.value.length is 2 7 FAIL item.value[0] should be 0 (of type number). Was [object FontFace] (of type object). 8 PASS item.value[1] is fontFace1 7 9 PASS item.done is true 10 PASS item.value is undefined 8 11 PASS item.done is false 9 12 PASS item.value is fontFace1 -
trunk/LayoutTests/fast/text/font-face-set-javascript.html
r199216 r200619 24 24 var item = iterator.next(); 25 25 shouldBeFalse("item.done"); 26 shouldBe("item.value", "[fontFace1, fontFace1]"); 26 shouldBe("item.value.length", "2"); 27 shouldBe("item.value[0]", "0"); 28 shouldBe("item.value[1]", "fontFace1"); 27 29 item = iterator.next(); 28 30 shouldBeTrue("item.done"); 31 shouldBe("item.value", "undefined"); 29 32 30 33 iterator = fontFaceSet.keys(); -
trunk/Source/WebCore/ChangeLog
r200618 r200619 1 2016-05-10 Youenn Fablet <youenn.fablet@crf.canon.fr> 2 3 NodeList should be iterable 4 https://bugs.webkit.org/show_bug.cgi?id=131443 5 <rdar://problem/25731519> 6 7 Reviewed by Darin Adler. 8 9 Test: fast/dom/nodeListIterator.html 10 11 Updating JSKeyValueIterator to support map and set iterators, 12 depending on the signature of the result type of DOMClass::Iterator::next method. 13 Symbol.iterator method is made the same as values method for set iterators. 14 15 Adding support for NodeList. 16 Updating FontFaceSet to take benefit of that. 17 18 * bindings/js/JSDOMBinding.h: 19 (WebCore::jsPair):. 20 * bindings/js/JSKeyValueIterator.h: 21 (WebCore::IteratorInspector::decltype): IteratorInspector detects whether the iterator is a set or map iterator. 22 (WebCore::IteratorInspector::test): 23 (WebCore::fillForEachArgumentsWithIteratorValue): Specializing according set/map iterator. 24 (WebCore::iteratorValueToJS): Ditto. 25 (WebCore::keyValueIteratorForEach): 26 (WebCore::JSKeyValueIterator<JSWrapper>::next): 27 * bindings/scripts/CodeGeneratorJS.pm: 28 (GenerateImplementationIterableFunctions): Removed the line forbidding set iterators. 29 Making Symbol.iterator function equal to values for set iterators. 30 * bindings/scripts/test/JS/JSTestNode.cpp: Rebasing with set iterator functions. 31 * bindings/scripts/test/JS/JSTestObj.cpp: Rebasing according updated function names. 32 * bindings/scripts/test/TestNode.idl: Making TestNode set iterable. 33 * css/FontFaceSet.cpp: 34 (WebCore::FontFaceSet::Iterator::next): Refactoring to make it a set iterator. 35 * css/FontFaceSet.h: 36 * css/FontFaceSet.idl: 37 * dom/NodeList.h: Making NodeList iterable. 38 (WebCore::NodeList::Iterator::Iterator): 39 (WebCore::NodeList::Iterator::next): 40 (WebCore::NodeList::createIterator): 41 * dom/NodeList.idl: 42 1 43 2016-05-09 Sergio Villar Senin <svillar@igalia.com> 2 44 -
trunk/Source/WebCore/bindings/js/JSDOMBinding.h
r200583 r200619 267 267 WEBCORE_EXPORT JSC::JSValue jsArray(JSC::ExecState*, JSDOMGlobalObject*, PassRefPtr<DOMStringList>); 268 268 269 template<typename Value1, typename Value2> JSC::JSValue jsPair(JSC::ExecState&, JSDOMGlobalObject*, const Value1&, const Value2&); 269 JSC::JSValue jsPair(JSC::ExecState&, JSDOMGlobalObject*, JSC::JSValue, JSC::JSValue); 270 template<typename FirstType, typename SecondType> JSC::JSValue jsPair(JSC::ExecState&, JSDOMGlobalObject*, const FirstType&, const SecondType&); 270 271 271 272 RefPtr<JSC::ArrayBufferView> toArrayBufferView(JSC::JSValue); … … 636 637 } 637 638 638 template<typename Value1, typename Value2> inline JSC::JSValue jsPair(JSC::ExecState& state, JSDOMGlobalObject* globalObject, const Value1& value1, const Value2&value2)639 inline JSC::JSValue jsPair(JSC::ExecState& state, JSDOMGlobalObject* globalObject, JSC::JSValue value1, JSC::JSValue value2) 639 640 { 640 641 JSC::MarkedArgumentBuffer args; 641 args.append( toJS(&state, globalObject, value1));642 args.append( toJS(&state, globalObject, value2));642 args.append(value1); 643 args.append(value2); 643 644 return constructArray(&state, 0, globalObject, args); 645 } 646 647 template<typename FirstType, typename SecondType> inline JSC::JSValue jsPair(JSC::ExecState& state, JSDOMGlobalObject* globalObject, const FirstType& value1, const SecondType& value2) 648 { 649 return jsPair(state, globalObject, toJS(&state, globalObject, value1), toJS(&state, globalObject, value2)); 644 650 } 645 651 -
trunk/Source/WebCore/bindings/js/JSDOMIterator.h
r200546 r200619 61 61 }; 62 62 63 template<typename IteratorValue> 64 class IteratorInspector { 65 private: 66 template<typename T> static constexpr auto test(int) -> decltype(std::declval<T>()->key, std::declval<T>()->value, bool()) { return true; } 67 template<typename T> static constexpr bool test(...) { return false; } 68 public: 69 static constexpr bool isMap = test<IteratorValue>(0); 70 static constexpr bool isSet = !isMap; 71 }; 72 63 73 enum class IterationKind { Key, Value, KeyValue }; 64 74 … … 106 116 107 117 template<typename JSWrapper> 108 JSC::EncodedJSValue createKeyValueIterator(JSC::ExecState& state, IterationKind kind, const char* propertyName) 118 JSC::EncodedJSValue iteratorCreate(JSC::ExecState&, IterationKind, const char*); 119 template<typename JSWrapper> 120 JSC::EncodedJSValue iteratorForEach(JSC::ExecState&, const char*); 121 122 template<typename JSWrapper> 123 JSC::EncodedJSValue iteratorCreate(JSC::ExecState& state, IterationKind kind, const char* propertyName) 109 124 { 110 125 auto wrapper = JSC::jsDynamicCast<JSWrapper*>(state.thisValue()); … … 115 130 } 116 131 117 template<typename JSWrapper> 118 JSC::EncodedJSValue keyValueIteratorForEach(JSC::ExecState& state, const char* propertyName) 132 template<typename IteratorValue> typename std::enable_if<IteratorInspector<IteratorValue>::isMap, JSC::JSValue>::type 133 toJS(JSC::ExecState& state, JSDOMGlobalObject* globalObject, IteratorValue& value, IterationKind kind) 134 { 135 ASSERT(value); 136 if (kind != IterationKind::KeyValue) 137 return toJS(&state, globalObject, (kind == IterationKind::Key) ? value->key : value->value); 138 139 return jsPair(state, globalObject, value->key, value->value); 140 } 141 142 template<typename IteratorValue> typename std::enable_if<IteratorInspector<IteratorValue>::isSet, JSC::JSValue>::type 143 toJS(JSC::ExecState& state, JSDOMGlobalObject* globalObject, IteratorValue& value, IterationKind kind) 144 { 145 ASSERT(value); 146 JSC::JSValue result = toJS(&state, globalObject, *value); 147 if (kind != IterationKind::KeyValue) 148 return result; 149 150 // FIXME: first pair value should be the index of result. 151 return jsPair(state, globalObject, result, result); 152 } 153 154 template<typename IteratorValue> typename std::enable_if<IteratorInspector<IteratorValue>::isMap, void>::type 155 appendForEachArguments(JSC::ExecState& state, JSDOMGlobalObject* globalObject, JSC::MarkedArgumentBuffer& arguments, IteratorValue& value) 156 { 157 ASSERT(value); 158 arguments.append(toJS(&state, globalObject, value->value)); 159 arguments.append(toJS(&state, globalObject, value->key)); 160 } 161 162 template<typename IteratorValue> typename std::enable_if<IteratorInspector<IteratorValue>::isSet, void>::type 163 appendForEachArguments(JSC::ExecState& state, JSDOMGlobalObject* globalObject, JSC::MarkedArgumentBuffer& arguments, IteratorValue& value) 164 { 165 ASSERT(value); 166 JSC::JSValue argument = toJS(&state, globalObject, *value); 167 arguments.append(argument); 168 arguments.append(argument); 169 } 170 171 template<typename JSWrapper> 172 JSC::EncodedJSValue iteratorForEach(JSC::ExecState& state, const char* propertyName) 119 173 { 120 174 auto wrapper = JSC::jsDynamicCast<JSWrapper*>(state.thisValue()); … … 130 184 while (auto value = iterator.next()) { 131 185 JSC::MarkedArgumentBuffer arguments; 132 arguments.append(toJS(&state, wrapper->globalObject(), value.value().value)); 133 arguments.append(toJS(&state, wrapper->globalObject(), value.value().key)); 186 appendForEachArguments(state, wrapper->globalObject(), arguments, value); 134 187 arguments.append(wrapper); 135 188 JSC::call(&state, state.argument(0), callType, callData, wrapper, arguments); … … 153 206 if (!iteratorValue) 154 207 return createIteratorResultObject(&state, JSC::jsUndefined(), true); 155 156 JSC::JSValue value; 157 if (m_kind == IterationKind::Value) 158 value = toJS(&state, globalObject(), iteratorValue.value().value); 159 else if (m_kind == IterationKind::Key) 160 value = toJS(&state, globalObject(), iteratorValue.value().key); 161 else 162 value = jsPair(state, globalObject(), iteratorValue.value().key, iteratorValue.value().value); 163 164 return createIteratorResultObject(&state, value, false); 208 return createIteratorResultObject(&state, toJS(state, globalObject(), iteratorValue, m_kind), false); 165 209 } 166 210 -
trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
r200607 r200619 4209 4209 my $interface = shift; 4210 4210 4211 if (not $interface->iterable->isKeyValue) {4212 die "No support yet for set iterators";4213 }4214 4215 4211 my $interfaceName = $interface->name; 4216 4212 my $className = "JS$interfaceName"; … … 4239 4235 $iterationKind = "Key" if $propertyName eq "keys"; 4240 4236 $iterationKind = "Value" if $propertyName eq "values"; 4237 $iterationKind = "Value" if $propertyName eq "[Symbol.Iterator]" and not $interface->iterable->isKeyValue; 4241 4238 push(@implContent, <<END); 4242 4239 JSC::EncodedJSValue JSC_HOST_CALL ${functionName}(JSC::ExecState* state) 4243 4240 { 4244 return createKeyValueIterator<${className}>(*state, IterationKind::${iterationKind}, "${propertyName}");4241 return iteratorCreate<${className}>(*state, IterationKind::${iterationKind}, "${propertyName}"); 4245 4242 } 4246 4243 … … 4250 4247 JSC::EncodedJSValue JSC_HOST_CALL ${functionName}(JSC::ExecState* state) 4251 4248 { 4252 return keyValueIteratorForEach<${className}>(*state, "${propertyName}");4249 return iteratorForEach<${className}>(*state, "${propertyName}"); 4253 4250 } 4254 4251 -
trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNode.cpp
r200448 r200619 25 25 #include "JSDOMBinding.h" 26 26 #include "JSDOMConstructor.h" 27 #include "JSDOMIterator.h" 27 28 #include "URL.h" 28 29 #include <runtime/Error.h> … … 33 34 34 35 namespace WebCore { 36 37 // Functions 38 39 JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionSymbolIterator(JSC::ExecState*); 40 JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionEntries(JSC::ExecState*); 41 JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionKeys(JSC::ExecState*); 42 JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionValues(JSC::ExecState*); 43 JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionForEach(JSC::ExecState*); 35 44 36 45 // Attributes … … 95 104 { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestNodeConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestNodeConstructor) } }, 96 105 { "name", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestNodeName), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestNodeName) } }, 106 { "entries", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestNodePrototypeFunctionEntries), (intptr_t) (0) } }, 107 { "keys", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestNodePrototypeFunctionKeys), (intptr_t) (0) } }, 108 { "values", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestNodePrototypeFunctionValues), (intptr_t) (0) } }, 109 { "forEach", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestNodePrototypeFunctionForEach), (intptr_t) (1) } }, 97 110 }; 98 111 … … 103 116 Base::finishCreation(vm); 104 117 reifyStaticProperties(vm, JSTestNodePrototypeTableValues, *this); 118 putDirect(vm, vm.propertyNames->iteratorSymbol, JSFunction::create(vm, globalObject(), 0, ASCIILiteral("[Symbol.Iterator]"), jsTestNodePrototypeFunctionSymbolIterator), ReadOnly | DontEnum); 105 119 } 106 120 … … 179 193 } 180 194 195 using TestNodeIterator = JSDOMIterator<JSTestNode>; 196 using TestNodeIteratorPrototype = JSDOMIteratorPrototype<JSTestNode>; 197 198 template<> 199 const JSC::ClassInfo TestNodeIterator::s_info = { "TestNode Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(TestNodeIterator) }; 200 201 template<> 202 const JSC::ClassInfo TestNodeIteratorPrototype::s_info = { "TestNode Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(TestNodeIteratorPrototype) }; 203 204 JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionSymbolIterator(JSC::ExecState* state) 205 { 206 return iteratorCreate<JSTestNode>(*state, IterationKind::Value, "[Symbol.Iterator]"); 207 } 208 209 JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionEntries(JSC::ExecState* state) 210 { 211 return iteratorCreate<JSTestNode>(*state, IterationKind::KeyValue, "entries"); 212 } 213 214 JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionKeys(JSC::ExecState* state) 215 { 216 return iteratorCreate<JSTestNode>(*state, IterationKind::Key, "keys"); 217 } 218 219 JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionValues(JSC::ExecState* state) 220 { 221 return iteratorCreate<JSTestNode>(*state, IterationKind::Value, "values"); 222 } 223 224 JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionForEach(JSC::ExecState* state) 225 { 226 return iteratorForEach<JSTestNode>(*state, "forEach"); 227 } 228 181 229 void JSTestNode::visitChildren(JSCell* cell, SlotVisitor& visitor) 182 230 { -
trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp
r200607 r200619 6153 6153 JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionSymbolIterator(JSC::ExecState* state) 6154 6154 { 6155 return createKeyValueIterator<JSTestObj>(*state, IterationKind::KeyValue, "[Symbol.Iterator]");6155 return iteratorCreate<JSTestObj>(*state, IterationKind::KeyValue, "[Symbol.Iterator]"); 6156 6156 } 6157 6157 6158 6158 JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionEntries(JSC::ExecState* state) 6159 6159 { 6160 return createKeyValueIterator<JSTestObj>(*state, IterationKind::KeyValue, "entries");6160 return iteratorCreate<JSTestObj>(*state, IterationKind::KeyValue, "entries"); 6161 6161 } 6162 6162 6163 6163 JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionKeys(JSC::ExecState* state) 6164 6164 { 6165 return createKeyValueIterator<JSTestObj>(*state, IterationKind::Key, "keys");6165 return iteratorCreate<JSTestObj>(*state, IterationKind::Key, "keys"); 6166 6166 } 6167 6167 6168 6168 JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionValues(JSC::ExecState* state) 6169 6169 { 6170 return createKeyValueIterator<JSTestObj>(*state, IterationKind::Value, "values");6170 return iteratorCreate<JSTestObj>(*state, IterationKind::Value, "values"); 6171 6171 } 6172 6172 6173 6173 JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionForEach(JSC::ExecState* state) 6174 6174 { 6175 return keyValueIteratorForEach<JSTestObj>(*state, "forEach");6175 return iteratorForEach<JSTestObj>(*state, "forEach"); 6176 6176 } 6177 6177 -
trunk/Source/WebCore/bindings/scripts/test/TestNode.idl
r199264 r200619 24 24 ] interface TestNode : Node { 25 25 attribute DOMString name; 26 27 iterable<TestNode>; 26 28 }; 27 29 -
trunk/Source/WebCore/css/FontFaceSet.cpp
r200546 r200619 77 77 } 78 78 79 Optional<WTF::KeyValuePair<RefPtr<FontFace>, RefPtr<FontFace>>> FontFaceSet::Iterator::next()79 RefPtr<FontFace> FontFaceSet::Iterator::next() 80 80 { 81 81 if (m_index == m_target->size()) 82 return Nullopt; 83 RefPtr<FontFace> item = m_target->backing()[m_index++].wrapper(); 84 return WTF::KeyValuePair<RefPtr<FontFace>, RefPtr<FontFace>>(item, item); 82 return nullptr; 83 return m_target->backing()[m_index++].wrapper(); 85 84 } 86 85 -
trunk/Source/WebCore/css/FontFaceSet.h
r200546 r200619 62 62 public: 63 63 explicit Iterator(FontFaceSet&); 64 Optional<WTF::KeyValuePair<RefPtr<FontFace>, RefPtr<FontFace>>> next();64 RefPtr<FontFace> next(); 65 65 66 66 private: -
trunk/Source/WebCore/css/FontFaceSet.idl
r200546 r200619 36 36 37 37 // FIXME: We should add support for the setlike declaration. 38 // As a first step this map iterable declaration should be changed to a set iterable. 39 iterable<FontFace, FontFace>; 38 iterable<FontFace>; 40 39 41 40 readonly attribute long size; -
trunk/Source/WebCore/dom/NodeList.h
r188829 r200619 41 41 virtual Node* item(unsigned index) const = 0; 42 42 43 class Iterator { 44 public: 45 explicit Iterator(NodeList& list) : m_list(list) { } 46 Node* next() { return m_list->item(m_index++); } 47 48 private: 49 size_t m_index { 0 }; 50 Ref<NodeList> m_list; 51 }; 52 Iterator createIterator() { return Iterator(*this); } 53 43 54 // Other methods (not part of DOM) 44 55 virtual bool isLiveNodeList() const { return false; } -
trunk/Source/WebCore/dom/NodeList.idl
r188829 r200619 28 28 getter Node item(unsigned long index); 29 29 readonly attribute unsigned long length; 30 iterable<Node>; 30 31 }; 31 32
Note: See TracChangeset
for help on using the changeset viewer.