aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/element.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/element.rs')
-rw-r--r--components/script/dom/element.rs184
1 files changed, 120 insertions, 64 deletions
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index f5832089202..cf40c038c81 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -5,7 +5,7 @@
//! Element nodes.
use app_units::Au;
-use cssparser::Color;
+use cssparser::{Color, ToCss};
use devtools_traits::AttrInfo;
use dom::activation::Activatable;
use dom::attr::AttrValue;
@@ -698,89 +698,145 @@ impl Element {
}
}
+ // this sync method is called upon modification of the style_attribute property,
+ // therefore, it should not trigger subsequent mutation events
+ fn sync_property_with_attrs_style(&self) {
+ let style_str = if let &Some(ref declarations) = &*self.style_attribute().borrow() {
+ declarations.to_css_string()
+ } else {
+ String::new()
+ };
+
+ let mut new_style = AttrValue::String(style_str);
+
+ if let Some(style_attr) = self.attrs.borrow().iter().find(|a| a.name() == &atom!("style")) {
+ style_attr.swap_value(&mut new_style);
+ return;
+ }
+
+ // explicitly not calling the push_new_attribute convenience method
+ // in order to avoid triggering mutation events
+ let window = window_from_node(self);
+ let attr = Attr::new(&window,
+ atom!("style"),
+ new_style,
+ atom!("style"),
+ ns!(),
+ Some(atom!("style")),
+ Some(self));
+
+ assert!(attr.GetOwnerElement().r() == Some(self));
+ self.attrs.borrow_mut().push(JS::from_ref(&attr));
+ }
+
pub fn remove_inline_style_property(&self, property: &str) {
- let mut inline_declarations = self.style_attribute.borrow_mut();
- if let &mut Some(ref mut declarations) = &mut *inline_declarations {
- let index = declarations.normal
- .iter()
- .position(|decl| decl.matches(property));
- if let Some(index) = index {
- Arc::make_mut(&mut declarations.normal).remove(index);
- return;
- }
+ fn remove(element: &Element, property: &str) {
+ let mut inline_declarations = element.style_attribute.borrow_mut();
+ if let &mut Some(ref mut declarations) = &mut *inline_declarations {
+ let index = declarations.normal
+ .iter()
+ .position(|decl| decl.matches(property));
+ if let Some(index) = index {
+ Arc::make_mut(&mut declarations.normal).remove(index);
+ return;
+ }
- let index = declarations.important
- .iter()
- .position(|decl| decl.matches(property));
- if let Some(index) = index {
- Arc::make_mut(&mut declarations.important).remove(index);
- return;
+ let index = declarations.important
+ .iter()
+ .position(|decl| decl.matches(property));
+ if let Some(index) = index {
+ Arc::make_mut(&mut declarations.important).remove(index);
+ return;
+ }
}
}
+
+ remove(self, property);
+ self.sync_property_with_attrs_style();
}
pub fn update_inline_style(&self,
- property_decl: PropertyDeclaration,
+ declarations: Vec<PropertyDeclaration>,
style_priority: StylePriority) {
- let mut inline_declarations = self.style_attribute().borrow_mut();
- if let &mut Some(ref mut declarations) = &mut *inline_declarations {
- let existing_declarations = if style_priority == StylePriority::Important {
- &mut declarations.important
- } else {
- &mut declarations.normal
- };
- // Usually, the reference count will be 1 here. But transitions could make it greater
- // than that.
- let existing_declarations = Arc::make_mut(existing_declarations);
- for declaration in &mut *existing_declarations {
- if declaration.name() == property_decl.name() {
- *declaration = property_decl;
- return;
+ fn update(element: &Element, mut declarations: Vec<PropertyDeclaration>, style_priority: StylePriority) {
+ let mut inline_declarations = element.style_attribute().borrow_mut();
+ if let &mut Some(ref mut existing_declarations) = &mut *inline_declarations {
+ let existing_declarations = if style_priority == StylePriority::Important {
+ &mut existing_declarations.important
+ } else {
+ &mut existing_declarations.normal
+ };
+
+ // Usually, the reference count will be 1 here. But transitions could make it greater
+ // than that.
+ let existing_declarations = Arc::make_mut(existing_declarations);
+
+ while let Some(mut incoming_declaration) = declarations.pop() {
+ let mut replaced = false;
+ for existing_declaration in &mut *existing_declarations {
+ if existing_declaration.name() == incoming_declaration.name() {
+ mem::swap(existing_declaration, &mut incoming_declaration);
+ replaced = true;
+ break;
+ }
+ }
+
+ if !replaced {
+ // inserting instead of pushing since the declarations are in reverse order
+ existing_declarations.insert(0, incoming_declaration);
+ }
}
+
+ return;
}
- existing_declarations.push(property_decl);
- return;
- }
- let (important, normal) = if style_priority == StylePriority::Important {
- (vec![property_decl], vec![])
- } else {
- (vec![], vec![property_decl])
- };
+ let (important, normal) = if style_priority == StylePriority::Important {
+ (declarations, vec![])
+ } else {
+ (vec![], declarations)
+ };
- *inline_declarations = Some(PropertyDeclarationBlock {
- important: Arc::new(important),
- normal: Arc::new(normal),
- });
+ *inline_declarations = Some(PropertyDeclarationBlock {
+ important: Arc::new(important),
+ normal: Arc::new(normal),
+ });
+ }
+
+ update(self, declarations, style_priority);
+ self.sync_property_with_attrs_style();
}
pub fn set_inline_style_property_priority(&self,
properties: &[&str],
style_priority: StylePriority) {
- let mut inline_declarations = self.style_attribute().borrow_mut();
- if let &mut Some(ref mut declarations) = &mut *inline_declarations {
- let (from, to) = if style_priority == StylePriority::Important {
- (&mut declarations.normal, &mut declarations.important)
- } else {
- (&mut declarations.important, &mut declarations.normal)
- };
-
- // Usually, the reference counts of `from` and `to` will be 1 here. But transitions
- // could make them greater than that.
- let from = Arc::make_mut(from);
- let to = Arc::make_mut(to);
- let mut new_from = Vec::new();
- for declaration in from.drain(..) {
- let name = declaration.name();
- if properties.iter().any(|p| name == **p) {
- to.push(declaration)
- } else {
- new_from.push(declaration)
- }
+ {
+ let mut inline_declarations = self.style_attribute().borrow_mut();
+ if let &mut Some(ref mut declarations) = &mut *inline_declarations {
+ let (from, to) = if style_priority == StylePriority::Important {
+ (&mut declarations.normal, &mut declarations.important)
+ } else {
+ (&mut declarations.important, &mut declarations.normal)
+ };
+
+ // Usually, the reference counts of `from` and `to` will be 1 here. But transitions
+ // could make them greater than that.
+ let from = Arc::make_mut(from);
+ let to = Arc::make_mut(to);
+ let mut new_from = Vec::new();
+ for declaration in from.drain(..) {
+ let name = declaration.name();
+ if properties.iter().any(|p| name == **p) {
+ to.push(declaration)
+ } else {
+ new_from.push(declaration)
+ }
+ }
+ mem::replace(from, new_from);
}
- mem::replace(from, new_from);
}
+
+ self.sync_property_with_attrs_style();
}
pub fn get_inline_style_declaration(&self,