@@ -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,61 @@ 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 ) ||
332+ !trySet (init.username ) ||
333+ !trySet (init.password ) ||
334+ !trySet (init.hostname ) ||
335+ !trySet (init.port ) ||
336+ !trySet (init.pathname ) ||
337+ !trySet (init.search ) ||
338+ !trySet (init.hash ) ||
339+ !trySet (init.base_url )) {
305340 return {};
306341 }
307- return result ;
342+ return NewDictionaryInstance (env-> context (), tmpl, values) ;
308343}
309344
310345std::optional<ada::url_pattern_init> URLPattern::URLPatternInit::FromJsObject (
@@ -364,12 +399,16 @@ MaybeLocal<Object> URLPattern::URLPatternComponentResult::ToJSObject(
364399 Environment* env, const ada::url_pattern_component_result& result) {
365400 auto isolate = env->isolate ();
366401 auto context = env->context ();
367- auto parsed_group = Object::New (isolate);
402+ LocalVector<Name> group_names (isolate);
403+ LocalVector<Value> group_values (isolate);
404+ group_names.reserve (result.groups .size ());
405+ group_values.reserve (result.groups .size ());
368406 for (const auto & [group_key, group_value] : result.groups ) {
369407 Local<Value> key;
370408 if (!ToV8Value (context, group_key).ToLocal (&key)) {
371409 return {};
372410 }
411+ group_names.push_back (key.As <Name>());
373412 Local<Value> value;
374413 if (group_value) {
375414 if (!ToV8Value (env->context (), *group_value).ToLocal (&value)) {
@@ -378,19 +417,27 @@ MaybeLocal<Object> URLPattern::URLPatternComponentResult::ToJSObject(
378417 } else {
379418 value = Undefined (isolate);
380419 }
381- if (parsed_group->Set (context, key, value).IsNothing ()) {
382- return {};
383- }
420+ group_values.push_back (value);
384421 }
422+ auto parsed_group = Object::New (isolate, Object::New (isolate),
423+ group_names.data (), group_values.data (), group_names.size ());
424+
385425 Local<Value> input;
386426 if (!ToV8Value (env->context (), result.input ).ToLocal (&input)) {
387427 return {};
388428 }
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));
429+
430+ auto tmpl = env->urlpatterncomponentresult_template ();
431+ if (tmpl.IsEmpty ()) {
432+ static constexpr std::string_view namesVec[] = {
433+ " input" ,
434+ " groups" ,
435+ };
436+ tmpl = DictionaryTemplate::New (isolate, namesVec);
437+ env->set_urlpatterncomponentresult_template (tmpl);
438+ }
439+ MaybeLocal<Value> values[] = {input, parsed_group};
440+ return NewDictionaryInstance (env->context (), tmpl, values);
394441}
395442
396443MaybeLocal<Value> URLPattern::URLPatternResult::ToJSValue (
0 commit comments