| Commit-Queue | +1 |
Hey Mason, here's the promised CL for SCER logic clean up. I was exploring using enum, but ended up finding using optional to be a fairly clean solution here. Lemme know how you think and we can iterate on it :)
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
Element::SetCustomElementRegistry interpret as the single authority:
* std::nullopt -> inherit (resolve to the document's global registry)
* std::optional(null) -> wait for a scoped registry to be assigned later
* std::optional(reg) -> explicit registry assignmentI still think this sets us up for bugs in the future:
`nullptr` - wait
`nullopt` - inherit
those are the same down to moving two letters and replacing one. Very easy to misread, and you always have to go look up which one means what.
How about you introduce a holding class that makes this all very clear. E.g.
```
class RegistryAssignment {
public:
enum class Type {
kInherit,
kExplicit,
kWaitForScopedRegistry
};
static RegistryAssignment Inherit() {
return RegistryAssignment(Type::kInherit, nullptr);
}
static RegistryAssignment Wait() {
return RegistryAssignment(Type::kWaitForScope, nullptr);
}
static RegistryAssignment Explicit(CustomElementRegistry*
registry) {
return RegistryAssignment(Type::kExplicit, registry);
}
bool IsInherit() const { return type_ == Type::kInherit; }
bool IsWait() const { return type_ == Type::kWaitForScope; }
bool IsExplicit() const { return type_ == Type::kExplicit; } CustomElementRegistry* Registry() const {
DCHECK(IsExplicit()); // Or whatever
return registry_;
}private:
RegistryAssignment(Type type, CustomElementRegistry* registry)
: type_(type), registry_(registry) {}
Type type_;
CustomElementRegistry* registry_;
};
```
Or something like that.
// std::nullopt means "inherit": the element resolves its registry through thee.g. you shouldn't need this comment
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
explanatory comments ateach site.Jayson Chennit: at each
Done
Element::SetCustomElementRegistry interpret as the single authority:
* std::nullopt -> inherit (resolve to the document's global registry)
* std::optional(null) -> wait for a scoped registry to be assigned later
* std::optional(reg) -> explicit registry assignmentDone.
// std::nullopt means "inherit": the element resolves its registry through thee.g. you shouldn't need this comment
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
Generally, I like this new approach. It's very explicit and clear at the call sites what's going on. Thanks for the conversion. Some comments, but I think we're on the right track.
Replace the (pointer, bool) pair with a single
std::optional<CustomElementRegistry*> "assignment" that both
TreeScope::SetCustomElementRegistry and
Element::SetCustomElementRegistry interpret as the single authority:
* std::nullopt -> inherit (resolve to the document's global registry)
* std::optional(null) -> wait for a scoped registry to be assigned later
* std::optional(reg) -> explicit registry assignment
I think this needs a re-write.
CustomElementRegistryAssignment registry_assignment,nit: I think everywhere here, the variable name could likely just be `registry` and it'd still be pretty clear.
if (RuntimeEnabledFeatures::ScopedCustomElementRegistryEnabled() &&
shadow_root->IsWaitingForScopedRegistry()) {
registry_assignment = CustomElementRegistryAssignment::Wait();
} else if (shadow_root_registry) {
registry_assignment =
CustomElementRegistryAssignment::Explicit(shadow_root_registry);
}nit:
```
CustomElementRegistryAssignment registry_assignment =
CustomElementRegistryAssignment::Inherit();
if (RuntimeEnabledFeatures::ScopedCustomElementRegistryEnabled()) {
if (shadow_root->IsWaitingForScopedRegistry()) {
registry_assignment = CustomElementRegistryAssignment::Wait();
} else if (shadow_root_registry) {
registry_assignment =
CustomElementRegistryAssignment::Explicit(shadow_root_registry);
}
} else {
DCHECK(!shadow_root_registry);
}
```
CustomElementRegistryAssignment assignment,nit: `registry`
bool explicitly_set) {It seems like `explicitly_set` needs to be removed, right? And replaced with a check of the `CustomElementRegistryAssignment` from the first param?
if (!RuntimeEnabledFeatures::ScopedCustomElementRegistryEnabled()) {
return;
}Why can't this stay a DCHECK?
mode, focus_delegation, slot_assignment, registry, serializable, clonable,This is currently implicitly converting to `CustomElementRegistryAssignment`. Likely this needs to be manually converted here/above.
CustomElementRegistryAssignment registry_assignment =
CustomElementRegistryAssignment::Inherit();
if (waiting_for_scoped_registry) {
registry_assignment = CustomElementRegistryAssignment::Wait();
} else if (registry) {
registry_assignment = CustomElementRegistryAssignment::Explicit(registry);
}Since roughly this pattern happens a couple places, maybe make a constructor like
```
CustomElementRegistryAssignment(bool wait_for_registry,
CustomElementRegistry* registry)
```
?
shadow_root.SetCustomElementRegistry(registry_assignment);Ahh - this answers my question from above. I think it'd be better to just do this here:
```
if (RuntimeEnabledFeatures::ScopedCustomElementRegistryEnabled()) {
shadow_root.SetCustomElementRegistry(registry);
}
```
waiting_for_registry_ = false;Do we need this on treescope? Perhaps just also store a CustomElementRegistryAssignment?
document_->SetCustomElementRegistry(custom_elements_.Get());Another implicit conversion
: type_(type), registry_(registry) {}Maybe also DCHECK here that things are correct, e.g. if it's Inherit, then registry should be null, etc.
return CustomElementRegistryAssignment(Type::kExplicit, registry);Maybe `DCHECK(registry)` here?
CustomElementRegistryAssignment(CustomElementRegistry* registry)This should definitely be `explicit` to avoid several implicit conversions above, some likely bugs.
// This is a transient, stack-only value (it holds a raw pointer and is never
// traced); do not store it as a member.Comment not needed - that's implied by `STACK_ALLOCATED()`.
// * Inherit -> resolve to the document's global registry (the
// default; nothing is stored).
// * Wait -> the registry is explicitly null and waiting for a
// scoped registry to be assigned later.
// * Explicit(reg) -> use `reg` (a scoped or global registry).But this is great.
// registry when one is assigned. This is an explicit, self-documenting
// replacement for a `(CustomElementRegistry*, bool waiting)` pair, whose three
// meaningful states were easy to confuse (see crbug.com/512514744):This sounds AI-ish, and likely isn't needed. 😊
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |