mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
auto merge of #1561 : SimonSapin/servo/refactor-namespace, r=pcwalton
This builds on top of #1560 (… which I realize now may confuse Critic) This refactors Namespace to reduce the overall amount of copying and conversion. In particular, it makes parsed selectors contain Namespace enums rather than strings.
This commit is contained in:
commit
edda06115a
18 changed files with 93 additions and 78 deletions
|
@ -22,6 +22,7 @@ use servo_net::local_image_cache::LocalImageCache;
|
|||
use servo_util::geometry::Au;
|
||||
use servo_util::geometry;
|
||||
use servo_util::range::*;
|
||||
use servo_util::namespace;
|
||||
use std::cast;
|
||||
use std::cell::RefCell;
|
||||
use std::cmp::ApproxEq;
|
||||
|
@ -127,7 +128,7 @@ impl ImageBoxInfo {
|
|||
|
||||
fn convert_length(node: &LayoutNode, name: &str) -> Option<Au> {
|
||||
node.with_element(|element| {
|
||||
element.get_attr(None, name).and_then(|string| {
|
||||
element.get_attr(&namespace::Null, name).and_then(|string| {
|
||||
let n: Option<int> = FromStr::from_str(string);
|
||||
n
|
||||
}).and_then(|pixels| Some(Au::from_px(pixels)))
|
||||
|
|
|
@ -19,11 +19,11 @@ use script::dom::element::{Element, HTMLAreaElementTypeId, HTMLAnchorElementType
|
|||
use script::dom::element::{HTMLLinkElementTypeId};
|
||||
use script::dom::htmliframeelement::HTMLIFrameElement;
|
||||
use script::dom::htmlimageelement::HTMLImageElement;
|
||||
use script::dom::namespace;
|
||||
use script::dom::namespace::Namespace;
|
||||
use script::dom::node::{AbstractNode, DocumentNodeTypeId, ElementNodeTypeId, Node, NodeTypeId};
|
||||
use script::dom::text::Text;
|
||||
use servo_msg::constellation_msg::{PipelineId, SubpageId};
|
||||
use servo_util::namespace;
|
||||
use servo_util::namespace::Namespace;
|
||||
use std::cast;
|
||||
use style::{PropertyDeclarationBlock, TElement, TNode, AttrSelector};
|
||||
|
||||
|
@ -289,10 +289,15 @@ impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> {
|
|||
} else {
|
||||
attr.name.as_slice()
|
||||
};
|
||||
// FIXME: avoid .clone() here? See #1367
|
||||
match element.get_attr(attr.namespace.clone(), name) {
|
||||
Some(value) => test(value),
|
||||
None => false,
|
||||
match attr.namespace {
|
||||
Some(ref ns) => {
|
||||
match element.get_attr(ns, name) {
|
||||
Some(value) => test(value),
|
||||
None => false,
|
||||
}
|
||||
},
|
||||
// FIXME: support `*|attr`, attribute selectors in any namespace
|
||||
None => return false,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -399,17 +404,16 @@ impl<'le> TElement for LayoutElement<'le> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn get_namespace_url<'a>(&'a self) -> &'a str {
|
||||
self.element.namespace.to_str().unwrap_or("")
|
||||
fn get_namespace<'a>(&'a self) -> &'a Namespace {
|
||||
&self.element.namespace
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_attr(&self, ns_url: Option<~str>, name: &str) -> Option<&'static str> {
|
||||
let namespace = Namespace::from_str(ns_url);
|
||||
fn get_attr(&self, namespace: &Namespace, name: &str) -> Option<&'static str> {
|
||||
unsafe { self.element.get_attr_val_for_layout(namespace, name) }
|
||||
}
|
||||
|
||||
fn get_link(&self) -> Option<~str> {
|
||||
fn get_link(&self) -> Option<&'static str> {
|
||||
// FIXME: This is HTML only.
|
||||
match self.element.node.type_id {
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/selectors.html#
|
||||
|
@ -417,8 +421,7 @@ impl<'le> TElement for LayoutElement<'le> {
|
|||
ElementNodeTypeId(HTMLAnchorElementTypeId) |
|
||||
ElementNodeTypeId(HTMLAreaElementTypeId) |
|
||||
ElementNodeTypeId(HTMLLinkElementTypeId) => {
|
||||
unsafe { self.element.get_attr_val_for_layout(namespace::Null, "href") }
|
||||
.map(|val| val.to_owned())
|
||||
unsafe { self.element.get_attr_val_for_layout(&namespace::Null, "href") }
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
use dom::bindings::codegen::AttrBinding;
|
||||
use dom::bindings::utils::{Reflectable, Reflector, DOMString};
|
||||
use dom::bindings::utils::reflect_dom_object;
|
||||
use dom::namespace::{Namespace, Null};
|
||||
use dom::window::Window;
|
||||
use servo_util::namespace::{Namespace, Null};
|
||||
|
||||
use std::util;
|
||||
|
||||
|
@ -89,7 +89,10 @@ impl Attr {
|
|||
}
|
||||
|
||||
pub fn GetNamespaceURI(&self) -> Option<DOMString> {
|
||||
self.namespace.to_str().map(|s| s.to_owned())
|
||||
match self.namespace.to_str() {
|
||||
"" => None,
|
||||
url => Some(url.to_owned()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn GetPrefix(&self) -> Option<DOMString> {
|
||||
|
|
|
@ -16,7 +16,6 @@ use dom::event::{AbstractEvent, Event};
|
|||
use dom::htmlcollection::HTMLCollection;
|
||||
use dom::htmldocument::HTMLDocument;
|
||||
use dom::mouseevent::MouseEvent;
|
||||
use dom::namespace::Null;
|
||||
use dom::node::{AbstractNode, Node, ElementNodeTypeId, DocumentNodeTypeId};
|
||||
use dom::text::Text;
|
||||
use dom::uievent::UIEvent;
|
||||
|
@ -24,6 +23,7 @@ use dom::window::Window;
|
|||
use dom::htmltitleelement::HTMLTitleElement;
|
||||
use html::hubbub_html_parser::build_element_from_tag;
|
||||
use layout_interface::{DocumentDamageLevel, ContentChangedDocumentDamage};
|
||||
use servo_util::namespace::Null;
|
||||
|
||||
use js::jsapi::{JSObject, JSContext, JSTracer};
|
||||
use std::ascii::StrAsciiExt;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
use dom::attr::Attr;
|
||||
use dom::attrlist::AttrList;
|
||||
use dom::bindings::utils::{Reflectable, DOMString, ErrorResult, Fallible, Reflector};
|
||||
use dom::bindings::utils::NamespaceError;
|
||||
use dom::bindings::utils::{null_str_as_empty_ref, NamespaceError};
|
||||
use dom::bindings::utils::{InvalidCharacter, QName, Name, InvalidXMLName, xml_name_type};
|
||||
use dom::htmlcollection::HTMLCollection;
|
||||
use dom::clientrect::ClientRect;
|
||||
|
@ -15,13 +15,13 @@ use dom::clientrectlist::ClientRectList;
|
|||
use dom::document::AbstractDocument;
|
||||
use dom::node::{AbstractNode, ElementNodeTypeId, Node, NodeIterator};
|
||||
use dom::document;
|
||||
use dom::namespace;
|
||||
use dom::namespace::{Namespace, Null};
|
||||
use dom::htmlserializer::serialize;
|
||||
use layout_interface::{ContentBoxQuery, ContentBoxResponse, ContentBoxesQuery};
|
||||
use layout_interface::{ContentBoxesResponse, ContentChangedDocumentDamage};
|
||||
use layout_interface::{MatchSelectorsDocumentDamage};
|
||||
use style;
|
||||
use servo_util::namespace;
|
||||
use servo_util::namespace::{Namespace, Null};
|
||||
|
||||
use std::ascii::StrAsciiExt;
|
||||
use std::cast;
|
||||
|
@ -152,13 +152,14 @@ impl Element {
|
|||
}).map(|&x| x)
|
||||
}
|
||||
|
||||
pub unsafe fn get_attr_val_for_layout(&self, namespace: Namespace, name: &str)
|
||||
#[inline]
|
||||
pub unsafe fn get_attr_val_for_layout(&self, namespace: &Namespace, name: &str)
|
||||
-> Option<&'static str> {
|
||||
self.attrs.iter().find(|attr: & &@mut Attr| {
|
||||
// unsafely avoid a borrow because this is accessed by many tasks
|
||||
// during parallel layout
|
||||
let attr: ***Box<Attr> = cast::transmute(attr);
|
||||
name == (***attr).data.local_name && (***attr).data.namespace == namespace
|
||||
name == (***attr).data.local_name && (***attr).data.namespace == *namespace
|
||||
}).map(|attr| {
|
||||
let attr: **Box<Attr> = cast::transmute(attr);
|
||||
cast::transmute((**attr).data.value.as_slice())
|
||||
|
@ -402,7 +403,7 @@ impl Element {
|
|||
}
|
||||
|
||||
pub fn GetAttributeNS(&self, namespace: Option<DOMString>, local_name: DOMString) -> Option<DOMString> {
|
||||
let namespace = Namespace::from_str(namespace);
|
||||
let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace));
|
||||
self.get_attribute(namespace, local_name)
|
||||
.map(|attr| attr.value.clone())
|
||||
}
|
||||
|
@ -430,7 +431,7 @@ impl Element {
|
|||
QName => {}
|
||||
}
|
||||
|
||||
let namespace = Namespace::from_str(namespace_url);
|
||||
let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace_url));
|
||||
self.set_attribute(abstract_self, namespace, name, value)
|
||||
}
|
||||
|
||||
|
@ -449,7 +450,7 @@ impl Element {
|
|||
abstract_self: AbstractNode,
|
||||
namespace: Option<DOMString>,
|
||||
localname: DOMString) -> ErrorResult {
|
||||
let namespace = Namespace::from_str(namespace);
|
||||
let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace));
|
||||
self.remove_attribute(abstract_self, namespace, localname)
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ use dom::bindings::codegen::HTMLDocumentBinding;
|
|||
use dom::bindings::utils::{Reflectable, Reflector, Traceable};
|
||||
use dom::document::{AbstractDocument, Document, HTML};
|
||||
use dom::htmlcollection::HTMLCollection;
|
||||
use dom::namespace::Null;
|
||||
use dom::window::Window;
|
||||
use servo_util::namespace::Null;
|
||||
|
||||
use js::jsapi::JSTracer;
|
||||
use std::str::eq_slice;
|
||||
|
|
|
@ -9,7 +9,7 @@ use dom::element::{Element, ElementTypeId, HTMLElementTypeId};
|
|||
use dom::node::{AbstractNode, Node};
|
||||
use js::jsapi::{JSContext, JSVal};
|
||||
use js::JSVAL_NULL;
|
||||
use dom::namespace;
|
||||
use servo_util::namespace;
|
||||
|
||||
pub struct HTMLElement {
|
||||
element: Element
|
||||
|
|
|
@ -7,7 +7,6 @@ use dom::bindings::utils::{DOMString, ErrorResult};
|
|||
use dom::document::AbstractDocument;
|
||||
use dom::element::HTMLImageElementTypeId;
|
||||
use dom::htmlelement::HTMLElement;
|
||||
use dom::namespace::Null;
|
||||
use dom::node::{AbstractNode, Node};
|
||||
use extra::url::Url;
|
||||
use servo_util::geometry::to_px;
|
||||
|
@ -15,6 +14,7 @@ use layout_interface::{ContentBoxQuery, ContentBoxResponse};
|
|||
use servo_net::image_cache_task;
|
||||
use servo_net::image_cache_task::ImageCacheTask;
|
||||
use servo_util::url::make_url;
|
||||
use servo_util::namespace::Null;
|
||||
|
||||
pub struct HTMLImageElement {
|
||||
htmlelement: HTMLElement,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* 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/. */
|
||||
|
||||
use dom::namespace;
|
||||
use servo_util::namespace;
|
||||
use dom::attr::Attr;
|
||||
use dom::node::NodeIterator;
|
||||
use dom::node::{DoctypeNodeTypeId, DocumentFragmentNodeTypeId, CommentNodeTypeId, DocumentNodeTypeId, ElementNodeTypeId, TextNodeTypeId, AbstractNode};
|
||||
|
|
|
@ -8,7 +8,6 @@ use dom::htmlelement::HTMLElement;
|
|||
use dom::htmlheadingelement::{Heading1, Heading2, Heading3, Heading4, Heading5, Heading6};
|
||||
use dom::htmliframeelement::IFrameSize;
|
||||
use dom::htmlformelement::HTMLFormElement;
|
||||
use dom::namespace::Null;
|
||||
use dom::node::{AbstractNode, ElementNodeTypeId};
|
||||
use dom::types::*;
|
||||
use html::cssparse::{InlineProvenance, StylesheetProvenance, UrlProvenance, spawn_css_parser};
|
||||
|
@ -22,6 +21,7 @@ use servo_net::image_cache_task::ImageCacheTask;
|
|||
use servo_net::resource_task::{Load, Payload, Done, ResourceTask, load_whole_resource};
|
||||
use servo_util::url::make_url;
|
||||
use servo_util::task::spawn_named;
|
||||
use servo_util::namespace::Null;
|
||||
use std::cast;
|
||||
use std::cell::RefCell;
|
||||
use std::comm::{Port, SharedChan};
|
||||
|
|
|
@ -136,7 +136,6 @@ pub mod dom {
|
|||
pub mod htmlunknownelement;
|
||||
pub mod location;
|
||||
pub mod mouseevent;
|
||||
pub mod namespace;
|
||||
pub mod navigator;
|
||||
pub mod node;
|
||||
pub mod nodelist;
|
||||
|
|
|
@ -13,7 +13,6 @@ use dom::event::{Event_, ResizeEvent, ReflowEvent, ClickEvent, MouseDownEvent, M
|
|||
use dom::event::Event;
|
||||
use dom::eventtarget::AbstractEventTarget;
|
||||
use dom::htmldocument::HTMLDocument;
|
||||
use dom::namespace::Null;
|
||||
use dom::node::AbstractNode;
|
||||
use dom::window::{TimerData, TimerHandle, Window};
|
||||
use html::hubbub_html_parser::HtmlParserResult;
|
||||
|
@ -47,6 +46,7 @@ use servo_net::resource_task::ResourceTask;
|
|||
use servo_util::geometry::to_frac_px;
|
||||
use servo_util::url::make_url;
|
||||
use servo_util::task::spawn_named;
|
||||
use servo_util::namespace::Null;
|
||||
use std::comm::{Port, SharedChan};
|
||||
use std::ptr;
|
||||
use std::str::eq_slice;
|
||||
|
|
|
@ -4,11 +4,12 @@
|
|||
|
||||
use std::hashmap::HashMap;
|
||||
use cssparser::ast::*;
|
||||
use servo_util::namespace::Namespace;
|
||||
use errors::log_css_error;
|
||||
|
||||
pub struct NamespaceMap {
|
||||
default: Option<~str>, // Optional URL
|
||||
prefix_map: HashMap<~str, ~str>, // prefix -> URL
|
||||
default: Option<Namespace>,
|
||||
prefix_map: HashMap<~str, Namespace>,
|
||||
}
|
||||
|
||||
|
||||
|
@ -29,7 +30,7 @@ pub fn parse_namespace_rule(rule: AtRule, namespaces: &mut NamespaceMap) {
|
|||
);
|
||||
if rule.block.is_some() { syntax_error!() }
|
||||
let mut prefix: Option<~str> = None;
|
||||
let mut url: Option<~str> = None;
|
||||
let mut ns: Option<Namespace> = None;
|
||||
let mut iter = rule.prelude.move_skip_whitespace();
|
||||
for component_value in iter {
|
||||
match component_value {
|
||||
|
@ -38,25 +39,25 @@ pub fn parse_namespace_rule(rule: AtRule, namespaces: &mut NamespaceMap) {
|
|||
prefix = Some(value);
|
||||
},
|
||||
URL(value) | String(value) => {
|
||||
if url.is_some() { syntax_error!() }
|
||||
url = Some(value);
|
||||
if ns.is_some() { syntax_error!() }
|
||||
ns = Some(Namespace::from_str(value));
|
||||
break
|
||||
},
|
||||
_ => syntax_error!(),
|
||||
}
|
||||
}
|
||||
if iter.next().is_some() { syntax_error!() }
|
||||
match (prefix, url) {
|
||||
(Some(prefix), Some(url)) => {
|
||||
if namespaces.prefix_map.swap(prefix, url).is_some() {
|
||||
match (prefix, ns) {
|
||||
(Some(prefix), Some(ns)) => {
|
||||
if namespaces.prefix_map.swap(prefix, ns).is_some() {
|
||||
log_css_error(location, "Duplicate @namespace rule");
|
||||
}
|
||||
},
|
||||
(None, Some(url)) => {
|
||||
(None, Some(ns)) => {
|
||||
if namespaces.default.is_some() {
|
||||
log_css_error(location, "Duplicate @namespace rule");
|
||||
}
|
||||
namespaces.default = Some(url);
|
||||
namespaces.default = Some(ns);
|
||||
},
|
||||
_ => syntax_error!()
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
//! style.
|
||||
|
||||
use selectors::AttrSelector;
|
||||
use servo_util::namespace::Namespace;
|
||||
|
||||
|
||||
pub trait TNode<E:TElement> : Clone {
|
||||
|
@ -23,9 +24,9 @@ pub trait TNode<E:TElement> : Clone {
|
|||
}
|
||||
|
||||
pub trait TElement {
|
||||
fn get_attr(&self, namespace: Option<~str>, attr: &str) -> Option<&'static str>;
|
||||
fn get_link(&self) -> Option<~str>;
|
||||
fn get_attr(&self, namespace: &Namespace, attr: &str) -> Option<&'static str>;
|
||||
fn get_link(&self) -> Option<&'static str>;
|
||||
fn get_local_name<'a>(&'a self) -> &'a str;
|
||||
fn get_namespace_url<'a>(&'a self) -> &'a str;
|
||||
fn get_namespace<'a>(&'a self) -> &'a Namespace;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ use std::ascii::StrAsciiExt;
|
|||
use std::hashmap::HashMap;
|
||||
use std::str;
|
||||
|
||||
use servo_util::namespace;
|
||||
|
||||
use media_queries::{Device, Screen};
|
||||
use node::{TElement, TNode};
|
||||
use properties::{PropertyDeclaration, PropertyDeclarationBlock};
|
||||
|
@ -73,7 +75,7 @@ impl SelectorMap {
|
|||
// At the end, we're going to sort the rules that we added, so remember where we began.
|
||||
let init_len = matching_rules_list.len();
|
||||
node.with_element(|element: &E| {
|
||||
match element.get_attr(None, "id") {
|
||||
match element.get_attr(&namespace::Null, "id") {
|
||||
Some(id) => {
|
||||
SelectorMap::get_matching_rules_from_hash(node,
|
||||
&self.id_hash,
|
||||
|
@ -83,7 +85,7 @@ impl SelectorMap {
|
|||
None => {}
|
||||
}
|
||||
|
||||
match element.get_attr(None, "class") {
|
||||
match element.get_attr(&namespace::Null, "class") {
|
||||
Some(ref class_attr) => {
|
||||
for class in class_attr.split(SELECTOR_WHITESPACE) {
|
||||
SelectorMap::get_matching_rules_from_hash(
|
||||
|
@ -486,16 +488,16 @@ fn matches_simple_selector<E:TElement,N:TNode<E>>(selector: &SimpleSelector, ele
|
|||
element.get_local_name().eq_ignore_ascii_case(name.as_slice())
|
||||
})
|
||||
}
|
||||
NamespaceSelector(ref url) => {
|
||||
NamespaceSelector(ref namespace) => {
|
||||
element.with_element(|element: &E| {
|
||||
element.get_namespace_url() == url.as_slice()
|
||||
element.get_namespace() == namespace
|
||||
})
|
||||
}
|
||||
// TODO: case-sensitivity depends on the document type and quirks mode
|
||||
// TODO: cache and intern IDs on elements.
|
||||
IDSelector(ref id) => {
|
||||
element.with_element(|element: &E| {
|
||||
match element.get_attr(None, "id") {
|
||||
match element.get_attr(&namespace::Null, "id") {
|
||||
Some(attr) => str::eq_slice(attr, *id),
|
||||
None => false
|
||||
}
|
||||
|
@ -504,7 +506,7 @@ fn matches_simple_selector<E:TElement,N:TNode<E>>(selector: &SimpleSelector, ele
|
|||
// TODO: cache and intern classe names on elements.
|
||||
ClassSelector(ref class) => {
|
||||
element.with_element(|element: &E| {
|
||||
match element.get_attr(None, "class") {
|
||||
match element.get_attr(&namespace::Null, "class") {
|
||||
None => false,
|
||||
// TODO: case-sensitivity depends on the document type and quirks mode
|
||||
Some(ref class_attr)
|
||||
|
@ -624,7 +626,7 @@ fn matches_generic_nth_child<'a,
|
|||
element.with_element(|element: &E| {
|
||||
node.with_element(|node: &E| {
|
||||
if element.get_local_name() == node.get_local_name() &&
|
||||
element.get_namespace_url() == node.get_namespace_url() {
|
||||
element.get_namespace() == node.get_namespace() {
|
||||
index += 1;
|
||||
}
|
||||
})
|
||||
|
|
|
@ -9,6 +9,9 @@ use extra::arc::Arc;
|
|||
use cssparser::ast::*;
|
||||
use cssparser::parse_nth;
|
||||
|
||||
use servo_util::namespace::Namespace;
|
||||
use servo_util::namespace;
|
||||
|
||||
use namespaces::NamespaceMap;
|
||||
|
||||
|
||||
|
@ -55,7 +58,7 @@ pub enum SimpleSelector {
|
|||
IDSelector(~str),
|
||||
ClassSelector(~str),
|
||||
LocalNameSelector(~str),
|
||||
NamespaceSelector(~str),
|
||||
NamespaceSelector(Namespace),
|
||||
|
||||
// Attribute selectors
|
||||
AttrExists(AttrSelector), // [foo]
|
||||
|
@ -89,7 +92,8 @@ pub enum SimpleSelector {
|
|||
pub struct AttrSelector {
|
||||
name: ~str,
|
||||
lower_name: ~str,
|
||||
namespace: Option<~str>,
|
||||
/// None means "any namespace", `*|attr`
|
||||
namespace: Option<Namespace>,
|
||||
}
|
||||
|
||||
|
||||
|
@ -270,7 +274,7 @@ fn parse_type_selector(iter: &mut Iter, namespaces: &NamespaceMap)
|
|||
QualifiedName(namespace, local_name) => {
|
||||
let mut simple_selectors = ~[];
|
||||
match namespace {
|
||||
Some(url) => simple_selectors.push(NamespaceSelector(url)),
|
||||
Some(ns) => simple_selectors.push(NamespaceSelector(ns)),
|
||||
None => (),
|
||||
}
|
||||
match local_name {
|
||||
|
@ -357,7 +361,8 @@ fn parse_one_simple_selector(iter: &mut Iter, namespaces: &NamespaceMap, inside_
|
|||
enum QualifiedNameParseResult {
|
||||
InvalidQualifiedName,
|
||||
NotAQualifiedName,
|
||||
QualifiedName(Option<~str>, Option<~str>) // Namespace URL, local name. None means '*'
|
||||
// Namespace URL, local name. None means '*'
|
||||
QualifiedName(Option<Namespace>, Option<~str>)
|
||||
}
|
||||
|
||||
fn parse_qualified_name(iter: &mut Iter, allow_universal: bool, namespaces: &NamespaceMap)
|
||||
|
@ -365,22 +370,22 @@ fn parse_qualified_name(iter: &mut Iter, allow_universal: bool, namespaces: &Nam
|
|||
#[inline]
|
||||
fn default_namespace(namespaces: &NamespaceMap, local_name: Option<~str>)
|
||||
-> QualifiedNameParseResult {
|
||||
QualifiedName(namespaces.default.as_ref().map(|url| url.to_owned()), local_name)
|
||||
QualifiedName(namespaces.default.as_ref().map(|ns| ns.clone()), local_name)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn explicit_namespace(iter: &mut Iter, allow_universal: bool, namespace_url: Option<~str>)
|
||||
fn explicit_namespace(iter: &mut Iter, allow_universal: bool, namespace: Option<Namespace>)
|
||||
-> QualifiedNameParseResult {
|
||||
assert!(iter.next() == Some(Delim('|')),
|
||||
"Implementation error, this should not happen.");
|
||||
match iter.peek() {
|
||||
Some(&Delim('*')) if allow_universal => {
|
||||
iter.next();
|
||||
QualifiedName(namespace_url, None)
|
||||
QualifiedName(namespace, None)
|
||||
},
|
||||
Some(&Ident(_)) => {
|
||||
let local_name = get_next_ident(iter);
|
||||
QualifiedName(namespace_url, Some(local_name))
|
||||
QualifiedName(namespace, Some(local_name))
|
||||
},
|
||||
_ => InvalidQualifiedName,
|
||||
}
|
||||
|
@ -391,11 +396,11 @@ fn parse_qualified_name(iter: &mut Iter, allow_universal: bool, namespaces: &Nam
|
|||
let value = get_next_ident(iter);
|
||||
match iter.peek() {
|
||||
Some(&Delim('|')) => {
|
||||
let namespace_url = match namespaces.prefix_map.find(&value) {
|
||||
let namespace = match namespaces.prefix_map.find(&value) {
|
||||
None => return InvalidQualifiedName, // Undeclared namespace prefix
|
||||
Some(ref url) => url.to_owned(),
|
||||
Some(ref ns) => (*ns).clone(),
|
||||
};
|
||||
explicit_namespace(iter, allow_universal, Some(namespace_url))
|
||||
explicit_namespace(iter, allow_universal, Some(namespace))
|
||||
},
|
||||
_ => default_namespace(namespaces, Some(value)),
|
||||
}
|
||||
|
@ -410,7 +415,7 @@ fn parse_qualified_name(iter: &mut Iter, allow_universal: bool, namespaces: &Nam
|
|||
},
|
||||
}
|
||||
},
|
||||
Some(&Delim('|')) => explicit_namespace(iter, allow_universal, Some(~"")),
|
||||
Some(&Delim('|')) => explicit_namespace(iter, allow_universal, Some(namespace::Null)),
|
||||
_ => NotAQualifiedName,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
* 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/. */
|
||||
|
||||
use dom::bindings::utils::{DOMString, null_str_as_empty_ref};
|
||||
|
||||
#[deriving(Eq, Clone)]
|
||||
pub enum Namespace {
|
||||
Null,
|
||||
|
@ -17,8 +15,9 @@ pub enum Namespace {
|
|||
}
|
||||
|
||||
impl Namespace {
|
||||
pub fn from_str(url: Option<DOMString>) -> Namespace {
|
||||
match null_str_as_empty_ref(&url) {
|
||||
/// Empty string for "no namespace"
|
||||
pub fn from_str(url: &str) -> Namespace {
|
||||
match url {
|
||||
"http://www.w3.org/1999/xhtml" => HTML,
|
||||
"http://www.w3.org/XML/1998/namespace" => XML,
|
||||
"http://www.w3.org/2000/xmlns/" => XMLNS,
|
||||
|
@ -29,16 +28,16 @@ impl Namespace {
|
|||
ns => Other(ns.to_owned())
|
||||
}
|
||||
}
|
||||
pub fn to_str<'a>(&'a self) -> Option<&'a str> {
|
||||
pub fn to_str<'a>(&'a self) -> &'a str {
|
||||
match *self {
|
||||
Null => None,
|
||||
HTML => Some("http://www.w3.org/1999/xhtml"),
|
||||
XML => Some("http://www.w3.org/XML/1998/namespace"),
|
||||
XMLNS => Some("http://www.w3.org/2000/xmlns/"),
|
||||
XLink => Some("http://www.w3.org/1999/xlink"),
|
||||
SVG => Some("http://www.w3.org/2000/svg"),
|
||||
MathML => Some("http://www.w3.org/1998/Math/MathML"),
|
||||
Other(ref x) => Some(x.as_slice())
|
||||
Null => "",
|
||||
HTML => "http://www.w3.org/1999/xhtml",
|
||||
XML => "http://www.w3.org/XML/1998/namespace",
|
||||
XMLNS => "http://www.w3.org/2000/xmlns/",
|
||||
XLink => "http://www.w3.org/1999/xlink",
|
||||
SVG => "http://www.w3.org/2000/svg",
|
||||
MathML => "http://www.w3.org/1998/Math/MathML",
|
||||
Other(ref x) => x.as_slice()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,4 +21,4 @@ pub mod debug;
|
|||
pub mod io;
|
||||
pub mod task;
|
||||
pub mod workqueue;
|
||||
|
||||
pub mod namespace;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue