aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/layout/construct.rs152
-rw-r--r--components/script_layout_interface/restyle_damage.rs2
-rw-r--r--components/style/traversal.rs2
-rw-r--r--tests/wpt/mozilla/meta/MANIFEST.json24
-rw-r--r--tests/wpt/mozilla/tests/css/inline_block_opacity_change.html26
-rw-r--r--tests/wpt/mozilla/tests/css/inline_block_opacity_change_ref.html17
6 files changed, 150 insertions, 73 deletions
diff --git a/components/layout/construct.rs b/components/layout/construct.rs
index bb7f0372189..b6e21f6d219 100644
--- a/components/layout/construct.rs
+++ b/components/layout/construct.rs
@@ -1408,88 +1408,98 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
return false
}
- let mut style = node.style(self.style_context()).clone();
- let mut data = node.mutate_layout_data().unwrap();
- let damage = data.restyle_damage;
- match *node.construction_result_mut(&mut *data) {
- ConstructionResult::None => true,
- ConstructionResult::Flow(ref mut flow, _) => {
- // The node's flow is of the same type and has the same set of children and can
- // therefore be repaired by simply propagating damage and style to the flow.
- if !flow.is_block_flow() {
- return false
- }
- let flow = flow_ref::deref_mut(flow);
- flow::mut_base(flow).restyle_damage.insert(damage);
- flow.repair_style_and_bubble_inline_sizes(&style);
- true
- }
- ConstructionResult::ConstructionItem(ConstructionItem::InlineFragments(
- ref mut inline_fragments_construction_result)) => {
- if !inline_fragments_construction_result.splits.is_empty() {
- return false
- }
-
- for fragment in inline_fragments_construction_result.fragments
- .fragments
- .iter_mut() {
- // Only mutate the styles of fragments that represent the dirty node (including
- // pseudo-element).
- if fragment.node != node.opaque() {
- continue
+ let mut set_has_newly_constructed_flow_flag = false;
+ let result = {
+ let mut style = node.style(self.style_context()).clone();
+ let mut data = node.mutate_layout_data().unwrap();
+ let damage = data.restyle_damage;
+
+ match *node.construction_result_mut(&mut *data) {
+ ConstructionResult::None => true,
+ ConstructionResult::Flow(ref mut flow, _) => {
+ // The node's flow is of the same type and has the same set of children and can
+ // therefore be repaired by simply propagating damage and style to the flow.
+ if !flow.is_block_flow() {
+ return false
}
- if fragment.pseudo != node.get_pseudo_element_type().strip() {
- continue
+
+ let flow = flow_ref::deref_mut(flow);
+ flow::mut_base(flow).restyle_damage.insert(damage);
+ flow.repair_style_and_bubble_inline_sizes(&style);
+ true
+ }
+ ConstructionResult::ConstructionItem(ConstructionItem::InlineFragments(
+ ref mut inline_fragments_construction_result)) => {
+ if !inline_fragments_construction_result.splits.is_empty() {
+ return false
}
- match fragment.specific {
- SpecificFragmentInfo::InlineBlock(ref mut inline_block_fragment) => {
- let flow_ref = flow_ref::deref_mut(&mut inline_block_fragment.flow_ref);
- flow::mut_base(flow_ref).restyle_damage.insert(damage);
- // FIXME(pcwalton): Fragment restyle damage too?
- flow_ref.repair_style_and_bubble_inline_sizes(&style);
- }
- SpecificFragmentInfo::InlineAbsoluteHypothetical(
- ref mut inline_absolute_hypothetical_fragment) => {
- let flow_ref = flow_ref::deref_mut(
- &mut inline_absolute_hypothetical_fragment.flow_ref);
- flow::mut_base(flow_ref).restyle_damage.insert(damage);
- // FIXME(pcwalton): Fragment restyle damage too?
- flow_ref.repair_style_and_bubble_inline_sizes(&style);
+ for fragment in inline_fragments_construction_result.fragments
+ .fragments
+ .iter_mut() {
+ // Only mutate the styles of fragments that represent the dirty node (including
+ // pseudo-element).
+ if fragment.node != node.opaque() {
+ continue
}
- SpecificFragmentInfo::InlineAbsolute(ref mut inline_absolute_fragment) => {
- let flow_ref = flow_ref::deref_mut(
- &mut inline_absolute_fragment.flow_ref);
- flow::mut_base(flow_ref).restyle_damage.insert(damage);
- // FIXME(pcwalton): Fragment restyle damage too?
- flow_ref.repair_style_and_bubble_inline_sizes(&style);
+ if fragment.pseudo != node.get_pseudo_element_type().strip() {
+ continue
}
- SpecificFragmentInfo::ScannedText(_) => {
- // Text fragments in ConstructionResult haven't been scanned yet
- unreachable!()
- }
- SpecificFragmentInfo::GeneratedContent(_) |
- SpecificFragmentInfo::UnscannedText(_) => {
- // We can't repair this unscanned text; we need to update the
- // scanned text fragments.
- //
- // TODO: Add code to find and repair the ScannedText fragments?
- return false
- }
- _ => {
- if node.is_replaced_content() {
- properties::modify_style_for_replaced_content(&mut style);
+
+ match fragment.specific {
+ SpecificFragmentInfo::InlineBlock(ref mut inline_block_fragment) => {
+ let flow_ref = flow_ref::deref_mut(&mut inline_block_fragment.flow_ref);
+ flow::mut_base(flow_ref).restyle_damage.insert(damage);
+ // FIXME(pcwalton): Fragment restyle damage too?
+ flow_ref.repair_style_and_bubble_inline_sizes(&style);
+ }
+ SpecificFragmentInfo::InlineAbsoluteHypothetical(
+ ref mut inline_absolute_hypothetical_fragment) => {
+ let flow_ref = flow_ref::deref_mut(
+ &mut inline_absolute_hypothetical_fragment.flow_ref);
+ flow::mut_base(flow_ref).restyle_damage.insert(damage);
+ // FIXME(pcwalton): Fragment restyle damage too?
+ flow_ref.repair_style_and_bubble_inline_sizes(&style);
+ }
+ SpecificFragmentInfo::InlineAbsolute(ref mut inline_absolute_fragment) => {
+ let flow_ref = flow_ref::deref_mut(
+ &mut inline_absolute_fragment.flow_ref);
+ flow::mut_base(flow_ref).restyle_damage.insert(damage);
+ // FIXME(pcwalton): Fragment restyle damage too?
+ flow_ref.repair_style_and_bubble_inline_sizes(&style);
+ }
+ SpecificFragmentInfo::ScannedText(_) => {
+ // Text fragments in ConstructionResult haven't been scanned yet
+ unreachable!()
+ }
+ SpecificFragmentInfo::GeneratedContent(_) |
+ SpecificFragmentInfo::UnscannedText(_) => {
+ // We can't repair this unscanned text; we need to update the
+ // scanned text fragments.
+ //
+ // TODO: Add code to find and repair the ScannedText fragments?
+ return false
+ }
+ _ => {
+ if node.is_replaced_content() {
+ properties::modify_style_for_replaced_content(&mut style);
+ }
+ fragment.repair_style(&style);
+ set_has_newly_constructed_flow_flag = true;
}
- fragment.repair_style(&style);
}
}
+ true
+ }
+ ConstructionResult::ConstructionItem(_) => {
+ false
}
- true
- }
- ConstructionResult::ConstructionItem(_) => {
- false
}
+ };
+ if set_has_newly_constructed_flow_flag {
+ node.insert_flags(HAS_NEWLY_CONSTRUCTED_FLOW);
}
+ return result;
}
}
diff --git a/components/script_layout_interface/restyle_damage.rs b/components/script_layout_interface/restyle_damage.rs
index 9e2cd1db514..ef33370e064 100644
--- a/components/script_layout_interface/restyle_damage.rs
+++ b/components/script_layout_interface/restyle_damage.rs
@@ -247,7 +247,7 @@ fn compute_damage(old: &ServoComputedValues, new: &ServoComputedValues) -> Resty
get_effects.box_shadow, get_effects.clip, get_inheritedtext.text_shadow, get_effects.filter,
get_effects.transform, get_effects.backface_visibility, get_effects.transform_style,
get_effects.transform_origin, get_effects.perspective, get_effects.perspective_origin,
- get_effects.mix_blend_mode, get_inheritedbox.image_rendering,
+ get_effects.mix_blend_mode, get_effects.opacity, get_inheritedbox.image_rendering,
// Note: May require REFLOW et al. if `visibility: collapse` is implemented.
get_inheritedbox.visibility
diff --git a/components/style/traversal.rs b/components/style/traversal.rs
index ed84fafa345..5f041919596 100644
--- a/components/style/traversal.rs
+++ b/components/style/traversal.rs
@@ -179,7 +179,7 @@ pub trait DomTraversalContext<N: TNode> {
/// Note that this is true unconditionally for servo, since it requires to
/// bubble the widths bottom-up for all the DOM.
fn should_process(&self, node: N) -> bool {
- node.is_dirty() || node.has_dirty_descendants()
+ opts::get().nonincremental_layout || node.is_dirty() || node.has_dirty_descendants()
}
/// Do an action over the child before pushing him to the work queue.
diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json
index 0546548d847..322e742d7a1 100644
--- a/tests/wpt/mozilla/meta/MANIFEST.json
+++ b/tests/wpt/mozilla/meta/MANIFEST.json
@@ -2496,6 +2496,18 @@
"url": "/_mozilla/css/inline_block_min_width.html"
}
],
+ "css/inline_block_opacity_change.html": [
+ {
+ "path": "css/inline_block_opacity_change.html",
+ "references": [
+ [
+ "/_mozilla/css/inline_block_opacity_change_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/inline_block_opacity_change.html"
+ }
+ ],
"css/inline_block_overflow.html": [
{
"path": "css/inline_block_overflow.html",
@@ -11788,6 +11800,18 @@
"url": "/_mozilla/css/inline_block_min_width.html"
}
],
+ "css/inline_block_opacity_change.html": [
+ {
+ "path": "css/inline_block_opacity_change.html",
+ "references": [
+ [
+ "/_mozilla/css/inline_block_opacity_change_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/inline_block_opacity_change.html"
+ }
+ ],
"css/inline_block_overflow.html": [
{
"path": "css/inline_block_overflow.html",
diff --git a/tests/wpt/mozilla/tests/css/inline_block_opacity_change.html b/tests/wpt/mozilla/tests/css/inline_block_opacity_change.html
new file mode 100644
index 00000000000..aa51ab444cd
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/inline_block_opacity_change.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="match" href="inline_block_opacity_change_ref.html">
+ <style>
+ #a {
+ background-color: green;
+ display: inline-block;
+ width: 1em;
+ opacity: 0.2;
+ }
+
+ #a.go {
+ opacity: 1;
+ }
+ </style>
+</head>
+
+<body>
+ <span style="transition: opacity .1s ease-out;" id="a">a</span>
+ <script>
+ document.body.offsetWidth; // force layout
+ document.querySelector('#a').classList.add('go');
+ </script>
+</body>
+</html>
diff --git a/tests/wpt/mozilla/tests/css/inline_block_opacity_change_ref.html b/tests/wpt/mozilla/tests/css/inline_block_opacity_change_ref.html
new file mode 100644
index 00000000000..d047a3a8517
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/inline_block_opacity_change_ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <style>
+ #a {
+ background-color: green;
+ display: inline-block;
+ width: 1em;
+ opacity: 1;
+ }
+ </style>
+</head>
+
+<body>
+ <span id="a">a</span>
+</body>
+</html>