aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/stylepropertymapreadonly.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/stylepropertymapreadonly.rs')
-rw-r--r--components/script/dom/stylepropertymapreadonly.rs103
1 files changed, 103 insertions, 0 deletions
diff --git a/components/script/dom/stylepropertymapreadonly.rs b/components/script/dom/stylepropertymapreadonly.rs
new file mode 100644
index 00000000000..3881bfcdd87
--- /dev/null
+++ b/components/script/dom/stylepropertymapreadonly.rs
@@ -0,0 +1,103 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+use crate::dom::bindings::codegen::Bindings::StylePropertyMapReadOnlyBinding::StylePropertyMapReadOnlyMethods;
+use crate::dom::bindings::reflector::reflect_dom_object;
+use crate::dom::bindings::reflector::Reflector;
+use crate::dom::bindings::root::{Dom, DomRoot};
+use crate::dom::bindings::str::DOMString;
+use crate::dom::cssstylevalue::CSSStyleValue;
+use crate::dom::globalscope::GlobalScope;
+use dom_struct::dom_struct;
+use servo_atoms::Atom;
+use std::cmp::Ordering;
+use std::collections::HashMap;
+use std::iter::Iterator;
+use style::custom_properties;
+
+#[dom_struct]
+pub struct StylePropertyMapReadOnly {
+ reflector: Reflector,
+ entries: HashMap<Atom, Dom<CSSStyleValue>>,
+}
+
+impl StylePropertyMapReadOnly {
+ fn new_inherited<Entries>(entries: Entries) -> StylePropertyMapReadOnly
+ where
+ Entries: IntoIterator<Item = (Atom, Dom<CSSStyleValue>)>,
+ {
+ StylePropertyMapReadOnly {
+ reflector: Reflector::new(),
+ entries: entries.into_iter().collect(),
+ }
+ }
+
+ pub fn from_iter<Entries>(
+ global: &GlobalScope,
+ entries: Entries,
+ ) -> DomRoot<StylePropertyMapReadOnly>
+ where
+ Entries: IntoIterator<Item = (Atom, String)>,
+ {
+ let mut keys = Vec::new();
+ rooted_vec!(let mut values);
+ let iter = entries.into_iter();
+ let (lo, _) = iter.size_hint();
+ keys.reserve(lo);
+ values.reserve(lo);
+ for (key, value) in iter {
+ let value = CSSStyleValue::new(global, value);
+ keys.push(key);
+ values.push(Dom::from_ref(&*value));
+ }
+ let iter = keys.drain(..).zip(values.iter().cloned());
+ reflect_dom_object(
+ Box::new(StylePropertyMapReadOnly::new_inherited(iter)),
+ global,
+ )
+ }
+}
+
+impl StylePropertyMapReadOnlyMethods for StylePropertyMapReadOnly {
+ /// <https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymapreadonly-get>
+ fn Get(&self, property: DOMString) -> Option<DomRoot<CSSStyleValue>> {
+ // TODO: avoid constructing an Atom
+ self.entries
+ .get(&Atom::from(property))
+ .map(|value| DomRoot::from_ref(&**value))
+ }
+
+ /// <https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymapreadonly-has>
+ fn Has(&self, property: DOMString) -> bool {
+ // TODO: avoid constructing an Atom
+ self.entries.contains_key(&Atom::from(property))
+ }
+
+ /// <https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymapreadonly-getproperties>
+ fn GetProperties(&self) -> Vec<DOMString> {
+ let mut result: Vec<DOMString> = self
+ .entries
+ .keys()
+ .map(|key| DOMString::from(&**key))
+ .collect();
+ // https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymap-getproperties
+ // requires this sort order
+ result.sort_by(|key1, key2| {
+ if let Ok(key1) = custom_properties::parse_name(key1) {
+ if let Ok(key2) = custom_properties::parse_name(key2) {
+ key1.cmp(key2)
+ } else {
+ Ordering::Greater
+ }
+ } else {
+ if let Ok(_) = custom_properties::parse_name(key2) {
+ Ordering::Less
+ } else {
+ key1.cmp(key2)
+ }
+ }
+ });
+ result
+ }
+}