mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
style: Be clearer about whether a declaration comes from parsing or not.
This introduces DeclarationSource, to see if a declaration has been parsed or set from CSSOM in a declaration block. The Servo_DeclarationBlock_SetFoo and similar callers are changed to DeclarationSource::CssOm because their semantics are more CSSOM-y, but it shouldn't matter since they should all be checked before hand with Servo_DeclarationBlock_PropertyIsSet.
This commit is contained in:
parent
a89a76e1fc
commit
25c303ee62
6 changed files with 116 additions and 79 deletions
|
@ -18,7 +18,7 @@ use servo_arc::Arc;
|
|||
use servo_url::ServoUrl;
|
||||
use std::ascii::AsciiExt;
|
||||
use style::attr::AttrValue;
|
||||
use style::properties::{Importance, PropertyDeclarationBlock, PropertyId, LonghandId, ShorthandId};
|
||||
use style::properties::{DeclarationSource, Importance, PropertyDeclarationBlock, PropertyId, LonghandId, ShorthandId};
|
||||
use style::properties::{parse_one_declaration_into, parse_style_attribute, SourcePropertyDeclaration};
|
||||
use style::selector_parser::PseudoElement;
|
||||
use style::shared_lock::Locked;
|
||||
|
@ -274,7 +274,11 @@ impl CSSStyleDeclaration {
|
|||
|
||||
// Step 7
|
||||
// Step 8
|
||||
*changed = pdb.extend_reset(declarations.drain(), importance);
|
||||
*changed = pdb.extend(
|
||||
declarations.drain(),
|
||||
importance,
|
||||
DeclarationSource::CssOm,
|
||||
);
|
||||
|
||||
Ok(())
|
||||
})
|
||||
|
|
|
@ -39,6 +39,17 @@ impl AnimationRules {
|
|||
}
|
||||
}
|
||||
|
||||
/// Whether a given declaration comes from CSS parsing, or from CSSOM.
|
||||
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
pub enum DeclarationSource {
|
||||
/// The declaration was obtained from CSS parsing of sheets and such.
|
||||
Parsing,
|
||||
/// The declaration was obtained from CSSOM.
|
||||
CssOm,
|
||||
}
|
||||
|
||||
/// A declaration [importance][importance].
|
||||
///
|
||||
/// [importance]: https://drafts.csswg.org/css-cascade/#importance
|
||||
|
@ -378,30 +389,15 @@ impl PropertyDeclarationBlock {
|
|||
}
|
||||
}
|
||||
|
||||
/// Adds or overrides the declaration for a given property in this block,
|
||||
/// **except** if an existing declaration for the same property is more
|
||||
/// important.
|
||||
/// Adds or overrides the declaration for a given property in this block.
|
||||
///
|
||||
/// Always ensures that the property declaration is at the end.
|
||||
pub fn extend(&mut self, drain: SourcePropertyDeclarationDrain, importance: Importance) {
|
||||
self.extend_common(drain, importance, false);
|
||||
}
|
||||
|
||||
/// Adds or overrides the declaration for a given property in this block,
|
||||
/// **even** if an existing declaration for the same property is more
|
||||
/// important, and reuses the same position in the block.
|
||||
///
|
||||
/// Returns whether anything changed.
|
||||
pub fn extend_reset(&mut self, drain: SourcePropertyDeclarationDrain,
|
||||
importance: Importance) -> bool {
|
||||
self.extend_common(drain, importance, true)
|
||||
}
|
||||
|
||||
fn extend_common(
|
||||
/// See the documentation of `push` to see what impact `source` has when the
|
||||
/// property is already there.
|
||||
pub fn extend(
|
||||
&mut self,
|
||||
mut drain: SourcePropertyDeclarationDrain,
|
||||
importance: Importance,
|
||||
overwrite_more_important_and_reuse_slot: bool,
|
||||
source: DeclarationSource,
|
||||
) -> bool {
|
||||
let all_shorthand_len = match drain.all_shorthand {
|
||||
AllShorthand::NotSet => 0,
|
||||
|
@ -415,10 +411,10 @@ impl PropertyDeclarationBlock {
|
|||
|
||||
let mut changed = false;
|
||||
for decl in &mut drain.declarations {
|
||||
changed |= self.push_common(
|
||||
changed |= self.push(
|
||||
decl,
|
||||
importance,
|
||||
overwrite_more_important_and_reuse_slot,
|
||||
source,
|
||||
);
|
||||
}
|
||||
match drain.all_shorthand {
|
||||
|
@ -426,20 +422,20 @@ impl PropertyDeclarationBlock {
|
|||
AllShorthand::CSSWideKeyword(keyword) => {
|
||||
for &id in ShorthandId::All.longhands() {
|
||||
let decl = PropertyDeclaration::CSSWideKeyword(id, keyword);
|
||||
changed |= self.push_common(
|
||||
changed |= self.push(
|
||||
decl,
|
||||
importance,
|
||||
overwrite_more_important_and_reuse_slot,
|
||||
source,
|
||||
);
|
||||
}
|
||||
}
|
||||
AllShorthand::WithVariables(unparsed) => {
|
||||
for &id in ShorthandId::All.longhands() {
|
||||
let decl = PropertyDeclaration::WithVariables(id, unparsed.clone());
|
||||
changed |= self.push_common(
|
||||
changed |= self.push(
|
||||
decl,
|
||||
importance,
|
||||
overwrite_more_important_and_reuse_slot,
|
||||
source,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -447,21 +443,24 @@ impl PropertyDeclarationBlock {
|
|||
changed
|
||||
}
|
||||
|
||||
/// Adds or overrides the declaration for a given property in this block,
|
||||
/// **except** if an existing declaration for the same property is more
|
||||
/// important.
|
||||
/// Adds or overrides the declaration for a given property in this block.
|
||||
///
|
||||
/// Ensures that, if inserted, it's inserted at the end of the declaration
|
||||
/// Depending on the value of `source`, this has a different behavior in the
|
||||
/// presence of another declaration with the same ID in the declaration
|
||||
/// block.
|
||||
pub fn push(&mut self, declaration: PropertyDeclaration, importance: Importance) {
|
||||
self.push_common(declaration, importance, false);
|
||||
}
|
||||
|
||||
fn push_common(
|
||||
///
|
||||
/// * For `DeclarationSource::Parsing`, this will not override a
|
||||
/// declaration with more importance, and will ensure that, if inserted,
|
||||
/// it's inserted at the end of the declaration block.
|
||||
///
|
||||
/// * For `DeclarationSource::CssOm`, this will override importance and
|
||||
/// will preserve the original position on the block.
|
||||
///
|
||||
pub fn push(
|
||||
&mut self,
|
||||
declaration: PropertyDeclaration,
|
||||
importance: Importance,
|
||||
overwrite_more_important_and_reuse_slot: bool
|
||||
source: DeclarationSource,
|
||||
) -> bool {
|
||||
let longhand_id = match declaration.id() {
|
||||
PropertyDeclarationId::Longhand(id) => Some(id),
|
||||
|
@ -481,7 +480,9 @@ impl PropertyDeclarationBlock {
|
|||
(false, true) => {}
|
||||
|
||||
(true, false) => {
|
||||
if !overwrite_more_important_and_reuse_slot {
|
||||
// For declarations set from the OM, less-important
|
||||
// declarations are overridden.
|
||||
if !matches!(source, DeclarationSource::CssOm) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -490,17 +491,22 @@ impl PropertyDeclarationBlock {
|
|||
}
|
||||
}
|
||||
|
||||
if overwrite_more_important_and_reuse_slot {
|
||||
*slot = declaration;
|
||||
self.declarations_importance.set(i as u32, importance.important());
|
||||
return true;
|
||||
match source {
|
||||
// CSSOM preserves the declaration position, and
|
||||
// overrides importance.
|
||||
DeclarationSource::CssOm => {
|
||||
*slot = declaration;
|
||||
self.declarations_importance.set(i as u32, importance.important());
|
||||
return true;
|
||||
}
|
||||
DeclarationSource::Parsing => {
|
||||
// NOTE(emilio): We could avoid this and just override for
|
||||
// properties not affected by logical props, but it's not
|
||||
// clear it's worth it given the `definitely_new` check.
|
||||
index_to_remove = Some(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(emilio): We could avoid this and just override for
|
||||
// properties not affected by logical props, but it's not
|
||||
// clear it's worth it given the `definitely_new` check.
|
||||
index_to_remove = Some(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1118,7 +1124,11 @@ pub fn parse_property_declaration_list<R>(context: &ParserContext,
|
|||
while let Some(declaration) = iter.next() {
|
||||
match declaration {
|
||||
Ok(importance) => {
|
||||
block.extend(iter.parser.declarations.drain(), importance);
|
||||
block.extend(
|
||||
iter.parser.declarations.drain(),
|
||||
importance,
|
||||
DeclarationSource::Parsing,
|
||||
);
|
||||
}
|
||||
Err((error, slice)) => {
|
||||
iter.parser.declarations.clear();
|
||||
|
|
|
@ -8,8 +8,8 @@ use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser, Parse
|
|||
use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule, SourceLocation};
|
||||
use error_reporting::{NullReporter, ContextualParseError, ParseErrorReporter};
|
||||
use parser::{ParserContext, ParserErrorContext};
|
||||
use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, PropertyId, PropertyParserContext};
|
||||
use properties::{PropertyDeclarationId, LonghandId, SourcePropertyDeclaration};
|
||||
use properties::{DeclarationSource, Importance, PropertyDeclaration, PropertyDeclarationBlock, PropertyId};
|
||||
use properties::{PropertyDeclarationId, PropertyParserContext, LonghandId, SourcePropertyDeclaration};
|
||||
use properties::LonghandIdSet;
|
||||
use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction;
|
||||
use servo_arc::Arc;
|
||||
|
@ -549,7 +549,11 @@ impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListPars
|
|||
while let Some(declaration) = iter.next() {
|
||||
match declaration {
|
||||
Ok(()) => {
|
||||
block.extend(iter.parser.declarations.drain(), Importance::Normal);
|
||||
block.extend(
|
||||
iter.parser.declarations.drain(),
|
||||
Importance::Normal,
|
||||
DeclarationSource::Parsing,
|
||||
);
|
||||
}
|
||||
Err((error, slice)) => {
|
||||
iter.parser.declarations.clear();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue