Skip to content

Commit ce8e50a

Browse files
committed
src: use DictionaryTemplate more in URLPattern
1 parent 15c276d commit ce8e50a

File tree

2 files changed

+74
-25
lines changed

2 files changed

+74
-25
lines changed

src/env_properties.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,8 @@
467467
V(streambaseoutputstream_constructor_template, v8::ObjectTemplate) \
468468
V(tcp_constructor_template, v8::FunctionTemplate) \
469469
V(tty_constructor_template, v8::FunctionTemplate) \
470+
V(urlpatterncomponentresult_template, v8::DictionaryTemplate) \
471+
V(urlpatterninit_template, v8::DictionaryTemplate) \
470472
V(urlpatternresult_template, v8::DictionaryTemplate) \
471473
V(write_wrap_template, v8::ObjectTemplate) \
472474
V(worker_cpu_profile_taker_template, v8::ObjectTemplate) \

src/node_url_pattern.cc

Lines changed: 72 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ using v8::FunctionTemplate;
6161
using v8::Global;
6262
using v8::Isolate;
6363
using v8::Local;
64+
using v8::LocalVector;
6465
using v8::MaybeLocal;
6566
using v8::Name;
6667
using 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

310345
std::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

396443
MaybeLocal<Value> URLPattern::URLPatternResult::ToJSValue(

0 commit comments

Comments
 (0)