aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings
diff options
context:
space:
mode:
authorrohan.prinja <rohan.prinja@samsung.com>2015-10-27 17:58:34 +0900
committerrohan.prinja <rohan.prinja@samsung.com>2015-10-30 20:26:29 +0900
commit45224028dbc1d75e6dfc8add19ff8e997c7ebb99 (patch)
treef5a113706605564ec491dbf9710842d79e5b2e5c /components/script/dom/bindings
parentbb2536cd014676263f5bfd5d98cf0fc69d2abee0 (diff)
downloadservo-45224028dbc1d75e6dfc8add19ff8e997c7ebb99.tar.gz
servo-45224028dbc1d75e6dfc8add19ff8e997c7ebb99.zip
more refactoring
Diffstat (limited to 'components/script/dom/bindings')
-rw-r--r--components/script/dom/bindings/callback.rs2
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py7
-rw-r--r--components/script/dom/bindings/conversions.rs4
-rw-r--r--components/script/dom/bindings/global.rs3
-rw-r--r--components/script/dom/bindings/inheritance.rs4
-rw-r--r--components/script/dom/bindings/js.rs3
-rw-r--r--components/script/dom/bindings/mod.rs3
-rw-r--r--components/script/dom/bindings/refcounted.rs3
-rw-r--r--components/script/dom/bindings/reflector.rs79
-rw-r--r--components/script/dom/bindings/trace.rs3
-rw-r--r--components/script/dom/bindings/utils.rs239
-rw-r--r--components/script/dom/bindings/xmlname.rs176
12 files changed, 276 insertions, 250 deletions
diff --git a/components/script/dom/bindings/callback.rs b/components/script/dom/bindings/callback.rs
index a879e469e27..1b067c5c596 100644
--- a/components/script/dom/bindings/callback.rs
+++ b/components/script/dom/bindings/callback.rs
@@ -6,7 +6,7 @@
use dom::bindings::error::{Error, Fallible};
use dom::bindings::global::global_object_for_js_object;
-use dom::bindings::utils::Reflectable;
+use dom::bindings::reflector::Reflectable;
use js::jsapi::GetGlobalForObjectCrossCompartment;
use js::jsapi::{Heap, MutableHandleObject, RootedObject, RootedValue};
use js::jsapi::{IsCallable, JSContext, JSObject, JS_WrapObject};
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index 51a4653279f..bd81592d43c 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -5197,6 +5197,7 @@ class CGBindingRoot(CGThing):
'dom::bindings::global::global_object_for_js_object',
'dom::bindings::js::{JS, Root, RootedReference}',
'dom::bindings::js::{OptionalRootedReference}',
+ 'dom::bindings::reflector::{Reflectable}',
'dom::bindings::utils::{create_dom_global, do_create_interface_objects}',
'dom::bindings::utils::ConstantSpec',
'dom::bindings::utils::{DOMClass}',
@@ -5206,7 +5207,6 @@ class CGBindingRoot(CGThing):
'dom::bindings::utils::{finalize_global, trace_global}',
'dom::bindings::utils::has_property_on_prototype',
'dom::bindings::utils::is_platform_object',
- 'dom::bindings::utils::{Reflectable}',
'dom::bindings::utils::throwing_constructor',
'dom::bindings::utils::get_dictionary_property',
'dom::bindings::utils::set_dictionary_property',
@@ -5915,10 +5915,11 @@ class GlobalGenRoots():
descriptors = config.getDescriptors(register=True, isCallback=False)
imports = [CGGeneric("use dom::types::*;\n"),
- CGGeneric("use dom::bindings::conversions::{Castable, DerivedFrom, get_dom_class};\n"),
+ CGGeneric("use dom::bindings::conversions::{DerivedFrom, get_dom_class};\n"),
+ CGGeneric("use dom::bindings::inheritance::Castable;\n"),
CGGeneric("use dom::bindings::js::{JS, LayoutJS, Root};\n"),
CGGeneric("use dom::bindings::trace::JSTraceable;\n"),
- CGGeneric("use dom::bindings::utils::Reflectable;\n"),
+ CGGeneric("use dom::bindings::reflector::Reflectable;\n"),
CGGeneric("use js::jsapi::JSTracer;\n\n"),
CGGeneric("use std::mem;\n\n")]
allprotos = []
diff --git a/components/script/dom/bindings/conversions.rs b/components/script/dom/bindings/conversions.rs
index c8f3b986623..1da266efe4c 100644
--- a/components/script/dom/bindings/conversions.rs
+++ b/components/script/dom/bindings/conversions.rs
@@ -38,7 +38,8 @@ use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::bindings::num::Finite;
use dom::bindings::str::{ByteString, USVString};
-use dom::bindings::utils::{DOMClass, Reflectable, Reflector};
+use dom::bindings::reflector::{Reflectable, Reflector};
+use dom::bindings::utils::DOMClass;
use js;
use js::glue::{GetProxyPrivate, IsWrapper, RUST_JS_NumberValue};
use js::glue::{RUST_JSID_IS_STRING, RUST_JSID_TO_STRING, UnwrapObject};
@@ -56,7 +57,6 @@ use libc;
use num::Float;
use num::traits::{Bounded, Zero};
use std::borrow::ToOwned;
-use std::mem;
use std::rc::Rc;
use std::{char, ptr, slice};
use util::str::DOMString;
diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs
index a1a1c68c8c0..d0b38196608 100644
--- a/components/script/dom/bindings/global.rs
+++ b/components/script/dom/bindings/global.rs
@@ -11,7 +11,8 @@ use devtools_traits::ScriptToDevtoolsControlMsg;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::conversions::native_from_reflector_jsmanaged;
use dom::bindings::js::{JS, Root};
-use dom::bindings::utils::{Reflectable, Reflector};
+use dom::bindings::reflector::Reflector;
+use dom::bindings::reflector::Reflectable;
use dom::window::{self, ScriptHelpers};
use dom::workerglobalscope::WorkerGlobalScope;
use ipc_channel::ipc::IpcSender;
diff --git a/components/script/dom/bindings/inheritance.rs b/components/script/dom/bindings/inheritance.rs
index 5878c44c5f3..6ee06999563 100644
--- a/components/script/dom/bindings/inheritance.rs
+++ b/components/script/dom/bindings/inheritance.rs
@@ -2,9 +2,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+//! The `Castable` trait.
+
use dom::bindings::conversions::get_dom_class;
use dom::bindings::conversions::{DerivedFrom, IDLInterface};
-use dom::bindings::utils::Reflectable;
+use dom::bindings::reflector::Reflectable;
use std::mem;
/// A trait to hold the cast functions of IDL interfaces that either derive
diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs
index 388a8ba81ef..d347b00bb4f 100644
--- a/components/script/dom/bindings/js.rs
+++ b/components/script/dom/bindings/js.rs
@@ -28,7 +28,8 @@ use dom::bindings::conversions::DerivedFrom;
use dom::bindings::inheritance::Castable;
use dom::bindings::trace::JSTraceable;
use dom::bindings::trace::trace_reflector;
-use dom::bindings::utils::{Reflectable, Reflector};
+use dom::bindings::reflector::Reflector;
+use dom::bindings::reflector::Reflectable;
use dom::node::Node;
use js::jsapi::{Heap, JSObject, JSTracer};
use js::jsval::JSVal;
diff --git a/components/script/dom/bindings/mod.rs b/components/script/dom/bindings/mod.rs
index 394c7b722bf..f4b795f8c58 100644
--- a/components/script/dom/bindings/mod.rs
+++ b/components/script/dom/bindings/mod.rs
@@ -137,14 +137,17 @@ pub mod cell;
pub mod conversions;
pub mod error;
pub mod global;
+pub mod inheritance;
pub mod js;
pub mod num;
pub mod proxyhandler;
pub mod refcounted;
+pub mod reflector;
pub mod str;
pub mod structuredclone;
pub mod trace;
pub mod utils;
+pub mod xmlname;
/// Generated JS-Rust bindings.
#[allow(missing_docs, non_snake_case)]
diff --git a/components/script/dom/bindings/refcounted.rs b/components/script/dom/bindings/refcounted.rs
index ee8647be3ce..e101d2bbd83 100644
--- a/components/script/dom/bindings/refcounted.rs
+++ b/components/script/dom/bindings/refcounted.rs
@@ -25,7 +25,8 @@
use core::nonzero::NonZero;
use dom::bindings::js::Root;
use dom::bindings::trace::trace_reflector;
-use dom::bindings::utils::{Reflectable, Reflector};
+use dom::bindings::reflector::Reflector;
+use dom::bindings::reflector::Reflectable;
use js::jsapi::{JSContext, JSTracer};
use libc;
use script_task::{CommonScriptMsg, ScriptChan};
diff --git a/components/script/dom/bindings/reflector.rs b/components/script/dom/bindings/reflector.rs
new file mode 100644
index 00000000000..3279f4de55e
--- /dev/null
+++ b/components/script/dom/bindings/reflector.rs
@@ -0,0 +1,79 @@
+/* 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 http://mozilla.org/MPL/2.0/. */
+
+//! The `Reflector` struct.
+
+use dom::bindings::global::GlobalRef;
+use dom::bindings::js::Root;
+use js::jsapi::{HandleObject, JSContext, JSObject};
+use std::cell::UnsafeCell;
+use std::ptr;
+
+/// Create the reflector for a new DOM object and yield ownership to the
+/// reflector.
+pub fn reflect_dom_object<T: Reflectable>
+ (obj: Box<T>,
+ global: GlobalRef,
+ wrap_fn: extern "Rust" fn(*mut JSContext, GlobalRef, Box<T>) -> Root<T>)
+ -> Root<T> {
+ wrap_fn(global.get_cx(), global, obj)
+}
+
+/// A struct to store a reference to the reflector of a DOM object.
+#[allow(raw_pointer_derive, unrooted_must_root)]
+#[must_root]
+#[servo_lang = "reflector"]
+#[derive(HeapSizeOf)]
+// If you're renaming or moving this field, update the path in plugins::reflector as well
+pub struct Reflector {
+ #[ignore_heap_size_of = "defined and measured in rust-mozjs"]
+ object: UnsafeCell<*mut JSObject>,
+}
+
+#[allow(unrooted_must_root)]
+impl PartialEq for Reflector {
+ fn eq(&self, other: &Reflector) -> bool {
+ unsafe { *self.object.get() == *other.object.get() }
+ }
+}
+
+impl Reflector {
+ /// Get the reflector.
+ #[inline]
+ pub fn get_jsobject(&self) -> HandleObject {
+ unsafe { HandleObject::from_marked_location(self.object.get()) }
+ }
+
+ /// Initialize the reflector. (May be called only once.)
+ pub fn set_jsobject(&mut self, object: *mut JSObject) {
+ unsafe {
+ let obj = self.object.get();
+ assert!((*obj).is_null());
+ assert!(!object.is_null());
+ *obj = object;
+ }
+ }
+
+ /// Return a pointer to the memory location at which the JS reflector
+ /// object is stored. Used to root the reflector, as
+ /// required by the JSAPI rooting APIs.
+ pub fn rootable(&self) -> *mut *mut JSObject {
+ self.object.get()
+ }
+
+ /// Create an uninitialized `Reflector`.
+ pub fn new() -> Reflector {
+ Reflector {
+ object: UnsafeCell::new(ptr::null_mut())
+ }
+ }
+}
+
+/// A trait to provide access to the `Reflector` for a DOM object.
+pub trait Reflectable {
+ /// Returns the receiver's reflector.
+ fn reflector(&self) -> &Reflector;
+ /// Initializes the Reflector
+ fn init_reflector(&mut self, obj: *mut JSObject);
+} \ No newline at end of file
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index c78429f8368..6ed7e45c45a 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -35,7 +35,8 @@ use canvas_traits::{CompositionOrBlending, LineCapStyle, LineJoinStyle, Repetiti
use cssparser::RGBA;
use dom::bindings::js::{JS, Root};
use dom::bindings::refcounted::Trusted;
-use dom::bindings::utils::{Reflectable, Reflector, WindowProxyHandler};
+use dom::bindings::reflector::{Reflectable, Reflector};
+use dom::bindings::utils::WindowProxyHandler;
use encoding::types::EncodingRef;
use euclid::length::Length as EuclidLength;
use euclid::matrix2d::Matrix2D;
diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs
index 6fae276271c..72c0745d3b1 100644
--- a/components/script/dom/bindings/utils.rs
+++ b/components/script/dom/bindings/utils.rs
@@ -49,14 +49,10 @@ use js::rust::{GCMethods, ToString, define_methods, define_properties};
use js::{JSFUN_CONSTRUCTOR, JSPROP_ENUMERATE, JS_CALLEE};
use js::{JSPROP_PERMANENT, JSPROP_READONLY};
use libc::{self, c_uint};
-use std::cell::UnsafeCell;
-use std::cmp::PartialEq;
use std::default::Default;
use std::ffi::CString;
use std::ptr;
-use string_cache::{Atom, Namespace};
use util::mem::HeapSizeOf;
-use util::str::DOMString;
/// Proxy handler for a WindowProxy.
#[allow(raw_pointer_derive)]
@@ -391,74 +387,6 @@ pub fn initialize_global(global: *mut JSObject) {
}
}
-/// A trait to provide access to the `Reflector` for a DOM object.
-pub trait Reflectable {
- /// Returns the receiver's reflector.
- fn reflector(&self) -> &Reflector;
- /// Initializes the Reflector
- fn init_reflector(&mut self, obj: *mut JSObject);
-}
-
-/// Create the reflector for a new DOM object and yield ownership to the
-/// reflector.
-pub fn reflect_dom_object<T: Reflectable>
- (obj: Box<T>,
- global: GlobalRef,
- wrap_fn: extern "Rust" fn(*mut JSContext, GlobalRef, Box<T>) -> Root<T>)
- -> Root<T> {
- wrap_fn(global.get_cx(), global, obj)
-}
-
-/// A struct to store a reference to the reflector of a DOM object.
-#[allow(raw_pointer_derive, unrooted_must_root)]
-#[must_root]
-#[servo_lang = "reflector"]
-#[derive(HeapSizeOf)]
-// If you're renaming or moving this field, update the path in plugins::reflector as well
-pub struct Reflector {
- #[ignore_heap_size_of = "defined and measured in rust-mozjs"]
- object: UnsafeCell<*mut JSObject>,
-}
-
-#[allow(unrooted_must_root)]
-impl PartialEq for Reflector {
- fn eq(&self, other: &Reflector) -> bool {
- unsafe { *self.object.get() == *other.object.get() }
- }
-}
-
-impl Reflector {
- /// Get the reflector.
- #[inline]
- pub fn get_jsobject(&self) -> HandleObject {
- unsafe { HandleObject::from_marked_location(self.object.get()) }
- }
-
- /// Initialize the reflector. (May be called only once.)
- pub fn set_jsobject(&mut self, object: *mut JSObject) {
- unsafe {
- let obj = self.object.get();
- assert!((*obj).is_null());
- assert!(!object.is_null());
- *obj = object;
- }
- }
-
- /// Return a pointer to the memory location at which the JS reflector
- /// object is stored. Used to root the reflector, as
- /// required by the JSAPI rooting APIs.
- pub fn rootable(&self) -> *mut *mut JSObject {
- self.object.get()
- }
-
- /// Create an uninitialized `Reflector`.
- pub fn new() -> Reflector {
- Reflector {
- object: UnsafeCell::new(ptr::null_mut())
- }
- }
-}
-
/// Gets the property `id` on `proxy`'s prototype. If it exists, `*found` is
/// set to true and `*vp` to the value, otherwise `*found` is set to false.
///
@@ -800,21 +728,6 @@ pub unsafe extern fn generic_lenient_setter(cx: *mut JSContext,
generic_call(cx, argc, vp, true, call_setter)
}
-/// Validate a qualified name. See https://dom.spec.whatwg.org/#validate for details.
-pub fn validate_qualified_name(qualified_name: &str) -> ErrorResult {
- match xml_name_type(qualified_name) {
- XMLName::InvalidXMLName => {
- // Step 1.
- Err(Error::InvalidCharacter)
- },
- XMLName::Name => {
- // Step 2.
- Err(Error::Namespace)
- },
- XMLName::QName => Ok(())
- }
-}
-
unsafe extern "C" fn instance_class_has_proto_at_depth(clasp: *const js::jsapi::Class,
proto_id: u32,
depth: u32) -> bool {
@@ -827,155 +740,3 @@ unsafe extern "C" fn instance_class_has_proto_at_depth(clasp: *const js::jsapi::
pub const DOM_CALLBACKS: DOMCallbacks = DOMCallbacks {
instanceClassMatchesProto: Some(instance_class_has_proto_at_depth),
};
-
-/// 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<Atom>, Atom)> {
- // Step 1.
- let namespace = namespace_from_domstring(namespace);
-
- // Step 2.
- try!(validate_qualified_name(qualified_name));
-
- let colon = ':';
-
- // Step 5.
- let mut parts = qualified_name.splitn(2, colon);
-
- let (maybe_prefix, local_name) = {
- let maybe_prefix = parts.next();
- let maybe_local_name = parts.next();
-
- debug_assert!(parts.next().is_none());
-
- if let Some(local_name) = maybe_local_name {
- debug_assert!(!maybe_prefix.unwrap().is_empty());
-
- (maybe_prefix, local_name)
- } else {
- (None, maybe_prefix.unwrap())
- }
- };
-
- debug_assert!(!local_name.contains(colon));
-
- match (namespace, maybe_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(Atom::from_slice), Atom::from_slice(local_name)))
- }
- }
-}
-
-/// Results of `xml_name_type`.
-#[derive(PartialEq)]
-#[allow(missing_docs)]
-pub enum XMLName {
- QName,
- Name,
- InvalidXMLName
-}
-
-/// Check if an element name is valid. See http://www.w3.org/TR/xml/#NT-Name
-/// for details.
-pub fn xml_name_type(name: &str) -> XMLName {
- fn is_valid_start(c: char) -> bool {
- match c {
- ':' |
- 'A' ... 'Z' |
- '_' |
- 'a' ... 'z' |
- '\u{C0}' ... '\u{D6}' |
- '\u{D8}' ... '\u{F6}' |
- '\u{F8}' ... '\u{2FF}' |
- '\u{370}' ... '\u{37D}' |
- '\u{37F}' ... '\u{1FFF}' |
- '\u{200C}' ... '\u{200D}' |
- '\u{2070}' ... '\u{218F}' |
- '\u{2C00}' ... '\u{2FEF}' |
- '\u{3001}' ... '\u{D7FF}' |
- '\u{F900}' ... '\u{FDCF}' |
- '\u{FDF0}' ... '\u{FFFD}' |
- '\u{10000}' ... '\u{EFFFF}' => true,
- _ => false,
- }
- }
-
- fn is_valid_continuation(c: char) -> bool {
- is_valid_start(c) || match c {
- '-' |
- '.' |
- '0' ... '9' |
- '\u{B7}' |
- '\u{300}' ... '\u{36F}' |
- '\u{203F}' ... '\u{2040}' => true,
- _ => false,
- }
- }
-
- let mut iter = name.chars();
- let mut non_qname_colons = false;
- let mut seen_colon = false;
- let mut last = match iter.next() {
- None => return XMLName::InvalidXMLName,
- Some(c) => {
- if !is_valid_start(c) {
- return XMLName::InvalidXMLName;
- }
- if c == ':' {
- non_qname_colons = true;
- }
- c
- }
- };
-
- for c in iter {
- if !is_valid_continuation(c) {
- return XMLName::InvalidXMLName;
- }
- if c == ':' {
- match seen_colon {
- true => non_qname_colons = true,
- false => seen_colon = true
- }
- }
- last = c
- }
-
- if last == ':' {
- non_qname_colons = true
- }
-
- match non_qname_colons {
- false => XMLName::QName,
- true => XMLName::Name
- }
-}
-
-/// Convert a possibly-null URL to a namespace.
-///
-/// If the URL is None, returns the empty namespace.
-pub fn namespace_from_domstring(url: Option<DOMString>) -> Namespace {
- match url {
- None => ns!(""),
- Some(ref s) => Namespace(Atom::from_slice(s)),
- }
-}
diff --git a/components/script/dom/bindings/xmlname.rs b/components/script/dom/bindings/xmlname.rs
new file mode 100644
index 00000000000..e8a53707420
--- /dev/null
+++ b/components/script/dom/bindings/xmlname.rs
@@ -0,0 +1,176 @@
+/* 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 http://mozilla.org/MPL/2.0/. */
+
+//! Functions for validating and extracting qualified XML names.
+
+use dom::bindings::error::{Error, ErrorResult, Fallible};
+use string_cache::{Atom, Namespace};
+use util::str::DOMString;
+
+/// Validate a qualified name. See https://dom.spec.whatwg.org/#validate for details.
+pub fn validate_qualified_name(qualified_name: &str) -> ErrorResult {
+ match xml_name_type(qualified_name) {
+ XMLName::InvalidXMLName => {
+ // Step 1.
+ Err(Error::InvalidCharacter)
+ },
+ XMLName::Name => {
+ // Step 2.
+ Err(Error::Namespace)
+ },
+ XMLName::QName => Ok(())
+ }
+}
+
+/// 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<Atom>, Atom)> {
+ // Step 1.
+ let namespace = namespace_from_domstring(namespace);
+
+ // Step 2.
+ try!(validate_qualified_name(qualified_name));
+
+ let colon = ':';
+
+ // Step 5.
+ let mut parts = qualified_name.splitn(2, colon);
+
+ let (maybe_prefix, local_name) = {
+ let maybe_prefix = parts.next();
+ let maybe_local_name = parts.next();
+
+ debug_assert!(parts.next().is_none());
+
+ if let Some(local_name) = maybe_local_name {
+ debug_assert!(!maybe_prefix.unwrap().is_empty());
+
+ (maybe_prefix, local_name)
+ } else {
+ (None, maybe_prefix.unwrap())
+ }
+ };
+
+ debug_assert!(!local_name.contains(colon));
+
+ match (namespace, maybe_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(Atom::from_slice), Atom::from_slice(local_name)))
+ }
+ }
+}
+
+/// Results of `xml_name_type`.
+#[derive(PartialEq)]
+#[allow(missing_docs)]
+pub enum XMLName {
+ QName,
+ Name,
+ InvalidXMLName
+}
+
+/// Check if an element name is valid. See http://www.w3.org/TR/xml/#NT-Name
+/// for details.
+pub fn xml_name_type(name: &str) -> XMLName {
+ fn is_valid_start(c: char) -> bool {
+ match c {
+ ':' |
+ 'A' ... 'Z' |
+ '_' |
+ 'a' ... 'z' |
+ '\u{C0}' ... '\u{D6}' |
+ '\u{D8}' ... '\u{F6}' |
+ '\u{F8}' ... '\u{2FF}' |
+ '\u{370}' ... '\u{37D}' |
+ '\u{37F}' ... '\u{1FFF}' |
+ '\u{200C}' ... '\u{200D}' |
+ '\u{2070}' ... '\u{218F}' |
+ '\u{2C00}' ... '\u{2FEF}' |
+ '\u{3001}' ... '\u{D7FF}' |
+ '\u{F900}' ... '\u{FDCF}' |
+ '\u{FDF0}' ... '\u{FFFD}' |
+ '\u{10000}' ... '\u{EFFFF}' => true,
+ _ => false,
+ }
+ }
+
+ fn is_valid_continuation(c: char) -> bool {
+ is_valid_start(c) || match c {
+ '-' |
+ '.' |
+ '0' ... '9' |
+ '\u{B7}' |
+ '\u{300}' ... '\u{36F}' |
+ '\u{203F}' ... '\u{2040}' => true,
+ _ => false,
+ }
+ }
+
+ let mut iter = name.chars();
+ let mut non_qname_colons = false;
+ let mut seen_colon = false;
+ let mut last = match iter.next() {
+ None => return XMLName::InvalidXMLName,
+ Some(c) => {
+ if !is_valid_start(c) {
+ return XMLName::InvalidXMLName;
+ }
+ if c == ':' {
+ non_qname_colons = true;
+ }
+ c
+ }
+ };
+
+ for c in iter {
+ if !is_valid_continuation(c) {
+ return XMLName::InvalidXMLName;
+ }
+ if c == ':' {
+ match seen_colon {
+ true => non_qname_colons = true,
+ false => seen_colon = true
+ }
+ }
+ last = c
+ }
+
+ if last == ':' {
+ non_qname_colons = true
+ }
+
+ match non_qname_colons {
+ false => XMLName::QName,
+ true => XMLName::Name
+ }
+}
+
+/// Convert a possibly-null URL to a namespace.
+///
+/// If the URL is None, returns the empty namespace.
+pub fn namespace_from_domstring(url: Option<DOMString>) -> Namespace {
+ match url {
+ None => ns!(""),
+ Some(ref s) => Namespace(Atom::from_slice(s)),
+ }
+}