mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Add script::dom::utils::validate_and_extract()
Accidentally fixes bugs about Document::createElementNS() where the implementation of "validate and extract" used to check whether the local name extracted from the qualified name was "xmlns" instead of the qualified name itself.
This commit is contained in:
parent
abc01d598a
commit
7b4f6126c8
5 changed files with 67 additions and 161 deletions
|
@ -7,14 +7,17 @@
|
|||
use dom::bindings::codegen::PrototypeList;
|
||||
use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH;
|
||||
use dom::bindings::conversions::{native_from_reflector_jsmanaged, is_dom_class};
|
||||
use dom::bindings::error::{Error, ErrorResult, throw_type_error};
|
||||
use dom::bindings::error::{Error, ErrorResult, Fallible, throw_type_error};
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::{Temporary, Root};
|
||||
use dom::browsercontext;
|
||||
use dom::window;
|
||||
use util::namespace;
|
||||
use util::str::DOMString;
|
||||
|
||||
use libc;
|
||||
use libc::c_uint;
|
||||
use std::borrow::ToOwned;
|
||||
use std::boxed;
|
||||
use std::cell::Cell;
|
||||
use std::ffi::CString;
|
||||
|
@ -43,6 +46,7 @@ use js::rust::with_compartment;
|
|||
use js::{JSPROP_ENUMERATE, JSPROP_READONLY, JSPROP_PERMANENT};
|
||||
use js::JSFUN_CONSTRUCTOR;
|
||||
use js;
|
||||
use string_cache::{Atom, Namespace};
|
||||
|
||||
/// Proxy handler for a WindowProxy.
|
||||
pub struct WindowProxyHandler(pub *const libc::c_void);
|
||||
|
@ -619,6 +623,53 @@ pub fn validate_qualified_name(qualified_name: &str) -> ErrorResult {
|
|||
}
|
||||
}
|
||||
|
||||
/// Validate a namespace and qualified name and extract their parts.
|
||||
/// See https://dom.spec.whatwg.org/#validate-and-extract for details.
|
||||
pub fn validate_and_extract(namespace: Option<DOMString>, qualified_name: &str)
|
||||
-> Fallible<(Namespace, Option<DOMString>, Atom)> {
|
||||
// Step 1.
|
||||
let namespace = namespace::from_domstring(namespace);
|
||||
|
||||
// Step 2.
|
||||
try!(validate_qualified_name(qualified_name));
|
||||
|
||||
let (prefix, local_name) = if qualified_name.contains(":") {
|
||||
// Step 5.
|
||||
let mut parts = qualified_name.splitn(1, ':');
|
||||
let prefix = parts.next().unwrap();
|
||||
debug_assert!(!prefix.is_empty());
|
||||
let local_name = parts.next().unwrap();
|
||||
debug_assert!(!local_name.contains(":"));
|
||||
(Some(prefix), local_name)
|
||||
} else {
|
||||
(None, qualified_name)
|
||||
};
|
||||
|
||||
match (namespace, prefix) {
|
||||
(ns!(""), Some(_)) => {
|
||||
// Step 6.
|
||||
Err(Error::Namespace)
|
||||
},
|
||||
(ref ns, Some("xml")) if ns != &ns!(XML) => {
|
||||
// Step 7.
|
||||
Err(Error::Namespace)
|
||||
},
|
||||
(ref ns, p) if ns != &ns!(XMLNS) &&
|
||||
(qualified_name == "xmlns" || p == Some("xmlns")) => {
|
||||
// Step 8.
|
||||
Err(Error::Namespace)
|
||||
},
|
||||
(ns!(XMLNS), p) if qualified_name != "xmlns" && p != Some("xmlns") => {
|
||||
// Step 9.
|
||||
Err(Error::Namespace)
|
||||
},
|
||||
(ns, p) => {
|
||||
// Step 10.
|
||||
Ok((ns, p.map(|s| s.to_owned()), Atom::from_slice(local_name)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Results of `xml_name_type`.
|
||||
#[derive(PartialEq)]
|
||||
#[allow(missing_docs)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue