aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/script/dom
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/script/dom')
-rw-r--r--src/components/script/dom/bindings/codegen/Bindings.conf2
-rw-r--r--src/components/script/dom/document.rs55
-rw-r--r--src/components/script/dom/element.rs12
-rw-r--r--src/components/script/dom/node.rs5
-rw-r--r--src/components/script/dom/webidls/Document.webidl2
5 files changed, 68 insertions, 8 deletions
diff --git a/src/components/script/dom/bindings/codegen/Bindings.conf b/src/components/script/dom/bindings/codegen/Bindings.conf
index 2ba358e4753..a40dfdf1fe6 100644
--- a/src/components/script/dom/bindings/codegen/Bindings.conf
+++ b/src/components/script/dom/bindings/codegen/Bindings.conf
@@ -33,6 +33,7 @@ DOMInterfaces = {
'createComment',
'createDocumentFragment',
'createElement',
+ 'createElementNS',
'createProcessingInstruction',
'createTextNode',
'embeds',
@@ -95,6 +96,7 @@ DOMInterfaces = {
'contains',
'insertBefore',
'isEqualNode',
+ 'namespaceURI',
'nodeName',
'nodeValue',
'normalize',
diff --git a/src/components/script/dom/document.rs b/src/components/script/dom/document.rs
index 16a96c0bb95..6d8c7fe9313 100644
--- a/src/components/script/dom/document.rs
+++ b/src/components/script/dom/document.rs
@@ -9,13 +9,13 @@ use dom::bindings::codegen::InheritTypes::{DocumentTypeCast, HTMLHtmlElementCast
use dom::bindings::codegen::DocumentBinding;
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
-use dom::bindings::error::{ErrorResult, Fallible, NotSupported, InvalidCharacter, HierarchyRequest};
-use dom::bindings::utils::{xml_name_type, InvalidXMLName};
+use dom::bindings::error::{ErrorResult, Fallible, NotSupported, InvalidCharacter, HierarchyRequest, NamespaceError};
+use dom::bindings::utils::{xml_name_type, InvalidXMLName, Name, QName};
use dom::comment::Comment;
use dom::documentfragment::DocumentFragment;
use dom::documenttype::DocumentType;
use dom::domimplementation::DOMImplementation;
-use dom::element::{Element, AttributeHandlers};
+use dom::element::{Element, AttributeHandlers, get_attribute_parts};
use dom::element::{HTMLHtmlElementTypeId, HTMLHeadElementTypeId, HTMLTitleElementTypeId};
use dom::element::{HTMLBodyElementTypeId, HTMLFrameSetElementTypeId};
use dom::event::Event;
@@ -37,8 +37,9 @@ use dom::location::Location;
use html::hubbub_html_parser::build_element_from_tag;
use hubbub::hubbub::{QuirksMode, NoQuirks, LimitedQuirks, FullQuirks};
use layout_interface::{DocumentDamageLevel, ContentChangedDocumentDamage};
+use servo_util::namespace;
use servo_util::namespace::{Namespace, Null};
-use servo_util::str::DOMString;
+use servo_util::str::{DOMString, null_str_as_empty_ref};
use collections::hashmap::HashMap;
use js::jsapi::JSContext;
@@ -263,6 +264,52 @@ impl Document {
Ok(build_element_from_tag(local_name, abstract_self))
}
+ // http://dom.spec.whatwg.org/#dom-document-createelementns
+ pub fn CreateElementNS(&self, abstract_self: &JS<Document>,
+ namespace: Option<DOMString>,
+ qualified_name: DOMString) -> Fallible<JS<Element>> {
+ let ns = Namespace::from_str(null_str_as_empty_ref(&namespace));
+ match xml_name_type(qualified_name) {
+ InvalidXMLName => {
+ debug!("Not a valid element name");
+ return Err(InvalidCharacter);
+ },
+ Name => {
+ debug!("Not a valid qualified element name");
+ return Err(NamespaceError);
+ },
+ QName => {}
+ }
+
+ let (prefix_from_qname, local_name_from_qname) = get_attribute_parts(qualified_name);
+ match (&ns, prefix_from_qname, local_name_from_qname.as_slice()) {
+ // throw if prefix is not null and namespace is null
+ (&namespace::Null, Some(_), _) => {
+ debug!("Namespace can't be null with a non-null prefix");
+ return Err(NamespaceError);
+ },
+ // throw if prefix is "xml" and namespace is not the XML namespace
+ (_, Some(ref prefix), _) if "xml" == *prefix && ns != namespace::XML => {
+ debug!("Namespace must be the xml namespace if the prefix is 'xml'");
+ return Err(NamespaceError);
+ },
+ // throw if namespace is the XMLNS namespace and neither qualifiedName nor prefix is "xmlns"
+ (&namespace::XMLNS, Some(ref prefix), _) if "xmlns" == *prefix => {},
+ (&namespace::XMLNS, _, "xmlns") => {},
+ (&namespace::XMLNS, _, _) => {
+ debug!("The prefix or the qualified name must be 'xmlns' if namespace is the XMLNS namespace ");
+ return Err(NamespaceError);
+ },
+ _ => {}
+ }
+
+ if ns == namespace::HTML {
+ Ok(build_element_from_tag(local_name_from_qname, abstract_self))
+ } else {
+ Ok(Element::new(local_name_from_qname, ns, abstract_self))
+ }
+ }
+
// http://dom.spec.whatwg.org/#dom-document-createdocumentfragment
pub fn CreateDocumentFragment(&self, abstract_self: &JS<Document>) -> JS<DocumentFragment> {
DocumentFragment::new(abstract_self)
diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs
index 11b83684090..fca1f9ad78c 100644
--- a/src/components/script/dom/element.rs
+++ b/src/components/script/dom/element.rs
@@ -6,6 +6,7 @@
use dom::attr::Attr;
use dom::attrlist::AttrList;
+use dom::bindings::codegen::ElementBinding;
use dom::bindings::codegen::InheritTypes::{ElementDerived, HTMLImageElementCast};
use dom::bindings::codegen::InheritTypes::{HTMLIFrameElementCast, NodeCast};
use dom::bindings::codegen::InheritTypes::HTMLObjectElementCast;
@@ -133,6 +134,8 @@ pub enum ElementTypeId {
HTMLUListElementTypeId,
HTMLVideoElementTypeId,
HTMLUnknownElementTypeId,
+
+ ElementTypeId,
}
//
@@ -140,7 +143,7 @@ pub enum ElementTypeId {
//
impl Element {
- pub fn new_inherited(type_id: ElementTypeId, tag_name: ~str, namespace: Namespace, document: JS<Document>) -> Element {
+ pub fn new_inherited(type_id: ElementTypeId, tag_name: DOMString, namespace: Namespace, document: JS<Document>) -> Element {
Element {
node: Node::new_inherited(ElementNodeTypeId(type_id), document),
tag_name: tag_name,
@@ -151,6 +154,11 @@ impl Element {
}
}
+ pub fn new(tag_name: DOMString, namespace: Namespace, document: &JS<Document>) -> JS<Element> {
+ let element = Element::new_inherited(ElementTypeId, tag_name, namespace, document.clone());
+ Node::reflect_node(~element, document, ElementBinding::Wrap)
+ }
+
pub fn html_element_in_html_document(&self) -> bool {
self.namespace == namespace::HTML &&
self.node.owner_doc().get().is_html_document
@@ -647,7 +655,7 @@ impl IElement for JS<Element> {
}
}
-fn get_attribute_parts(name: DOMString) -> (Option<~str>, ~str) {
+pub fn get_attribute_parts(name: DOMString) -> (Option<~str>, ~str) {
//FIXME: Throw for XML-invalid names
//FIXME: Throw for XMLNS-invalid names
let (prefix, local_name) = if name.contains(":") {
diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs
index 0a35b5b6b0d..77ca388be9e 100644
--- a/src/components/script/dom/node.rs
+++ b/src/components/script/dom/node.rs
@@ -1734,8 +1734,9 @@ impl Node {
}
// http://dom.spec.whatwg.org/#dom-node-namespaceuri
- pub fn GetNamespaceURI(&self) -> Option<DOMString> {
- None
+ pub fn GetNamespaceURI(&self, abstract_self: &JS<Node>) -> Option<DOMString> {
+ let element: Option<JS<Element>> = ElementCast::to(abstract_self);
+ element.map(|element| element.get().namespace.to_str().to_owned())
}
// http://dom.spec.whatwg.org/#dom-node-prefix
diff --git a/src/components/script/dom/webidls/Document.webidl b/src/components/script/dom/webidls/Document.webidl
index 81a54021ee7..6dd0cb658a2 100644
--- a/src/components/script/dom/webidls/Document.webidl
+++ b/src/components/script/dom/webidls/Document.webidl
@@ -28,6 +28,8 @@ interface Document : Node {
[Creator, Throws]
Element createElement(DOMString localName);
+ [Creator, Throws]
+ Element createElementNS(DOMString? namespace, DOMString qualifiedName);
[Creator]
DocumentFragment createDocumentFragment();
[Creator]