mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
style: Have the CSSOM appending behavior behind a pref and only enable it on Nightly.
Bug: 1461285 Reviewed-by: emilio MozReview-Commit-ID: 6BzPTNjXjyA
This commit is contained in:
parent
2be1375745
commit
d4ea70fd34
1 changed files with 55 additions and 12 deletions
|
@ -47,8 +47,12 @@ pub enum DeclarationPushMode {
|
||||||
/// importance, the new declaration will be discarded. Otherwise, it will
|
/// importance, the new declaration will be discarded. Otherwise, it will
|
||||||
/// be appended to the end of the declaration block.
|
/// be appended to the end of the declaration block.
|
||||||
Parsing,
|
Parsing,
|
||||||
|
/// In this mode, if there is an existing declaration of the same property,
|
||||||
|
/// the value is updated in-place. Otherwise it's appended. This is one
|
||||||
|
/// possible behavior of CSSOM.
|
||||||
|
Update,
|
||||||
/// In this mode, the new declaration is always pushed to the end of the
|
/// In this mode, the new declaration is always pushed to the end of the
|
||||||
/// declaration block. This is for CSSOM.
|
/// declaration block. This is another possible behavior of CSSOM.
|
||||||
Append,
|
Append,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,10 +418,49 @@ impl PropertyDeclarationBlock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether the property is definitely new for this declaration
|
||||||
|
/// block. It returns true when the declaration is a non-custom longhand
|
||||||
|
/// and it doesn't exist in the block, and returns false otherwise.
|
||||||
|
#[inline]
|
||||||
|
fn is_definitely_new(&self, decl: &PropertyDeclaration) -> bool {
|
||||||
|
match decl.id() {
|
||||||
|
PropertyDeclarationId::Longhand(id) => !self.longhands.contains(id),
|
||||||
|
PropertyDeclarationId::Custom(..) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns whether calling extend with `DeclarationPushMode::Update`
|
||||||
|
/// will cause this declaration block to change.
|
||||||
|
pub fn will_change_in_update_mode(
|
||||||
|
&self,
|
||||||
|
source_declarations: &SourcePropertyDeclaration,
|
||||||
|
importance: Importance,
|
||||||
|
) -> bool {
|
||||||
|
// XXX The type of parameter seems to be necessary because otherwise
|
||||||
|
// the compiler complains about `decl` not living long enough in the
|
||||||
|
// all_shorthand expression. Why?
|
||||||
|
let needs_update = |decl: &_| {
|
||||||
|
if self.is_definitely_new(decl) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
self.declarations.iter().enumerate()
|
||||||
|
.find(|&(_, ref slot)| slot.id() == decl.id())
|
||||||
|
.map_or(true, |(i, slot)| {
|
||||||
|
let important = self.declarations_importance[i];
|
||||||
|
*slot != *decl || important != importance.important()
|
||||||
|
})
|
||||||
|
};
|
||||||
|
source_declarations.declarations.iter().any(&needs_update) ||
|
||||||
|
source_declarations.all_shorthand.declarations().any(|decl| needs_update(&decl))
|
||||||
|
}
|
||||||
|
|
||||||
/// Adds or overrides the declaration for a given property in this block.
|
/// Adds or overrides the declaration for a given property in this block.
|
||||||
///
|
///
|
||||||
/// See the documentation of `push` to see what impact `source` has when the
|
/// See the documentation of `push` to see what impact `source` has when the
|
||||||
/// property is already there.
|
/// property is already there.
|
||||||
|
///
|
||||||
|
/// When calling with `DeclarationPushMode::Update`, this should not change
|
||||||
|
/// anything if `will_change_in_update_mode` returns false.
|
||||||
pub fn extend(
|
pub fn extend(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut drain: SourcePropertyDeclarationDrain,
|
mut drain: SourcePropertyDeclarationDrain,
|
||||||
|
@ -473,16 +516,7 @@ impl PropertyDeclarationBlock {
|
||||||
importance: Importance,
|
importance: Importance,
|
||||||
mode: DeclarationPushMode,
|
mode: DeclarationPushMode,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let longhand_id = match declaration.id() {
|
if !self.is_definitely_new(&declaration) {
|
||||||
PropertyDeclarationId::Longhand(id) => Some(id),
|
|
||||||
PropertyDeclarationId::Custom(..) => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let definitely_new = longhand_id.map_or(false, |id| {
|
|
||||||
!self.longhands.contains(id)
|
|
||||||
});
|
|
||||||
|
|
||||||
if !definitely_new {
|
|
||||||
let mut index_to_remove = None;
|
let mut index_to_remove = None;
|
||||||
for (i, slot) in self.declarations.iter_mut().enumerate() {
|
for (i, slot) in self.declarations.iter_mut().enumerate() {
|
||||||
if slot.id() != declaration.id() {
|
if slot.id() != declaration.id() {
|
||||||
|
@ -514,6 +548,15 @@ impl PropertyDeclarationBlock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if matches!(mode, DeclarationPushMode::Update) {
|
||||||
|
let important = self.declarations_importance[i];
|
||||||
|
if *slot == declaration && important == importance.important() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*slot = declaration;
|
||||||
|
self.declarations_importance.set(i, importance.important());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
index_to_remove = Some(i);
|
index_to_remove = Some(i);
|
||||||
break;
|
break;
|
||||||
|
@ -528,7 +571,7 @@ impl PropertyDeclarationBlock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(id) = longhand_id {
|
if let PropertyDeclarationId::Longhand(id) = declaration.id() {
|
||||||
self.longhands.insert(id);
|
self.longhands.insert(id);
|
||||||
}
|
}
|
||||||
self.declarations.push(declaration);
|
self.declarations.push(declaration);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue