diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs index 95ff73e2cb75..43c1226b2952 100644 --- a/components/script/dom/attr.rs +++ b/components/script/dom/attr.rs @@ -173,13 +173,18 @@ impl Attr { pub fn set_value(&self, mut value: AttrValue, owner: &Element) { assert!(Some(owner) == self.owner().r()); owner.will_mutate_attr(); - mem::swap(&mut *self.value.borrow_mut(), &mut value); + self.swap_value(&mut value); if self.identifier.namespace == ns!() { vtable_for(owner.upcast()) .attribute_mutated(self, AttributeMutation::Set(Some(&value))); } } + /// Used to swap the attribute's value without triggering mutation events + pub fn swap_value(&self, value: &mut AttrValue) { + mem::swap(&mut *self.value.borrow_mut(), value); + } + pub fn identifier(&self) -> &AttrIdentifier { &self.identifier } diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index a05587fffa77..cf40c038c81e 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -698,6 +698,8 @@ 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() @@ -705,20 +707,26 @@ impl Element { String::new() }; - let new_style = AttrValue::String(style_str); + 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.set_value(new_style, self); + style_attr.swap_value(&mut new_style); return; } - self.push_new_attribute( - atom!("style"), - new_style, - atom!("style"), - ns!(), - Some(atom!("style")) - ); + // 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) {