@@ -61,6 +61,7 @@ using v8::FunctionTemplate;
6161using v8::Global;
6262using v8::Isolate;
6363using v8::Local;
64+ using v8::LocalVector;
6465using v8::MaybeLocal;
6566using v8::Name;
6667using v8::NewStringType;
@@ -284,27 +285,56 @@ MaybeLocal<Value> URLPattern::URLPatternInit::ToJsObject(
284285 Environment* env, const ada::url_pattern_init& init) {
285286 auto isolate = env->isolate ();
286287 auto context = env->context ();
287- auto result = Object::New (isolate);
288288
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 ;
294329 };
295330
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 )) {
305335 return {};
306336 }
307- return result ;
337+ return NewDictionaryInstance (env-> context (), tmpl, values) ;
308338}
309339
310340std::optional<ada::url_pattern_init> URLPattern::URLPatternInit::FromJsObject (
@@ -364,12 +394,16 @@ MaybeLocal<Object> URLPattern::URLPatternComponentResult::ToJSObject(
364394 Environment* env, const ada::url_pattern_component_result& result) {
365395 auto isolate = env->isolate ();
366396 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 ());
368401 for (const auto & [group_key, group_value] : result.groups ) {
369402 Local<Value> key;
370403 if (!ToV8Value (context, group_key).ToLocal (&key)) {
371404 return {};
372405 }
406+ group_names.push_back (key.As <Name>());
373407 Local<Value> value;
374408 if (group_value) {
375409 if (!ToV8Value (env->context (), *group_value).ToLocal (&value)) {
@@ -378,19 +412,30 @@ MaybeLocal<Object> URLPattern::URLPatternComponentResult::ToJSObject(
378412 } else {
379413 value = Undefined (isolate);
380414 }
381- if (parsed_group->Set (context, key, value).IsNothing ()) {
382- return {};
383- }
415+ group_values.push_back (value);
384416 }
417+ auto parsed_group = Object::New (isolate,
418+ Object::New (isolate),
419+ group_names.data (),
420+ group_values.data (),
421+ group_names.size ());
422+
385423 Local<Value> input;
386424 if (!ToV8Value (env->context (), result.input ).ToLocal (&input)) {
387425 return {};
388426 }
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);
394439}
395440
396441MaybeLocal<Value> URLPattern::URLPatternResult::ToJSValue (
0 commit comments