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:
Anthony Ramine 2015-04-08 01:29:27 +02:00
parent abc01d598a
commit 7b4f6126c8
5 changed files with 67 additions and 161 deletions

View file

@ -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)]