Skip to content

Commit d17f299

Browse files
jasnelltargos
authored andcommitted
src: use DictionaryTemplate more in URLPattern
PR-URL: #59892 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
1 parent 8f32746 commit d17f299

File tree

2 files changed

+72
-25
lines changed

2 files changed

+72
-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: 70 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,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

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

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

0 commit comments

Comments
 (0)