src: use DictionaryTemplate more in URLPattern · nodejs/node@d17f299

@@ -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);

288288289-

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

};

295330296-

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

}

309339310340

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

}

395440396441

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