mirror of
https://github.com/servo/servo.git
synced 2025-07-14 19:03:40 +01:00
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:
parent
e14556959d
commit
5b507dc871
17 changed files with 380 additions and 872 deletions
219
components/script/dom/bindings/domname.rs
Normal file
219
components/script/dom/bindings/domname.rs
Normal file
|
@ -0,0 +1,219 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//! Functions for validating names as defined in the DOM Standard: <https://dom.spec.whatwg.org/#namespaces>
|
||||
|
||||
use html5ever::{LocalName, Namespace, Prefix, ns};
|
||||
use script_bindings::error::{Error, Fallible};
|
||||
use script_bindings::str::DOMString;
|
||||
|
||||
/// <https://infra.spec.whatwg.org/#xml-namespace>
|
||||
const XML_NAMESPACE: &str = "http://www.w3.org/XML/1998/namespace";
|
||||
|
||||
/// <https://infra.spec.whatwg.org/#xmlns-namespace>
|
||||
const XMLNS_NAMESPACE: &str = "http://www.w3.org/2000/xmlns/";
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#valid-namespace-prefix>
|
||||
fn is_valid_namespace_prefix(p: &str) -> bool {
|
||||
// A string is a valid namespace prefix if its length
|
||||
// is at least 1 and it does not contain ASCII whitespace,
|
||||
// U+0000 NULL, U+002F (/), or U+003E (>).
|
||||
|
||||
if p.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
!p.chars()
|
||||
.any(|c| c.is_ascii_whitespace() || matches!(c, '\u{0000}' | '\u{002F}' | '\u{003E}'))
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#valid-attribute-local-name>
|
||||
pub(crate) fn is_valid_attribute_local_name(name: &str) -> bool {
|
||||
// A string is a valid attribute local name if its length
|
||||
// is at least 1 and it does not contain ASCII whitespace,
|
||||
// U+0000 NULL, U+002F (/), U+003D (=), or U+003E (>).
|
||||
|
||||
if name.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
!name.chars().any(|c| {
|
||||
c.is_ascii_whitespace() || matches!(c, '\u{0000}' | '\u{002F}' | '\u{003D}' | '\u{003E}')
|
||||
})
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#valid-element-local-name>
|
||||
pub(crate) fn is_valid_element_local_name(name: &str) -> bool {
|
||||
// Step 1. If name’s length is 0, then return false.
|
||||
if name.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let mut iter = name.chars();
|
||||
|
||||
// SAFETY: we have already checked that the &str is not empty
|
||||
let c0 = iter.next().unwrap();
|
||||
|
||||
// Step 2. If name’s 0th code point is an ASCII alpha, then:
|
||||
if c0.is_ascii_alphabetic() {
|
||||
for c in iter {
|
||||
// Step 2.1 If name contains ASCII whitespace,
|
||||
// U+0000 NULL, U+002F (/), or U+003E (>), then return false.
|
||||
if c.is_ascii_whitespace() || matches!(c, '\u{0000}' | '\u{002F}' | '\u{003E}') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
// Step 3. If name’s 0th code point is not U+003A (:), U+005F (_),
|
||||
// or in the range U+0080 to U+10FFFF, inclusive, then return false.
|
||||
else if matches!(c0, '\u{003A}' | '\u{005F}' | '\u{0080}'..='\u{10FFF}') {
|
||||
for c in iter {
|
||||
// Step 4. If name’s subsequent code points,
|
||||
// if any, are not ASCII alphas, ASCII digits,
|
||||
// U+002D (-), U+002E (.), U+003A (:), U+005F (_),
|
||||
// or in the range U+0080 to U+10FFFF, inclusive,
|
||||
// then return false.
|
||||
if !c.is_ascii_alphanumeric() &&
|
||||
!matches!(
|
||||
c,
|
||||
'\u{002D}' | '\u{002E}' | '\u{003A}' | '\u{005F}' | '\u{0080}'..='\u{10FFF}'
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#valid-doctype-name>
|
||||
pub(crate) fn is_valid_doctype_name(name: &str) -> bool {
|
||||
// A string is a valid doctype name if it does not contain
|
||||
// ASCII whitespace, U+0000 NULL, or U+003E (>).
|
||||
!name
|
||||
.chars()
|
||||
.any(|c| c.is_ascii_whitespace() || matches!(c, '\u{0000}' | '\u{003E}'))
|
||||
}
|
||||
|
||||
/// Convert a possibly-null URL to a namespace.
|
||||
///
|
||||
/// If the URL is None, returns the empty namespace.
|
||||
pub(crate) fn namespace_from_domstring(url: Option<DOMString>) -> Namespace {
|
||||
match url {
|
||||
None => ns!(),
|
||||
Some(s) => Namespace::from(s),
|
||||
}
|
||||
}
|
||||
|
||||
/// Context for [`validate_and_extract`] a namespace and qualified name
|
||||
///
|
||||
/// <https://dom.spec.whatwg.org/#validate-and-extract>
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub(crate) enum Context {
|
||||
Attribute,
|
||||
Element,
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#validate-and-extract>
|
||||
pub(crate) fn validate_and_extract(
|
||||
namespace: Option<DOMString>,
|
||||
qualified_name: &str,
|
||||
context: Context,
|
||||
) -> Fallible<(Namespace, Option<Prefix>, LocalName)> {
|
||||
// Step 1. If namespace is the empty string, then set it to null.
|
||||
let namespace = namespace_from_domstring(namespace);
|
||||
|
||||
// Step 2. Let prefix be null.
|
||||
let mut prefix = None;
|
||||
// Step 3. Let localName be qualifiedName.
|
||||
let mut local_name = qualified_name;
|
||||
// Step 4. If qualifiedName contains a U+003A (:):
|
||||
if let Some(idx) = qualified_name.find(':') {
|
||||
// Step 4.1. Let splitResult be the result of running
|
||||
// strictly split given qualifiedName and U+003A (:).
|
||||
let p = &qualified_name[..idx];
|
||||
|
||||
// Step 5. If prefix is not a valid namespace prefix,
|
||||
// then throw an "InvalidCharacterError" DOMException.
|
||||
if !is_valid_namespace_prefix(p) {
|
||||
debug!("Not a valid namespace prefix");
|
||||
return Err(Error::InvalidCharacter);
|
||||
}
|
||||
|
||||
// Step 4.2. Set prefix to splitResult[0].
|
||||
prefix = Some(p);
|
||||
|
||||
// Step 4.3. Set localName to splitResult[1].
|
||||
let remaining = &qualified_name[(idx + 1).min(qualified_name.len())..];
|
||||
match remaining.find(':') {
|
||||
Some(end) => local_name = &remaining[..end],
|
||||
None => local_name = remaining,
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(p) = prefix {
|
||||
// Step 5. If prefix is not a valid namespace prefix,
|
||||
// then throw an "InvalidCharacterError" DOMException.
|
||||
if !is_valid_namespace_prefix(p) {
|
||||
debug!("Not a valid namespace prefix");
|
||||
return Err(Error::InvalidCharacter);
|
||||
}
|
||||
}
|
||||
|
||||
match context {
|
||||
// Step 6. If context is "attribute" and localName
|
||||
// is not a valid attribute local name, then
|
||||
// throw an "InvalidCharacterError" DOMException.
|
||||
Context::Attribute => {
|
||||
if !is_valid_attribute_local_name(local_name) {
|
||||
debug!("Not a valid attribute name");
|
||||
return Err(Error::InvalidCharacter);
|
||||
}
|
||||
},
|
||||
// Step 7. If context is "element" and localName
|
||||
// is not a valid element local name, then
|
||||
// throw an "InvalidCharacterError" DOMException.
|
||||
Context::Element => {
|
||||
if !is_valid_element_local_name(local_name) {
|
||||
debug!("Not a valid element name");
|
||||
return Err(Error::InvalidCharacter);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
match prefix {
|
||||
// Step 8. If prefix is non-null and namespace is null,
|
||||
// then throw a "NamespaceError" DOMException.
|
||||
Some(_) if namespace.is_empty() => Err(Error::Namespace),
|
||||
// Step 9. If prefix is "xml" and namespace is not the XML namespace,
|
||||
// then throw a "NamespaceError" DOMException.
|
||||
Some("xml") if *namespace != *XML_NAMESPACE => Err(Error::Namespace),
|
||||
// Step 10. If either qualifiedName or prefix is "xmlns" and namespace
|
||||
// is not the XMLNS namespace, then throw a "NamespaceError" DOMException.
|
||||
p if (qualified_name == "xmlns" || p == Some("xmlns")) &&
|
||||
*namespace != *XMLNS_NAMESPACE =>
|
||||
{
|
||||
Err(Error::Namespace)
|
||||
},
|
||||
Some(_) if qualified_name == "xmlns" && *namespace != *XMLNS_NAMESPACE => {
|
||||
Err(Error::Namespace)
|
||||
},
|
||||
// Step 11. If namespace is the XMLNS namespace and neither qualifiedName
|
||||
// nor prefix is "xmlns", then throw a "NamespaceError" DOMException.
|
||||
p if *namespace == *XMLNS_NAMESPACE &&
|
||||
(qualified_name != "xmlns" && p != Some("xmlns")) =>
|
||||
{
|
||||
Err(Error::Namespace)
|
||||
},
|
||||
// Step 12. Return (namespace, prefix, localName).
|
||||
_ => Ok((
|
||||
namespace,
|
||||
prefix.map(Prefix::from),
|
||||
LocalName::from(local_name),
|
||||
)),
|
||||
}
|
||||
}
|
|
@ -139,6 +139,7 @@ pub(crate) mod buffer_source;
|
|||
pub(crate) mod cell;
|
||||
pub(crate) mod constructor;
|
||||
pub(crate) mod conversions;
|
||||
pub(crate) mod domname;
|
||||
pub(crate) mod error;
|
||||
pub(crate) mod frozenarray;
|
||||
pub(crate) mod function;
|
||||
|
|
|
@ -4,14 +4,9 @@
|
|||
|
||||
//! Functions for validating and extracting qualified XML names.
|
||||
|
||||
use html5ever::{LocalName, Namespace, Prefix, ns};
|
||||
|
||||
use crate::dom::bindings::error::{Error, Fallible};
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
|
||||
/// Check if an element name is valid. See <http://www.w3.org/TR/xml/#NT-Name>
|
||||
/// for details.
|
||||
fn is_valid_start(c: char) -> bool {
|
||||
pub(crate) fn is_valid_start(c: char) -> bool {
|
||||
matches!(c, ':' |
|
||||
'A'..='Z' |
|
||||
'_' |
|
||||
|
@ -30,7 +25,7 @@ fn is_valid_start(c: char) -> bool {
|
|||
'\u{10000}'..='\u{EFFFF}')
|
||||
}
|
||||
|
||||
fn is_valid_continuation(c: char) -> bool {
|
||||
pub(crate) fn is_valid_continuation(c: char) -> bool {
|
||||
is_valid_start(c) ||
|
||||
matches!(c,
|
||||
'-' |
|
||||
|
@ -41,103 +36,6 @@ fn is_valid_continuation(c: char) -> bool {
|
|||
'\u{203F}'..='\u{2040}')
|
||||
}
|
||||
|
||||
/// Validate a qualified name. See <https://dom.spec.whatwg.org/#validate> for details.
|
||||
///
|
||||
/// On success, this returns a tuple `(prefix, local name)`.
|
||||
pub(crate) fn validate_and_extract_qualified_name(
|
||||
qualified_name: &str,
|
||||
) -> Fallible<(Option<&str>, &str)> {
|
||||
if qualified_name.is_empty() {
|
||||
// Qualified names must not be empty
|
||||
return Err(Error::InvalidCharacter);
|
||||
}
|
||||
let mut colon_offset = None;
|
||||
let mut at_start_of_name = true;
|
||||
|
||||
for (byte_position, c) in qualified_name.char_indices() {
|
||||
if c == ':' {
|
||||
if colon_offset.is_some() {
|
||||
// Qualified names must not contain more than one colon
|
||||
return Err(Error::InvalidCharacter);
|
||||
}
|
||||
colon_offset = Some(byte_position);
|
||||
at_start_of_name = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if at_start_of_name {
|
||||
if !is_valid_start(c) {
|
||||
// Name segments must begin with a valid start character
|
||||
return Err(Error::InvalidCharacter);
|
||||
}
|
||||
at_start_of_name = false;
|
||||
} else if !is_valid_continuation(c) {
|
||||
// Name segments must consist of valid characters
|
||||
return Err(Error::InvalidCharacter);
|
||||
}
|
||||
}
|
||||
|
||||
let Some(colon_offset) = colon_offset else {
|
||||
// Simple case: there is no prefix
|
||||
return Ok((None, qualified_name));
|
||||
};
|
||||
|
||||
let (prefix, local_name) = qualified_name.split_at(colon_offset);
|
||||
let local_name = &local_name[1..]; // Remove the colon
|
||||
|
||||
if prefix.is_empty() || local_name.is_empty() {
|
||||
// Neither prefix nor local name can be empty
|
||||
return Err(Error::InvalidCharacter);
|
||||
}
|
||||
|
||||
Ok((Some(prefix), local_name))
|
||||
}
|
||||
|
||||
/// Validate a namespace and qualified name and extract their parts.
|
||||
/// See <https://dom.spec.whatwg.org/#validate-and-extract> for details.
|
||||
pub(crate) fn validate_and_extract(
|
||||
namespace: Option<DOMString>,
|
||||
qualified_name: &str,
|
||||
) -> Fallible<(Namespace, Option<Prefix>, LocalName)> {
|
||||
// Step 1. If namespace is the empty string, then set it to null.
|
||||
let namespace = namespace_from_domstring(namespace);
|
||||
|
||||
// Step 2. Validate qualifiedName.
|
||||
// Step 3. Let prefix be null.
|
||||
// Step 4. Let localName be qualifiedName.
|
||||
// Step 5. If qualifiedName contains a U+003A (:):
|
||||
// NOTE: validate_and_extract_qualified_name does all of these things for us, because
|
||||
// it's easier to do them together
|
||||
let (prefix, local_name) = validate_and_extract_qualified_name(qualified_name)?;
|
||||
debug_assert!(!local_name.contains(':'));
|
||||
|
||||
match (namespace, prefix) {
|
||||
(ns!(), Some(_)) => {
|
||||
// Step 6. If prefix is non-null and namespace is null, then throw a "NamespaceError" DOMException.
|
||||
Err(Error::Namespace)
|
||||
},
|
||||
(ref ns, Some("xml")) if ns != &ns!(xml) => {
|
||||
// Step 7. If prefix is "xml" and namespace is not the XML namespace,
|
||||
// then throw a "NamespaceError" DOMException.
|
||||
Err(Error::Namespace)
|
||||
},
|
||||
(ref ns, p) if ns != &ns!(xmlns) && (qualified_name == "xmlns" || p == Some("xmlns")) => {
|
||||
// Step 8. If either qualifiedName or prefix is "xmlns" and namespace is not the XMLNS namespace,
|
||||
// then throw a "NamespaceError" DOMException.
|
||||
Err(Error::Namespace)
|
||||
},
|
||||
(ns!(xmlns), p) if qualified_name != "xmlns" && p != Some("xmlns") => {
|
||||
// Step 9. If namespace is the XMLNS namespace and neither qualifiedName nor prefix is "xmlns",
|
||||
// then throw a "NamespaceError" DOMException.
|
||||
Err(Error::Namespace)
|
||||
},
|
||||
(ns, p) => {
|
||||
// Step 10. Return namespace, prefix, and localName.
|
||||
Ok((ns, p.map(Prefix::from), LocalName::from(local_name)))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn matches_name_production(name: &str) -> bool {
|
||||
let mut iter = name.chars();
|
||||
|
||||
|
@ -146,13 +44,3 @@ pub(crate) fn matches_name_production(name: &str) -> bool {
|
|||
}
|
||||
iter.all(is_valid_continuation)
|
||||
}
|
||||
|
||||
/// Convert a possibly-null URL to a namespace.
|
||||
///
|
||||
/// If the URL is None, returns the empty namespace.
|
||||
pub(crate) fn namespace_from_domstring(url: Option<DOMString>) -> Namespace {
|
||||
match url {
|
||||
None => ns!(),
|
||||
Some(s) => Namespace::from(s),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
use dom_struct::dom_struct;
|
||||
use html5ever::{local_name, ns};
|
||||
use script_bindings::error::Error;
|
||||
use script_traits::DocumentActivity;
|
||||
|
||||
use crate::document_loader::DocumentLoader;
|
||||
|
@ -13,14 +14,12 @@ use crate::dom::bindings::codegen::Bindings::DocumentBinding::{
|
|||
};
|
||||
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||
use crate::dom::bindings::codegen::UnionTypes::StringOrElementCreationOptions;
|
||||
use crate::dom::bindings::domname::{is_valid_doctype_name, namespace_from_domstring};
|
||||
use crate::dom::bindings::error::Fallible;
|
||||
use crate::dom::bindings::inheritance::Castable;
|
||||
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::bindings::xmlname::{
|
||||
namespace_from_domstring, validate_and_extract_qualified_name,
|
||||
};
|
||||
use crate::dom::document::{Document, DocumentSource, HasBrowsingContext, IsHTMLDocument};
|
||||
use crate::dom::documenttype::DocumentType;
|
||||
use crate::dom::htmlbodyelement::HTMLBodyElement;
|
||||
|
@ -58,6 +57,7 @@ impl DOMImplementation {
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#domimplementation
|
||||
#[allow(non_snake_case)]
|
||||
impl DOMImplementationMethods<crate::DomTypeHolder> for DOMImplementation {
|
||||
/// <https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype>
|
||||
fn CreateDocumentType(
|
||||
|
@ -67,8 +67,12 @@ impl DOMImplementationMethods<crate::DomTypeHolder> for DOMImplementation {
|
|||
sysid: DOMString,
|
||||
can_gc: CanGc,
|
||||
) -> Fallible<DomRoot<DocumentType>> {
|
||||
// Step 1. Validate qualifiedName.
|
||||
validate_and_extract_qualified_name(&qualified_name)?;
|
||||
// Step 1. If name is not a valid doctype name, then throw an
|
||||
// "InvalidCharacterError" DOMException.
|
||||
if !is_valid_doctype_name(&qualified_name) {
|
||||
debug!("Not a valid doctype name");
|
||||
return Err(Error::InvalidCharacter);
|
||||
}
|
||||
|
||||
Ok(DocumentType::new(
|
||||
qualified_name,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -11,12 +11,12 @@ use style::str::split_html_space_chars;
|
|||
use stylo_atoms::Atom;
|
||||
|
||||
use crate::dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods;
|
||||
use crate::dom::bindings::domname::namespace_from_domstring;
|
||||
use crate::dom::bindings::inheritance::Castable;
|
||||
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::bindings::trace::JSTraceable;
|
||||
use crate::dom::bindings::xmlname::namespace_from_domstring;
|
||||
use crate::dom::element::Element;
|
||||
use crate::dom::node::{Node, NodeTraits};
|
||||
use crate::dom::window::Window;
|
||||
|
|
|
@ -8,11 +8,11 @@ use html5ever::LocalName;
|
|||
use crate::dom::attr::Attr;
|
||||
use crate::dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::NamedNodeMapBinding::NamedNodeMapMethods;
|
||||
use crate::dom::bindings::domname::namespace_from_domstring;
|
||||
use crate::dom::bindings::error::{Error, Fallible};
|
||||
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::bindings::xmlname::namespace_from_domstring;
|
||||
use crate::dom::element::Element;
|
||||
use crate::dom::window::Window;
|
||||
use crate::script_runtime::CanGc;
|
||||
|
|
|
@ -76,6 +76,7 @@ use crate::dom::bindings::codegen::Bindings::ShadowRootBinding::{
|
|||
use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
||||
use crate::dom::bindings::codegen::UnionTypes::NodeOrString;
|
||||
use crate::dom::bindings::conversions::{self, DerivedFrom};
|
||||
use crate::dom::bindings::domname::namespace_from_domstring;
|
||||
use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
|
||||
use crate::dom::bindings::inheritance::{
|
||||
Castable, CharacterDataTypeId, ElementTypeId, EventTargetTypeId, HTMLElementTypeId, NodeTypeId,
|
||||
|
@ -85,7 +86,6 @@ use crate::dom::bindings::refcounted::Trusted;
|
|||
use crate::dom::bindings::reflector::{DomObject, DomObjectWrap, reflect_dom_object_with_proto};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot, DomSlice, LayoutDom, MutNullableDom, ToLayout};
|
||||
use crate::dom::bindings::str::{DOMString, USVString};
|
||||
use crate::dom::bindings::xmlname::namespace_from_domstring;
|
||||
use crate::dom::characterdata::{CharacterData, LayoutCharacterDataHelpers};
|
||||
use crate::dom::cssstylesheet::CSSStyleSheet;
|
||||
use crate::dom::customelementregistry::{CallbackReaction, try_upgrade_element};
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
use std::fmt;
|
||||
|
||||
use html5ever::{QualName, local_name, namespace_prefix, ns};
|
||||
use html5ever::{LocalName, Namespace, Prefix, QualName, local_name, namespace_prefix, ns};
|
||||
|
||||
use super::parser::{
|
||||
AdditiveOp, Axis, EqualityOp, Expr, FilterExpr, KindTest, Literal, MultiplicativeOp, NodeTest,
|
||||
|
@ -14,9 +14,11 @@ use super::parser::{
|
|||
use super::{EvaluationCtx, Value};
|
||||
use crate::dom::attr::Attr;
|
||||
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||
use crate::dom::bindings::domname::namespace_from_domstring;
|
||||
use crate::dom::bindings::inheritance::{Castable, CharacterDataTypeId, NodeTypeId};
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::xmlname::validate_and_extract;
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::bindings::xmlname;
|
||||
use crate::dom::element::Element;
|
||||
use crate::dom::node::{Node, ShadowIncluding};
|
||||
use crate::dom::processinginstruction::ProcessingInstruction;
|
||||
|
@ -253,6 +255,111 @@ impl Evaluatable for PathExpr {
|
|||
}
|
||||
}
|
||||
|
||||
/// Error types for validate and extract a qualified name following
|
||||
/// the XML naming rules.
|
||||
#[derive(Debug)]
|
||||
enum ValidationError {
|
||||
InvalidCharacter,
|
||||
Namespace,
|
||||
}
|
||||
|
||||
/// Validate a qualified name following the XML naming rules.
|
||||
///
|
||||
/// On success, this returns a tuple `(prefix, local name)`.
|
||||
fn validate_and_extract_qualified_name(
|
||||
qualified_name: &str,
|
||||
) -> Result<(Option<&str>, &str), ValidationError> {
|
||||
if qualified_name.is_empty() {
|
||||
// Qualified names must not be empty
|
||||
return Err(ValidationError::InvalidCharacter);
|
||||
}
|
||||
let mut colon_offset = None;
|
||||
let mut at_start_of_name = true;
|
||||
|
||||
for (byte_position, c) in qualified_name.char_indices() {
|
||||
if c == ':' {
|
||||
if colon_offset.is_some() {
|
||||
// Qualified names must not contain more than one colon
|
||||
return Err(ValidationError::InvalidCharacter);
|
||||
}
|
||||
colon_offset = Some(byte_position);
|
||||
at_start_of_name = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if at_start_of_name {
|
||||
if !xmlname::is_valid_start(c) {
|
||||
// Name segments must begin with a valid start character
|
||||
return Err(ValidationError::InvalidCharacter);
|
||||
}
|
||||
at_start_of_name = false;
|
||||
} else if !xmlname::is_valid_continuation(c) {
|
||||
// Name segments must consist of valid characters
|
||||
return Err(ValidationError::InvalidCharacter);
|
||||
}
|
||||
}
|
||||
|
||||
let Some(colon_offset) = colon_offset else {
|
||||
// Simple case: there is no prefix
|
||||
return Ok((None, qualified_name));
|
||||
};
|
||||
|
||||
let (prefix, local_name) = qualified_name.split_at(colon_offset);
|
||||
let local_name = &local_name[1..]; // Remove the colon
|
||||
|
||||
if prefix.is_empty() || local_name.is_empty() {
|
||||
// Neither prefix nor local name can be empty
|
||||
return Err(ValidationError::InvalidCharacter);
|
||||
}
|
||||
|
||||
Ok((Some(prefix), local_name))
|
||||
}
|
||||
|
||||
/// Validate a namespace and qualified name following the XML naming rules
|
||||
/// and extract their parts.
|
||||
fn validate_and_extract(
|
||||
namespace: Option<DOMString>,
|
||||
qualified_name: &str,
|
||||
) -> Result<(Namespace, Option<Prefix>, LocalName), ValidationError> {
|
||||
// Step 1. If namespace is the empty string, then set it to null.
|
||||
let namespace = namespace_from_domstring(namespace);
|
||||
|
||||
// Step 2. Validate qualifiedName.
|
||||
// Step 3. Let prefix be null.
|
||||
// Step 4. Let localName be qualifiedName.
|
||||
// Step 5. If qualifiedName contains a U+003A (:):
|
||||
// NOTE: validate_and_extract_qualified_name does all of these things for us, because
|
||||
// it's easier to do them together
|
||||
let (prefix, local_name) = validate_and_extract_qualified_name(qualified_name)?;
|
||||
debug_assert!(!local_name.contains(':'));
|
||||
|
||||
match (namespace, prefix) {
|
||||
(ns!(), Some(_)) => {
|
||||
// Step 6. If prefix is non-null and namespace is null, then throw a "NamespaceError" DOMException.
|
||||
Err(ValidationError::Namespace)
|
||||
},
|
||||
(ref ns, Some("xml")) if ns != &ns!(xml) => {
|
||||
// Step 7. If prefix is "xml" and namespace is not the XML namespace,
|
||||
// then throw a "NamespaceError" DOMException.
|
||||
Err(ValidationError::Namespace)
|
||||
},
|
||||
(ref ns, p) if ns != &ns!(xmlns) && (qualified_name == "xmlns" || p == Some("xmlns")) => {
|
||||
// Step 8. If either qualifiedName or prefix is "xmlns" and namespace is not the XMLNS namespace,
|
||||
// then throw a "NamespaceError" DOMException.
|
||||
Err(ValidationError::Namespace)
|
||||
},
|
||||
(ns!(xmlns), p) if qualified_name != "xmlns" && p != Some("xmlns") => {
|
||||
// Step 9. If namespace is the XMLNS namespace and neither qualifiedName nor prefix is "xmlns",
|
||||
// then throw a "NamespaceError" DOMException.
|
||||
Err(ValidationError::Namespace)
|
||||
},
|
||||
(ns, p) => {
|
||||
// Step 10. Return namespace, prefix, and localName.
|
||||
Ok((ns, p.map(Prefix::from), LocalName::from(local_name)))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct QualNameConverter<'a> {
|
||||
qname: &'a ParserQualName,
|
||||
context: &'a EvaluationCtx,
|
||||
|
|
|
@ -1,216 +0,0 @@
|
|||
[DOMImplementation-createDocument.html]
|
||||
[createDocument test: null,";foo",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for null,";foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for null,";foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: null,"f}oo",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for null,"f}oo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for null,"f}oo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: null,"foo}",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for null,"foo}",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for null,"foo}",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: null,"\\ufffffoo",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for null,"\\ufffffoo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for null,"\\ufffffoo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: null,"f\\uffffoo",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for null,"f\\uffffoo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for null,"f\\uffffoo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: null,"foo\\uffff",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for null,"foo\\uffff",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for null,"foo\\uffff",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: null,"f<oo",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for null,"f<oo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for null,"f<oo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: null,":foo",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for null,":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for null,":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: null,"f:o:o",null,"NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: "",":foo",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for "",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for "",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: undefined,":foo",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for undefined,":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for undefined,":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: undefined,"f::oo",null,"NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: "http://example.com/","fo<o",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for "http://example.com/","fo<o",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for "http://example.com/","fo<o",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: "http://example.com/",":foo",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for "http://example.com/",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for "http://example.com/",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: "http://example.com/","f:o:o",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for "http://example.com/","f:o:o",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for "http://example.com/","f:o:o",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: "http://example.com/","f::oo",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for "http://example.com/","f::oo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for "http://example.com/","f::oo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: "http://example.com/","0:a",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for "http://example.com/","0:a",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for "http://example.com/","0:a",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: "http://example.com/","a:;",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for "http://example.com/","a:;",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for "http://example.com/","a:;",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: "http://example.com/","a:̀",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for "http://example.com/","a:̀",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for "http://example.com/","a:̀",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: "http://example.com/","̀:a",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for "http://example.com/","̀:a",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for "http://example.com/","̀:a",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: "http://example.com/",";:a",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for "http://example.com/",";:a",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for "http://example.com/",";:a",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: "http://example.com/","prefix::local",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for "http://example.com/","prefix::local",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for "http://example.com/","prefix::local",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: "/",":foo",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for "/",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for "/",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: "http://www.w3.org/XML/1998/namespace",":foo",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for "http://www.w3.org/XML/1998/namespace",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for "http://www.w3.org/XML/1998/namespace",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: "http://www.w3.org/2000/xmlns/",":foo",null,"NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: "foo:",":foo",null,null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: metadata for "foo:",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test: characterSet aliases for "foo:",":foo",null]
|
||||
expected: FAIL
|
|
@ -1,141 +0,0 @@
|
|||
[DOMImplementation-createDocumentType.html]
|
||||
[createDocumentType("", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("1foo", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("@foo", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("foo@", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("f@oo", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:{", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:}", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:~", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:'", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:!", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:@", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:#", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:$", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:%", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:^", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:&", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:*", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:(", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:)", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:+", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:=", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:[", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:\]", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:\\\\", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:/", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:;", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:`", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:<", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:,", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("edi:\\"", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("{", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("}", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("'", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("~", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("`", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("@", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("#", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("$", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("%", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("^", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("&", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("*", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("(", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType(")", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType(":foo", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("foo:", "", "") should work]
|
||||
expected: FAIL
|
||||
|
||||
[createDocumentType("prefix::local", "", "") should work]
|
||||
expected: FAIL
|
|
@ -1,42 +0,0 @@
|
|||
[Document-createAttribute.html]
|
||||
[HTML document.createAttribute("invalid^Name")]
|
||||
expected: FAIL
|
||||
|
||||
[XML document.createAttribute("invalid^Name")]
|
||||
expected: FAIL
|
||||
|
||||
[HTML document.createAttribute("\\\\")]
|
||||
expected: FAIL
|
||||
|
||||
[XML document.createAttribute("\\\\")]
|
||||
expected: FAIL
|
||||
|
||||
[HTML document.createAttribute("'")]
|
||||
expected: FAIL
|
||||
|
||||
[XML document.createAttribute("'")]
|
||||
expected: FAIL
|
||||
|
||||
[HTML document.createAttribute("\\"")]
|
||||
expected: FAIL
|
||||
|
||||
[XML document.createAttribute("\\"")]
|
||||
expected: FAIL
|
||||
|
||||
[HTML document.createAttribute("0")]
|
||||
expected: FAIL
|
||||
|
||||
[XML document.createAttribute("0")]
|
||||
expected: FAIL
|
||||
|
||||
[HTML document.createAttribute("0:a")]
|
||||
expected: FAIL
|
||||
|
||||
[XML document.createAttribute("0:a")]
|
||||
expected: FAIL
|
||||
|
||||
[HTML document.createAttribute("~")]
|
||||
expected: FAIL
|
||||
|
||||
[XML document.createAttribute("~")]
|
||||
expected: FAIL
|
|
@ -1,72 +0,0 @@
|
|||
[Document-createElement.html]
|
||||
[createElement("̀foo") in HTML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("̀foo") in XML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("̀foo") in XHTML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("f}oo") in HTML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("f}oo") in XML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("f}oo") in XHTML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("foo}") in HTML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("foo}") in XML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("foo}") in XHTML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("\\ufffffoo") in HTML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("\\ufffffoo") in XML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("\\ufffffoo") in XHTML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("f\\uffffoo") in HTML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("f\\uffffoo") in XML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("f\\uffffoo") in XHTML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("foo\\uffff") in HTML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("foo\\uffff") in XML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("foo\\uffff") in XHTML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("f<oo") in HTML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("f<oo") in XML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("f<oo") in XHTML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("̀") in HTML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("̀") in XML document]
|
||||
expected: FAIL
|
||||
|
||||
[createElement("̀") in XHTML document]
|
||||
expected: FAIL
|
|
@ -1,234 +0,0 @@
|
|||
[Document-createElementNS.html]
|
||||
[createElementNS test in HTML document: null,";foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: null,";foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: null,";foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: null,"f}oo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: null,"f}oo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: null,"f}oo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: null,"foo}",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: null,"foo}",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: null,"foo}",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: null,"\\ufffffoo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: null,"\\ufffffoo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: null,"\\ufffffoo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: null,"f\\uffffoo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: null,"f\\uffffoo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: null,"f\\uffffoo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: null,"foo\\uffff",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: null,"foo\\uffff",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: null,"foo\\uffff",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: null,"f<oo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: null,"f<oo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: null,"f<oo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: null,":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: null,":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: null,":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: null,"f:o:o","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: null,"f:o:o","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: null,"f:o:o","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: "",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: "",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: "",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: undefined,":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: undefined,":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: undefined,":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: undefined,"f::oo","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: undefined,"f::oo","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: undefined,"f::oo","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: "http://example.com/","fo<o",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: "http://example.com/","fo<o",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: "http://example.com/","fo<o",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: "http://example.com/",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: "http://example.com/",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: "http://example.com/",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: "http://example.com/","f:o:o",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: "http://example.com/","f:o:o",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: "http://example.com/","f:o:o",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: "http://example.com/","f::oo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: "http://example.com/","f::oo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: "http://example.com/","f::oo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: "http://example.com/","0:a",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: "http://example.com/","0:a",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: "http://example.com/","0:a",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: "http://example.com/","a:;",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: "http://example.com/","a:;",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: "http://example.com/","a:;",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: "http://example.com/","a:̀",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: "http://example.com/","a:̀",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: "http://example.com/","a:̀",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: "http://example.com/","̀:a",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: "http://example.com/","̀:a",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: "http://example.com/","̀:a",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: "http://example.com/",";:a",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: "http://example.com/",";:a",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: "http://example.com/",";:a",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: "http://example.com/","prefix::local",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: "http://example.com/","prefix::local",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: "http://example.com/","prefix::local",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: "/",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: "/",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: "/",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: "http://www.w3.org/XML/1998/namespace",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: "http://www.w3.org/XML/1998/namespace",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: "http://www.w3.org/XML/1998/namespace",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: "http://www.w3.org/2000/xmlns/",":foo","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: "http://www.w3.org/2000/xmlns/",":foo","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: "http://www.w3.org/2000/xmlns/",":foo","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in HTML document: "foo:",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XML document: "foo:",":foo",null]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test in XHTML document: "foo:",":foo",null]
|
||||
expected: FAIL
|
6
tests/wpt/meta/dom/nodes/attributes.html.ini
vendored
6
tests/wpt/meta/dom/nodes/attributes.html.ini
vendored
|
@ -1,6 +0,0 @@
|
|||
[attributes.html]
|
||||
[Basic functionality should be intact. (toggleAttribute)]
|
||||
expected: FAIL
|
||||
|
||||
[Basic functionality should be intact.]
|
||||
expected: FAIL
|
|
@ -1,15 +0,0 @@
|
|||
[name-validation.html]
|
||||
[Valid and invalid characters in createElement.]
|
||||
expected: FAIL
|
||||
|
||||
[Valid and invalid characters in createElementNS and createDocument.]
|
||||
expected: FAIL
|
||||
|
||||
[Valid and invalid characters in setAttribute, toggleAttribute, and createAttribute.]
|
||||
expected: FAIL
|
||||
|
||||
[Valid and invalid characters in setAttributeNS and createAttributeNS.]
|
||||
expected: FAIL
|
||||
|
||||
[Valid and invalid characters in createDocumentType.]
|
||||
expected: FAIL
|
Loading…
Add table
Add a link
Reference in a new issue