diff options
Diffstat (limited to 'components/style/namespaces.rs')
-rw-r--r-- | components/style/namespaces.rs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/components/style/namespaces.rs b/components/style/namespaces.rs new file mode 100644 index 00000000000..6ea1e4b4c3a --- /dev/null +++ b/components/style/namespaces.rs @@ -0,0 +1,64 @@ +/* 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/. */ + +use cssparser::ast::*; +use std::collections::hashmap::HashMap; +use servo_util::namespace::Namespace; +use errors::log_css_error; + +pub struct NamespaceMap { + pub default: Option<Namespace>, + pub prefix_map: HashMap<String, Namespace>, +} + + +impl NamespaceMap { + pub fn new() -> NamespaceMap { + NamespaceMap { default: None, prefix_map: HashMap::new() } + } +} + + +pub fn parse_namespace_rule(rule: AtRule, namespaces: &mut NamespaceMap) { + let location = rule.location; + macro_rules! syntax_error( + () => {{ + log_css_error(location, "Invalid @namespace rule"); + return + }}; + ); + if rule.block.is_some() { syntax_error!() } + let mut prefix: Option<String> = None; + let mut ns: Option<Namespace> = None; + let mut iter = rule.prelude.move_skip_whitespace(); + for component_value in iter { + match component_value { + Ident(value) => { + if prefix.is_some() { syntax_error!() } + prefix = Some(value.into_string()); + }, + URL(value) | String(value) => { + if ns.is_some() { syntax_error!() } + ns = Some(Namespace::from_str(value.as_slice())); + break + }, + _ => syntax_error!(), + } + } + if iter.next().is_some() { syntax_error!() } + 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(ns)) => { + if namespaces.default.is_some() { + log_css_error(location, "Duplicate @namespace rule"); + } + namespaces.default = Some(ns); + }, + _ => syntax_error!() + } +} |