aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4urlobject.cpp
diff options
context:
space:
mode:
authorMaximilian Goldstein <max.goldstein@qt.io>2020-04-09 13:34:01 +0200
committerMaximilian Goldstein <max.goldstein@qt.io>2020-05-06 10:45:48 +0200
commita714a3a446a47b3ac18de6cea1e6c4ca01535170 (patch)
tree2569eb6ec42f4b537bc18477b88d9a718f444012 /src/qml/jsruntime/qv4urlobject.cpp
parent22f9e5fb1ed643f284f50b9417bdbafdfb20566b (diff)
Implement URLSearchParams
Implements URLSearchParams (https://url.spec.whatwg.org/#urlsearchparams), completing our implementation of the URL object. Still needs the for..of iterator to get implemented. Change-Id: Iad33ed2f3fe0b2598ca2b0b21a4743f5f7dc19fd Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4urlobject.cpp')
-rw-r--r--src/qml/jsruntime/qv4urlobject.cpp760
1 files changed, 760 insertions, 0 deletions
diff --git a/src/qml/jsruntime/qv4urlobject.cpp b/src/qml/jsruntime/qv4urlobject.cpp
index 15e827680e..73b1510d2e 100644
--- a/src/qml/jsruntime/qv4urlobject.cpp
+++ b/src/qml/jsruntime/qv4urlobject.cpp
@@ -37,15 +37,24 @@
**
****************************************************************************/
+#include "qv4arrayiterator_p.h"
#include "qv4urlobject_p.h"
+#include "qv4stringobject_p.h"
#include <QtCore/QUrl>
+#include <qv4jscall_p.h>
+#include <qv4objectiterator_p.h>
+
using namespace QV4;
DEFINE_OBJECT_VTABLE(UrlObject);
DEFINE_OBJECT_VTABLE(UrlCtor);
+DEFINE_OBJECT_VTABLE(UrlSearchParamsObject);
+DEFINE_OBJECT_VTABLE(UrlSearchParamsCtor);
+
+
void Heap::UrlCtor::init(QV4::ExecutionContext *scope)
{
Heap::FunctionObject::init(scope, QLatin1String("URL"));
@@ -71,6 +80,7 @@ void UrlPrototype::init(ExecutionEngine *engine, Object *ctor)
defineAccessorProperty(QLatin1String("port"), method_getPort, method_setPort);
defineAccessorProperty(QLatin1String("protocol"), method_getProtocol, method_setProtocol);
defineAccessorProperty(QLatin1String("search"), method_getSearch, method_setSearch);
+ defineAccessorProperty(QLatin1String("searchParams"), method_getSearchParams, nullptr);
defineAccessorProperty(QLatin1String("username"), method_getUsername, method_setUsername);
}
@@ -623,6 +633,21 @@ ReturnedValue UrlPrototype::method_setUsername(const FunctionObject *b, const Va
return Encode::undefined();
}
+ReturnedValue UrlPrototype::method_getSearchParams(const FunctionObject *b, const Value *thisObject,
+ const Value *, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ Scoped<UrlObject> r(scope, thisObject->as<UrlObject>());
+
+ Scoped<UrlSearchParamsObject> usp(scope, v4->newUrlSearchParamsObject());
+
+ usp->initializeParams(r->search());
+
+ return usp->asReturnedValue();
+}
+
ReturnedValue UrlCtor::virtualCallAsConstructor(const FunctionObject *that, const Value *argv,
int argc, const Value *newTarget)
{
@@ -687,3 +712,738 @@ ReturnedValue UrlCtor::virtualCallAsConstructor(const FunctionObject *that, cons
return obj->asReturnedValue();
}
+
+
+void Heap::UrlSearchParamsCtor::init(QV4::ExecutionContext *scope)
+{
+ Heap::FunctionObject::init(scope, QLatin1String("URLSearchParams"));
+}
+
+void UrlSearchParamsPrototype::init(ExecutionEngine *engine, Object *ctor)
+{
+ Q_UNUSED(ctor)
+
+ Scope scope(engine);
+ ScopedObject o(scope);
+
+ defineDefaultProperty(QLatin1String("toString"), method_toString);
+ defineDefaultProperty(QLatin1String("sort"), method_sort);
+ defineDefaultProperty(QLatin1String("append"), method_append);
+ defineDefaultProperty(QLatin1String("delete"), method_delete);
+ defineDefaultProperty(QLatin1String("has"), method_has);
+ defineDefaultProperty(QLatin1String("set"), method_set);
+ defineDefaultProperty(QLatin1String("get"), method_get);
+ defineDefaultProperty(QLatin1String("getAll"), method_getAll);
+ defineDefaultProperty(QLatin1String("forEach"), method_forEach);
+ defineDefaultProperty(QLatin1String("entries"), method_entries);
+ defineDefaultProperty(QLatin1String("keys"), method_keys);
+ defineDefaultProperty(QLatin1String("values"), method_values);
+}
+
+ReturnedValue UrlSearchParamsCtor::virtualCallAsConstructor(const FunctionObject *that, const Value *argv,
+ int argc, const Value *newTarget)
+{
+ ExecutionEngine *v4 = that->engine();
+
+ if (argc > 1)
+ return v4->throwError(QLatin1String("Invalid amount of arguments"));
+
+ Scope scope(v4);
+
+ ScopedValue arg(scope, argv[0]);
+ ArrayObject *argArrayObject = arg->as<ArrayObject>();
+ Object *argObject = arg->as<Object>();
+
+ ReturnedValue o = Encode(v4->newUrlSearchParamsObject());
+
+ if (!newTarget)
+ return o;
+
+ ScopedObject obj(scope, o);
+ obj->setProtoFromNewTarget(newTarget);
+
+ UrlSearchParamsObject *urlSearchParamsObject = obj->as<UrlSearchParamsObject>();
+
+ if (argArrayObject != nullptr) {
+ ScopedArrayObject argArray(scope, argArrayObject);
+
+ uint len = argArray->getLength();
+
+ for (uint i = 0; i < len; i++) {
+ QV4::Value pair = argArray->get(i);
+ auto *pairArrayObject = pair.as<ArrayObject>();
+
+ if (pairArrayObject == nullptr) {
+ return v4->throwTypeError(
+ QLatin1String("element %1 is not a pair").arg(QString::number(i)));
+ }
+
+
+ ScopedArrayObject pairArray(scope, pairArrayObject);
+
+
+ uint pairLen = pairArray->getLength();
+
+
+ if (pairLen != 2) {
+ return v4->throwTypeError(QLatin1String("pair %1 has %2 elements instead of 2")
+ .arg(QString::number(i))
+ .arg(QString::number(pairLen)));
+ }
+ }
+
+ urlSearchParamsObject->initializeParams(argArray);
+ } else if (argObject != nullptr) {
+ ScopedObject scopedObject(scope, argObject);
+ urlSearchParamsObject->initializeParams(scopedObject);
+ } else {
+ QString value = argc > 0 ? arg->toQString() : QLatin1String("");
+ urlSearchParamsObject->initializeParams(value);
+ }
+
+ return obj->asReturnedValue();
+}
+
+void UrlSearchParamsObject::initializeParams()
+{
+ auto *arrayObject = engine()->newArrayObject(0);
+ auto *keys = engine()->newArrayObject(0);
+ auto *values = engine()->newArrayObject(0);
+
+ d()->params.set(engine(), arrayObject);
+ d()->keys.set(engine(), keys);
+ d()->values.set(engine(), values);
+}
+
+void UrlSearchParamsObject::initializeParams(QString value)
+{
+ Q_ASSERT(d()->params == nullptr);
+
+ initializeParams();
+
+ if (value.startsWith(QLatin1Char('?')))
+ value = value.mid(1);
+
+ const QStringList params = value.split(QLatin1Char('&'));
+
+ for (const QString& param : params) {
+ if (param.isEmpty())
+ continue;
+
+ QString key, value;
+
+ int equalsIndex = param.indexOf(QLatin1Char('='));
+ if (equalsIndex != -1) {
+ key = param.left(equalsIndex);
+ value = param.mid(equalsIndex+1);
+ } else {
+ key = param;
+ }
+
+ append(engine()->newString(key), engine()->newString(value));
+ }
+}
+
+void UrlSearchParamsObject::initializeParams(ScopedArrayObject& params)
+{
+ Q_ASSERT(d()->params == nullptr);
+
+ Scope scope(engine());
+
+ uint len = params->getLength();
+ auto *keys = engine()->newArrayObject(len);
+ auto *values = engine()->newArrayObject(len);
+
+ ScopedArrayObject scopedKeys(scope, keys);
+ ScopedArrayObject scopedValues(scope, values);
+
+ for (uint i = 0; i < len; i++)
+ {
+ QV4::Value pair = params->get(i);
+ auto *pairArrayObject = pair.as<ArrayObject>();
+
+ QV4::Value key = pairArrayObject->get(uint(0));
+ QV4::Value value = pairArrayObject->get(uint(1));
+
+ scopedKeys->put(i, key);
+ scopedValues->put(i, value);
+ }
+
+
+ d()->params.set(engine(), params->d());
+ d()->keys.set(engine(), keys);
+ d()->values.set(engine(), values);
+}
+
+void UrlSearchParamsObject::initializeParams(ScopedObject& params)
+{
+ Q_ASSERT(d()->params == nullptr);
+
+ initializeParams();
+
+ Scope scope(engine());
+ ObjectIterator it(scope, params, ObjectIterator::EnumerableOnly);
+
+ ScopedValue name(scope);
+ ScopedValue val(scope);
+
+ while (true) {
+ name = it.nextPropertyNameAsString(val);
+ if (name->isNull())
+ break;
+
+ Heap::String *nameStr = name->as<String>()->d();
+ Heap::String *valStr = val->toString(engine());
+
+ append(nameStr, valStr);
+ }
+}
+
+void UrlSearchParamsObject::setParams(QList<QStringList> params)
+{
+ auto *arrayObject = engine()->newArrayObject(0);
+ auto *keys = engine()->newArrayObject(0);
+ auto *values = engine()->newArrayObject(0);
+
+ Scope scope(engine());
+
+ ScopedArrayObject scopedArray(scope, arrayObject);
+
+ ScopedArrayObject scopedKeys(scope, keys);
+ ScopedArrayObject scopedValues(scope, values);
+
+ uint len = 0;
+
+ for (const QStringList& param : params) {
+
+ auto *valuePair = engine()->newArrayObject(2);
+
+ ScopedArrayObject valuePairObject(scope, valuePair);
+
+ ScopedValue key(scope, Value::fromHeapObject(engine()->newString(param[0])));
+ ScopedValue value(scope, Value::fromHeapObject(engine()->newString(param[1])));
+ valuePairObject->put(uint(0), key);
+ valuePairObject->put(uint(1), value);
+
+ scopedKeys->put(len, key);
+ scopedValues->put(len, value);
+
+ scopedArray->put(len, valuePairObject);
+ len++;
+ }
+
+ d()->params.set(engine(), arrayObject);
+ d()->keys.set(engine(), keys);
+ d()->values.set(engine(), values);
+}
+
+void UrlSearchParamsObject::append(Heap::String *name, Heap::String *value)
+{
+ Scope scope(engine());
+
+ ScopedArrayObject scopedArray(scope, d()->params);
+ ScopedArrayObject scopedKeys(scope, d()->keys);
+ ScopedArrayObject scopedValues(scope, d()->values);
+
+ auto *valuePair = engine()->newArrayObject(2);
+
+ ScopedArrayObject valuePairObject(scope, valuePair);
+
+ ScopedValue keyScoped(scope, Value::fromHeapObject(name));
+ ScopedValue valueScoped(scope, Value::fromHeapObject(value));
+ valuePairObject->put(uint(0), keyScoped);
+ valuePairObject->put(uint(1), valueScoped);
+
+ uint len = scopedArray->getLength();
+
+ scopedKeys->put(len, keyScoped);
+ scopedValues->put(len, valueScoped);
+
+ scopedArray->put(len, valuePairObject);
+}
+
+QList<QStringList> UrlSearchParamsObject::params() const
+{
+ auto *arrayObject = d()->params.get();
+ Scope scope(engine());
+ ScopedArrayObject scopedArray(scope, arrayObject);
+
+ QList<QStringList> result;
+
+ uint len = scopedArray->getLength();
+
+ for (uint i = 0; i < len; i++) {
+ QV4::Value pair = scopedArray->get(i);
+ auto *pairArrayObject = pair.as<ArrayObject>();
+
+ QV4::Value key = pairArrayObject->get(uint(0));
+ QV4::Value value = pairArrayObject->get(uint(1));
+
+ result << QStringList { key.toQString(), value.toQString() };
+ }
+
+ return result;
+}
+
+int UrlSearchParamsObject::length() const
+{
+ auto *arrayObject = d()->params.get();
+ Scope scope(engine());
+ ScopedArrayObject scopedArray(scope, arrayObject);
+
+ return scopedArray->getLength();
+}
+
+int UrlSearchParamsObject::indexOf(QString name, int last) const
+{
+ auto *arrayObject = d()->params.get();
+ Scope scope(engine());
+ ScopedArrayObject scopedArray(scope, arrayObject);
+
+ int len = scopedArray->getLength();
+
+ for (int i = last + 1; i < len; i++) {
+ QV4::Value pair = scopedArray->get(i);
+ auto *pairArrayObject = pair.as<ArrayObject>();
+
+ QV4::Value key = pairArrayObject->get(uint(0));
+
+ if (key.toQString() == name)
+ return i;
+ }
+
+ return -1;
+}
+
+QString UrlSearchParamsObject::stringAt(int index, int pairIndex) const
+{
+ auto *arrayObject = d()->params.get();
+ Scope scope(engine());
+ ScopedArrayObject scopedArray(scope, arrayObject);
+
+ if (index >= scopedArray->getLength())
+ return {};
+
+ QV4::Value pair = scopedArray->get(index);
+ auto *pairArrayObject = pair.as<ArrayObject>();
+
+ QV4::Value value = pairArrayObject->get(pairIndex);
+
+ return value.toQString();
+}
+
+QV4::Heap::String * UrlSearchParamsObject::stringAtRaw(int index, int pairIndex) const
+{
+ auto *arrayObject = d()->params.get();
+ Scope scope(engine());
+ ScopedArrayObject scopedArray(scope, arrayObject);
+
+ if (index >= scopedArray->getLength())
+ return nullptr;
+
+ QV4::Value pair = scopedArray->get(index);
+ auto *pairArrayObject = pair.as<ArrayObject>();
+
+ QV4::Value value = pairArrayObject->get(pairIndex);
+
+ return value.as<String>()->d();
+}
+
+QString UrlSearchParamsObject::nameAt(int index) const
+{
+ return stringAt(index, 0);
+}
+
+QV4::Heap::String * UrlSearchParamsObject::nameAtRaw(int index) const
+{
+ return stringAtRaw(index, 0);
+}
+
+
+QString UrlSearchParamsObject::valueAt(int index) const
+{
+ return stringAt(index, 1);
+}
+
+QV4::Heap::String * UrlSearchParamsObject::valueAtRaw(int index) const
+{
+ return stringAtRaw(index, 1);
+}
+
+
+struct UrlSearchParamsObjectOwnPropertyKeyIterator : ObjectOwnPropertyKeyIterator
+{
+ ~UrlSearchParamsObjectOwnPropertyKeyIterator() override = default;
+ PropertyKey next(const QV4::Object *o, Property *pd = nullptr,
+ PropertyAttributes *attrs = nullptr) override;
+};
+
+PropertyKey UrlSearchParamsObjectOwnPropertyKeyIterator::next(const QV4::Object *o, Property *pd,
+ PropertyAttributes *attrs)
+{
+ const UrlSearchParamsObject *usp = static_cast<const UrlSearchParamsObject *>(o);
+
+ Scope scope(usp);
+
+ uint len = usp->length();
+ if (arrayIndex < len) {
+ uint index = arrayIndex;
+ ++arrayIndex;
+ if (attrs)
+ *attrs = Attr_NotConfigurable | Attr_NotWritable;
+ if (pd)
+ pd->value = usp->engine()->newString(usp->nameAt(index));
+ return PropertyKey::fromArrayIndex(index);
+ }
+
+ return ObjectOwnPropertyKeyIterator::next(o, pd, attrs);
+}
+
+OwnPropertyKeyIterator *UrlSearchParamsObject::virtualOwnPropertyKeys(const Object *m,
+ Value *target)
+{
+ *target = *m;
+ return new UrlSearchParamsObjectOwnPropertyKeyIterator;
+}
+
+PropertyAttributes UrlSearchParamsObject::virtualGetOwnProperty(const Managed *m, PropertyKey id,
+ Property *p)
+{
+ PropertyAttributes attributes = Object::virtualGetOwnProperty(m, id, p);
+ if (attributes != Attr_Invalid)
+ return attributes;
+
+ if (id.isArrayIndex()) {
+ const int index = id.asArrayIndex();
+ const auto usp = static_cast<const UrlSearchParamsObject *>(m);
+ if (index < usp->length()) {
+ if (p)
+ p->value = usp->engine()->newString(usp->nameAt(index));
+ return Attr_NotConfigurable | Attr_NotWritable;
+ }
+ }
+
+ return Object::virtualGetOwnProperty(m, id, p);
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_toString(const FunctionObject *b, const Value *thisObject,
+ const Value *, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ auto params = o->params();
+
+ QString value;
+
+ for (const QStringList &pair : params)
+ value += QLatin1String("%1=%2&").arg(QString::fromUtf8(QUrl::toPercentEncoding(pair[0])),
+ QString::fromUtf8(QUrl::toPercentEncoding(pair[1])));
+
+ value.chop(1);
+
+ return Encode(v4->newString(value));
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_sort(const FunctionObject *b, const Value *thisObject,
+ const Value *, int)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ QList<QStringList> params = o->params();
+ std::stable_sort(params.begin(), params.end(), [](QStringList a, QStringList b) { return a[0] < b[0]; });
+
+ o->setParams(params);
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_append(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 2)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ ScopedValue argName(scope, argv[0]);
+ ScopedValue argValue(scope, argv[1]);
+
+ String *argNameString = argName->stringValue();
+
+ if (argNameString == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid argument provided"));
+
+ ScopedString name(scope, argName->as<String>());
+ ScopedString value(scope, argValue->toString(v4));
+
+
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ o->append(name->d(), value->d());
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_delete(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 1)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ ScopedValue argName(scope, argv[0]);
+
+ String *argNameString = argName->stringValue();
+
+ if (argNameString == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid argument provided"));
+
+ QString name = argNameString->toQString();
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ QList<QStringList> params = o->params();
+
+ auto to_remove = std::remove_if(params.begin(), params.end(), [&name](QStringList pair) {
+ return pair[0] == name;
+ });
+
+ params.erase(to_remove, params.end());
+
+ o->setParams(params);
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_has(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 1)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ ScopedValue argName(scope, argv[0]);
+
+ String *argNameString = argName->stringValue();
+
+ if (argNameString == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid argument provided"));
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ QString name = argNameString->toQString();
+
+ return Encode(o->indexOf(name) != -1);
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_set(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 2)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ ScopedValue argName(scope, argv[0]);
+ ScopedValue argValue(scope, argv[1]);
+
+ String *argNameString = argName->stringValue();
+
+ if (argNameString == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid argument provided"));
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ QString name = argNameString->toQString();
+ QString value = argValue->toQString();
+
+ auto params = o->params();
+
+ bool matched = false;
+
+ for (auto *it = params.begin(); it != params.end();) {
+ QStringList &param = *it;
+ if (param[0] == name) {
+ if (!matched) {
+ param[1] = value;
+ matched = true;
+ } else {
+ it = params.erase(it);
+ continue;
+ }
+ }
+ it++;
+ }
+
+ if (!matched)
+ params << QStringList { name, value };
+
+ o->setParams(params);
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_get(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 1)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ ScopedValue argName(scope, argv[0]);
+
+ String *argNameString = argName->stringValue();
+
+ if (argNameString == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid argument provided"));
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ QString name = argNameString->toQString();
+
+ int index = o->indexOf(name);
+
+ if (index == -1)
+ return Encode::null();
+
+ return Encode(o->valueAtRaw(index));
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_getAll(const FunctionObject *b,
+ const Value *thisObject, const Value *argv,
+ int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 1)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ ScopedValue argName(scope, argv[0]);
+
+ String *argNameString = argName->stringValue();
+
+ if (argNameString == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid argument provided"));
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ QString name = argNameString->toQString();
+
+ auto *arrayObject = v4->newArrayObject(0);
+ ScopedArrayObject result(scope, arrayObject);
+
+ int i = 0;
+ for (int index = o->indexOf(name); index != -1; index = o->indexOf(name, index)) {
+ ScopedValue value(scope, Value::fromHeapObject(o->valueAtRaw(index)));
+ result->put(i++, value);
+ }
+
+ return Encode(arrayObject);
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_forEach(const FunctionObject *b,
+ const Value *thisObject, const Value *argv,
+ int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 1)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ ScopedValue argFunc(scope, argv[0]);
+
+ FunctionObject *func = argFunc->as<FunctionObject>();
+
+ if (func == nullptr)
+ return v4->throwTypeError(QLatin1String("Invalid argument: must be a function"));
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ for (int i = 0; i < o->length(); i++) {
+ Scoped<String> name(scope, o->nameAtRaw(i));
+ Scoped<String> value(scope, o->valueAtRaw(i));
+
+ QV4::JSCallData calldata(scope, 2);
+
+ calldata->args[0] = value;
+ calldata->args[1] = name;
+
+ func->call(calldata);
+ }
+
+ return Encode::undefined();
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_entries(const FunctionObject *b,
+ const Value *thisObject, const Value *,
+ int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 0)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ ScopedObject params(scope, o->d()->params.get());
+
+ Scoped<ArrayIteratorObject> paramsIterator(scope, v4->newArrayIteratorObject(params));
+ paramsIterator->d()->iterationKind = IteratorKind::KeyValueIteratorKind;
+ return paramsIterator->asReturnedValue();
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_keys(const FunctionObject *b,
+ const Value *thisObject, const Value *,
+ int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 0)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ ScopedObject keys(scope, o->d()->keys.get());
+
+ Scoped<ArrayIteratorObject> keysIterator(scope, v4->newArrayIteratorObject(keys));
+ keysIterator->d()->iterationKind = IteratorKind::KeyValueIteratorKind;
+ return keysIterator->asReturnedValue();
+}
+
+ReturnedValue UrlSearchParamsPrototype::method_values(const FunctionObject *b,
+ const Value *thisObject, const Value *,
+ int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+
+ if (argc != 0)
+ return v4->throwError(QLatin1String("Bad amount of arguments"));
+
+ Scoped<UrlSearchParamsObject> o(scope, thisObject->as<UrlSearchParamsObject>());
+
+ ScopedObject values(scope, o->d()->values.get());
+
+ Scoped<ArrayIteratorObject> valuesIterator(scope, v4->newArrayIteratorObject(values));
+ valuesIterator->d()->iterationKind = IteratorKind::KeyValueIteratorKind;
+ return valuesIterator->asReturnedValue();
+}