style: Store MediaFeatureDescription references as an index into the MEDIA_FEATURES array.

The current use of a static reference is incompatible with sharing style sheet data
across processes.

Differential Revision: https://phabricator.services.mozilla.com/D11845
This commit is contained in:
Cameron McCormack 2018-11-14 21:33:01 +00:00 committed by Emilio Cobos Álvarez
parent 1576dd4c5b
commit dad9ad6b31
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C

View file

@ -10,8 +10,12 @@ use super::media_feature::{KeywordDiscriminant, ParsingRequirements};
use super::Device; use super::Device;
use crate::context::QuirksMode; use crate::context::QuirksMode;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use crate::gecko::media_features::MEDIA_FEATURES;
#[cfg(feature = "gecko")]
use crate::gecko_bindings::structs; use crate::gecko_bindings::structs;
use crate::parser::{Parse, ParserContext}; use crate::parser::{Parse, ParserContext};
#[cfg(feature = "servo")]
use crate::servo::media_queries::MEDIA_FEATURES;
use crate::str::{starts_with_ignore_ascii_case, string_as_ascii_lowercase}; use crate::str::{starts_with_ignore_ascii_case, string_as_ascii_lowercase};
use crate::stylesheets::Origin; use crate::stylesheets::Origin;
use crate::values::computed::{self, ToComputedValue}; use crate::values::computed::{self, ToComputedValue};
@ -150,14 +154,14 @@ impl RangeOrOperator {
/// the media query contained, and the range to evaluate. /// the media query contained, and the range to evaluate.
#[derive(Clone, Debug, MallocSizeOf)] #[derive(Clone, Debug, MallocSizeOf)]
pub struct MediaFeatureExpression { pub struct MediaFeatureExpression {
feature: &'static MediaFeatureDescription, feature_index: usize,
value: Option<MediaExpressionValue>, value: Option<MediaExpressionValue>,
range_or_operator: Option<RangeOrOperator>, range_or_operator: Option<RangeOrOperator>,
} }
impl PartialEq for MediaFeatureExpression { impl PartialEq for MediaFeatureExpression {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.feature as *const _ == other.feature as *const _ && self.feature_index == other.feature_index &&
self.value == other.value && self.value == other.value &&
self.range_or_operator == other.range_or_operator self.range_or_operator == other.range_or_operator
} }
@ -170,8 +174,9 @@ impl ToCss for MediaFeatureExpression {
{ {
dest.write_str("(")?; dest.write_str("(")?;
if self let feature = self.feature();
.feature
if feature
.requirements .requirements
.contains(ParsingRequirements::WEBKIT_PREFIX) .contains(ParsingRequirements::WEBKIT_PREFIX)
{ {
@ -186,7 +191,7 @@ impl ToCss for MediaFeatureExpression {
} }
// NB: CssStringWriter not needed, feature names are under control. // NB: CssStringWriter not needed, feature names are under control.
write!(dest, "{}", self.feature.name)?; write!(dest, "{}", feature.name)?;
if let Some(RangeOrOperator::Operator(op)) = self.range_or_operator { if let Some(RangeOrOperator::Operator(op)) = self.range_or_operator {
dest.write_char(' ')?; dest.write_char(' ')?;
@ -240,17 +245,22 @@ fn consume_operation_or_colon(input: &mut Parser) -> Result<Option<Operator>, ()
impl MediaFeatureExpression { impl MediaFeatureExpression {
fn new( fn new(
feature: &'static MediaFeatureDescription, feature_index: usize,
value: Option<MediaExpressionValue>, value: Option<MediaExpressionValue>,
range_or_operator: Option<RangeOrOperator>, range_or_operator: Option<RangeOrOperator>,
) -> Self { ) -> Self {
debug_assert!(feature_index < MEDIA_FEATURES.len());
Self { Self {
feature, feature_index,
value, value,
range_or_operator, range_or_operator,
} }
} }
fn feature(&self) -> &'static MediaFeatureDescription {
&MEDIA_FEATURES[self.feature_index]
}
/// Parse a media expression of the form: /// Parse a media expression of the form:
/// ///
/// ``` /// ```
@ -270,12 +280,8 @@ impl MediaFeatureExpression {
context: &ParserContext, context: &ParserContext,
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> { ) -> Result<Self, ParseError<'i>> {
#[cfg(feature = "gecko")]
use crate::gecko::media_features::MEDIA_FEATURES;
#[cfg(feature = "servo")]
use crate::servo::media_queries::MEDIA_FEATURES;
// FIXME: remove extra indented block when lifetimes are non-lexical // FIXME: remove extra indented block when lifetimes are non-lexical
let feature_index;
let feature; let feature;
let range; let range;
{ {
@ -319,14 +325,15 @@ impl MediaFeatureExpression {
}; };
let atom = Atom::from(string_as_ascii_lowercase(feature_name)); let atom = Atom::from(string_as_ascii_lowercase(feature_name));
match MEDIA_FEATURES.iter().find(|f| f.name == atom) { match MEDIA_FEATURES.iter().enumerate().find(|(_, f)| f.name == atom) {
Some(f) => Ok((f, range)), Some((i, f)) => Ok((i, f, range)),
None => Err(()), None => Err(()),
} }
}; };
match result { match result {
Ok((f, r)) => { Ok((i, f, r)) => {
feature_index = i;
feature = f; feature = f;
range = r; range = r;
}, },
@ -365,7 +372,7 @@ impl MediaFeatureExpression {
); );
} }
return Ok(Self::new(feature, None, None)); return Ok(Self::new(feature_index, None, None));
}, },
Ok(operator) => operator, Ok(operator) => operator,
}; };
@ -396,7 +403,7 @@ impl MediaFeatureExpression {
.new_custom_error(StyleParseErrorKind::MediaQueryExpectedFeatureValue) .new_custom_error(StyleParseErrorKind::MediaQueryExpectedFeatureValue)
})?; })?;
Ok(Self::new(feature, Some(value), range_or_operator)) Ok(Self::new(feature_index, Some(value), range_or_operator))
} }
/// Returns whether this media query evaluates to true for the given device. /// Returns whether this media query evaluates to true for the given device.
@ -412,7 +419,7 @@ impl MediaFeatureExpression {
}; };
} }
match self.feature.evaluator { match self.feature().evaluator {
Evaluator::Length(eval) => { Evaluator::Length(eval) => {
let computed = expect!(Length).map(|specified| { let computed = expect!(Length).map(|specified| {
computed::Context::for_media_query_evaluation(device, quirks_mode, |context| { computed::Context::for_media_query_evaluation(device, quirks_mode, |context| {
@ -492,7 +499,7 @@ impl MediaExpressionValue {
MediaExpressionValue::IntRatio(ratio) => ratio.to_css(dest), MediaExpressionValue::IntRatio(ratio) => ratio.to_css(dest),
MediaExpressionValue::Resolution(ref r) => r.to_css(dest), MediaExpressionValue::Resolution(ref r) => r.to_css(dest),
MediaExpressionValue::Ident(ref ident) => serialize_atom_identifier(ident, dest), MediaExpressionValue::Ident(ref ident) => serialize_atom_identifier(ident, dest),
MediaExpressionValue::Enumerated(value) => match for_expr.feature.evaluator { MediaExpressionValue::Enumerated(value) => match for_expr.feature().evaluator {
Evaluator::Enumerated { serializer, .. } => dest.write_str(&*serializer(value)), Evaluator::Enumerated { serializer, .. } => dest.write_str(&*serializer(value)),
_ => unreachable!(), _ => unreachable!(),
}, },