mirror of
https://github.com/servo/servo.git
synced 2025-08-08 06:55:31 +01:00
style: Make media feature evaluation take a computed::Context
This has no behavior change right now, but will simplify sharing code with container queries. Container queries will have container information in the computed::Context (this is necessary anyways for container-based units), so this avoids having to have different code for media and container queries. Differential Revision: https://phabricator.services.mozilla.com/D144152
This commit is contained in:
parent
6279504ddb
commit
8d8b5942be
6 changed files with 119 additions and 125 deletions
|
@ -9,9 +9,7 @@ use crate::gecko_bindings::structs;
|
||||||
use crate::media_queries::media_feature::{AllowsRanges, ParsingRequirements};
|
use crate::media_queries::media_feature::{AllowsRanges, ParsingRequirements};
|
||||||
use crate::media_queries::media_feature::{Evaluator, MediaFeatureDescription};
|
use crate::media_queries::media_feature::{Evaluator, MediaFeatureDescription};
|
||||||
use crate::media_queries::{Device, MediaType};
|
use crate::media_queries::{Device, MediaType};
|
||||||
use crate::values::computed::CSSPixelLength;
|
use crate::values::computed::{Context, CSSPixelLength, Ratio, Resolution};
|
||||||
use crate::values::computed::Ratio;
|
|
||||||
use crate::values::computed::Resolution;
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use euclid::default::Size2D;
|
use euclid::default::Size2D;
|
||||||
|
|
||||||
|
@ -25,46 +23,46 @@ fn device_size(device: &Device) -> Size2D<Au> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-4/#width
|
/// https://drafts.csswg.org/mediaqueries-4/#width
|
||||||
fn eval_width(device: &Device) -> CSSPixelLength {
|
fn eval_width(context: &Context) -> CSSPixelLength {
|
||||||
CSSPixelLength::new(device.au_viewport_size().width.to_f32_px())
|
CSSPixelLength::new(context.device().au_viewport_size().width.to_f32_px())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-4/#device-width
|
/// https://drafts.csswg.org/mediaqueries-4/#device-width
|
||||||
fn eval_device_width(device: &Device) -> CSSPixelLength {
|
fn eval_device_width(context: &Context) -> CSSPixelLength {
|
||||||
CSSPixelLength::new(device_size(device).width.to_f32_px())
|
CSSPixelLength::new(device_size(context.device()).width.to_f32_px())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-4/#height
|
/// https://drafts.csswg.org/mediaqueries-4/#height
|
||||||
fn eval_height(device: &Device) -> CSSPixelLength {
|
fn eval_height(context: &Context) -> CSSPixelLength {
|
||||||
CSSPixelLength::new(device.au_viewport_size().height.to_f32_px())
|
CSSPixelLength::new(context.device().au_viewport_size().height.to_f32_px())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-4/#device-height
|
/// https://drafts.csswg.org/mediaqueries-4/#device-height
|
||||||
fn eval_device_height(device: &Device) -> CSSPixelLength {
|
fn eval_device_height(context: &Context) -> CSSPixelLength {
|
||||||
CSSPixelLength::new(device_size(device).height.to_f32_px())
|
CSSPixelLength::new(device_size(context.device()).height.to_f32_px())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_aspect_ratio_for<F>(device: &Device, get_size: F) -> Ratio
|
fn eval_aspect_ratio_for<F>(context: &Context, get_size: F) -> Ratio
|
||||||
where
|
where
|
||||||
F: FnOnce(&Device) -> Size2D<Au>,
|
F: FnOnce(&Device) -> Size2D<Au>,
|
||||||
{
|
{
|
||||||
let size = get_size(device);
|
let size = get_size(context.device());
|
||||||
Ratio::new(size.width.0 as f32, size.height.0 as f32)
|
Ratio::new(size.width.0 as f32, size.height.0 as f32)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-4/#aspect-ratio
|
/// https://drafts.csswg.org/mediaqueries-4/#aspect-ratio
|
||||||
fn eval_aspect_ratio(device: &Device) -> Ratio {
|
fn eval_aspect_ratio(context: &Context) -> Ratio {
|
||||||
eval_aspect_ratio_for(device, Device::au_viewport_size)
|
eval_aspect_ratio_for(context, Device::au_viewport_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-4/#device-aspect-ratio
|
/// https://drafts.csswg.org/mediaqueries-4/#device-aspect-ratio
|
||||||
fn eval_device_aspect_ratio(device: &Device) -> Ratio {
|
fn eval_device_aspect_ratio(context: &Context) -> Ratio {
|
||||||
eval_aspect_ratio_for(device, device_size)
|
eval_aspect_ratio_for(context, device_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://compat.spec.whatwg.org/#css-media-queries-webkit-device-pixel-ratio
|
/// https://compat.spec.whatwg.org/#css-media-queries-webkit-device-pixel-ratio
|
||||||
fn eval_device_pixel_ratio(device: &Device) -> f32 {
|
fn eval_device_pixel_ratio(context: &Context) -> f32 {
|
||||||
eval_resolution(device).dppx()
|
eval_resolution(context).dppx()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, FromPrimitive, Parse, ToCss)]
|
#[derive(Clone, Copy, Debug, FromPrimitive, Parse, ToCss)]
|
||||||
|
@ -74,7 +72,7 @@ enum Orientation {
|
||||||
Portrait,
|
Portrait,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_orientation_for<F>(device: &Device, value: Option<Orientation>, get_size: F) -> bool
|
fn eval_orientation_for<F>(context: &Context, value: Option<Orientation>, get_size: F) -> bool
|
||||||
where
|
where
|
||||||
F: FnOnce(&Device) -> Size2D<Au>,
|
F: FnOnce(&Device) -> Size2D<Au>,
|
||||||
{
|
{
|
||||||
|
@ -83,7 +81,7 @@ where
|
||||||
None => return true,
|
None => return true,
|
||||||
};
|
};
|
||||||
|
|
||||||
let size = get_size(device);
|
let size = get_size(context.device());
|
||||||
|
|
||||||
// Per spec, square viewports should be 'portrait'
|
// Per spec, square viewports should be 'portrait'
|
||||||
let is_landscape = size.width > size.height;
|
let is_landscape = size.width > size.height;
|
||||||
|
@ -94,13 +92,13 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-4/#orientation
|
/// https://drafts.csswg.org/mediaqueries-4/#orientation
|
||||||
fn eval_orientation(device: &Device, value: Option<Orientation>) -> bool {
|
fn eval_orientation(context: &Context, value: Option<Orientation>) -> bool {
|
||||||
eval_orientation_for(device, value, Device::au_viewport_size)
|
eval_orientation_for(context, value, Device::au_viewport_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// FIXME: There's no spec for `-moz-device-orientation`.
|
/// FIXME: There's no spec for `-moz-device-orientation`.
|
||||||
fn eval_device_orientation(device: &Device, value: Option<Orientation>) -> bool {
|
fn eval_device_orientation(context: &Context, value: Option<Orientation>) -> bool {
|
||||||
eval_orientation_for(device, value, device_size)
|
eval_orientation_for(context, value, device_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Values for the display-mode media feature.
|
/// Values for the display-mode media feature.
|
||||||
|
@ -115,22 +113,22 @@ pub enum DisplayMode {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://w3c.github.io/manifest/#the-display-mode-media-feature
|
/// https://w3c.github.io/manifest/#the-display-mode-media-feature
|
||||||
fn eval_display_mode(device: &Device, query_value: Option<DisplayMode>) -> bool {
|
fn eval_display_mode(context: &Context, query_value: Option<DisplayMode>) -> bool {
|
||||||
match query_value {
|
match query_value {
|
||||||
Some(v) => v == unsafe { bindings::Gecko_MediaFeatures_GetDisplayMode(device.document()) },
|
Some(v) => v == unsafe { bindings::Gecko_MediaFeatures_GetDisplayMode(context.device().document()) },
|
||||||
None => true,
|
None => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-4/#grid
|
/// https://drafts.csswg.org/mediaqueries-4/#grid
|
||||||
fn eval_grid(_: &Device) -> bool {
|
fn eval_grid(_: &Context) -> bool {
|
||||||
// Gecko doesn't support grid devices (e.g., ttys), so the 'grid' feature
|
// Gecko doesn't support grid devices (e.g., ttys), so the 'grid' feature
|
||||||
// is always 0.
|
// is always 0.
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://compat.spec.whatwg.org/#css-media-queries-webkit-transform-3d
|
/// https://compat.spec.whatwg.org/#css-media-queries-webkit-transform-3d
|
||||||
fn eval_transform_3d(_: &Device) -> bool {
|
fn eval_transform_3d(_: &Context) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,32 +140,32 @@ enum Scan {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-4/#scan
|
/// https://drafts.csswg.org/mediaqueries-4/#scan
|
||||||
fn eval_scan(_: &Device, _: Option<Scan>) -> bool {
|
fn eval_scan(_: &Context, _: Option<Scan>) -> bool {
|
||||||
// Since Gecko doesn't support the 'tv' media type, the 'scan' feature never
|
// Since Gecko doesn't support the 'tv' media type, the 'scan' feature never
|
||||||
// matches.
|
// matches.
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-4/#color
|
/// https://drafts.csswg.org/mediaqueries-4/#color
|
||||||
fn eval_color(device: &Device) -> u32 {
|
fn eval_color(context: &Context) -> u32 {
|
||||||
unsafe { bindings::Gecko_MediaFeatures_GetColorDepth(device.document()) }
|
unsafe { bindings::Gecko_MediaFeatures_GetColorDepth(context.device().document()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-4/#color-index
|
/// https://drafts.csswg.org/mediaqueries-4/#color-index
|
||||||
fn eval_color_index(_: &Device) -> u32 {
|
fn eval_color_index(_: &Context) -> u32 {
|
||||||
// We should return zero if the device does not use a color lookup table.
|
// We should return zero if the device does not use a color lookup table.
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-4/#monochrome
|
/// https://drafts.csswg.org/mediaqueries-4/#monochrome
|
||||||
fn eval_monochrome(device: &Device) -> u32 {
|
fn eval_monochrome(context: &Context) -> u32 {
|
||||||
// For color devices we should return 0.
|
// For color devices we should return 0.
|
||||||
unsafe { bindings::Gecko_MediaFeatures_GetMonochromeBitsPerPixel(device.document()) }
|
unsafe { bindings::Gecko_MediaFeatures_GetMonochromeBitsPerPixel(context.device().document()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-4/#resolution
|
/// https://drafts.csswg.org/mediaqueries-4/#resolution
|
||||||
fn eval_resolution(device: &Device) -> Resolution {
|
fn eval_resolution(context: &Context) -> Resolution {
|
||||||
let resolution_dppx = unsafe { bindings::Gecko_MediaFeatures_GetResolution(device.document()) };
|
let resolution_dppx = unsafe { bindings::Gecko_MediaFeatures_GetResolution(context.device().document()) };
|
||||||
Resolution::from_dppx(resolution_dppx)
|
Resolution::from_dppx(resolution_dppx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,9 +198,9 @@ pub enum DynamicRange {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-5/#prefers-reduced-motion
|
/// https://drafts.csswg.org/mediaqueries-5/#prefers-reduced-motion
|
||||||
fn eval_prefers_reduced_motion(device: &Device, query_value: Option<PrefersReducedMotion>) -> bool {
|
fn eval_prefers_reduced_motion(context: &Context, query_value: Option<PrefersReducedMotion>) -> bool {
|
||||||
let prefers_reduced =
|
let prefers_reduced =
|
||||||
unsafe { bindings::Gecko_MediaFeatures_PrefersReducedMotion(device.document()) };
|
unsafe { bindings::Gecko_MediaFeatures_PrefersReducedMotion(context.device().document()) };
|
||||||
let query_value = match query_value {
|
let query_value = match query_value {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
None => return prefers_reduced,
|
None => return prefers_reduced,
|
||||||
|
@ -230,9 +228,9 @@ pub enum PrefersContrast {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-5/#prefers-contrast
|
/// https://drafts.csswg.org/mediaqueries-5/#prefers-contrast
|
||||||
fn eval_prefers_contrast(device: &Device, query_value: Option<PrefersContrast>) -> bool {
|
fn eval_prefers_contrast(context: &Context, query_value: Option<PrefersContrast>) -> bool {
|
||||||
let prefers_contrast =
|
let prefers_contrast =
|
||||||
unsafe { bindings::Gecko_MediaFeatures_PrefersContrast(device.document()) };
|
unsafe { bindings::Gecko_MediaFeatures_PrefersContrast(context.device().document()) };
|
||||||
match query_value {
|
match query_value {
|
||||||
Some(v) => v == prefers_contrast,
|
Some(v) => v == prefers_contrast,
|
||||||
None => prefers_contrast != PrefersContrast::NoPreference,
|
None => prefers_contrast != PrefersContrast::NoPreference,
|
||||||
|
@ -251,8 +249,8 @@ pub enum ForcedColors {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-5/#forced-colors
|
/// https://drafts.csswg.org/mediaqueries-5/#forced-colors
|
||||||
fn eval_forced_colors(device: &Device, query_value: Option<ForcedColors>) -> bool {
|
fn eval_forced_colors(context: &Context, query_value: Option<ForcedColors>) -> bool {
|
||||||
let forced = !device.use_document_colors();
|
let forced = !context.device().use_document_colors();
|
||||||
match query_value {
|
match query_value {
|
||||||
Some(query_value) => forced == (query_value == ForcedColors::Active),
|
Some(query_value) => forced == (query_value == ForcedColors::Active),
|
||||||
None => forced,
|
None => forced,
|
||||||
|
@ -269,7 +267,7 @@ enum OverflowBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-4/#mf-overflow-block
|
/// https://drafts.csswg.org/mediaqueries-4/#mf-overflow-block
|
||||||
fn eval_overflow_block(device: &Device, query_value: Option<OverflowBlock>) -> bool {
|
fn eval_overflow_block(context: &Context, query_value: Option<OverflowBlock>) -> bool {
|
||||||
// For the time being, assume that printing (including previews)
|
// For the time being, assume that printing (including previews)
|
||||||
// is the only time when we paginate, and we are otherwise always
|
// is the only time when we paginate, and we are otherwise always
|
||||||
// scrolling. This is true at the moment in Firefox, but may need
|
// scrolling. This is true at the moment in Firefox, but may need
|
||||||
|
@ -277,7 +275,7 @@ fn eval_overflow_block(device: &Device, query_value: Option<OverflowBlock>) -> b
|
||||||
// billboard mode that doesn't support overflow at all).
|
// billboard mode that doesn't support overflow at all).
|
||||||
//
|
//
|
||||||
// If this ever changes, don't forget to change eval_overflow_inline too.
|
// If this ever changes, don't forget to change eval_overflow_inline too.
|
||||||
let scrolling = device.media_type() != MediaType::print();
|
let scrolling = context.device().media_type() != MediaType::print();
|
||||||
let query_value = match query_value {
|
let query_value = match query_value {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
None => return true,
|
None => return true,
|
||||||
|
@ -298,9 +296,9 @@ enum OverflowInline {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-4/#mf-overflow-inline
|
/// https://drafts.csswg.org/mediaqueries-4/#mf-overflow-inline
|
||||||
fn eval_overflow_inline(device: &Device, query_value: Option<OverflowInline>) -> bool {
|
fn eval_overflow_inline(context: &Context, query_value: Option<OverflowInline>) -> bool {
|
||||||
// See the note in eval_overflow_block.
|
// See the note in eval_overflow_block.
|
||||||
let scrolling = device.media_type() != MediaType::print();
|
let scrolling = context.device().media_type() != MediaType::print();
|
||||||
let query_value = match query_value {
|
let query_value = match query_value {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
None => return scrolling,
|
None => return scrolling,
|
||||||
|
@ -313,12 +311,12 @@ fn eval_overflow_inline(device: &Device, query_value: Option<OverflowInline>) ->
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_eval_prefers_color_scheme(
|
fn do_eval_prefers_color_scheme(
|
||||||
device: &Device,
|
context: &Context,
|
||||||
use_content: bool,
|
use_content: bool,
|
||||||
query_value: Option<PrefersColorScheme>,
|
query_value: Option<PrefersColorScheme>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let prefers_color_scheme =
|
let prefers_color_scheme =
|
||||||
unsafe { bindings::Gecko_MediaFeatures_PrefersColorScheme(device.document(), use_content) };
|
unsafe { bindings::Gecko_MediaFeatures_PrefersColorScheme(context.device().document(), use_content) };
|
||||||
match query_value {
|
match query_value {
|
||||||
Some(v) => prefers_color_scheme == v,
|
Some(v) => prefers_color_scheme == v,
|
||||||
None => true,
|
None => true,
|
||||||
|
@ -326,30 +324,30 @@ fn do_eval_prefers_color_scheme(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme
|
/// https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme
|
||||||
fn eval_prefers_color_scheme(device: &Device, query_value: Option<PrefersColorScheme>) -> bool {
|
fn eval_prefers_color_scheme(context: &Context, query_value: Option<PrefersColorScheme>) -> bool {
|
||||||
do_eval_prefers_color_scheme(device, /* use_content = */ false, query_value)
|
do_eval_prefers_color_scheme(context, /* use_content = */ false, query_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_content_prefers_color_scheme(
|
fn eval_content_prefers_color_scheme(
|
||||||
device: &Device,
|
context: &Context,
|
||||||
query_value: Option<PrefersColorScheme>,
|
query_value: Option<PrefersColorScheme>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
do_eval_prefers_color_scheme(device, /* use_content = */ true, query_value)
|
do_eval_prefers_color_scheme(context, /* use_content = */ true, query_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-5/#dynamic-range
|
/// https://drafts.csswg.org/mediaqueries-5/#dynamic-range
|
||||||
fn eval_dynamic_range(device: &Device, query_value: Option<DynamicRange>) -> bool {
|
fn eval_dynamic_range(context: &Context, query_value: Option<DynamicRange>) -> bool {
|
||||||
let dynamic_range =
|
let dynamic_range =
|
||||||
unsafe { bindings::Gecko_MediaFeatures_DynamicRange(device.document()) };
|
unsafe { bindings::Gecko_MediaFeatures_DynamicRange(context.device().document()) };
|
||||||
match query_value {
|
match query_value {
|
||||||
Some(v) => dynamic_range >= v,
|
Some(v) => dynamic_range >= v,
|
||||||
None => false,
|
None => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// https://drafts.csswg.org/mediaqueries-5/#video-dynamic-range
|
/// https://drafts.csswg.org/mediaqueries-5/#video-dynamic-range
|
||||||
fn eval_video_dynamic_range(device: &Device, query_value: Option<DynamicRange>) -> bool {
|
fn eval_video_dynamic_range(context: &Context, query_value: Option<DynamicRange>) -> bool {
|
||||||
let dynamic_range =
|
let dynamic_range =
|
||||||
unsafe { bindings::Gecko_MediaFeatures_VideoDynamicRange(device.document()) };
|
unsafe { bindings::Gecko_MediaFeatures_VideoDynamicRange(context.device().document()) };
|
||||||
match query_value {
|
match query_value {
|
||||||
Some(v) => dynamic_range >= v,
|
Some(v) => dynamic_range >= v,
|
||||||
None => false,
|
None => false,
|
||||||
|
@ -365,15 +363,15 @@ bitflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn primary_pointer_capabilities(device: &Device) -> PointerCapabilities {
|
fn primary_pointer_capabilities(context: &Context) -> PointerCapabilities {
|
||||||
PointerCapabilities::from_bits_truncate(unsafe {
|
PointerCapabilities::from_bits_truncate(unsafe {
|
||||||
bindings::Gecko_MediaFeatures_PrimaryPointerCapabilities(device.document())
|
bindings::Gecko_MediaFeatures_PrimaryPointerCapabilities(context.device().document())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn all_pointer_capabilities(device: &Device) -> PointerCapabilities {
|
fn all_pointer_capabilities(context: &Context) -> PointerCapabilities {
|
||||||
PointerCapabilities::from_bits_truncate(unsafe {
|
PointerCapabilities::from_bits_truncate(unsafe {
|
||||||
bindings::Gecko_MediaFeatures_AllPointerCapabilities(device.document())
|
bindings::Gecko_MediaFeatures_AllPointerCapabilities(context.device().document())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,13 +400,13 @@ fn eval_pointer_capabilities(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-4/#pointer
|
/// https://drafts.csswg.org/mediaqueries-4/#pointer
|
||||||
fn eval_pointer(device: &Device, query_value: Option<Pointer>) -> bool {
|
fn eval_pointer(context: &Context, query_value: Option<Pointer>) -> bool {
|
||||||
eval_pointer_capabilities(query_value, primary_pointer_capabilities(device))
|
eval_pointer_capabilities(query_value, primary_pointer_capabilities(context))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-4/#descdef-media-any-pointer
|
/// https://drafts.csswg.org/mediaqueries-4/#descdef-media-any-pointer
|
||||||
fn eval_any_pointer(device: &Device, query_value: Option<Pointer>) -> bool {
|
fn eval_any_pointer(context: &Context, query_value: Option<Pointer>) -> bool {
|
||||||
eval_pointer_capabilities(query_value, all_pointer_capabilities(device))
|
eval_pointer_capabilities(query_value, all_pointer_capabilities(context))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, FromPrimitive, Parse, ToCss)]
|
#[derive(Clone, Copy, Debug, FromPrimitive, Parse, ToCss)]
|
||||||
|
@ -435,33 +433,33 @@ fn eval_hover_capabilities(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-4/#hover
|
/// https://drafts.csswg.org/mediaqueries-4/#hover
|
||||||
fn eval_hover(device: &Device, query_value: Option<Hover>) -> bool {
|
fn eval_hover(context: &Context, query_value: Option<Hover>) -> bool {
|
||||||
eval_hover_capabilities(query_value, primary_pointer_capabilities(device))
|
eval_hover_capabilities(query_value, primary_pointer_capabilities(context))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/mediaqueries-4/#descdef-media-any-hover
|
/// https://drafts.csswg.org/mediaqueries-4/#descdef-media-any-hover
|
||||||
fn eval_any_hover(device: &Device, query_value: Option<Hover>) -> bool {
|
fn eval_any_hover(context: &Context, query_value: Option<Hover>) -> bool {
|
||||||
eval_hover_capabilities(query_value, all_pointer_capabilities(device))
|
eval_hover_capabilities(query_value, all_pointer_capabilities(context))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_moz_is_glyph(device: &Device) -> bool {
|
fn eval_moz_is_glyph(context: &Context) -> bool {
|
||||||
device.document().mIsSVGGlyphsDocument()
|
context.device().document().mIsSVGGlyphsDocument()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_moz_print_preview(device: &Device) -> bool {
|
fn eval_moz_print_preview(context: &Context) -> bool {
|
||||||
let is_print_preview = device.is_print_preview();
|
let is_print_preview = context.device().is_print_preview();
|
||||||
if is_print_preview {
|
if is_print_preview {
|
||||||
debug_assert_eq!(device.media_type(), MediaType::print());
|
debug_assert_eq!(context.device().media_type(), MediaType::print());
|
||||||
}
|
}
|
||||||
is_print_preview
|
is_print_preview
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_moz_non_native_content_theme(device: &Device) -> bool {
|
fn eval_moz_non_native_content_theme(context: &Context) -> bool {
|
||||||
unsafe { bindings::Gecko_MediaFeatures_ShouldAvoidNativeTheme(device.document()) }
|
unsafe { bindings::Gecko_MediaFeatures_ShouldAvoidNativeTheme(context.device().document()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_moz_is_resource_document(device: &Device) -> bool {
|
fn eval_moz_is_resource_document(context: &Context) -> bool {
|
||||||
unsafe { bindings::Gecko_MediaFeatures_IsResourceDocument(device.document()) }
|
unsafe { bindings::Gecko_MediaFeatures_IsResourceDocument(context.device().document()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allows front-end CSS to discern platform via media queries.
|
/// Allows front-end CSS to discern platform via media queries.
|
||||||
|
@ -487,7 +485,7 @@ pub enum Platform {
|
||||||
WindowsWin10,
|
WindowsWin10,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_moz_platform(_: &Device, query_value: Option<Platform>) -> bool {
|
fn eval_moz_platform(_: &Context, query_value: Option<Platform>) -> bool {
|
||||||
let query_value = match query_value {
|
let query_value = match query_value {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
None => return false,
|
None => return false,
|
||||||
|
@ -496,13 +494,13 @@ fn eval_moz_platform(_: &Device, query_value: Option<Platform>) -> bool {
|
||||||
unsafe { bindings::Gecko_MediaFeatures_MatchesPlatform(query_value) }
|
unsafe { bindings::Gecko_MediaFeatures_MatchesPlatform(query_value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_moz_windows_non_native_menus(device: &Device) -> bool {
|
fn eval_moz_windows_non_native_menus(context: &Context) -> bool {
|
||||||
let use_non_native_menus = match static_prefs::pref!("browser.display.windows.non_native_menus")
|
let use_non_native_menus = match static_prefs::pref!("browser.display.windows.non_native_menus")
|
||||||
{
|
{
|
||||||
0 => false,
|
0 => false,
|
||||||
1 => true,
|
1 => true,
|
||||||
_ => {
|
_ => {
|
||||||
eval_moz_platform(device, Some(Platform::WindowsWin10)) &&
|
eval_moz_platform(context, Some(Platform::WindowsWin10)) &&
|
||||||
get_lnf_int_as_bool(bindings::LookAndFeel_IntID::WindowsDefaultTheme as i32)
|
get_lnf_int_as_bool(bindings::LookAndFeel_IntID::WindowsDefaultTheme as i32)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -510,8 +508,8 @@ fn eval_moz_windows_non_native_menus(device: &Device) -> bool {
|
||||||
use_non_native_menus
|
use_non_native_menus
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_moz_overlay_scrollbars(device: &Device) -> bool {
|
fn eval_moz_overlay_scrollbars(context: &Context) -> bool {
|
||||||
unsafe { bindings::Gecko_MediaFeatures_UseOverlayScrollbars(device.document()) }
|
unsafe { bindings::Gecko_MediaFeatures_UseOverlayScrollbars(context.device().document()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_lnf_int(int_id: i32) -> i32 {
|
fn get_lnf_int(int_id: i32) -> i32 {
|
||||||
|
@ -540,7 +538,7 @@ fn get_scrollbar_end_forward(int_id: i32) -> bool {
|
||||||
|
|
||||||
macro_rules! lnf_int_feature {
|
macro_rules! lnf_int_feature {
|
||||||
($feature_name:expr, $int_id:ident, $get_value:ident) => {{
|
($feature_name:expr, $int_id:ident, $get_value:ident) => {{
|
||||||
fn __eval(_: &Device) -> bool {
|
fn __eval(_: &Context) -> bool {
|
||||||
$get_value(bindings::LookAndFeel_IntID::$int_id as i32)
|
$get_value(bindings::LookAndFeel_IntID::$int_id as i32)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -567,7 +565,7 @@ macro_rules! lnf_int_feature {
|
||||||
/// you also need to add them to kMediaQueryPrefs in nsXPLookAndFeel.cpp
|
/// you also need to add them to kMediaQueryPrefs in nsXPLookAndFeel.cpp
|
||||||
macro_rules! bool_pref_feature {
|
macro_rules! bool_pref_feature {
|
||||||
($feature_name:expr, $pref:tt) => {{
|
($feature_name:expr, $pref:tt) => {{
|
||||||
fn __eval(_: &Device) -> bool {
|
fn __eval(_: &Context) -> bool {
|
||||||
static_prefs::pref!($pref)
|
static_prefs::pref!($pref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
//!
|
//!
|
||||||
//! https://drafts.csswg.org/mediaqueries-4/#typedef-media-condition
|
//! https://drafts.csswg.org/mediaqueries-4/#typedef-media-condition
|
||||||
|
|
||||||
use super::{Device, MediaFeatureExpression};
|
use super::MediaFeatureExpression;
|
||||||
use crate::context::QuirksMode;
|
|
||||||
use crate::parser::ParserContext;
|
use crate::parser::ParserContext;
|
||||||
|
use crate::values::computed;
|
||||||
use cssparser::{Parser, Token};
|
use cssparser::{Parser, Token};
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
||||||
|
@ -168,16 +168,16 @@ impl MediaCondition {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether this condition matches the device and quirks mode.
|
/// Whether this condition matches the device and quirks mode.
|
||||||
pub fn matches(&self, device: &Device, quirks_mode: QuirksMode) -> bool {
|
pub fn matches(&self, context: &computed::Context) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
MediaCondition::Feature(ref f) => f.matches(device, quirks_mode),
|
MediaCondition::Feature(ref f) => f.matches(context),
|
||||||
MediaCondition::InParens(ref c) => c.matches(device, quirks_mode),
|
MediaCondition::InParens(ref c) => c.matches(context),
|
||||||
MediaCondition::Not(ref c) => !c.matches(device, quirks_mode),
|
MediaCondition::Not(ref c) => !c.matches(context),
|
||||||
MediaCondition::Operation(ref conditions, op) => {
|
MediaCondition::Operation(ref conditions, op) => {
|
||||||
let mut iter = conditions.iter();
|
let mut iter = conditions.iter();
|
||||||
match op {
|
match op {
|
||||||
Operator::And => iter.all(|c| c.matches(device, quirks_mode)),
|
Operator::And => iter.all(|c| c.matches(context)),
|
||||||
Operator::Or => iter.any(|c| c.matches(device, quirks_mode)),
|
Operator::Or => iter.any(|c| c.matches(context)),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,8 @@
|
||||||
|
|
||||||
//! Media features.
|
//! Media features.
|
||||||
|
|
||||||
use super::Device;
|
|
||||||
use crate::parser::ParserContext;
|
use crate::parser::ParserContext;
|
||||||
use crate::values::computed::Ratio;
|
use crate::values::computed::{self, CSSPixelLength, Resolution, Ratio};
|
||||||
use crate::values::computed::{CSSPixelLength, Resolution};
|
|
||||||
use crate::Atom;
|
use crate::Atom;
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -16,7 +14,7 @@ use style_traits::ParseError;
|
||||||
/// A generic discriminant for an enum value.
|
/// A generic discriminant for an enum value.
|
||||||
pub type KeywordDiscriminant = u8;
|
pub type KeywordDiscriminant = u8;
|
||||||
|
|
||||||
type MediaFeatureGetter<T> = fn(device: &Device) -> T;
|
type MediaFeatureGetter<T> = fn(device: &computed::Context) -> T;
|
||||||
|
|
||||||
/// Serializes a given discriminant.
|
/// Serializes a given discriminant.
|
||||||
///
|
///
|
||||||
|
@ -54,7 +52,7 @@ pub enum Evaluator {
|
||||||
serializer: KeywordSerializer,
|
serializer: KeywordSerializer,
|
||||||
/// The evaluator itself. This is guaranteed to be called with a
|
/// The evaluator itself. This is guaranteed to be called with a
|
||||||
/// keyword that `parser` has produced.
|
/// keyword that `parser` has produced.
|
||||||
evaluator: fn(&Device, Option<KeywordDiscriminant>) -> bool,
|
evaluator: fn(&computed::Context, Option<KeywordDiscriminant>) -> bool,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,14 +82,14 @@ macro_rules! keyword_evaluator {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __evaluate(
|
fn __evaluate(
|
||||||
device: &$crate::media_queries::Device,
|
context: &$crate::values::computed::Context,
|
||||||
value: Option<$crate::media_queries::media_feature::KeywordDiscriminant>,
|
value: Option<$crate::media_queries::media_feature::KeywordDiscriminant>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// This unwrap is ok because the only discriminants that get
|
// This unwrap is ok because the only discriminants that get
|
||||||
// back to us is the ones that `parse` produces.
|
// back to us is the ones that `parse` produces.
|
||||||
let value: Option<$keyword_type> =
|
let value: Option<$keyword_type> =
|
||||||
value.map(|kw| ::num_traits::cast::FromPrimitive::from_u8(kw).unwrap());
|
value.map(|kw| ::num_traits::cast::FromPrimitive::from_u8(kw).unwrap());
|
||||||
$actual_evaluator(device, value)
|
$actual_evaluator(context, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
$crate::media_queries::media_feature::Evaluator::Enumerated {
|
$crate::media_queries::media_feature::Evaluator::Enumerated {
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
|
|
||||||
use super::media_feature::{Evaluator, MediaFeatureDescription};
|
use super::media_feature::{Evaluator, MediaFeatureDescription};
|
||||||
use super::media_feature::{KeywordDiscriminant, ParsingRequirements};
|
use super::media_feature::{KeywordDiscriminant, ParsingRequirements};
|
||||||
use super::Device;
|
|
||||||
use crate::context::QuirksMode;
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use crate::gecko::media_features::MEDIA_FEATURES;
|
use crate::gecko::media_features::MEDIA_FEATURES;
|
||||||
use crate::parser::{Parse, ParserContext};
|
use crate::parser::{Parse, ParserContext};
|
||||||
|
@ -381,7 +379,7 @@ impl MediaFeatureExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether this media query evaluates to true for the given device.
|
/// Returns whether this media query evaluates to true for the given device.
|
||||||
pub fn matches(&self, device: &Device, quirks_mode: QuirksMode) -> bool {
|
pub fn matches(&self, context: &computed::Context) -> bool {
|
||||||
let value = self.value.as_ref();
|
let value = self.value.as_ref();
|
||||||
|
|
||||||
macro_rules! expect {
|
macro_rules! expect {
|
||||||
|
@ -396,21 +394,19 @@ 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| {
|
specified.to_computed_value(context)
|
||||||
specified.to_computed_value(context)
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
let length = eval(device);
|
let length = eval(context);
|
||||||
RangeOrOperator::evaluate(self.range_or_operator, computed, length)
|
RangeOrOperator::evaluate(self.range_or_operator, computed, length)
|
||||||
},
|
},
|
||||||
Evaluator::Integer(eval) => {
|
Evaluator::Integer(eval) => {
|
||||||
let computed = expect!(Integer).cloned();
|
let computed = expect!(Integer).cloned();
|
||||||
let integer = eval(device);
|
let integer = eval(context);
|
||||||
RangeOrOperator::evaluate(self.range_or_operator, computed, integer)
|
RangeOrOperator::evaluate(self.range_or_operator, computed, integer)
|
||||||
},
|
},
|
||||||
Evaluator::Float(eval) => {
|
Evaluator::Float(eval) => {
|
||||||
let computed = expect!(Float).cloned();
|
let computed = expect!(Float).cloned();
|
||||||
let float = eval(device);
|
let float = eval(context);
|
||||||
RangeOrOperator::evaluate(self.range_or_operator, computed, float)
|
RangeOrOperator::evaluate(self.range_or_operator, computed, float)
|
||||||
}
|
}
|
||||||
Evaluator::NumberRatio(eval) => {
|
Evaluator::NumberRatio(eval) => {
|
||||||
|
@ -422,26 +418,24 @@ impl MediaFeatureExpression {
|
||||||
Some(ratio) => ratio.used_value(),
|
Some(ratio) => ratio.used_value(),
|
||||||
None => return true,
|
None => return true,
|
||||||
};
|
};
|
||||||
let ratio = eval(device);
|
let ratio = eval(context);
|
||||||
RangeOrOperator::evaluate_with_query_value(self.range_or_operator, computed, ratio)
|
RangeOrOperator::evaluate_with_query_value(self.range_or_operator, computed, ratio)
|
||||||
},
|
},
|
||||||
Evaluator::Resolution(eval) => {
|
Evaluator::Resolution(eval) => {
|
||||||
let computed = expect!(Resolution).map(|specified| {
|
let computed = expect!(Resolution).map(|specified| {
|
||||||
computed::Context::for_media_query_evaluation(device, quirks_mode, |context| {
|
specified.to_computed_value(context).dppx()
|
||||||
specified.to_computed_value(context).dppx()
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
let resolution = eval(device).dppx();
|
let resolution = eval(context).dppx();
|
||||||
RangeOrOperator::evaluate(self.range_or_operator, computed, resolution)
|
RangeOrOperator::evaluate(self.range_or_operator, computed, resolution)
|
||||||
},
|
},
|
||||||
Evaluator::Enumerated { evaluator, .. } => {
|
Evaluator::Enumerated { evaluator, .. } => {
|
||||||
debug_assert!(self.range_or_operator.is_none(), "Ranges with keywords?");
|
debug_assert!(self.range_or_operator.is_none(), "Ranges with keywords?");
|
||||||
evaluator(device, expect!(Enumerated).cloned())
|
evaluator(context, expect!(Enumerated).cloned())
|
||||||
},
|
},
|
||||||
Evaluator::BoolInteger(eval) => {
|
Evaluator::BoolInteger(eval) => {
|
||||||
debug_assert!(self.range_or_operator.is_none(), "Ranges with bools?");
|
debug_assert!(self.range_or_operator.is_none(), "Ranges with bools?");
|
||||||
let computed = expect!(BoolInteger).cloned();
|
let computed = expect!(BoolInteger).cloned();
|
||||||
let boolean = eval(device);
|
let boolean = eval(context);
|
||||||
computed.map_or(boolean, |v| v == boolean)
|
computed.map_or(boolean, |v| v == boolean)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ use super::{Device, MediaQuery, Qualifier};
|
||||||
use crate::context::QuirksMode;
|
use crate::context::QuirksMode;
|
||||||
use crate::error_reporting::ContextualParseError;
|
use crate::error_reporting::ContextualParseError;
|
||||||
use crate::parser::ParserContext;
|
use crate::parser::ParserContext;
|
||||||
|
use crate::values::computed;
|
||||||
use cssparser::{Delimiter, Parser};
|
use cssparser::{Delimiter, Parser};
|
||||||
use cssparser::{ParserInput, Token};
|
use cssparser::{ParserInput, Token};
|
||||||
|
|
||||||
|
@ -74,15 +75,17 @@ impl MediaList {
|
||||||
pub fn evaluate(&self, device: &Device, quirks_mode: QuirksMode) -> bool {
|
pub fn evaluate(&self, device: &Device, quirks_mode: QuirksMode) -> bool {
|
||||||
// Check if it is an empty media query list or any queries match.
|
// Check if it is an empty media query list or any queries match.
|
||||||
// https://drafts.csswg.org/mediaqueries-4/#mq-list
|
// https://drafts.csswg.org/mediaqueries-4/#mq-list
|
||||||
self.media_queries.is_empty() ||
|
if self.media_queries.is_empty() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
computed::Context::for_media_query_evaluation(device, quirks_mode, |context| {
|
||||||
self.media_queries.iter().any(|mq| {
|
self.media_queries.iter().any(|mq| {
|
||||||
let media_match = mq.media_type.matches(device.media_type());
|
let media_match = mq.media_type.matches(device.media_type());
|
||||||
|
|
||||||
// Check if the media condition match.
|
// Check if the media condition match.
|
||||||
let query_match = media_match &&
|
let query_match = media_match &&
|
||||||
mq.condition
|
mq.condition.as_ref().map_or(true, |c| c.matches(context));
|
||||||
.as_ref()
|
|
||||||
.map_or(true, |c| c.matches(device, quirks_mode));
|
|
||||||
|
|
||||||
// Apply the logical NOT qualifier to the result
|
// Apply the logical NOT qualifier to the result
|
||||||
match mq.qualifier {
|
match mq.qualifier {
|
||||||
|
@ -90,6 +93,7 @@ impl MediaList {
|
||||||
_ => query_match,
|
_ => query_match,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether this `MediaList` contains no media queries.
|
/// Whether this `MediaList` contains no media queries.
|
||||||
|
|
|
@ -56,12 +56,12 @@ impl SourceSizeList {
|
||||||
|
|
||||||
/// Evaluate this <source-size-list> to get the final viewport length.
|
/// Evaluate this <source-size-list> to get the final viewport length.
|
||||||
pub fn evaluate(&self, device: &Device, quirks_mode: QuirksMode) -> Au {
|
pub fn evaluate(&self, device: &Device, quirks_mode: QuirksMode) -> Au {
|
||||||
let matching_source_size = self
|
|
||||||
.source_sizes
|
|
||||||
.iter()
|
|
||||||
.find(|source_size| source_size.condition.matches(device, quirks_mode));
|
|
||||||
|
|
||||||
computed::Context::for_media_query_evaluation(device, quirks_mode, |context| {
|
computed::Context::for_media_query_evaluation(device, quirks_mode, |context| {
|
||||||
|
let matching_source_size = self
|
||||||
|
.source_sizes
|
||||||
|
.iter()
|
||||||
|
.find(|source_size| source_size.condition.matches(context));
|
||||||
|
|
||||||
match matching_source_size {
|
match matching_source_size {
|
||||||
Some(source_size) => source_size.value.to_computed_value(context),
|
Some(source_size) => source_size.value.to_computed_value(context),
|
||||||
None => match self.value {
|
None => match self.value {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue