style: Force to stop computing children if we find the parent has display: none.

This commit is contained in:
Emilio Cobos Álvarez 2016-08-05 11:22:20 -07:00
parent 436c1b3089
commit 544a117911
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
9 changed files with 254 additions and 116 deletions

View file

@ -6,6 +6,7 @@ use context::StandaloneStyleContext;
use std::mem;
use style::context::SharedStyleContext;
use style::dom::OpaqueNode;
use style::traversal::RestyleResult;
use style::traversal::{DomTraversalContext, recalc_style_at};
use wrapper::GeckoNode;
@ -27,12 +28,12 @@ impl<'lc, 'ln> DomTraversalContext<GeckoNode<'ln>> for RecalcStyleOnly<'lc> {
}
}
fn process_preorder(&self, node: GeckoNode<'ln>) {
fn process_preorder(&self, node: GeckoNode<'ln>) -> RestyleResult {
// FIXME(pcwalton): Stop allocating here. Ideally this should just be done by the HTML
// parser.
node.initialize_data();
recalc_style_at(&self.context, self.root, node);
recalc_style_at(&self.context, self.root, node)
}
fn process_postorder(&self, _: GeckoNode<'ln>) {

View file

@ -95,16 +95,40 @@ impl<'ln> GeckoNode<'ln> {
}
}
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Debug)]
pub struct GeckoRestyleDamage(nsChangeHint);
impl TRestyleDamage for GeckoRestyleDamage {
type PreExistingComputedValues = nsStyleContext;
fn empty() -> Self {
use std::mem;
GeckoRestyleDamage(unsafe { mem::transmute(0u32) })
}
fn compute(source: Option<&nsStyleContext>,
new_style: &Arc<ComputedValues>) -> Self {
type Helpers = ArcHelpers<ServoComputedValues, ComputedValues>;
let context = match source {
Some(ctx) => ctx as *const nsStyleContext as *mut nsStyleContext,
// If there's no style source (that is, no style context), there can
// be two reasons for it.
//
// The first one, is that this is not an incremental restyle (so we
// also don't have the old computed values). In that case the best
// we can do is return rebuild_and_reflow.
//
// The second one is that this is an incremental restyle, but the
// node has display: none. In this case, the old computed values
// should still be present, and we should be able to compare the new
// to the old display to see if it effectively needs a reflow, or we
// can do nothing on it because the old and the new display values
// are none.
//
// This is done outside of this method in servo itself, so we
// effectively only need to check for the first case. Ideally, we
// should be able to assert that in this case the display values
// differ or are not none, but we can't reach the node from here.
None => return Self::rebuild_and_reflow(),
};