@@ -61,6 +61,7 @@ using v8::FunctionTemplate;
61
61
using v8::Global;
62
62
using v8::Isolate;
63
63
using v8::Local;
64
+ using v8::LocalVector;
64
65
using v8::MaybeLocal;
65
66
using v8::Name;
66
67
using v8::NewStringType;
@@ -284,27 +285,56 @@ MaybeLocal<Value> URLPattern::URLPatternInit::ToJsObject(
284
285
Environment* env, const ada::url_pattern_init& init) {
285
286
auto isolate = env->isolate ();
286
287
auto context = env->context ();
287
- auto result = Object::New (isolate);
288
288
289
- const auto trySet = [&](auto name, const std::optional<std::string>& val) {
290
- if (!val) return true ;
291
- Local<Value> temp;
292
- return ToV8Value (context, *val).ToLocal (&temp) &&
293
- result->Set (context, name, temp).IsJust ();
289
+ auto tmpl = env->urlpatterninit_template ();
290
+ if (tmpl.IsEmpty ()) {
291
+ static constexpr std::string_view namesVec[] = {
292
+ " protocol" ,
293
+ " username" ,
294
+ " password" ,
295
+ " hostname" ,
296
+ " port" ,
297
+ " pathname" ,
298
+ " search" ,
299
+ " hash" ,
300
+ " baseURL" ,
301
+ };
302
+ tmpl = DictionaryTemplate::New (isolate, namesVec);
303
+ env->set_urlpatterninit_template (tmpl);
304
+ }
305
+
306
+ MaybeLocal<Value> values[] = {
307
+ Undefined (isolate), // protocol
308
+ Undefined (isolate), // username
309
+ Undefined (isolate), // password
310
+ Undefined (isolate), // hostname
311
+ Undefined (isolate), // port
312
+ Undefined (isolate), // pathname
313
+ Undefined (isolate), // search
314
+ Undefined (isolate), // hash
315
+ Undefined (isolate), // baseURL
316
+ };
317
+
318
+ int idx = 0 ;
319
+ Local<Value> temp;
320
+ const auto trySet = [&](const std::optional<std::string>& val) {
321
+ if (val.has_value ()) {
322
+ if (!ToV8Value (context, *val).ToLocal (&temp)) {
323
+ return false ;
324
+ }
325
+ values[idx] = temp;
326
+ }
327
+ idx++;
328
+ return true ;
294
329
};
295
330
296
- if (!trySet (env->protocol_string (), init.protocol ) ||
297
- !trySet (env->username_string (), init.username ) ||
298
- !trySet (env->password_string (), init.password ) ||
299
- !trySet (env->hostname_string (), init.hostname ) ||
300
- !trySet (env->port_string (), init.port ) ||
301
- !trySet (env->pathname_string (), init.pathname ) ||
302
- !trySet (env->search_string (), init.search ) ||
303
- !trySet (env->hash_string (), init.hash ) ||
304
- !trySet (env->base_url_string (), init.base_url )) {
331
+ if (!trySet (init.protocol ) || !trySet (init.username ) ||
332
+ !trySet (init.password ) || !trySet (init.hostname ) || !trySet (init.port ) ||
333
+ !trySet (init.pathname ) || !trySet (init.search ) || !trySet (init.hash ) ||
334
+ !trySet (init.base_url )) {
305
335
return {};
306
336
}
307
- return result ;
337
+ return NewDictionaryInstance (env-> context (), tmpl, values) ;
308
338
}
309
339
310
340
std::optional<ada::url_pattern_init> URLPattern::URLPatternInit::FromJsObject (
@@ -364,12 +394,16 @@ MaybeLocal<Object> URLPattern::URLPatternComponentResult::ToJSObject(
364
394
Environment* env, const ada::url_pattern_component_result& result) {
365
395
auto isolate = env->isolate ();
366
396
auto context = env->context ();
367
- auto parsed_group = Object::New (isolate);
397
+ LocalVector<Name> group_names (isolate);
398
+ LocalVector<Value> group_values (isolate);
399
+ group_names.reserve (result.groups .size ());
400
+ group_values.reserve (result.groups .size ());
368
401
for (const auto & [group_key, group_value] : result.groups ) {
369
402
Local<Value> key;
370
403
if (!ToV8Value (context, group_key).ToLocal (&key)) {
371
404
return {};
372
405
}
406
+ group_names.push_back (key.As <Name>());
373
407
Local<Value> value;
374
408
if (group_value) {
375
409
if (!ToV8Value (env->context (), *group_value).ToLocal (&value)) {
@@ -378,19 +412,30 @@ MaybeLocal<Object> URLPattern::URLPatternComponentResult::ToJSObject(
378
412
} else {
379
413
value = Undefined (isolate);
380
414
}
381
- if (parsed_group->Set (context, key, value).IsNothing ()) {
382
- return {};
383
- }
415
+ group_values.push_back (value);
384
416
}
417
+ auto parsed_group = Object::New (isolate,
418
+ Object::New (isolate),
419
+ group_names.data (),
420
+ group_values.data (),
421
+ group_names.size ());
422
+
385
423
Local<Value> input;
386
424
if (!ToV8Value (env->context (), result.input ).ToLocal (&input)) {
387
425
return {};
388
426
}
389
- Local<Name> names[] = {env->input_string (), env->groups_string ()};
390
- Local<Value> values[] = {input, parsed_group};
391
- DCHECK_EQ (arraysize (names), arraysize (values));
392
- return Object::New (
393
- isolate, Object::New (isolate), names, values, arraysize (names));
427
+
428
+ auto tmpl = env->urlpatterncomponentresult_template ();
429
+ if (tmpl.IsEmpty ()) {
430
+ static constexpr std::string_view namesVec[] = {
431
+ " input" ,
432
+ " groups" ,
433
+ };
434
+ tmpl = DictionaryTemplate::New (isolate, namesVec);
435
+ env->set_urlpatterncomponentresult_template (tmpl);
436
+ }
437
+ MaybeLocal<Value> values[] = {input, parsed_group};
438
+ return NewDictionaryInstance (env->context (), tmpl, values);
394
439
}
395
440
396
441
MaybeLocal<Value> URLPattern::URLPatternResult::ToJSValue (
0 commit comments