Ensure unique LayerIds for pseudo-elements

Currently pseudo-elements, like the fragments created for ::before and
::after, with layers will have the same LayerId as the body of their
owning fragments. Instead all LayerIds should be unique.

Fixes #2010.
This commit is contained in:
Martin Robinson 2015-09-08 18:59:30 -07:00
parent 1b6d4daf85
commit 1e6f797268
9 changed files with 128 additions and 41 deletions

View file

@ -35,36 +35,63 @@ impl FrameTreeId {
}
}
#[derive(Clone, PartialEq, Eq, Copy, Hash, Deserialize, Serialize, HeapSizeOf)]
pub enum LayerType {
/// A layer for the fragment body itself.
FragmentBody,
/// An extra layer created for a DOM fragments with overflow:scroll.
OverflowScroll,
/// A layer created to contain ::before pseudo-element content.
BeforePseudoContent,
/// A layer created to contain ::after pseudo-element content.
AfterPseudoContent,
}
#[derive(Clone, PartialEq, Eq, Copy, Hash, Deserialize, Serialize, HeapSizeOf)]
pub struct LayerId(
/// A base layer ID, currently derived from DOM element pointer address.
pub usize,
/// FIXME(#2010, pcwalton): A marker for overflow scroll layers.
pub u32,
/// A sub ID, which is used for synthesizing new layers for content that
/// belongs on top of this layer. This prevents accidentally making colliding
/// layer ids.
pub u32
/// The type of the layer. This serves to differentiate layers that share fragments.
LayerType,
/// The identifier for this layer's fragment, derived from the fragment memory address.
usize,
/// Whether or not this layer is a companion layer, synthesized to ensure that
/// content on top of this layer's fragment has the proper rendering order.
bool
);
impl Debug for LayerId {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let LayerId(a, b, c) = *self;
write!(f, "Layer({}, {}, {})", a, b, c)
let LayerId(layer_type, id, companion) = *self;
let type_string = match layer_type {
LayerType::FragmentBody => "-FragmentBody",
LayerType::OverflowScroll => "-OverflowScroll",
LayerType::BeforePseudoContent => "-BeforePseudoContent",
LayerType::AfterPseudoContent => "-AfterPseudoContent",
};
let companion_string = if companion {
"-companion"
} else {
""
};
write!(f, "{}{}{}", id, type_string, companion_string)
}
}
impl LayerId {
/// FIXME(#2011, pcwalton): This is unfortunate. Maybe remove this in the future.
pub fn null() -> LayerId {
LayerId(0, 0, 0)
LayerId(LayerType::FragmentBody, 0, false)
}
pub fn next_layer_id(&self) -> LayerId {
let LayerId(a, b, sub_id) = *self;
LayerId(a, b, sub_id + 1)
pub fn new_of_type(layer_type: LayerType, fragment_id: usize) -> LayerId {
LayerId(layer_type, fragment_id, false)
}
pub fn companion_layer_id(&self) -> LayerId {
let LayerId(layer_type, id, companion) = *self;
assert!(!companion);
LayerId(layer_type, id, true)
}
}