Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qv4urlobject.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
6
7#include <QtCore/QUrl>
8
9#include <qv4jscall_p.h>
10#include <qv4objectiterator_p.h>
11
12using namespace QV4;
13
16
19
20
21void Heap::UrlCtor::init(QV4::ExecutionEngine *engine)
22{
23 Heap::FunctionObject::init(engine, QLatin1String("URL"));
24}
25
26void UrlPrototype::init(ExecutionEngine *engine, Object *ctor)
27{
28 Q_UNUSED(ctor);
29
30 Scope scope(engine);
31 ScopedObject o(scope);
32
33 defineDefaultProperty(QLatin1String("toString"), method_getHref);
34 defineDefaultProperty(QLatin1String("toJSON"), method_getHref);
35
36 defineAccessorProperty(QLatin1String("hash"), method_getHash, method_setHash);
37 defineAccessorProperty(QLatin1String("host"), method_getHost, method_setHost);
38 defineAccessorProperty(QLatin1String("hostname"), method_getHostname, method_setHostname);
39 defineAccessorProperty(QLatin1String("href"), method_getHref, method_setHref);
40 defineAccessorProperty(QLatin1String("origin"), method_getOrigin, nullptr);
41 defineAccessorProperty(QLatin1String("password"), method_getPassword, method_setPassword);
42 defineAccessorProperty(QLatin1String("pathname"), method_getPathname, method_setPathname);
43 defineAccessorProperty(QLatin1String("port"), method_getPort, method_setPort);
44 defineAccessorProperty(QLatin1String("protocol"), method_getProtocol, method_setProtocol);
45 defineAccessorProperty(QLatin1String("search"), method_getSearch, method_setSearch);
46 defineAccessorProperty(QLatin1String("searchParams"), method_getSearchParams, nullptr);
47 defineAccessorProperty(QLatin1String("username"), method_getUsername, method_setUsername);
48}
49
50bool UrlObject::setHash(QString hash)
51{
52 if (hash.startsWith(QLatin1Char('#')))
53 hash = hash.mid(1);
54
55 QUrl url = toQUrl();
56 url.setFragment(hash);
57
58 if (!url.isValid())
59 return false;
60
61 d()->hash.set(engine(), engine()->newString(url.fragment()));
62 d()->href.set(engine(), engine()->newString(url.toString()));
63
64 return true;
65}
66
67bool UrlObject::setHostname(QString host)
68{
69 QUrl url = toQUrl();
70 url.setHost(host);
71
72 if (!url.isValid())
73 return false;
74
75 d()->hostname.set(engine(), engine()->newString(url.host()));
76 d()->href.set(engine(), engine()->newString(url.toString()));
77
78 updateOrigin();
79 updateHost();
80
81 return true;
82}
83
84bool UrlObject::setHost(QString hostname)
85{
86 int port = -1;
87
88 if (hostname.contains(QLatin1Char(':'))) {
89 const QStringList list = hostname.split(QLatin1Char(':'));
90 hostname = list[0];
91 port = list[1].toInt();
92 }
93
94 QUrl url = toQUrl();
95 url.setHost(hostname);
96 url.setPort(port);
97
98 if (!url.isValid())
99 return false;
100
101 if (url.port() != -1)
102 d()->port.set(engine(), engine()->newString(QString::number(url.port())));
103
104 d()->hostname.set(engine(), engine()->newString(url.host()));
105 d()->href.set(engine(), engine()->newString(url.toString()));
106
107 updateOrigin();
108 updateHost();
109
110 return true;
111}
112
113bool UrlObject::setHref(QString href)
114{
115 const QUrl url(href);
116 if (!url.isValid() || url.isRelative())
117 return false;
118
119 setUrl(url);
120 return true;
121}
122
123void UrlObject::setUrl(const QUrl &url)
124{
125 d()->hash.set(engine(), engine()->newString(url.fragment()));
126 d()->hostname.set(engine(), engine()->newString(url.host()));
127 d()->href.set(engine(), engine()->newString(url.toString(QUrl::ComponentFormattingOptions(QUrl::ComponentFormattingOption::FullyEncoded))));
128 d()->password.set(engine(), engine()->newString(url.password()));
129 d()->pathname.set(engine(), engine()->newString(url.path()));
130 d()->port.set(engine(),
131 engine()->newString(url.port() == -1 ? QLatin1String("")
132 : QString::number(url.port())));
133 d()->protocol.set(engine(), engine()->newString(url.scheme() + QLatin1Char(':')));
134 d()->search.set(engine(), engine()->newString(url.query(QUrl::ComponentFormattingOptions(QUrl::ComponentFormattingOption::FullyEncoded))));
135 d()->username.set(engine(), engine()->newString(url.userName()));
136
137 updateOrigin();
138 updateHost();
139}
140
141bool UrlObject::setPassword(QString password)
142{
143 QUrl url = toQUrl();
144 url.setPassword(password);
145
146 if (!url.isValid())
147 return false;
148
149 d()->password.set(engine(), engine()->newString(url.password()));
150 d()->href.set(engine(), engine()->newString(url.toString()));
151
152 return true;
153}
154
155bool UrlObject::setPathname(QString pathname)
156{
157 QUrl url = toQUrl();
158 url.setPath(pathname);
159
160 if (!url.isValid())
161 return false;
162
163 d()->pathname.set(engine(), engine()->newString(url.path()));
164 d()->href.set(engine(), engine()->newString(url.toString()));
165
166 return true;
167}
168
169bool UrlObject::setPort(QString port)
170{
171 QUrl url = toQUrl();
172 url.setPort(port.isEmpty() ? -1 : port.toInt());
173
174 if (!url.isValid())
175 return false;
176
177 d()->port.set(engine(),
178 engine()->newString(url.port() == -1 ? QLatin1String("")
179 : QString::number(url.port())));
180 d()->href.set(engine(), engine()->newString(url.toString()));
181
182 updateOrigin();
183 updateHost();
184
185 return true;
186}
187
188bool UrlObject::setProtocol(QString protocolOrScheme)
189{
190 QUrl url = toQUrl();
191 // If there is one or several ':' in the protocolOrScheme,
192 // everything from the first colon is removed.
193
194 qsizetype firstColonPos = protocolOrScheme.indexOf(QLatin1Char(':'));
195
196 if (firstColonPos != -1)
197 protocolOrScheme.truncate(firstColonPos);
198
199 url.setScheme(protocolOrScheme);
200
201 if (!url.isValid())
202 return false;
203
204 d()->protocol.set(engine(), engine()->newString(url.scheme() + QLatin1Char(':')));
205 d()->href.set(engine(), engine()->newString(url.toString()));
206
207 updateOrigin();
208 updateHost();
209
210 return true;
211}
212
213bool UrlObject::setSearch(QString search)
214{
215 QUrl url = toQUrl();
216
217 if (search.startsWith(QLatin1Char('?')))
218 search = search.mid(1);
219
220 url.setQuery(search);
221
222 if (!url.isValid())
223 return false;
224
225 d()->search.set(engine(), engine()->newString(url.query()));
226 d()->href.set(engine(), engine()->newString(url.toString()));
227
228 return true;
229}
230
231bool UrlObject::setUsername(QString username)
232{
233 QUrl url = toQUrl();
234 url.setUserName(username);
235
236 if (!url.isValid())
237 return false;
238
239 d()->username.set(engine(), engine()->newString(url.userName()));
240 d()->href.set(engine(), engine()->newString(url.toString()));
241
242 return true;
243}
244
245QString UrlObject::search() const
246{
247 auto url = QUrl(href());
248 if (auto url = QUrl(href()); !url.hasQuery() || url.query().isEmpty())
249 return QLatin1String("");
250
251 constexpr auto options = QUrl::ComponentFormattingOption::EncodeSpaces
252 | QUrl::ComponentFormattingOption::EncodeUnicode
253 | QUrl::ComponentFormattingOption::EncodeReserved;
254 return u'?' + url.query(options);
255}
256
257QUrl UrlObject::toQUrl() const
258{
259 return QUrl(href());
260}
261
262void UrlObject::updateOrigin()
263{
264 QUrl url = toQUrl();
265
266 QString proto = url.scheme();
267
268 // A blob's origin is the origin of the URL that it points to
269 if (proto == QLatin1String("blob")) {
270 url = QUrl(url.path());
271 proto = url.scheme();
272 }
273
274 QString origin;
275 if (proto == QLatin1String("http") || proto == QLatin1String("https")
276 || proto == QLatin1String("ftp")) {
277 origin = QLatin1String("%1://%2").arg(url.scheme(), url.host());
278
279 if (url.port() != -1)
280 origin.append(QLatin1String(":") + QString::number(url.port()));
281 }
282
283 d()->origin.set(engine(), engine()->newString(origin));
284}
285
286void UrlObject::updateHost()
287{
288 QUrl url = toQUrl();
289
290 QString host = url.host();
291
292 if (url.port() != -1)
293 host.append(QLatin1String(":") + QString::number(url.port()));
294
295 d()->host.set(engine(), engine()->newString(host));
296}
297
298static bool checkUrlObjectType(ExecutionEngine *v4, const Scoped<UrlObject> &r)
299{
300 if (r)
301 return true;
302
303 v4->throwTypeError(QStringLiteral("Value of \"this\" must be of type URL"));
304 return false;
305}
306
307ReturnedValue UrlPrototype::method_getHash(const FunctionObject *b, const Value *thisObject,
308 const Value *, int)
309{
310 ExecutionEngine *v4 = b->engine();
311 Scope scope(v4);
312
313 Scoped<UrlObject> r(scope, thisObject);
314 if (!checkUrlObjectType(v4, r))
315 return Encode::undefined();
316
317 return Encode(v4->newString(r->hash()));
318}
319
320ReturnedValue UrlPrototype::method_setHash(const FunctionObject *b, const Value *thisObject,
321 const Value *argv, int)
322{
323 ExecutionEngine *v4 = b->engine();
324 Scope scope(v4);
325
326 ScopedValue arg(scope, argv[0]);
327 String *stringValue = arg->stringValue();
328
329 if (stringValue == nullptr)
330 return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
331
332 Scoped<UrlObject> r(scope, thisObject);
333 if (!checkUrlObjectType(v4, r))
334 return Encode::undefined();
335
336 r->setHash(stringValue->toQString());
337
338 return Encode::undefined();
339}
340
341ReturnedValue UrlPrototype::method_getHost(const FunctionObject *b, const Value *thisObject,
342 const Value *, int)
343{
344 ExecutionEngine *v4 = b->engine();
345 Scope scope(v4);
346
347 Scoped<UrlObject> r(scope, thisObject);
348 if (!checkUrlObjectType(v4, r))
349 return Encode::undefined();
350
351 return Encode(v4->newString(r->host()));
352}
353
354ReturnedValue UrlPrototype::method_setHost(const FunctionObject *b, const Value *thisObject,
355 const Value *argv, int)
356{
357 ExecutionEngine *v4 = b->engine();
358 Scope scope(v4);
359
360 ScopedValue arg(scope, argv[0]);
361 String *stringValue = arg->stringValue();
362
363 if (stringValue == nullptr)
364 return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
365
366 Scoped<UrlObject> r(scope, thisObject);
367 if (!checkUrlObjectType(v4, r))
368 return Encode::undefined();
369
370 QString host = stringValue->toQString();
371 if (!r->setHost(host))
372 return v4->throwTypeError(QLatin1String("Invalid host: %1").arg(host));
373
374 return Encode::undefined();
375}
376
377ReturnedValue UrlPrototype::method_getHostname(const FunctionObject *b, const Value *thisObject,
378 const Value *, int)
379{
380 ExecutionEngine *v4 = b->engine();
381 Scope scope(v4);
382
383 Scoped<UrlObject> r(scope, thisObject);
384 if (!checkUrlObjectType(v4, r))
385 return Encode::undefined();
386
387 return Encode(v4->newString(r->hostname()));
388}
389
390ReturnedValue UrlPrototype::method_setHostname(const FunctionObject *b, const Value *thisObject,
391 const Value *argv, int)
392{
393 ExecutionEngine *v4 = b->engine();
394 Scope scope(v4);
395
396 ScopedValue arg(scope, argv[0]);
397 String *stringValue = arg->stringValue();
398
399 if (stringValue == nullptr)
400 return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
401
402 Scoped<UrlObject> r(scope, thisObject);
403 if (!checkUrlObjectType(v4, r))
404 return Encode::undefined();
405
406 QString hostname = stringValue->toQString();
407 if (!r->setHostname(hostname))
408 return v4->throwTypeError(QLatin1String("Invalid hostname: %1").arg(hostname));
409
410 return Encode::undefined();
411}
412
413ReturnedValue UrlPrototype::method_getHref(const FunctionObject *b, const Value *thisObject,
414 const Value *, int)
415{
416 ExecutionEngine *v4 = b->engine();
417 Scope scope(v4);
418
419 Scoped<UrlObject> r(scope, thisObject);
420 if (!checkUrlObjectType(v4, r))
421 return Encode::undefined();
422
423 return Encode(v4->newString(r->href()));
424}
425
426ReturnedValue UrlPrototype::method_setHref(const FunctionObject *b, const Value *thisObject,
427 const Value *argv, int)
428{
429 ExecutionEngine *v4 = b->engine();
430 Scope scope(v4);
431
432 ScopedValue arg(scope, argv[0]);
433 String *stringValue = arg->stringValue();
434
435 if (stringValue == nullptr)
436 return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
437
438 Scoped<UrlObject> r(scope, thisObject);
439 if (!checkUrlObjectType(v4, r))
440 return Encode::undefined();
441
442 QString href = stringValue->toQString();
443 if (!r->setHref(href))
444 return v4->throwTypeError(QLatin1String("Invalid URL: %1").arg(href));
445
446 return Encode::undefined();
447}
448
449ReturnedValue UrlPrototype::method_getOrigin(const FunctionObject *b, const Value *thisObject,
450 const Value *, int)
451{
452 ExecutionEngine *v4 = b->engine();
453 Scope scope(v4);
454
455 Scoped<UrlObject> r(scope, thisObject);
456 if (!checkUrlObjectType(v4, r))
457 return Encode::undefined();
458
459 return Encode(v4->newString(r->origin()));
460}
461
462ReturnedValue UrlPrototype::method_getPassword(const FunctionObject *b, const Value *thisObject,
463 const Value *, int)
464{
465 ExecutionEngine *v4 = b->engine();
466 Scope scope(v4);
467
468 Scoped<UrlObject> r(scope, thisObject);
469 if (!checkUrlObjectType(v4, r))
470 return Encode::undefined();
471
472 return Encode(v4->newString(r->password()));
473}
474
475ReturnedValue UrlPrototype::method_setPassword(const FunctionObject *b, const Value *thisObject,
476 const Value *argv, int)
477{
478 ExecutionEngine *v4 = b->engine();
479 Scope scope(v4);
480
481 ScopedValue arg(scope, argv[0]);
482 String *stringValue = arg->stringValue();
483
484 if (stringValue == nullptr)
485 return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
486
487 Scoped<UrlObject> r(scope, thisObject);
488 if (!checkUrlObjectType(v4, r))
489 return Encode::undefined();
490
491 r->setPassword(stringValue->toQString());
492
493 return Encode::undefined();
494}
495
496ReturnedValue UrlPrototype::method_getPathname(const FunctionObject *b, const Value *thisObject,
497 const Value *, int)
498{
499 ExecutionEngine *v4 = b->engine();
500 Scope scope(v4);
501
502 Scoped<UrlObject> r(scope, thisObject);
503 if (!checkUrlObjectType(v4, r))
504 return Encode::undefined();
505
506 return Encode(v4->newString(r->pathname()));
507}
508
509ReturnedValue UrlPrototype::method_setPathname(const FunctionObject *b, const Value *thisObject,
510 const Value *argv, int)
511{
512 ExecutionEngine *v4 = b->engine();
513 Scope scope(v4);
514
515 ScopedValue arg(scope, argv[0]);
516 String *stringValue = arg->stringValue();
517
518 if (stringValue == nullptr)
519 return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
520
521 Scoped<UrlObject> r(scope, thisObject);
522 if (!checkUrlObjectType(v4, r))
523 return Encode::undefined();
524
525 r->setPathname(stringValue->toQString());
526
527 return Encode::undefined();
528}
529
530ReturnedValue UrlPrototype::method_getPort(const FunctionObject *b, const Value *thisObject,
531 const Value *, int)
532{
533 ExecutionEngine *v4 = b->engine();
534 Scope scope(v4);
535
536 Scoped<UrlObject> r(scope, thisObject);
537 if (!checkUrlObjectType(v4, r))
538 return Encode::undefined();
539
540 return Encode(v4->newString(r->port()));
541}
542
543ReturnedValue UrlPrototype::method_setPort(const FunctionObject *b, const Value *thisObject,
544 const Value *argv, int)
545{
546 ExecutionEngine *v4 = b->engine();
547 Scope scope(v4);
548
549 ScopedValue arg(scope, argv[0]);
550 String *stringValue = arg->stringValue();
551
552 QString port;
553
554 if (stringValue != nullptr)
555 port = stringValue->toQString();
556 else if (arg->isInt32())
557 port = QString::number(arg->toInt32());
558 else
559 return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
560
561 Scoped<UrlObject> r(scope, thisObject);
562 if (!checkUrlObjectType(v4, r))
563 return Encode::undefined();
564
565 if (!r->setPort(port))
566 return v4->throwTypeError(QLatin1String("Invalid port: %1").arg(port));
567
568 return Encode::undefined();
569}
570
571ReturnedValue UrlPrototype::method_getProtocol(const FunctionObject *b, const Value *thisObject,
572 const Value *, int)
573{
574 ExecutionEngine *v4 = b->engine();
575 Scope scope(v4);
576
577 Scoped<UrlObject> r(scope, thisObject);
578 if (!checkUrlObjectType(v4, r))
579 return Encode::undefined();
580
581 return Encode(v4->newString(r->protocol()));
582}
583
584ReturnedValue UrlPrototype::method_setProtocol(const FunctionObject *b, const Value *thisObject,
585 const Value *argv, int)
586{
587 ExecutionEngine *v4 = b->engine();
588 Scope scope(v4);
589
590 ScopedValue arg(scope, argv[0]);
591 String *stringValue = arg->stringValue();
592
593 if (stringValue == nullptr)
594 return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
595
596 Scoped<UrlObject> r(scope, thisObject);
597 if (!checkUrlObjectType(v4, r))
598 return Encode::undefined();
599
600 r->setProtocol(stringValue->toQString());
601
602 return Encode::undefined();
603}
604
605ReturnedValue UrlPrototype::method_getSearch(const FunctionObject *b, const Value *thisObject,
606 const Value *, int)
607{
608 ExecutionEngine *v4 = b->engine();
609 Scope scope(v4);
610
611 Scoped<UrlObject> r(scope, thisObject);
612 if (!checkUrlObjectType(v4, r))
613 return Encode::undefined();
614
615 return Encode(v4->newString(r->search()));
616}
617
618ReturnedValue UrlPrototype::method_setSearch(const FunctionObject *b, const Value *thisObject,
619 const Value *argv, int)
620{
621 ExecutionEngine *v4 = b->engine();
622 Scope scope(v4);
623
624 ScopedValue arg(scope, argv[0]);
625 String *stringValue = arg->stringValue();
626
627 if (stringValue == nullptr)
628 return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
629
630 Scoped<UrlObject> r(scope, thisObject);
631 if (!checkUrlObjectType(v4, r))
632 return Encode::undefined();
633
634 r->setSearch(stringValue->toQString());
635
636 return Encode::undefined();
637}
638
639ReturnedValue UrlPrototype::method_getUsername(const FunctionObject *b, const Value *thisObject,
640 const Value *, int)
641{
642 ExecutionEngine *v4 = b->engine();
643 Scope scope(v4);
644
645 Scoped<UrlObject> r(scope, thisObject);
646 if (!checkUrlObjectType(v4, r))
647 return Encode::undefined();
648
649 return Encode(v4->newString(r->username()));
650}
651
652ReturnedValue UrlPrototype::method_setUsername(const FunctionObject *b, const Value *thisObject,
653 const Value *argv, int)
654{
655 ExecutionEngine *v4 = b->engine();
656 Scope scope(v4);
657
658 ScopedValue arg(scope, argv[0]);
659 String *stringValue = arg->stringValue();
660
661 if (stringValue == nullptr)
662 return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
663
664 Scoped<UrlObject> r(scope, thisObject);
665 if (!checkUrlObjectType(v4, r))
666 return Encode::undefined();
667
668 r->setUsername(stringValue->toQString());
669
670 return Encode::undefined();
671}
672
673ReturnedValue UrlPrototype::method_getSearchParams(const FunctionObject *b, const Value *thisObject,
674 const Value *, int)
675{
676 ExecutionEngine *v4 = b->engine();
677 Scope scope(v4);
678
679 Scoped<UrlObject> r(scope, thisObject);
680 if (!checkUrlObjectType(v4, r))
681 return Encode::undefined();
682
683 Scoped<UrlSearchParamsObject> usp(scope, v4->newUrlSearchParamsObject());
684
685 usp->setUrlObject(thisObject->as<UrlObject>());
686 usp->initializeParams(r->search());
687
688 return usp->asReturnedValue();
689}
690
691ReturnedValue UrlCtor::virtualCallAsConstructor(const FunctionObject *that, const Value *argv,
692 int argc, const Value *newTarget)
693{
694 ExecutionEngine *v4 = that->engine();
695
696 if (argc < 1 || argc > 2)
697 return v4->throwError(QLatin1String("Invalid amount of arguments"));
698
699 Scope scope(v4);
700
701 ScopedValue arg1(scope, argv[0]);
702
703 QString arg1String = arg1->toQString();
704 QString urlString;
705
706 if (argc == 2) {
707 ScopedValue arg2(scope, argv[1]);
708 String *arg2StringValue = arg2->stringValue();
709
710 if (arg2StringValue == nullptr)
711 return v4->throwTypeError(QLatin1String("Invalid parameter provided"));
712
713 QUrl url = QUrl(arg2StringValue->toQString());
714 QUrl relativeUrl = QUrl(arg1String);
715
716 QString baseUrlPath = url.path();
717 QString relativePath = relativeUrl.path();
718
719 // If the base URL contains a path the last section of it is discarded
720 int lastSlash = baseUrlPath.lastIndexOf(QLatin1Char('/'));
721 if (lastSlash != -1)
722 baseUrlPath.truncate(lastSlash);
723
724 if (!relativePath.startsWith(QLatin1Char('/')))
725 relativePath = relativePath.prepend(QLatin1Char('/'));
726
727 url.setPath(baseUrlPath + relativePath);
728 url.setFragment(relativeUrl.fragment());
729 url.setQuery(relativeUrl.query());
730
731 urlString = url.toString();
732 } else {
733 urlString = arg1String;
734 }
735
736 ReturnedValue o = Encode(v4->newUrlObject());
737
738 if (!newTarget)
739 return o;
740
741 ScopedObject obj(scope, o);
742 obj->setProtoFromNewTarget(newTarget);
743
744 UrlObject *urlObject = obj->as<UrlObject>();
745
746 if (!urlObject->setHref(urlString))
747 return v4->throwTypeError(QLatin1String("Invalid URL: %1").arg(urlString));
748
749 return obj->asReturnedValue();
750}
751
752
753void Heap::UrlSearchParamsCtor::init(QV4::ExecutionEngine *engine)
754{
755 Heap::FunctionObject::init(engine, QLatin1String("URLSearchParams"));
756}
757
758void UrlSearchParamsPrototype::init(ExecutionEngine *engine, Object *ctor)
759{
760 Q_UNUSED(ctor);
761
762 Scope scope(engine);
763 ScopedObject o(scope);
764
765 defineDefaultProperty(QLatin1String("toString"), method_toString);
766 defineDefaultProperty(QLatin1String("sort"), method_sort);
767 defineDefaultProperty(QLatin1String("append"), method_append);
768 defineDefaultProperty(QLatin1String("delete"), method_delete);
769 defineDefaultProperty(QLatin1String("has"), method_has);
770 defineDefaultProperty(QLatin1String("set"), method_set);
771 defineDefaultProperty(QLatin1String("get"), method_get);
772 defineDefaultProperty(QLatin1String("getAll"), method_getAll);
773 defineDefaultProperty(QLatin1String("forEach"), method_forEach);
774 defineDefaultProperty(QLatin1String("entries"), method_entries);
775 defineDefaultProperty(QLatin1String("keys"), method_keys);
776 defineDefaultProperty(QLatin1String("values"), method_values);
777}
778
779ReturnedValue UrlSearchParamsCtor::virtualCallAsConstructor(const FunctionObject *that, const Value *argv,
780 int argc, const Value *newTarget)
781{
782 ExecutionEngine *v4 = that->engine();
783
784 if (argc > 1)
785 return v4->throwError(QLatin1String("Invalid amount of arguments"));
786
787 Scope scope(v4);
788
789 ScopedValue arg(scope, argv[0]);
790 ArrayObject *argArrayObject = arg->as<ArrayObject>();
791 Object *argObject = arg->as<Object>();
792
793 ReturnedValue o = Encode(v4->newUrlSearchParamsObject());
794
795 if (!newTarget)
796 return o;
797
798 ScopedObject obj(scope, o);
799 obj->setProtoFromNewTarget(newTarget);
800
801 UrlSearchParamsObject *urlSearchParamsObject = obj->as<UrlSearchParamsObject>();
802
803 if (argArrayObject != nullptr) {
804 ScopedArrayObject argArray(scope, argArrayObject);
805
806 uint len = argArray->getLength();
807
808 for (uint i = 0; i < len; i++) {
809 // safe to user fromReturnedValue: Normal array, which will ensure marking
810 QV4::Value pair = Value::fromReturnedValue(argArray->get(i));
811 auto *pairArrayObject = pair.as<ArrayObject>();
812
813 if (pairArrayObject == nullptr) {
814 return v4->throwTypeError(
815 QLatin1String("element %1 is not a pair").arg(QString::number(i)));
816 }
817
818
819 ScopedArrayObject pairArray(scope, pairArrayObject);
820
821
822 uint pairLen = pairArray->getLength();
823
824
825 if (pairLen != 2) {
826 return v4->throwTypeError(QLatin1String("pair %1 has %2 elements instead of 2")
827 .arg(QString::number(i))
828 .arg(QString::number(pairLen)));
829 }
830 }
831
832 urlSearchParamsObject->initializeParams(argArray);
833 } else if (argObject != nullptr) {
834 ScopedObject scopedObject(scope, argObject);
835 urlSearchParamsObject->initializeParams(scopedObject);
836 } else {
837 QString value = argc > 0 ? arg->toQString() : QLatin1String("");
838 urlSearchParamsObject->initializeParams(value);
839 }
840
841 return obj->asReturnedValue();
842}
843
844void UrlSearchParamsObject::initializeParams()
845{
846 auto *arrayObject = engine()->newArrayObject(0);
847 auto *keys = engine()->newArrayObject(0);
848 auto *values = engine()->newArrayObject(0);
849
850 d()->params.set(engine(), arrayObject);
851 d()->keys.set(engine(), keys);
852 d()->values.set(engine(), values);
853}
854
855void UrlSearchParamsObject::initializeParams(QString value)
856{
857 Q_ASSERT(d()->params == nullptr);
858
859 initializeParams();
860
861 if (value.startsWith(QLatin1Char('?')))
862 value = value.mid(1);
863
864 const QStringList params = value.split(QLatin1Char('&'));
865
866 for (const QString& param : params) {
867 if (param.isEmpty())
868 continue;
869
870 QString key, value;
871
872 int equalsIndex = param.indexOf(QLatin1Char('='));
873 if (equalsIndex != -1) {
874 key = param.left(equalsIndex);
875 value = param.mid(equalsIndex+1);
876 } else {
877 key = param;
878 }
879
880 append(engine()->newString(key), engine()->newString(value));
881 }
882}
883
884void UrlSearchParamsObject::initializeParams(ScopedArrayObject& params)
885{
886 Q_ASSERT(d()->params == nullptr);
887
888 Scope scope(engine());
889
890 uint len = params->getLength();
891 auto *keys = engine()->newArrayObject(len);
892 auto *values = engine()->newArrayObject(len);
893
894 ScopedArrayObject scopedKeys(scope, keys);
895 ScopedArrayObject scopedValues(scope, values);
896
897 for (uint i = 0; i < len; i++)
898 {
899 // fromReturnedValue is safe; everything is reachable via params
900 // so the gc won't collect it; we control params, so there can't be
901 // any weird proxy magic
902 QV4::Value pair = Value::fromReturnedValue(params->get(i));
903 auto *pairArrayObject = pair.as<ArrayObject>();
904
905 QV4::Value key = Value::fromReturnedValue(pairArrayObject->get(uint(0)));
906 QV4::Value value = Value::fromReturnedValue(pairArrayObject->get(uint(1)));
907
908 scopedKeys->put(i, key);
909 scopedValues->put(i, value);
910 }
911
912
913 d()->params.set(engine(), params->d());
914 d()->keys.set(engine(), keys);
915 d()->values.set(engine(), values);
916}
917
918void UrlSearchParamsObject::initializeParams(ScopedObject& params)
919{
920 Q_ASSERT(d()->params == nullptr);
921
922 initializeParams();
923
924 Scope scope(engine());
925 ObjectIterator it(scope, params, ObjectIterator::EnumerableOnly);
926
927 ScopedValue name(scope);
928 ScopedValue val(scope);
929
930 while (true) {
931 name = it.nextPropertyNameAsString(val);
932 if (name->isNull())
933 break;
934
935 Heap::String *nameStr = name->as<String>()->d();
936 Heap::String *valStr = val->toString(engine());
937
938 append(nameStr, valStr);
939 }
940}
941
942void UrlSearchParamsObject::setParams(QList<QStringList> params)
943{
944 auto *arrayObject = engine()->newArrayObject(0);
945 auto *keys = engine()->newArrayObject(0);
946 auto *values = engine()->newArrayObject(0);
947
948 Scope scope(engine());
949
950 ScopedArrayObject scopedArray(scope, arrayObject);
951
952 ScopedArrayObject scopedKeys(scope, keys);
953 ScopedArrayObject scopedValues(scope, values);
954
955 uint len = 0;
956
957 for (const QStringList& param : params) {
958
959 auto *valuePair = engine()->newArrayObject(2);
960
961 ScopedArrayObject valuePairObject(scope, valuePair);
962
963 ScopedValue key(scope, Value::fromHeapObject(engine()->newString(param[0])));
964 ScopedValue value(scope, Value::fromHeapObject(engine()->newString(param[1])));
965 valuePairObject->put(uint(0), key);
966 valuePairObject->put(uint(1), value);
967
968 scopedKeys->put(len, key);
969 scopedValues->put(len, value);
970
971 scopedArray->put(len, valuePairObject);
972 len++;
973 }
974
975 d()->params.set(engine(), arrayObject);
976 d()->keys.set(engine(), keys);
977 d()->values.set(engine(), values);
978}
979
980void UrlSearchParamsObject::setUrlObject(const UrlObject *url)
981{
982 d()->url.set(engine(), url->d());
983}
984
985void UrlSearchParamsObject::append(Heap::String *name, Heap::String *value)
986{
987 Scope scope(engine());
988
989 ScopedArrayObject scopedArray(scope, d()->params);
990 ScopedArrayObject scopedKeys(scope, d()->keys);
991 ScopedArrayObject scopedValues(scope, d()->values);
992
993 auto *valuePair = engine()->newArrayObject(2);
994
995 ScopedArrayObject valuePairObject(scope, valuePair);
996
997 ScopedValue keyScoped(scope, Value::fromHeapObject(name));
998 ScopedValue valueScoped(scope, Value::fromHeapObject(value));
999 valuePairObject->put(uint(0), keyScoped);
1000 valuePairObject->put(uint(1), valueScoped);
1001
1002 uint len = scopedArray->getLength();
1003
1004 scopedKeys->put(len, keyScoped);
1005 scopedValues->put(len, valueScoped);
1006
1007 scopedArray->put(len, valuePairObject);
1008}
1009
1010QList<QStringList> UrlSearchParamsObject::params() const
1011{
1012 auto *arrayObject = d()->params.get();
1013 Scope scope(engine());
1014 ScopedArrayObject scopedArray(scope, arrayObject);
1015
1016 QList<QStringList> result;
1017
1018 uint len = scopedArray->getLength();
1019
1020 for (uint i = 0; i < len; i++) {
1021 QV4::Value pair = Value::fromReturnedValue(scopedArray->get(i));
1022 auto *pairArrayObject = pair.as<ArrayObject>();
1023
1024 QV4::Value key = Value::fromReturnedValue(pairArrayObject->get(uint(0)));
1025 QV4::Value value = Value::fromReturnedValue(pairArrayObject->get(uint(1)));
1026
1027 result << QStringList { key.toQString(), value.toQString() };
1028 }
1029
1030 return result;
1031}
1032
1033Heap::UrlObject *UrlSearchParamsObject::urlObject() const
1034{
1035 return d()->url.get();
1036}
1037
1038QString UrlSearchParamsObject::searchString() const
1039{
1040 QString search = QLatin1String("");
1041 auto params = this->params();
1042 auto len = params.size();
1043 for (int i = 0; i < len; ++i) {
1044 const QStringList &param = params[i];
1045 search += param[0] + QLatin1Char('=') + param[1];
1046 if (i != len - 1)
1047 search += QLatin1Char('&');
1048 }
1049 return search;
1050}
1051
1052int UrlSearchParamsObject::length() const
1053{
1054 auto *arrayObject = d()->params.get();
1055 Scope scope(engine());
1056 ScopedArrayObject scopedArray(scope, arrayObject);
1057
1058 return scopedArray->getLength();
1059}
1060
1061int UrlSearchParamsObject::indexOf(QString name, int last) const
1062{
1063 auto *arrayObject = d()->params.get();
1064 Scope scope(engine());
1065 ScopedArrayObject scopedArray(scope, arrayObject);
1066
1067 int len = scopedArray->getLength();
1068
1069 for (int i = last + 1; i < len; i++) {
1070 // fromReturnedValue is safe, scopedArray is a normal array and takes care of marking
1071 QV4::Value pair = Value::fromReturnedValue(scopedArray->get(i));
1072 auto *pairArrayObject = pair.as<ArrayObject>();
1073
1074 QV4::Value key = Value::fromReturnedValue(pairArrayObject->get(uint(0)));
1075
1076 if (key.toQString() == name)
1077 return i;
1078 }
1079
1080 return -1;
1081}
1082
1083QString UrlSearchParamsObject::stringAt(int index, int pairIndex) const
1084{
1085 auto *arrayObject = d()->params.get();
1086 Scope scope(engine());
1087 ScopedArrayObject scopedArray(scope, arrayObject);
1088
1089 if (index >= scopedArray->getLength())
1090 return {};
1091
1092 QV4::Value pair = Value::fromReturnedValue(scopedArray->get(index));
1093 auto *pairArrayObject = pair.as<ArrayObject>();
1094
1095 QV4::Value value = Value::fromReturnedValue(pairArrayObject->get(pairIndex));
1096
1097 return value.toQString();
1098}
1099
1100QV4::Heap::String * UrlSearchParamsObject::stringAtRaw(int index, int pairIndex) const
1101{
1102 auto *arrayObject = d()->params.get();
1103 Scope scope(engine());
1104 ScopedArrayObject scopedArray(scope, arrayObject);
1105
1106 if (index >= scopedArray->getLength())
1107 return nullptr;
1108
1109 QV4::Value pair = Value::fromReturnedValue(scopedArray->get(index));
1110 auto *pairArrayObject = pair.as<ArrayObject>();
1111
1112 QV4::Value value = Value::fromReturnedValue(pairArrayObject->get(pairIndex));
1113
1114 return value.as<String>()->d();
1115}
1116
1117QString UrlSearchParamsObject::nameAt(int index) const
1118{
1119 return stringAt(index, 0);
1120}
1121
1122QV4::Heap::String * UrlSearchParamsObject::nameAtRaw(int index) const
1123{
1124 return stringAtRaw(index, 0);
1125}
1126
1127
1128QString UrlSearchParamsObject::valueAt(int index) const
1129{
1130 return stringAt(index, 1);
1131}
1132
1133QV4::Heap::String * UrlSearchParamsObject::valueAtRaw(int index) const
1134{
1135 return stringAtRaw(index, 1);
1136}
1137
1138
1140{
1142 PropertyKey next(const QV4::Object *o, Property *pd = nullptr,
1143 PropertyAttributes *attrs = nullptr) override;
1144};
1145
1147 PropertyAttributes *attrs)
1148{
1149 const UrlSearchParamsObject *usp = static_cast<const UrlSearchParamsObject *>(o);
1150
1151 Scope scope(usp);
1152
1153 uint len = usp->length();
1154 if (arrayIndex < len) {
1155 uint index = arrayIndex;
1156 ++arrayIndex;
1157 if (attrs)
1158 *attrs = Attr_NotConfigurable | Attr_NotWritable;
1159 if (pd)
1160 pd->value = usp->engine()->newString(usp->nameAt(index));
1161 return PropertyKey::fromArrayIndex(index);
1162 }
1163
1164 return ObjectOwnPropertyKeyIterator::next(o, pd, attrs);
1165}
1166
1167OwnPropertyKeyIterator *UrlSearchParamsObject::virtualOwnPropertyKeys(const Object *m,
1168 Value *target)
1169{
1170 *target = *m;
1171 return new UrlSearchParamsObjectOwnPropertyKeyIterator;
1172}
1173
1174PropertyAttributes UrlSearchParamsObject::virtualGetOwnProperty(const Managed *m, PropertyKey id,
1175 Property *p)
1176{
1177 PropertyAttributes attributes = Object::virtualGetOwnProperty(m, id, p);
1178 if (attributes != Attr_Invalid)
1179 return attributes;
1180
1181 if (id.isArrayIndex()) {
1182 const int index = id.asArrayIndex();
1183 const auto usp = static_cast<const UrlSearchParamsObject *>(m);
1184 if (index < usp->length()) {
1185 if (p)
1186 p->value = usp->engine()->newString(usp->nameAt(index));
1187 return Attr_NotConfigurable | Attr_NotWritable;
1188 }
1189 }
1190
1191 return Object::virtualGetOwnProperty(m, id, p);
1192}
1193
1194static bool checkSearchParamsType(ExecutionEngine *v4, const Scoped<UrlSearchParamsObject> &o)
1195{
1196 if (o)
1197 return true;
1198
1199 v4->throwTypeError(QStringLiteral("Value of \"this\" must be of type URLSearchParams"));
1200 return false;
1201}
1202
1203ReturnedValue UrlSearchParamsPrototype::method_toString(
1204 const FunctionObject *b, const Value *thisObject, const Value *, int)
1205{
1206 ExecutionEngine *v4 = b->engine();
1207 Scope scope(v4);
1208
1209 Scoped<UrlSearchParamsObject> o(scope, thisObject);
1210 if (!checkSearchParamsType(v4, o))
1211 return Encode::undefined();
1212
1213 auto params = o->params();
1214
1215 QString value;
1216
1217 for (const QStringList &pair : params)
1218 value += QLatin1String("%1=%2&").arg(QString::fromUtf8(QUrl::toPercentEncoding(pair[0])),
1219 QString::fromUtf8(QUrl::toPercentEncoding(pair[1])));
1220
1221 value.chop(1);
1222
1223 return Encode(v4->newString(value));
1224}
1225
1226ReturnedValue UrlSearchParamsPrototype::method_sort(const FunctionObject *b, const Value *thisObject,
1227 const Value *, int)
1228{
1229 ExecutionEngine *v4 = b->engine();
1230 Scope scope(v4);
1231
1232 Scoped<UrlSearchParamsObject> o(scope, thisObject);
1233 if (!checkSearchParamsType(v4, o))
1234 return Encode::undefined();
1235
1236 QList<QStringList> params = o->params();
1237 std::stable_sort(params.begin(), params.end(), [](QStringList a, QStringList b) { return a[0] < b[0]; });
1238
1239 o->setParams(params);
1240
1241 return Encode::undefined();
1242}
1243
1244ReturnedValue UrlSearchParamsPrototype::method_append(const FunctionObject *b, const Value *thisObject,
1245 const Value *argv, int argc)
1246{
1247 ExecutionEngine *v4 = b->engine();
1248 Scope scope(v4);
1249
1250 if (argc != 2)
1251 return v4->throwError(QLatin1String("Bad amount of arguments"));
1252
1253 ScopedValue argName(scope, argv[0]);
1254 ScopedValue argValue(scope, argv[1]);
1255
1256 String *argNameString = argName->stringValue();
1257
1258 if (argNameString == nullptr)
1259 return v4->throwTypeError(QLatin1String("Invalid argument provided"));
1260
1261 ScopedString name(scope, argName->as<String>());
1262 ScopedString value(scope, argValue->toString(v4));
1263
1264 Scoped<UrlSearchParamsObject> o(scope, thisObject);
1265 if (!checkSearchParamsType(v4, o))
1266 return Encode::undefined();
1267
1268 o->append(name->d(), value->d());
1269
1270 return Encode::undefined();
1271}
1272
1273ReturnedValue UrlSearchParamsPrototype::method_delete(const FunctionObject *b, const Value *thisObject,
1274 const Value *argv, int argc)
1275{
1276 ExecutionEngine *v4 = b->engine();
1277 Scope scope(v4);
1278
1279 if (argc != 1)
1280 return v4->throwError(QLatin1String("Bad amount of arguments"));
1281
1282 ScopedValue argName(scope, argv[0]);
1283
1284 String *argNameString = argName->stringValue();
1285
1286 if (argNameString == nullptr)
1287 return v4->throwTypeError(QLatin1String("Invalid argument provided"));
1288
1289 QString name = argNameString->toQString();
1290
1291 Scoped<UrlSearchParamsObject> o(scope, thisObject);
1292 if (!checkSearchParamsType(v4, o))
1293 return Encode::undefined();
1294
1295 QList<QStringList> params = o->params();
1296 params.removeIf([&name](const auto &pair) { return pair.at(0) == name; });
1297
1298 o->setParams(params);
1299
1300 return Encode::undefined();
1301}
1302
1303ReturnedValue UrlSearchParamsPrototype::method_has(const FunctionObject *b, const Value *thisObject,
1304 const Value *argv, int argc)
1305{
1306 ExecutionEngine *v4 = b->engine();
1307 Scope scope(v4);
1308
1309 if (argc != 1)
1310 return v4->throwError(QLatin1String("Bad amount of arguments"));
1311
1312 ScopedValue argName(scope, argv[0]);
1313
1314 String *argNameString = argName->stringValue();
1315
1316 if (argNameString == nullptr)
1317 return v4->throwTypeError(QLatin1String("Invalid argument provided"));
1318
1319 Scoped<UrlSearchParamsObject> o(scope, thisObject);
1320 if (!checkSearchParamsType(v4, o))
1321 return Encode::undefined();
1322
1323 QString name = argNameString->toQString();
1324
1325 return Encode(o->indexOf(name) != -1);
1326}
1327
1328ReturnedValue UrlSearchParamsPrototype::method_set(const FunctionObject *b, const Value *thisObject,
1329 const Value *argv, int argc)
1330{
1331 ExecutionEngine *v4 = b->engine();
1332 Scope scope(v4);
1333
1334 if (argc != 2)
1335 return v4->throwError(QLatin1String("Bad amount of arguments"));
1336
1337 ScopedValue argName(scope, argv[0]);
1338 ScopedValue argValue(scope, argv[1]);
1339
1340 String *argNameString = argName->stringValue();
1341
1342 if (argNameString == nullptr)
1343 return v4->throwTypeError(QLatin1String("Invalid argument provided"));
1344
1345 Scoped<UrlSearchParamsObject> o(scope, thisObject);
1346 if (!checkSearchParamsType(v4, o))
1347 return Encode::undefined();
1348
1349 QString name = argNameString->toQString();
1350 QString value = argValue->toQString();
1351
1352 auto params = o->params();
1353
1354 bool matched = false;
1355
1356 for (auto it = params.begin(); it != params.end();) {
1357 QStringList &param = *it;
1358 if (param[0] == name) {
1359 if (!matched) {
1360 param[1] = value;
1361 matched = true;
1362 } else {
1363 it = params.erase(it);
1364 continue;
1365 }
1366 }
1367 it++;
1368 }
1369
1370 if (!matched)
1371 params << QStringList { name, value };
1372
1373 o->setParams(params);
1374
1375 Scoped<UrlObject> scopedUrlObject(scope, o->d()->url.get());
1376 if (scopedUrlObject)
1377 scopedUrlObject->setSearch(o->searchString());
1378
1379 return Encode::undefined();
1380}
1381
1382ReturnedValue UrlSearchParamsPrototype::method_get(const FunctionObject *b, const Value *thisObject,
1383 const Value *argv, int argc)
1384{
1385 ExecutionEngine *v4 = b->engine();
1386 Scope scope(v4);
1387
1388 if (argc != 1)
1389 return v4->throwError(QLatin1String("Bad amount of arguments"));
1390
1391 ScopedValue argName(scope, argv[0]);
1392
1393 String *argNameString = argName->stringValue();
1394
1395 if (argNameString == nullptr)
1396 return v4->throwTypeError(QLatin1String("Invalid argument provided"));
1397
1398 Scoped<UrlSearchParamsObject> o(scope, thisObject);
1399 if (!checkSearchParamsType(v4, o))
1400 return Encode::undefined();
1401
1402 QString name = argNameString->toQString();
1403
1404 int index = o->indexOf(name);
1405
1406 if (index == -1)
1407 return Encode::null();
1408
1409 return Encode(o->valueAtRaw(index));
1410}
1411
1412ReturnedValue UrlSearchParamsPrototype::method_getAll(const FunctionObject *b,
1413 const Value *thisObject, const Value *argv,
1414 int argc)
1415{
1416 ExecutionEngine *v4 = b->engine();
1417 Scope scope(v4);
1418
1419 if (argc != 1)
1420 return v4->throwError(QLatin1String("Bad amount of arguments"));
1421
1422 ScopedValue argName(scope, argv[0]);
1423
1424 String *argNameString = argName->stringValue();
1425
1426 if (argNameString == nullptr)
1427 return v4->throwTypeError(QLatin1String("Invalid argument provided"));
1428
1429 Scoped<UrlSearchParamsObject> o(scope, thisObject);
1430 if (!checkSearchParamsType(v4, o))
1431 return Encode::undefined();
1432
1433 QString name = argNameString->toQString();
1434
1435 auto *arrayObject = v4->newArrayObject(0);
1436 ScopedArrayObject result(scope, arrayObject);
1437
1438 int i = 0;
1439 for (int index = o->indexOf(name); index != -1; index = o->indexOf(name, index)) {
1440 ScopedValue value(scope, Value::fromHeapObject(o->valueAtRaw(index)));
1441 result->put(i++, value);
1442 }
1443
1444 return Encode(arrayObject);
1445}
1446
1447ReturnedValue UrlSearchParamsPrototype::method_forEach(const FunctionObject *b,
1448 const Value *thisObject, const Value *argv,
1449 int argc)
1450{
1451 ExecutionEngine *v4 = b->engine();
1452 Scope scope(v4);
1453
1454 if (argc != 1)
1455 return v4->throwError(QLatin1String("Bad amount of arguments"));
1456
1457 ScopedValue argFunc(scope, argv[0]);
1458
1459 FunctionObject *func = argFunc->as<FunctionObject>();
1460
1461 if (func == nullptr)
1462 return v4->throwTypeError(QLatin1String("Invalid argument: must be a function"));
1463
1464 Scoped<UrlSearchParamsObject> o(scope, thisObject);
1465 if (!checkSearchParamsType(v4, o))
1466 return Encode::undefined();
1467
1468 for (int i = 0; i < o->length(); i++) {
1469 Scoped<String> name(scope, o->nameAtRaw(i));
1470 Scoped<String> value(scope, o->valueAtRaw(i));
1471
1472 QV4::JSCallArguments calldata(scope, 2);
1473
1474 calldata.args[0] = value;
1475 calldata.args[1] = name;
1476
1477 func->call(calldata);
1478 }
1479
1480 return Encode::undefined();
1481}
1482
1483ReturnedValue UrlSearchParamsPrototype::method_entries(const FunctionObject *b,
1484 const Value *thisObject, const Value *,
1485 int argc)
1486{
1487 ExecutionEngine *v4 = b->engine();
1488 Scope scope(v4);
1489
1490 if (argc != 0)
1491 return v4->throwError(QLatin1String("Bad amount of arguments"));
1492
1493 Scoped<UrlSearchParamsObject> o(scope, thisObject);
1494 if (!checkSearchParamsType(v4, o))
1495 return Encode::undefined();
1496
1497 ScopedObject params(scope, o->d()->params.get());
1498
1499 Scoped<ArrayIteratorObject> paramsIterator(scope, v4->newArrayIteratorObject(params));
1500 paramsIterator->d()->iterationKind = IteratorKind::KeyValueIteratorKind;
1501 return paramsIterator->asReturnedValue();
1502}
1503
1504ReturnedValue UrlSearchParamsPrototype::method_keys(const FunctionObject *b,
1505 const Value *thisObject, const Value *,
1506 int argc)
1507{
1508 ExecutionEngine *v4 = b->engine();
1509 Scope scope(v4);
1510
1511 if (argc != 0)
1512 return v4->throwError(QLatin1String("Bad amount of arguments"));
1513
1514 Scoped<UrlSearchParamsObject> o(scope, thisObject);
1515 if (!checkSearchParamsType(v4, o))
1516 return Encode::undefined();
1517
1518 ScopedObject keys(scope, o->d()->keys.get());
1519
1520 Scoped<ArrayIteratorObject> keysIterator(scope, v4->newArrayIteratorObject(keys));
1521 keysIterator->d()->iterationKind = IteratorKind::KeyValueIteratorKind;
1522 return keysIterator->asReturnedValue();
1523}
1524
1525ReturnedValue UrlSearchParamsPrototype::method_values(const FunctionObject *b,
1526 const Value *thisObject, const Value *,
1527 int argc)
1528{
1529 ExecutionEngine *v4 = b->engine();
1530 Scope scope(v4);
1531
1532 if (argc != 0)
1533 return v4->throwError(QLatin1String("Bad amount of arguments"));
1534
1535 Scoped<UrlSearchParamsObject> o(scope, thisObject);
1536 if (!checkSearchParamsType(v4, o))
1537 return Encode::undefined();
1538
1539 ScopedObject values(scope, o->d()->values.get());
1540
1541 Scoped<ArrayIteratorObject> valuesIterator(scope, v4->newArrayIteratorObject(values));
1542 valuesIterator->d()->iterationKind = IteratorKind::KeyValueIteratorKind;
1543 return valuesIterator->asReturnedValue();
1544}
Definition qjsvalue.h:23
DEFINE_OBJECT_VTABLE(UrlCtor)
DEFINE_OBJECT_VTABLE(UrlSearchParamsObject)
DEFINE_OBJECT_VTABLE(UrlSearchParamsCtor)
static bool checkSearchParamsType(ExecutionEngine *v4, const Scoped< UrlSearchParamsObject > &o)
static bool checkUrlObjectType(ExecutionEngine *v4, const Scoped< UrlObject > &r)
DEFINE_OBJECT_VTABLE(UrlObject)
PropertyKey next(const QV4::Object *o, Property *pd=nullptr, PropertyAttributes *attrs=nullptr) override
~UrlSearchParamsObjectOwnPropertyKeyIterator() override=default