servo: Merge #18405 - Handle dynamic font color change (from pylbrecht:dynamic.attribute.change); r=emilio
authorP. Albrecht <palbrecht@mailbox.org>
Thu, 07 Sep 2017 10:24:16 -0500
changeset 428983 5391c8a2ffddb40b82cfd63c9c6c7554e598b87c
parent 428982 75e4a2e292967513f19c32c59d104df0f49a1cb3
child 428984 3248148e4d09168ae250d296a9a6fac15a28035f
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
servo: Merge #18405 - Handle dynamic font color change (from pylbrecht:dynamic.attribute.change); r=emilio <!-- Please describe your changes on the following line: --> <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #18371. <!-- Either: --> - [X] There are tests for these changes <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> r? @emilio Source-Repo: https://github.com/servo/servo Source-Revision: 85167c8b7d2fb0e0e90283db750b601d789cd6ea
servo/components/script/dom/document.rs
servo/components/script/dom/element.rs
servo/components/script/dom/htmlfontelement.rs
servo/components/script/dom/virtualmethods.rs
--- a/servo/components/script/dom/document.rs
+++ b/servo/components/script/dom/document.rs
@@ -83,16 +83,17 @@ use dom::servoparser::ServoParser;
 use dom::storageevent::StorageEvent;
 use dom::stylesheetlist::StyleSheetList;
 use dom::text::Text;
 use dom::touch::Touch;
 use dom::touchevent::TouchEvent;
 use dom::touchlist::TouchList;
 use dom::treewalker::TreeWalker;
 use dom::uievent::UIEvent;
+use dom::virtualmethods::vtable_for;
 use dom::webglcontextevent::WebGLContextEvent;
 use dom::window::{ReflowReason, Window};
 use dom::windowproxy::WindowProxy;
 use dom_struct::dom_struct;
 use encoding::EncodingRef;
 use encoding::all::UTF_8;
 use euclid::{Point2D, Vector2D};
 use html5ever::{LocalName, Namespace, QualName};
@@ -2494,20 +2495,17 @@ impl Document {
         let mut entry = self.ensure_pending_restyle(el);
         if entry.snapshot.is_none() {
             entry.snapshot = Some(Snapshot::new(el.html_element_in_html_document()));
         }
         if attr.local_name() == &local_name!("style") {
             entry.hint.insert(RESTYLE_STYLE_ATTRIBUTE);
         }
 
-        // FIXME(emilio): This should become something like
-        // element.is_attribute_mapped(attr.local_name()).
-        if attr.local_name() == &local_name!("width") ||
-           attr.local_name() == &local_name!("height") {
+        if vtable_for(el.upcast()).attribute_is_mapped(attr) {
             entry.hint.insert(RESTYLE_SELF);
         }
 
         let snapshot = entry.snapshot.as_mut().unwrap();
         if attr.local_name() == &local_name!("id") {
             snapshot.id_changed = true;
         } else if attr.local_name() == &local_name!("class") {
             snapshot.class_changed = true;
--- a/servo/components/script/dom/element.rs
+++ b/servo/components/script/dom/element.rs
@@ -2298,16 +2298,26 @@ impl ElementMethods for Element {
     }
 }
 
 impl VirtualMethods for Element {
     fn super_type(&self) -> Option<&VirtualMethods> {
         Some(self.upcast::<Node>() as &VirtualMethods)
     }
 
+    fn attribute_is_mapped(&self, attr: &Attr) -> bool {
+        // FIXME: This should be more fine-grained, not all elements care about these.
+        if attr.local_name() == &local_name!("width") ||
+           attr.local_name() == &local_name!("height") {
+            return true;
+        }
+
+        self.super_type().unwrap().attribute_is_mapped(attr)
+    }
+
     fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) {
         self.super_type().unwrap().attribute_mutated(attr, mutation);
         let node = self.upcast::<Node>();
         let doc = node.owner_doc();
         match attr.local_name() {
             &local_name!("style") => {
                 // Modifying the `style` attribute might change style.
                 *self.style_attribute.borrow_mut() = match mutation {
--- a/servo/components/script/dom/htmlfontelement.rs
+++ b/servo/components/script/dom/htmlfontelement.rs
@@ -1,13 +1,14 @@
 /* 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::RGBA;
+use dom::attr::Attr;
 use dom::bindings::codegen::Bindings::HTMLFontElementBinding;
 use dom::bindings::codegen::Bindings::HTMLFontElementBinding::HTMLFontElementMethods;
 use dom::bindings::inheritance::Castable;
 use dom::bindings::js::{LayoutJS, Root};
 use dom::bindings::str::DOMString;
 use dom::document::Document;
 use dom::element::{Element, RawLayoutElementHelpers};
 use dom::htmlelement::HTMLElement;
@@ -65,16 +66,25 @@ impl HTMLFontElementMethods for HTMLFont
     }
 }
 
 impl VirtualMethods for HTMLFontElement {
     fn super_type(&self) -> Option<&VirtualMethods> {
         Some(self.upcast::<HTMLElement>() as &VirtualMethods)
     }
 
+    fn attribute_is_mapped(&self, attr: &Attr) -> bool {
+        if attr.local_name() == &local_name!("color") {
+            return true;
+        }
+
+        // FIXME: Should also return true for `size` and `face` changes!
+        self.super_type().unwrap().attribute_is_mapped(attr)
+    }
+
     fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue {
         match name {
             &local_name!("face") => AttrValue::from_atomic(value.into()),
             &local_name!("color") => AttrValue::from_legacy_color(value.into()),
             &local_name!("size") => parse_size(&value),
             _ => self.super_type().unwrap().parse_plain_attribute(name, value),
         }
     }
--- a/servo/components/script/dom/virtualmethods.rs
+++ b/servo/components/script/dom/virtualmethods.rs
@@ -65,16 +65,25 @@ pub trait VirtualMethods {
     /// https://dom.spec.whatwg.org/#attribute-is-set
     /// https://dom.spec.whatwg.org/#attribute-is-removed
     fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) {
         if let Some(s) = self.super_type() {
             s.attribute_mutated(attr, mutation);
         }
     }
 
+    /// Returns `true` if given attribute `attr` affects style of the
+    /// given element.
+    fn attribute_is_mapped(&self, attr: &Attr) -> bool {
+        match self.super_type() {
+            Some(s) => s.attribute_is_mapped(attr),
+            None => false
+        }
+    }
+
     /// Returns the right AttrValue variant for the attribute with name `name`
     /// on this element.
     fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue {
         match self.super_type() {
             Some(ref s) => s.parse_plain_attribute(name, value),
             _ => AttrValue::String(value.into()),
         }
     }