Revert "Backport several style changes from Gecko (5) (#30099)" (#30104)

This reverts commit 8e15389cae.
This commit is contained in:
Oriol Brufau 2023-08-16 08:24:42 +02:00 committed by GitHub
parent 8e15389cae
commit d6ae8dc112
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
152 changed files with 4622 additions and 5862 deletions

View file

@ -15,7 +15,7 @@ use crate::gecko_bindings::structs::{
RawServoKeyframesRule, RawServoLayerBlockRule, RawServoLayerStatementRule, RawServoMediaList,
RawServoMediaRule, RawServoMozDocumentRule, RawServoNamespaceRule, RawServoPageRule,
RawServoScrollTimelineRule, RawServoStyleRule, RawServoStyleSheetContents,
RawServoSupportsRule, RawServoContainerRule, ServoCssRules,
RawServoSupportsRule, ServoCssRules,
};
use crate::gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI, Strong};
use crate::media_queries::MediaList;
@ -26,7 +26,7 @@ use crate::stylesheets::keyframes_rule::Keyframe;
use crate::stylesheets::{
CounterStyleRule, CssRules, DocumentRule, FontFaceRule, FontFeatureValuesRule, ImportRule,
KeyframesRule, LayerBlockRule, LayerStatementRule, MediaRule, NamespaceRule, PageRule,
ScrollTimelineRule, StyleRule, StylesheetContents, SupportsRule, ContainerRule,
ScrollTimelineRule, StyleRule, StylesheetContents, SupportsRule,
};
use servo_arc::{Arc, ArcBorrow};
use std::{mem, ptr};
@ -98,9 +98,6 @@ impl_arc_ffi!(Locked<ScrollTimelineRule> => RawServoScrollTimelineRule
impl_arc_ffi!(Locked<SupportsRule> => RawServoSupportsRule
[Servo_SupportsRule_AddRef, Servo_SupportsRule_Release]);
impl_arc_ffi!(Locked<ContainerRule> => RawServoContainerRule
[Servo_ContainerRule_AddRef, Servo_ContainerRule_Release]);
impl_arc_ffi!(Locked<DocumentRule> => RawServoMozDocumentRule
[Servo_DocumentRule_AddRef, Servo_DocumentRule_Release]);

View file

@ -129,12 +129,6 @@ impl StylesheetInDocument for GeckoStyleSheet {
pub struct PerDocumentStyleDataImpl {
/// Rule processor.
pub stylist: Stylist,
/// A cache from element to resolved style.
pub undisplayed_style_cache: crate::traversal::UndisplayedStyleCache,
/// The generation for which our cache is valid.
pub undisplayed_style_cache_generation: u64,
}
/// The data itself is an `AtomicRefCell`, which guarantees the proper semantics
@ -149,8 +143,6 @@ impl PerDocumentStyleData {
PerDocumentStyleData(AtomicRefCell::new(PerDocumentStyleDataImpl {
stylist: Stylist::new(device, quirks_mode.into()),
undisplayed_style_cache: Default::default(),
undisplayed_style_cache_generation: 0,
}))
}
@ -185,6 +177,12 @@ impl PerDocumentStyleDataImpl {
self.stylist.device().default_computed_values_arc()
}
/// Returns whether visited styles are enabled.
#[inline]
pub fn visited_styles_enabled(&self) -> bool {
unsafe { bindings::Gecko_VisitedStylesEnabled(self.stylist.device().document()) }
}
/// Measure heap usage.
pub fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
self.stylist.add_size_of(ops, sizes);

View file

@ -6,10 +6,13 @@
use crate::gecko_bindings::bindings;
use crate::gecko_bindings::structs;
use crate::queries::feature::{AllowsRanges, Evaluator, FeatureFlags, QueryFeatureDescription};
use crate::queries::values::Orientation;
use crate::media_queries::media_feature::{AllowsRanges, ParsingRequirements};
use crate::media_queries::media_feature::{Evaluator, MediaFeatureDescription};
use crate::media_queries::media_feature_expression::RangeOrOperator;
use crate::media_queries::{Device, MediaType};
use crate::values::computed::{Context, CSSPixelLength, Ratio, Resolution};
use crate::values::computed::CSSPixelLength;
use crate::values::computed::Ratio;
use crate::values::computed::Resolution;
use app_units::Au;
use euclid::default::Size2D;
@ -23,56 +26,150 @@ fn device_size(device: &Device) -> Size2D<Au> {
}
/// https://drafts.csswg.org/mediaqueries-4/#width
fn eval_width(context: &Context) -> CSSPixelLength {
CSSPixelLength::new(context.device().au_viewport_size().width.to_f32_px())
fn eval_width(
device: &Device,
value: Option<CSSPixelLength>,
range_or_operator: Option<RangeOrOperator>,
) -> bool {
RangeOrOperator::evaluate(
range_or_operator,
value.map(Au::from),
device.au_viewport_size().width,
)
}
/// https://drafts.csswg.org/mediaqueries-4/#device-width
fn eval_device_width(context: &Context) -> CSSPixelLength {
CSSPixelLength::new(device_size(context.device()).width.to_f32_px())
fn eval_device_width(
device: &Device,
value: Option<CSSPixelLength>,
range_or_operator: Option<RangeOrOperator>,
) -> bool {
RangeOrOperator::evaluate(
range_or_operator,
value.map(Au::from),
device_size(device).width,
)
}
/// https://drafts.csswg.org/mediaqueries-4/#height
fn eval_height(context: &Context) -> CSSPixelLength {
CSSPixelLength::new(context.device().au_viewport_size().height.to_f32_px())
fn eval_height(
device: &Device,
value: Option<CSSPixelLength>,
range_or_operator: Option<RangeOrOperator>,
) -> bool {
RangeOrOperator::evaluate(
range_or_operator,
value.map(Au::from),
device.au_viewport_size().height,
)
}
/// https://drafts.csswg.org/mediaqueries-4/#device-height
fn eval_device_height(context: &Context) -> CSSPixelLength {
CSSPixelLength::new(device_size(context.device()).height.to_f32_px())
fn eval_device_height(
device: &Device,
value: Option<CSSPixelLength>,
range_or_operator: Option<RangeOrOperator>,
) -> bool {
RangeOrOperator::evaluate(
range_or_operator,
value.map(Au::from),
device_size(device).height,
)
}
fn eval_aspect_ratio_for<F>(context: &Context, get_size: F) -> Ratio
fn eval_aspect_ratio_for<F>(
device: &Device,
query_value: Option<Ratio>,
range_or_operator: Option<RangeOrOperator>,
get_size: F,
) -> bool
where
F: FnOnce(&Device) -> Size2D<Au>,
{
let size = get_size(context.device());
Ratio::new(size.width.0 as f32, size.height.0 as f32)
// A ratio of 0/0 behaves as the ratio 1/0, so we need to call used_value()
// to convert it if necessary.
// FIXME: we may need to update here once
// https://github.com/w3c/csswg-drafts/issues/4954 got resolved.
let query_value = match query_value {
Some(v) => v.used_value(),
None => return true,
};
let size = get_size(device);
let value = Ratio::new(size.width.0 as f32, size.height.0 as f32);
RangeOrOperator::evaluate_with_query_value(range_or_operator, query_value, value)
}
/// https://drafts.csswg.org/mediaqueries-4/#aspect-ratio
fn eval_aspect_ratio(context: &Context) -> Ratio {
eval_aspect_ratio_for(context, Device::au_viewport_size)
fn eval_aspect_ratio(
device: &Device,
query_value: Option<Ratio>,
range_or_operator: Option<RangeOrOperator>,
) -> bool {
eval_aspect_ratio_for(
device,
query_value,
range_or_operator,
Device::au_viewport_size,
)
}
/// https://drafts.csswg.org/mediaqueries-4/#device-aspect-ratio
fn eval_device_aspect_ratio(context: &Context) -> Ratio {
eval_aspect_ratio_for(context, device_size)
fn eval_device_aspect_ratio(
device: &Device,
query_value: Option<Ratio>,
range_or_operator: Option<RangeOrOperator>,
) -> bool {
eval_aspect_ratio_for(device, query_value, range_or_operator, device_size)
}
/// https://compat.spec.whatwg.org/#css-media-queries-webkit-device-pixel-ratio
fn eval_device_pixel_ratio(context: &Context) -> f32 {
eval_resolution(context).dppx()
fn eval_device_pixel_ratio(
device: &Device,
query_value: Option<f32>,
range_or_operator: Option<RangeOrOperator>,
) -> bool {
eval_resolution(
device,
query_value.map(Resolution::from_dppx),
range_or_operator,
)
}
#[derive(Clone, Copy, Debug, FromPrimitive, Parse, ToCss)]
#[repr(u8)]
enum Orientation {
Landscape,
Portrait,
}
fn eval_orientation_for<F>(device: &Device, value: Option<Orientation>, get_size: F) -> bool
where
F: FnOnce(&Device) -> Size2D<Au>,
{
let query_orientation = match value {
Some(v) => v,
None => return true,
};
let size = get_size(device);
// Per spec, square viewports should be 'portrait'
let is_landscape = size.width > size.height;
match query_orientation {
Orientation::Landscape => is_landscape,
Orientation::Portrait => !is_landscape,
}
}
/// https://drafts.csswg.org/mediaqueries-4/#orientation
fn eval_orientation(context: &Context, value: Option<Orientation>) -> bool {
Orientation::eval(context.device().au_viewport_size(), value)
fn eval_orientation(device: &Device, value: Option<Orientation>) -> bool {
eval_orientation_for(device, value, Device::au_viewport_size)
}
/// FIXME: There's no spec for `-moz-device-orientation`.
fn eval_device_orientation(context: &Context, value: Option<Orientation>) -> bool {
Orientation::eval(device_size(context.device()), value)
fn eval_device_orientation(device: &Device, value: Option<Orientation>) -> bool {
eval_orientation_for(device, value, device_size)
}
/// Values for the display-mode media feature.
@ -87,23 +184,25 @@ pub enum DisplayMode {
}
/// https://w3c.github.io/manifest/#the-display-mode-media-feature
fn eval_display_mode(context: &Context, query_value: Option<DisplayMode>) -> bool {
fn eval_display_mode(device: &Device, query_value: Option<DisplayMode>) -> bool {
match query_value {
Some(v) => v == unsafe { bindings::Gecko_MediaFeatures_GetDisplayMode(context.device().document()) },
Some(v) => v == unsafe { bindings::Gecko_MediaFeatures_GetDisplayMode(device.document()) },
None => true,
}
}
/// https://drafts.csswg.org/mediaqueries-4/#grid
fn eval_grid(_: &Context) -> bool {
fn eval_grid(_: &Device, query_value: Option<bool>, _: Option<RangeOrOperator>) -> bool {
// Gecko doesn't support grid devices (e.g., ttys), so the 'grid' feature
// is always 0.
false
let supports_grid = false;
query_value.map_or(supports_grid, |v| v == supports_grid)
}
/// https://compat.spec.whatwg.org/#css-media-queries-webkit-transform-3d
fn eval_transform_3d(_: &Context) -> bool {
true
fn eval_transform_3d(_: &Device, query_value: Option<bool>, _: Option<RangeOrOperator>) -> bool {
let supports_transforms = true;
query_value.map_or(supports_transforms, |v| v == supports_transforms)
}
#[derive(Clone, Copy, Debug, FromPrimitive, Parse, ToCss)]
@ -114,33 +213,58 @@ enum Scan {
}
/// https://drafts.csswg.org/mediaqueries-4/#scan
fn eval_scan(_: &Context, _: Option<Scan>) -> bool {
fn eval_scan(_: &Device, _: Option<Scan>) -> bool {
// Since Gecko doesn't support the 'tv' media type, the 'scan' feature never
// matches.
false
}
/// https://drafts.csswg.org/mediaqueries-4/#color
fn eval_color(context: &Context) -> u32 {
unsafe { bindings::Gecko_MediaFeatures_GetColorDepth(context.device().document()) }
fn eval_color(
device: &Device,
query_value: Option<u32>,
range_or_operator: Option<RangeOrOperator>,
) -> bool {
let color_bits_per_channel =
unsafe { bindings::Gecko_MediaFeatures_GetColorDepth(device.document()) };
RangeOrOperator::evaluate(range_or_operator, query_value, color_bits_per_channel)
}
/// https://drafts.csswg.org/mediaqueries-4/#color-index
fn eval_color_index(_: &Context) -> u32 {
fn eval_color_index(
_: &Device,
query_value: Option<u32>,
range_or_operator: Option<RangeOrOperator>,
) -> bool {
// We should return zero if the device does not use a color lookup table.
0
let index = 0;
RangeOrOperator::evaluate(range_or_operator, query_value, index)
}
/// https://drafts.csswg.org/mediaqueries-4/#monochrome
fn eval_monochrome(context: &Context) -> u32 {
fn eval_monochrome(
device: &Device,
query_value: Option<u32>,
range_or_operator: Option<RangeOrOperator>,
) -> bool {
// For color devices we should return 0.
unsafe { bindings::Gecko_MediaFeatures_GetMonochromeBitsPerPixel(context.device().document()) }
let depth =
unsafe { bindings::Gecko_MediaFeatures_GetMonochromeBitsPerPixel(device.document()) };
RangeOrOperator::evaluate(range_or_operator, query_value, depth)
}
/// https://drafts.csswg.org/mediaqueries-4/#resolution
fn eval_resolution(context: &Context) -> Resolution {
let resolution_dppx = unsafe { bindings::Gecko_MediaFeatures_GetResolution(context.device().document()) };
Resolution::from_dppx(resolution_dppx)
fn eval_resolution(
device: &Device,
query_value: Option<Resolution>,
range_or_operator: Option<RangeOrOperator>,
) -> bool {
let resolution_dppx = unsafe { bindings::Gecko_MediaFeatures_GetResolution(device.document()) };
RangeOrOperator::evaluate(
range_or_operator,
query_value.map(|r| r.dppx()),
resolution_dppx,
)
}
#[derive(Clone, Copy, Debug, FromPrimitive, Parse, ToCss)]
@ -159,22 +283,10 @@ pub enum PrefersColorScheme {
Dark,
}
/// Values for the dynamic-range and video-dynamic-range media features.
/// https://drafts.csswg.org/mediaqueries-5/#dynamic-range
/// This implements PartialOrd so that lower values will correctly match
/// higher capabilities.
#[derive(Clone, Copy, Debug, FromPrimitive, Parse, PartialEq, PartialOrd, ToCss)]
#[repr(u8)]
#[allow(missing_docs)]
pub enum DynamicRange {
Standard,
High,
}
/// https://drafts.csswg.org/mediaqueries-5/#prefers-reduced-motion
fn eval_prefers_reduced_motion(context: &Context, query_value: Option<PrefersReducedMotion>) -> bool {
fn eval_prefers_reduced_motion(device: &Device, query_value: Option<PrefersReducedMotion>) -> bool {
let prefers_reduced =
unsafe { bindings::Gecko_MediaFeatures_PrefersReducedMotion(context.device().document()) };
unsafe { bindings::Gecko_MediaFeatures_PrefersReducedMotion(device.document()) };
let query_value = match query_value {
Some(v) => v,
None => return prefers_reduced,
@ -191,20 +303,19 @@ fn eval_prefers_reduced_motion(context: &Context, query_value: Option<PrefersRed
#[derive(Clone, Copy, Debug, FromPrimitive, Parse, PartialEq, ToCss)]
#[repr(u8)]
pub enum PrefersContrast {
/// More contrast is preferred.
/// More contrast is preferred. Corresponds to an accessibility theme
/// being enabled or Firefox forcing high contrast colors.
More,
/// Low contrast is preferred.
Less,
/// Custom (not more, not less).
Custom,
/// The default value if neither high or low contrast is enabled.
NoPreference,
}
/// https://drafts.csswg.org/mediaqueries-5/#prefers-contrast
fn eval_prefers_contrast(context: &Context, query_value: Option<PrefersContrast>) -> bool {
fn eval_prefers_contrast(device: &Device, query_value: Option<PrefersContrast>) -> bool {
let prefers_contrast =
unsafe { bindings::Gecko_MediaFeatures_PrefersContrast(context.device().document()) };
unsafe { bindings::Gecko_MediaFeatures_PrefersContrast(device.document()) };
match query_value {
Some(v) => v == prefers_contrast,
None => prefers_contrast != PrefersContrast::NoPreference,
@ -223,8 +334,8 @@ pub enum ForcedColors {
}
/// https://drafts.csswg.org/mediaqueries-5/#forced-colors
fn eval_forced_colors(context: &Context, query_value: Option<ForcedColors>) -> bool {
let forced = !context.device().use_document_colors();
fn eval_forced_colors(device: &Device, query_value: Option<ForcedColors>) -> bool {
let forced = !device.use_document_colors();
match query_value {
Some(query_value) => forced == (query_value == ForcedColors::Active),
None => forced,
@ -241,7 +352,7 @@ enum OverflowBlock {
}
/// https://drafts.csswg.org/mediaqueries-4/#mf-overflow-block
fn eval_overflow_block(context: &Context, query_value: Option<OverflowBlock>) -> bool {
fn eval_overflow_block(device: &Device, query_value: Option<OverflowBlock>) -> bool {
// For the time being, assume that printing (including previews)
// is the only time when we paginate, and we are otherwise always
// scrolling. This is true at the moment in Firefox, but may need
@ -249,7 +360,7 @@ fn eval_overflow_block(context: &Context, query_value: Option<OverflowBlock>) ->
// billboard mode that doesn't support overflow at all).
//
// If this ever changes, don't forget to change eval_overflow_inline too.
let scrolling = context.device().media_type() != MediaType::print();
let scrolling = device.media_type() != MediaType::print();
let query_value = match query_value {
Some(v) => v,
None => return true,
@ -270,9 +381,9 @@ enum OverflowInline {
}
/// https://drafts.csswg.org/mediaqueries-4/#mf-overflow-inline
fn eval_overflow_inline(context: &Context, query_value: Option<OverflowInline>) -> bool {
fn eval_overflow_inline(device: &Device, query_value: Option<OverflowInline>) -> bool {
// See the note in eval_overflow_block.
let scrolling = context.device().media_type() != MediaType::print();
let scrolling = device.media_type() != MediaType::print();
let query_value = match query_value {
Some(v) => v,
None => return scrolling,
@ -284,41 +395,13 @@ fn eval_overflow_inline(context: &Context, query_value: Option<OverflowInline>)
}
}
#[derive(Clone, Copy, Debug, FromPrimitive, Parse, ToCss)]
#[repr(u8)]
enum Update {
None,
Slow,
Fast,
}
/// https://drafts.csswg.org/mediaqueries-4/#update
fn eval_update(context: &Context, query_value: Option<Update>) -> bool {
// This has similar caveats to those described in eval_overflow_block.
// For now, we report that print (incl. print media simulation,
// which can in fact update but is limited to the developer tools)
// is `update: none` and that all other contexts are `update: fast`,
// which may not be true for future platforms, like e-ink devices.
let can_update = context.device().media_type() != MediaType::print();
let query_value = match query_value {
Some(v) => v,
None => return can_update,
};
match query_value {
Update::None => !can_update,
Update::Slow => false,
Update::Fast => can_update,
}
}
fn do_eval_prefers_color_scheme(
context: &Context,
device: &Device,
use_content: bool,
query_value: Option<PrefersColorScheme>,
) -> bool {
let prefers_color_scheme =
unsafe { bindings::Gecko_MediaFeatures_PrefersColorScheme(context.device().document(), use_content) };
unsafe { bindings::Gecko_MediaFeatures_PrefersColorScheme(device.document(), use_content) };
match query_value {
Some(v) => prefers_color_scheme == v,
None => true,
@ -326,34 +409,15 @@ fn do_eval_prefers_color_scheme(
}
/// https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme
fn eval_prefers_color_scheme(context: &Context, query_value: Option<PrefersColorScheme>) -> bool {
do_eval_prefers_color_scheme(context, /* use_content = */ false, query_value)
fn eval_prefers_color_scheme(device: &Device, query_value: Option<PrefersColorScheme>) -> bool {
do_eval_prefers_color_scheme(device, /* use_content = */ false, query_value)
}
fn eval_content_prefers_color_scheme(
context: &Context,
device: &Device,
query_value: Option<PrefersColorScheme>,
) -> bool {
do_eval_prefers_color_scheme(context, /* use_content = */ true, query_value)
}
/// https://drafts.csswg.org/mediaqueries-5/#dynamic-range
fn eval_dynamic_range(context: &Context, query_value: Option<DynamicRange>) -> bool {
let dynamic_range =
unsafe { bindings::Gecko_MediaFeatures_DynamicRange(context.device().document()) };
match query_value {
Some(v) => dynamic_range >= v,
None => false,
}
}
/// https://drafts.csswg.org/mediaqueries-5/#video-dynamic-range
fn eval_video_dynamic_range(context: &Context, query_value: Option<DynamicRange>) -> bool {
let dynamic_range =
unsafe { bindings::Gecko_MediaFeatures_VideoDynamicRange(context.device().document()) };
match query_value {
Some(v) => dynamic_range >= v,
None => false,
}
do_eval_prefers_color_scheme(device, /* use_content = */ true, query_value)
}
bitflags! {
@ -365,15 +429,15 @@ bitflags! {
}
}
fn primary_pointer_capabilities(context: &Context) -> PointerCapabilities {
fn primary_pointer_capabilities(device: &Device) -> PointerCapabilities {
PointerCapabilities::from_bits_truncate(unsafe {
bindings::Gecko_MediaFeatures_PrimaryPointerCapabilities(context.device().document())
bindings::Gecko_MediaFeatures_PrimaryPointerCapabilities(device.document())
})
}
fn all_pointer_capabilities(context: &Context) -> PointerCapabilities {
fn all_pointer_capabilities(device: &Device) -> PointerCapabilities {
PointerCapabilities::from_bits_truncate(unsafe {
bindings::Gecko_MediaFeatures_AllPointerCapabilities(context.device().document())
bindings::Gecko_MediaFeatures_AllPointerCapabilities(device.document())
})
}
@ -402,13 +466,13 @@ fn eval_pointer_capabilities(
}
/// https://drafts.csswg.org/mediaqueries-4/#pointer
fn eval_pointer(context: &Context, query_value: Option<Pointer>) -> bool {
eval_pointer_capabilities(query_value, primary_pointer_capabilities(context))
fn eval_pointer(device: &Device, query_value: Option<Pointer>) -> bool {
eval_pointer_capabilities(query_value, primary_pointer_capabilities(device))
}
/// https://drafts.csswg.org/mediaqueries-4/#descdef-media-any-pointer
fn eval_any_pointer(context: &Context, query_value: Option<Pointer>) -> bool {
eval_pointer_capabilities(query_value, all_pointer_capabilities(context))
fn eval_any_pointer(device: &Device, query_value: Option<Pointer>) -> bool {
eval_pointer_capabilities(query_value, all_pointer_capabilities(device))
}
#[derive(Clone, Copy, Debug, FromPrimitive, Parse, ToCss)]
@ -435,33 +499,54 @@ fn eval_hover_capabilities(
}
/// https://drafts.csswg.org/mediaqueries-4/#hover
fn eval_hover(context: &Context, query_value: Option<Hover>) -> bool {
eval_hover_capabilities(query_value, primary_pointer_capabilities(context))
fn eval_hover(device: &Device, query_value: Option<Hover>) -> bool {
eval_hover_capabilities(query_value, primary_pointer_capabilities(device))
}
/// https://drafts.csswg.org/mediaqueries-4/#descdef-media-any-hover
fn eval_any_hover(context: &Context, query_value: Option<Hover>) -> bool {
eval_hover_capabilities(query_value, all_pointer_capabilities(context))
fn eval_any_hover(device: &Device, query_value: Option<Hover>) -> bool {
eval_hover_capabilities(query_value, all_pointer_capabilities(device))
}
fn eval_moz_is_glyph(context: &Context) -> bool {
context.device().document().mIsSVGGlyphsDocument()
fn eval_moz_is_glyph(
device: &Device,
query_value: Option<bool>,
_: Option<RangeOrOperator>,
) -> bool {
let is_glyph = device.document().mIsSVGGlyphsDocument();
query_value.map_or(is_glyph, |v| v == is_glyph)
}
fn eval_moz_print_preview(context: &Context) -> bool {
let is_print_preview = context.device().is_print_preview();
fn eval_moz_print_preview(
device: &Device,
query_value: Option<bool>,
_: Option<RangeOrOperator>,
) -> bool {
let is_print_preview = device.is_print_preview();
if is_print_preview {
debug_assert_eq!(context.device().media_type(), MediaType::print());
debug_assert_eq!(device.media_type(), MediaType::print());
}
is_print_preview
query_value.map_or(is_print_preview, |v| v == is_print_preview)
}
fn eval_moz_non_native_content_theme(context: &Context) -> bool {
unsafe { bindings::Gecko_MediaFeatures_ShouldAvoidNativeTheme(context.device().document()) }
fn eval_moz_non_native_content_theme(
device: &Device,
query_value: Option<bool>,
_: Option<RangeOrOperator>,
) -> bool {
let non_native_theme =
unsafe { bindings::Gecko_MediaFeatures_ShouldAvoidNativeTheme(device.document()) };
query_value.map_or(non_native_theme, |v| v == non_native_theme)
}
fn eval_moz_is_resource_document(context: &Context) -> bool {
unsafe { bindings::Gecko_MediaFeatures_IsResourceDocument(context.device().document()) }
fn eval_moz_is_resource_document(
device: &Device,
query_value: Option<bool>,
_: Option<RangeOrOperator>,
) -> bool {
let is_resource_doc =
unsafe { bindings::Gecko_MediaFeatures_IsResourceDocument(device.document()) };
query_value.map_or(is_resource_doc, |v| v == is_resource_doc)
}
/// Allows front-end CSS to discern platform via media queries.
@ -487,7 +572,7 @@ pub enum Platform {
WindowsWin10,
}
fn eval_moz_platform(_: &Context, query_value: Option<Platform>) -> bool {
fn eval_moz_platform(_: &Device, query_value: Option<Platform>) -> bool {
let query_value = match query_value {
Some(v) => v,
None => return false,
@ -496,22 +581,32 @@ fn eval_moz_platform(_: &Context, query_value: Option<Platform>) -> bool {
unsafe { bindings::Gecko_MediaFeatures_MatchesPlatform(query_value) }
}
fn eval_moz_windows_non_native_menus(context: &Context) -> bool {
fn eval_moz_windows_non_native_menus(
device: &Device,
query_value: Option<bool>,
_: Option<RangeOrOperator>,
) -> bool {
let use_non_native_menus = match static_prefs::pref!("browser.display.windows.non_native_menus")
{
0 => false,
1 => true,
_ => {
eval_moz_platform(context, Some(Platform::WindowsWin10)) &&
eval_moz_platform(device, Some(Platform::WindowsWin10)) &&
get_lnf_int_as_bool(bindings::LookAndFeel_IntID::WindowsDefaultTheme as i32)
},
};
use_non_native_menus
query_value.map_or(use_non_native_menus, |v| v == use_non_native_menus)
}
fn eval_moz_overlay_scrollbars(context: &Context) -> bool {
unsafe { bindings::Gecko_MediaFeatures_UseOverlayScrollbars(context.device().document()) }
fn eval_moz_overlay_scrollbars(
device: &Device,
query_value: Option<bool>,
_: Option<RangeOrOperator>,
) -> bool {
let use_overlay =
unsafe { bindings::Gecko_MediaFeatures_UseOverlayScrollbars(device.document()) };
query_value.map_or(use_overlay, |v| v == use_overlay)
}
fn get_lnf_int(int_id: i32) -> i32 {
@ -540,15 +635,16 @@ fn get_scrollbar_end_forward(int_id: i32) -> bool {
macro_rules! lnf_int_feature {
($feature_name:expr, $int_id:ident, $get_value:ident) => {{
fn __eval(_: &Context) -> bool {
$get_value(bindings::LookAndFeel_IntID::$int_id as i32)
fn __eval(_: &Device, query_value: Option<bool>, _: Option<RangeOrOperator>) -> bool {
let value = $get_value(bindings::LookAndFeel_IntID::$int_id as i32);
query_value.map_or(value, |v| v == value)
}
feature!(
$feature_name,
AllowsRanges::No,
Evaluator::BoolInteger(__eval),
FeatureFlags::CHROME_AND_UA_ONLY,
ParsingRequirements::CHROME_AND_UA_ONLY,
)
}};
($feature_name:expr, $int_id:ident) => {{
@ -565,18 +661,18 @@ macro_rules! lnf_int_feature {
/// pref, with `rust: true`. The feature name needs to be defined in
/// `StaticAtoms.py` just like the others. In order to support dynamic changes,
/// you also need to add them to kMediaQueryPrefs in nsXPLookAndFeel.cpp
#[allow(unused)]
macro_rules! bool_pref_feature {
($feature_name:expr, $pref:tt) => {{
fn __eval(_: &Context) -> bool {
static_prefs::pref!($pref)
fn __eval(_: &Device, query_value: Option<bool>, _: Option<RangeOrOperator>) -> bool {
let value = static_prefs::pref!($pref);
query_value.map_or(value, |v| v == value)
}
feature!(
$feature_name,
AllowsRanges::No,
Evaluator::BoolInteger(__eval),
FeatureFlags::CHROME_AND_UA_ONLY,
ParsingRequirements::CHROME_AND_UA_ONLY,
)
}};
}
@ -586,54 +682,54 @@ macro_rules! bool_pref_feature {
/// to support new types in these entries and (2) ensuring that either
/// nsPresContext::MediaFeatureValuesChanged is called when the value that
/// would be returned by the evaluator function could change.
pub static MEDIA_FEATURES: [QueryFeatureDescription; 59] = [
pub static MEDIA_FEATURES: [MediaFeatureDescription; 58] = [
feature!(
atom!("width"),
AllowsRanges::Yes,
Evaluator::Length(eval_width),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("height"),
AllowsRanges::Yes,
Evaluator::Length(eval_height),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("aspect-ratio"),
AllowsRanges::Yes,
Evaluator::NumberRatio(eval_aspect_ratio),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("orientation"),
AllowsRanges::No,
keyword_evaluator!(eval_orientation, Orientation),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("device-width"),
AllowsRanges::Yes,
Evaluator::Length(eval_device_width),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("device-height"),
AllowsRanges::Yes,
Evaluator::Length(eval_device_height),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("device-aspect-ratio"),
AllowsRanges::Yes,
Evaluator::NumberRatio(eval_device_aspect_ratio),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("-moz-device-orientation"),
AllowsRanges::No,
keyword_evaluator!(eval_device_orientation, Orientation),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
// Webkit extensions that we support for de-facto web compatibility.
// -webkit-{min|max}-device-pixel-ratio (controlled with its own pref):
@ -641,68 +737,68 @@ pub static MEDIA_FEATURES: [QueryFeatureDescription; 59] = [
atom!("device-pixel-ratio"),
AllowsRanges::Yes,
Evaluator::Float(eval_device_pixel_ratio),
FeatureFlags::WEBKIT_PREFIX,
ParsingRequirements::WEBKIT_PREFIX,
),
// -webkit-transform-3d.
feature!(
atom!("transform-3d"),
AllowsRanges::No,
Evaluator::BoolInteger(eval_transform_3d),
FeatureFlags::WEBKIT_PREFIX,
ParsingRequirements::WEBKIT_PREFIX,
),
feature!(
atom!("-moz-device-pixel-ratio"),
AllowsRanges::Yes,
Evaluator::Float(eval_device_pixel_ratio),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("resolution"),
AllowsRanges::Yes,
Evaluator::Resolution(eval_resolution),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("display-mode"),
AllowsRanges::No,
keyword_evaluator!(eval_display_mode, DisplayMode),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("grid"),
AllowsRanges::No,
Evaluator::BoolInteger(eval_grid),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("scan"),
AllowsRanges::No,
keyword_evaluator!(eval_scan, Scan),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("color"),
AllowsRanges::Yes,
Evaluator::Integer(eval_color),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("color-index"),
AllowsRanges::Yes,
Evaluator::Integer(eval_color_index),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("monochrome"),
AllowsRanges::Yes,
Evaluator::Integer(eval_monochrome),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("prefers-reduced-motion"),
AllowsRanges::No,
keyword_evaluator!(eval_prefers_reduced_motion, PrefersReducedMotion),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("prefers-contrast"),
@ -713,49 +809,31 @@ pub static MEDIA_FEATURES: [QueryFeatureDescription; 59] = [
// layout.css.prefers-contrast.enabled preference. See
// disabed_by_pref in media_feature_expression.rs for how that
// is done.
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("forced-colors"),
AllowsRanges::No,
keyword_evaluator!(eval_forced_colors, ForcedColors),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("overflow-block"),
AllowsRanges::No,
keyword_evaluator!(eval_overflow_block, OverflowBlock),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("overflow-inline"),
AllowsRanges::No,
keyword_evaluator!(eval_overflow_inline, OverflowInline),
FeatureFlags::empty(),
),
feature!(
atom!("update"),
AllowsRanges::No,
keyword_evaluator!(eval_update, Update),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("prefers-color-scheme"),
AllowsRanges::No,
keyword_evaluator!(eval_prefers_color_scheme, PrefersColorScheme),
FeatureFlags::empty(),
),
feature!(
atom!("dynamic-range"),
AllowsRanges::No,
keyword_evaluator!(eval_dynamic_range, DynamicRange),
FeatureFlags::empty(),
),
feature!(
atom!("video-dynamic-range"),
AllowsRanges::No,
keyword_evaluator!(eval_video_dynamic_range, DynamicRange),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
// Evaluates to the preferred color scheme for content. Only useful in
// chrome context, where the chrome color-scheme and the content
@ -764,31 +842,31 @@ pub static MEDIA_FEATURES: [QueryFeatureDescription; 59] = [
atom!("-moz-content-prefers-color-scheme"),
AllowsRanges::No,
keyword_evaluator!(eval_content_prefers_color_scheme, PrefersColorScheme),
FeatureFlags::CHROME_AND_UA_ONLY,
ParsingRequirements::CHROME_AND_UA_ONLY,
),
feature!(
atom!("pointer"),
AllowsRanges::No,
keyword_evaluator!(eval_pointer, Pointer),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("any-pointer"),
AllowsRanges::No,
keyword_evaluator!(eval_any_pointer, Pointer),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("hover"),
AllowsRanges::No,
keyword_evaluator!(eval_hover, Hover),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
feature!(
atom!("any-hover"),
AllowsRanges::No,
keyword_evaluator!(eval_any_hover, Hover),
FeatureFlags::empty(),
ParsingRequirements::empty(),
),
// Internal -moz-is-glyph media feature: applies only inside SVG glyphs.
// Internal because it is really only useful in the user agent anyway
@ -797,43 +875,43 @@ pub static MEDIA_FEATURES: [QueryFeatureDescription; 59] = [
atom!("-moz-is-glyph"),
AllowsRanges::No,
Evaluator::BoolInteger(eval_moz_is_glyph),
FeatureFlags::CHROME_AND_UA_ONLY,
ParsingRequirements::CHROME_AND_UA_ONLY,
),
feature!(
atom!("-moz-is-resource-document"),
AllowsRanges::No,
Evaluator::BoolInteger(eval_moz_is_resource_document),
FeatureFlags::CHROME_AND_UA_ONLY,
ParsingRequirements::CHROME_AND_UA_ONLY,
),
feature!(
atom!("-moz-platform"),
AllowsRanges::No,
keyword_evaluator!(eval_moz_platform, Platform),
FeatureFlags::CHROME_AND_UA_ONLY,
ParsingRequirements::CHROME_AND_UA_ONLY,
),
feature!(
atom!("-moz-print-preview"),
AllowsRanges::No,
Evaluator::BoolInteger(eval_moz_print_preview),
FeatureFlags::CHROME_AND_UA_ONLY,
ParsingRequirements::CHROME_AND_UA_ONLY,
),
feature!(
atom!("-moz-non-native-content-theme"),
AllowsRanges::No,
Evaluator::BoolInteger(eval_moz_non_native_content_theme),
FeatureFlags::CHROME_AND_UA_ONLY,
ParsingRequirements::CHROME_AND_UA_ONLY,
),
feature!(
atom!("-moz-windows-non-native-menus"),
AllowsRanges::No,
Evaluator::BoolInteger(eval_moz_windows_non_native_menus),
FeatureFlags::CHROME_AND_UA_ONLY,
ParsingRequirements::CHROME_AND_UA_ONLY,
),
feature!(
atom!("-moz-overlay-scrollbars"),
AllowsRanges::No,
Evaluator::BoolInteger(eval_moz_overlay_scrollbars),
FeatureFlags::CHROME_AND_UA_ONLY,
ParsingRequirements::CHROME_AND_UA_ONLY,
),
lnf_int_feature!(
atom!("-moz-scrollbar-start-backward"),
@ -855,6 +933,10 @@ pub static MEDIA_FEATURES: [QueryFeatureDescription; 59] = [
ScrollArrowStyle,
get_scrollbar_end_forward
),
lnf_int_feature!(
atom!("-moz-scrollbar-thumb-proportional"),
ScrollSliderStyle
),
lnf_int_feature!(atom!("-moz-menubar-drag"), MenuBarDrag),
lnf_int_feature!(atom!("-moz-windows-default-theme"), WindowsDefaultTheme),
lnf_int_feature!(atom!("-moz-mac-graphite-theme"), MacGraphiteTheme),
@ -877,4 +959,8 @@ pub static MEDIA_FEATURES: [QueryFeatureDescription; 59] = [
GTKCSDReversedPlacement
),
lnf_int_feature!(atom!("-moz-system-dark-theme"), SystemUsesDarkTheme),
bool_pref_feature!(
atom!("-moz-proton-places-tooltip"),
"browser.proton.places-tooltip.enabled"
),
];

View file

@ -17,7 +17,6 @@ use crate::values::computed::font::GenericFontFamily;
use crate::values::computed::{ColorScheme, Length};
use crate::values::specified::color::SystemColor;
use crate::values::specified::font::FONT_MEDIUM_PX;
use crate::values::specified::ViewportVariant;
use crate::values::{CustomIdent, KeyframesName};
use app_units::{Au, AU_PER_PX};
use cssparser::RGBA;
@ -59,9 +58,6 @@ pub struct Device {
/// Whether any styles computed in the document relied on the viewport size
/// by using vw/vh/vmin/vmax units.
used_viewport_size: AtomicBool,
/// Whether any styles computed in the document relied on the viewport size
/// by using dvw/dvh/dvmin/dvmax units.
used_dynamic_viewport_size: AtomicBool,
/// The CssEnvironment object responsible of getting CSS environment
/// variables.
environment: CssEnvironment,
@ -104,7 +100,6 @@ impl Device {
used_root_font_size: AtomicBool::new(false),
used_font_metrics: AtomicBool::new(false),
used_viewport_size: AtomicBool::new(false),
used_dynamic_viewport_size: AtomicBool::new(false),
environment: CssEnvironment,
}
}
@ -272,8 +267,6 @@ impl Device {
self.used_root_font_size.store(false, Ordering::Relaxed);
self.used_font_metrics.store(false, Ordering::Relaxed);
self.used_viewport_size.store(false, Ordering::Relaxed);
self.used_dynamic_viewport_size
.store(false, Ordering::Relaxed);
}
/// Returns whether we ever looked up the root font size of the Device.
@ -344,10 +337,7 @@ impl Device {
/// Returns the current viewport size in app units, recording that it's been
/// used for viewport unit resolution.
pub fn au_viewport_size_for_viewport_unit_resolution(
&self,
variant: ViewportVariant,
) -> Size2D<Au> {
pub fn au_viewport_size_for_viewport_unit_resolution(&self) -> Size2D<Au> {
self.used_viewport_size.store(true, Ordering::Relaxed);
let pc = match self.pres_context() {
Some(pc) => pc,
@ -358,42 +348,8 @@ impl Device {
return self.page_size_minus_default_margin(pc);
}
match variant {
ViewportVariant::UADefault => {
let size = &pc.mSizeForViewportUnits;
Size2D::new(Au(size.width), Au(size.height))
},
ViewportVariant::Small => {
let size = &pc.mVisibleArea;
Size2D::new(Au(size.width), Au(size.height))
},
ViewportVariant::Large => {
let size = &pc.mVisibleArea;
// Looks like IntCoordTyped is treated as if it's u32 in Rust.
debug_assert!(
/* pc.mDynamicToolbarMaxHeight >=0 && */
pc.mDynamicToolbarMaxHeight < i32::MAX as u32
);
Size2D::new(
Au(size.width),
Au(size.height
+ pc.mDynamicToolbarMaxHeight as i32 * pc.mCurAppUnitsPerDevPixel),
)
},
ViewportVariant::Dynamic => {
self.used_dynamic_viewport_size.store(true, Ordering::Relaxed);
let size = &pc.mVisibleArea;
// Looks like IntCoordTyped is treated as if it's u32 in Rust.
debug_assert!(
/* pc.mDynamicToolbarHeight >=0 && */
pc.mDynamicToolbarHeight < i32::MAX as u32
);
Size2D::new(
Au(size.width),
Au(size.height + pc.mDynamicToolbarHeight as i32 * pc.mCurAppUnitsPerDevPixel),
)
},
}
let size = &pc.mSizeForViewportUnits;
Size2D::new(Au(size.width), Au(size.height))
}
/// Returns whether we ever looked up the viewport size of the Device.
@ -401,21 +357,11 @@ impl Device {
self.used_viewport_size.load(Ordering::Relaxed)
}
/// Returns whether we ever looked up the dynamic viewport size of the Device.
pub fn used_dynamic_viewport_size(&self) -> bool {
self.used_dynamic_viewport_size.load(Ordering::Relaxed)
}
/// Returns whether font metrics have been queried.
pub fn used_font_metrics(&self) -> bool {
self.used_font_metrics.load(Ordering::Relaxed)
}
/// Returns whether visited styles are enabled.
pub fn visited_styles_enabled(&self) -> bool {
unsafe { bindings::Gecko_VisitedStylesEnabled(self.document()) }
}
/// Returns the device pixel ratio.
pub fn device_pixel_ratio(&self) -> Scale<f32, CSSPixel, DevicePixel> {
let pc = match self.pres_context() {

View file

@ -54,7 +54,7 @@ macro_rules! apply_non_ts_list {
("-moz-styleeditor-transitioning", MozStyleeditorTransitioning, IN_STYLEEDITOR_TRANSITIONING_STATE, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS),
("fullscreen", Fullscreen, IN_FULLSCREEN_STATE, _),
("-moz-modal-dialog", MozModalDialog, IN_MODAL_DIALOG_STATE, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS),
("-moz-topmost-modal", MozTopmostModal, IN_TOPMOST_MODAL_TOP_LAYER_STATE, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS),
("-moz-topmost-modal-dialog", MozTopmostModalDialog, IN_TOPMOST_MODAL_DIALOG_STATE, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS),
("-moz-broken", MozBroken, IN_BROKEN_STATE, _),
("-moz-loading", MozLoading, IN_LOADING_STATE, _),
("-moz-has-dir-attr", MozHasDirAttr, IN_HAS_DIR_ATTR_STATE, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS),
@ -92,6 +92,8 @@ macro_rules! apply_non_ts_list {
("-moz-is-html", MozIsHTML, _, _),
("-moz-placeholder", MozPlaceholder, _, _),
("-moz-lwtheme", MozLWTheme, _, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME),
("-moz-lwtheme-brighttext", MozLWThemeBrightText, _, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME),
("-moz-lwtheme-darktext", MozLWThemeDarkText, _, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME),
("-moz-window-inactive", MozWindowInactive, _, _),
]
}

View file

@ -139,6 +139,15 @@ impl NonTSPseudoClass {
/// Returns whether the pseudo-class is enabled in content sheets.
#[inline]
fn is_enabled_in_content(&self) -> bool {
if matches!(
*self,
Self::MozLWTheme | Self::MozLWThemeBrightText | Self::MozLWThemeDarkText
) {
return static_prefs::pref!("layout.css.moz-lwtheme.content.enabled");
}
if let NonTSPseudoClass::MozLocaleDir(..) = *self {
return static_prefs::pref!("layout.css.moz-locale-dir.content.enabled");
}
!self.has_any_flag(NonTSPseudoClassFlag::PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME)
}
@ -175,6 +184,8 @@ impl NonTSPseudoClass {
},
NonTSPseudoClass::MozWindowInactive => DocumentState::WINDOW_INACTIVE,
NonTSPseudoClass::MozLWTheme => DocumentState::LWTHEME,
NonTSPseudoClass::MozLWThemeBrightText => DocumentState::LWTHEME_BRIGHTTEXT,
NonTSPseudoClass::MozLWThemeDarkText => DocumentState::LWTHEME_DARKTEXT,
_ => DocumentState::empty(),
}
}
@ -197,13 +208,15 @@ impl NonTSPseudoClass {
NonTSPseudoClass::MozNativeAnonymous |
// :-moz-placeholder is parsed but never matches.
NonTSPseudoClass::MozPlaceholder |
// :-moz-lwtheme, :-moz-locale-dir and
// :-moz-window-inactive depend only on the state of the
// document, which is invariant across all the elements
// involved in a given style cache.
NonTSPseudoClass::MozLWTheme |
// :-moz-locale-dir and :-moz-window-inactive depend only on
// the state of the document, which is invariant across all
// the elements involved in a given style cache.
NonTSPseudoClass::MozLocaleDir(_) |
NonTSPseudoClass::MozWindowInactive
NonTSPseudoClass::MozWindowInactive |
// Similar for the document themes.
NonTSPseudoClass::MozLWTheme |
NonTSPseudoClass::MozLWThemeBrightText |
NonTSPseudoClass::MozLWThemeDarkText
)
}
}
@ -445,9 +458,3 @@ unsafe impl HasFFI for SelectorList<SelectorImpl> {
}
unsafe impl HasSimpleFFI for SelectorList<SelectorImpl> {}
unsafe impl HasBoxFFI for SelectorList<SelectorImpl> {}
// Selector and component sizes are important for matching performance.
size_of_test!(selectors::parser::Selector<SelectorImpl>, 8);
size_of_test!(selectors::parser::Component<SelectorImpl>, 24);
size_of_test!(PseudoElement, 16);
size_of_test!(NonTSPseudoClass, 16);

View file

@ -44,14 +44,14 @@ unsafe fn get_class_or_part_from_attr(attr: &structs::nsAttrValue) -> Class {
structs::nsAttrValue_ValueType_eAtomArray
);
// NOTE: Bindgen doesn't deal with AutoTArray, so cast it below.
let attr_array: *mut _ = *(*container)
let array: *mut u8 = *(*container)
.__bindgen_anon_1
.mValue
.as_ref()
.__bindgen_anon_1
.mAtomArray
.as_ref();
let array = (*attr_array).mArray.as_ptr() as *const structs::nsTArray<structs::RefPtr<nsAtom>>;
let array = array as *const structs::nsTArray<structs::RefPtr<nsAtom>>;
return Class::More(&**array);
}
debug_assert_eq!(base_type, structs::nsAttrValue_ValueBaseType_eStringBase);

View file

@ -66,8 +66,6 @@ use crate::stylist::CascadeData;
use crate::values::{AtomIdent, AtomString};
use crate::CaseSensitivityExt;
use crate::LocalName;
use app_units::Au;
use euclid::default::Size2D;
use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
use fxhash::FxHashMap;
use selectors::attr::{AttrSelectorOperation, AttrSelectorOperator};
@ -323,11 +321,6 @@ impl<'ln> GeckoNode<'ln> {
self.flags() & (NODE_IS_IN_SHADOW_TREE as u32) != 0
}
#[inline]
fn is_connected(&self) -> bool {
self.get_bool_flag(nsINode_BooleanFlag::IsConnected)
}
/// WARNING: This logic is duplicated in Gecko's FlattenedTreeParentIsParent.
/// Make sure to mirror any modifications in both places.
#[inline]
@ -1037,21 +1030,6 @@ impl<'le> TElement for GeckoElement<'le> {
}
}
#[inline]
fn primary_box_size(&self) -> Size2D<Au> {
if !self.as_node().is_connected() {
return Size2D::zero();
}
unsafe {
let frame = self.0._base._base._base.__bindgen_anon_1.mPrimaryFrame.as_ref();
if frame.is_null() {
return Size2D::zero();
}
Size2D::new(Au((**frame).mRect.width), Au((**frame).mRect.height))
}
}
/// Return the list of slotted nodes of this node.
#[inline]
fn slotted_nodes(&self) -> &[Self::ConcreteNode] {
@ -1415,6 +1393,16 @@ impl<'le> TElement for GeckoElement<'le> {
self.is_root_of_native_anonymous_subtree()
}
unsafe fn set_selector_flags(&self, flags: ElementSelectorFlags) {
debug_assert!(!flags.is_empty());
self.set_flags(selector_flags_to_node_flags(flags));
}
fn has_selector_flags(&self, flags: ElementSelectorFlags) -> bool {
let node_flags = selector_flags_to_node_flags(flags);
(self.flags() & node_flags) == node_flags
}
#[inline]
fn may_have_animations(&self) -> bool {
if let Some(pseudo) = self.implemented_pseudo_element() {
@ -1513,7 +1501,7 @@ impl<'le> TElement for GeckoElement<'le> {
) -> bool {
use crate::properties::LonghandIdSet;
let after_change_ui_style = after_change_style.get_ui();
let after_change_box_style = after_change_style.get_box();
let existing_transitions = self.css_transitions_info();
let mut transitions_to_keep = LonghandIdSet::new();
for transition_property in after_change_style.transition_properties() {
@ -1523,7 +1511,7 @@ impl<'le> TElement for GeckoElement<'le> {
transitions_to_keep.insert(physical_longhand);
if self.needs_transitions_update_per_property(
physical_longhand,
after_change_ui_style.transition_combined_duration_at(transition_property.index),
after_change_box_style.transition_combined_duration_at(transition_property.index),
before_change_style,
after_change_style,
&existing_transitions,
@ -1605,9 +1593,23 @@ impl<'le> TElement for GeckoElement<'le> {
use crate::properties::longhands::_x_lang::SpecifiedValue as SpecifiedLang;
use crate::properties::longhands::_x_text_zoom::SpecifiedValue as SpecifiedZoom;
use crate::properties::longhands::color::SpecifiedValue as SpecifiedColor;
use crate::properties::longhands::text_align::SpecifiedValue as SpecifiedTextAlign;
use crate::stylesheets::layer_rule::LayerOrder;
use crate::values::specified::color::Color;
lazy_static! {
static ref TH_RULE: ApplicableDeclarationBlock = {
let global_style_data = &*GLOBAL_STYLE_DATA;
let pdb = PropertyDeclarationBlock::with_one(
PropertyDeclaration::TextAlign(SpecifiedTextAlign::MozCenterOrInherit),
Importance::Normal,
);
let arc = Arc::new_leaked(global_style_data.shared_lock.wrap(pdb));
ApplicableDeclarationBlock::from_declarations(
arc,
ServoCascadeLevel::PresHints,
LayerOrder::root(),
)
};
static ref TABLE_COLOR_RULE: ApplicableDeclarationBlock = {
let global_style_data = &*GLOBAL_STYLE_DATA;
let pdb = PropertyDeclarationBlock::with_one(
@ -1652,7 +1654,9 @@ impl<'le> TElement for GeckoElement<'le> {
let ns = self.namespace_id();
// <th> elements get a default MozCenterOrInherit which may get overridden
if ns == structs::kNameSpaceID_XHTML as i32 {
if self.local_name().as_ptr() == atom!("table").as_ptr() &&
if self.local_name().as_ptr() == atom!("th").as_ptr() {
hints.push(TH_RULE.clone());
} else if self.local_name().as_ptr() == atom!("table").as_ptr() &&
self.as_node().owner_doc().quirks_mode() == QuirksMode::Quirks
{
hints.push(TABLE_COLOR_RULE.clone());
@ -1844,11 +1848,6 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
None
}
fn set_selector_flags(&self, flags: ElementSelectorFlags) {
debug_assert!(!flags.is_empty());
self.set_flags(selector_flags_to_node_flags(flags));
}
fn attr_matches(
&self,
ns: &NamespaceConstraint<&Namespace>,
@ -1961,11 +1960,15 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
self.local_name() == other.local_name() && self.namespace() == other.namespace()
}
fn match_non_ts_pseudo_class(
fn match_non_ts_pseudo_class<F>(
&self,
pseudo_class: &NonTSPseudoClass,
context: &mut MatchingContext<Self::Impl>,
) -> bool {
flags_setter: &mut F,
) -> bool
where
F: FnMut(&Self, ElementSelectorFlags),
{
use selectors::matching::*;
match *pseudo_class {
NonTSPseudoClass::Autofill |
@ -2006,7 +2009,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
NonTSPseudoClass::MozDirAttrRTL |
NonTSPseudoClass::MozDirAttrLikeAuto |
NonTSPseudoClass::MozModalDialog |
NonTSPseudoClass::MozTopmostModal |
NonTSPseudoClass::MozTopmostModalDialog |
NonTSPseudoClass::Active |
NonTSPseudoClass::Hover |
NonTSPseudoClass::MozAutofillPreview |
@ -2021,9 +2024,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
self.is_link() && context.visited_handling().matches_visited()
},
NonTSPseudoClass::MozFirstNode => {
if context.needs_selector_flags() {
self.apply_selector_flags(ElementSelectorFlags::HAS_EDGE_CHILD_SELECTOR);
}
flags_setter(self, ElementSelectorFlags::HAS_EDGE_CHILD_SELECTOR);
let mut elem = self.as_node();
while let Some(prev) = elem.prev_sibling() {
if prev.contains_non_whitespace_content() {
@ -2034,9 +2035,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
true
},
NonTSPseudoClass::MozLastNode => {
if context.needs_selector_flags() {
self.apply_selector_flags(ElementSelectorFlags::HAS_EDGE_CHILD_SELECTOR);
}
flags_setter(self, ElementSelectorFlags::HAS_EDGE_CHILD_SELECTOR);
let mut elem = self.as_node();
while let Some(next) = elem.next_sibling() {
if next.contains_non_whitespace_content() {
@ -2047,9 +2046,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
true
},
NonTSPseudoClass::MozOnlyWhitespace => {
if context.needs_selector_flags() {
self.apply_selector_flags(ElementSelectorFlags::HAS_EMPTY_SELECTOR);
}
flags_setter(self, ElementSelectorFlags::HAS_EMPTY_SELECTOR);
if self
.as_node()
.dom_children()
@ -2071,6 +2068,8 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
NonTSPseudoClass::MozIsHTML => self.is_html_element_in_html_document(),
NonTSPseudoClass::MozLWTheme |
NonTSPseudoClass::MozLWThemeBrightText |
NonTSPseudoClass::MozLWThemeDarkText |
NonTSPseudoClass::MozLocaleDir(..) |
NonTSPseudoClass::MozWindowInactive => {
let state_bit = pseudo_class.document_state_flag();