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

@ -88,15 +88,16 @@ use crate::dom::bindings::codegen::UnionTypes::{
NodeOrString, TrustedHTMLOrNullIsEmptyString, TrustedHTMLOrString, TrustedScriptURLOrUSVString,
};
use crate::dom::bindings::conversions::DerivedFrom;
use crate::dom::bindings::domname::{
self, is_valid_attribute_local_name, namespace_from_domstring,
};
use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
use crate::dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId};
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
use crate::dom::bindings::reflector::DomObject;
use crate::dom::bindings::root::{Dom, DomRoot, LayoutDom, MutNullableDom, ToLayout};
use crate::dom::bindings::str::{DOMString, USVString};
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::characterdata::CharacterData;
use crate::dom::create::create_element;
use crate::dom::csp::{CspReporting, InlineCheckType};
@ -2664,6 +2665,7 @@ impl Element {
}
}
#[allow(non_snake_case)]
impl ElementMethods<crate::DomTypeHolder> for Element {
// https://dom.spec.whatwg.org/#dom-element-namespaceuri
fn GetNamespaceURI(&self) -> Option<DOMString> {
@ -2784,8 +2786,9 @@ impl ElementMethods<crate::DomTypeHolder> for Element {
force: Option<bool>,
can_gc: CanGc,
) -> Fallible<bool> {
// Step 1.
if !matches_name_production(&name) {
// Step 1. If qualifiedName is not a valid attribute local name,
// then throw an "InvalidCharacterError" DOMException.
if !is_valid_attribute_local_name(&name) {
return Err(Error::InvalidCharacter);
}
@ -2827,9 +2830,9 @@ impl ElementMethods<crate::DomTypeHolder> for Element {
/// <https://dom.spec.whatwg.org/#dom-element-setattribute>
fn SetAttribute(&self, name: DOMString, value: DOMString, can_gc: CanGc) -> ErrorResult {
// Step 1. If qualifiedName does not match the Name production in XML,
// then throw an "InvalidCharacterError" DOMException.
if !matches_name_production(&name) {
// Step 1. If qualifiedName is not a valid attribute local name,
// then throw an "InvalidCharacterError" DOMException.
if !is_valid_attribute_local_name(&name) {
return Err(Error::InvalidCharacter);
}
@ -2858,7 +2861,11 @@ impl ElementMethods<crate::DomTypeHolder> for Element {
value: DOMString,
can_gc: CanGc,
) -> ErrorResult {
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)?;
let qualified_name = LocalName::from(qualified_name);
let value = self.parse_attribute(&namespace, &local_name, value);
self.set_first_matching_attribute(