script: Update name validation for attribute, element, and doctype (#37747)

A recent update in the spec (https://github.com/whatwg/dom/pull/1079)
introduced new rules for name validation of attribute, element, and
doctype. This PR implements the new name validation rules in
`components/script/dom/bindings/domname.rs`. The old XML name validation
rules are not fully removed because there remains a few usage of it in
`ProcessingInstructions` and `xpath`.

Testing: Covered by WPT tests
Fixes: #37746

---------

Signed-off-by: minghuaw <michael.wu1107@gmail.com>
Signed-off-by: Minghua Wu <michael.wu1107@gmail.com>
Co-authored-by: Xiaocheng Hu <xiaochengh.work@gmail.com>
This commit is contained in:
minghuaw 2025-07-11 10:45:52 +08:00 committed by GitHub
parent e14556959d
commit 5b507dc871
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 380 additions and 872 deletions

View file

@ -110,6 +110,9 @@ use crate::dom::bindings::codegen::Bindings::XPathNSResolverBinding::XPathNSReso
use crate::dom::bindings::codegen::UnionTypes::{
NodeOrString, StringOrElementCreationOptions, TrustedHTMLOrString,
};
use crate::dom::bindings::domname::{
self, is_valid_attribute_local_name, is_valid_element_local_name, namespace_from_domstring,
};
use crate::dom::bindings::error::{Error, ErrorInfo, ErrorResult, Fallible};
use crate::dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId};
use crate::dom::bindings::num::Finite;
@ -120,9 +123,7 @@ use crate::dom::bindings::str::{DOMString, USVString};
use crate::dom::bindings::trace::{HashMapTracedValues, NoTrace};
#[cfg(feature = "webgpu")]
use crate::dom::bindings::weakref::WeakRef;
use crate::dom::bindings::xmlname::{
matches_name_production, namespace_from_domstring, validate_and_extract,
};
use crate::dom::bindings::xmlname::matches_name_production;
use crate::dom::canvasrenderingcontext2d::CanvasRenderingContext2D;
use crate::dom::cdatasection::CDATASection;
use crate::dom::clipboardevent::{ClipboardEvent, ClipboardEventType};
@ -5507,8 +5508,9 @@ impl DocumentMethods<crate::DomTypeHolder> for Document {
options: StringOrElementCreationOptions,
can_gc: CanGc,
) -> Fallible<DomRoot<Element>> {
// Step 1. If localName does not match the Name production, then throw an "InvalidCharacterError" DOMException.
if !matches_name_production(&local_name) {
// Step 1. If localName is not a valid element local name,
// then throw an "InvalidCharacterError" DOMException.
if !is_valid_element_local_name(&local_name) {
debug!("Not a valid element name");
return Err(Error::InvalidCharacter);
}
@ -5549,9 +5551,11 @@ impl DocumentMethods<crate::DomTypeHolder> for Document {
options: StringOrElementCreationOptions,
can_gc: CanGc,
) -> Fallible<DomRoot<Element>> {
// Step 1. Let namespace, prefix, and localName be the result of passing namespace and qualifiedName
// to validate and extract.
let (namespace, prefix, local_name) = validate_and_extract(namespace, &qualified_name)?;
// Step 1. Let (namespace, prefix, localName) be the result of
// validating and extracting namespace and qualifiedName given "element".
let context = domname::Context::Element;
let (namespace, prefix, local_name) =
domname::validate_and_extract(namespace, &qualified_name, context)?;
// Step 2. Let is be null.
// Step 3. If options is a dictionary and options["is"] exists, then set is to it.
@ -5577,10 +5581,10 @@ impl DocumentMethods<crate::DomTypeHolder> for Document {
/// <https://dom.spec.whatwg.org/#dom-document-createattribute>
fn CreateAttribute(&self, mut local_name: DOMString, can_gc: CanGc) -> Fallible<DomRoot<Attr>> {
// Step 1. If localName does not match the Name production in XML,
// then throw an "InvalidCharacterError" DOMException.
if !matches_name_production(&local_name) {
debug!("Not a valid element name");
// Step 1. If localName is not a valid attribute local name,
// then throw an "InvalidCharacterError" DOMException
if !is_valid_attribute_local_name(&local_name) {
debug!("Not a valid attribute name");
return Err(Error::InvalidCharacter);
}
if self.is_html_document {
@ -5608,7 +5612,11 @@ impl DocumentMethods<crate::DomTypeHolder> for Document {
qualified_name: DOMString,
can_gc: CanGc,
) -> Fallible<DomRoot<Attr>> {
let (namespace, prefix, local_name) = validate_and_extract(namespace, &qualified_name)?;
// Step 1. Let (namespace, prefix, localName) be the result of validating and
// extracting namespace and qualifiedName given "attribute".
let context = domname::Context::Attribute;
let (namespace, prefix, local_name) =
domname::validate_and_extract(namespace, &qualified_name, context)?;
let value = AttrValue::String("".to_owned());
let qualified_name = LocalName::from(qualified_name);
Ok(Attr::new(