Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions style/custom_properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,18 @@ impl CssEnvironment {
return None;
}

#[cfg(feature = "servo")]
if *name == Atom::from("preferred-text-scale") {
return Some(VariableValue::from_token(
Token::Number {
has_sign: false,
value: device.preferred_text_scale(),
int_value: None,
},
url_data,
));
}

if let Some(var) = ENVIRONMENT_VARIABLES.iter().find(|var| var.name == *name) {
return Some((var.evaluator)(device, url_data));
}
Expand Down
82 changes: 82 additions & 0 deletions style/device/servo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ impl Default for ServoMediaFeaturePreferences {
pub(super) struct ExtraDeviceData {
/// The current media type used by de device.
media_type: MediaType,
/// User preferred text scale exposed through CSS env().
preferred_text_scale: f32,
/// The current viewport size, in CSS pixels.
viewport_size: Size2D<f32, CSSPixel>,
/// The current screen size, in device pixels.
Expand Down Expand Up @@ -148,6 +150,7 @@ impl Device {
body_text_color: AtomicU32::new(AbsoluteColor::BLACK.to_nscolor()),
extra: ExtraDeviceData {
media_type,
preferred_text_scale: 1.0,
viewport_size,
device_size,
device_pixel_ratio,
Expand All @@ -162,6 +165,21 @@ impl Device {
}
}

/// User preferred text scale exposed by `env(preferred-text-scale)`.
pub fn preferred_text_scale(&self) -> f32 {
self.extra.preferred_text_scale
}

/// Set the CSS environment text scale. The embedder must invalidate styles
/// that depend on environment variables when this value changes.
pub fn set_preferred_text_scale(&mut self, scale: f32) {
assert!(
scale.is_finite() && scale > 0.0,
"preferred text scale must be finite and positive"
);
self.extra.preferred_text_scale = scale;
}

/// Returns the computed line-height for the font in a given computed values instance.
///
/// If you pass down an element, then the used line-height is returned.
Expand Down Expand Up @@ -571,6 +589,70 @@ fn used_color_scheme_is_dark(
mod tests {
use super::*;

#[derive(Debug)]
struct TestFontMetrics;

impl FontMetricsProvider for TestFontMetrics {
fn query_font_metrics(
&self,
_vertical: bool,
_font: &Font,
_base_size: CSSPixelLength,
_flags: QueryFontMetricsFlags,
) -> FontMetrics {
FontMetrics::default()
}

fn base_size_for_generic(&self, _generic: GenericFontFamily) -> Length {
Length::new(16.0)
}
}

#[test]
fn preferred_text_scale_environment_tracks_device_and_rejects_invalid_values() {
let mut device = Device::new(
MediaType::screen(),
QuirksMode::NoQuirks,
euclid::size2(100.0, 100.0),
euclid::size2(100.0, 100.0),
Scale::new(1.0),
Box::new(TestFontMetrics),
ComputedValues::initial_values_with_font_override(Font::initial_values()),
PrefersColorScheme::Light,
PointerCapabilities::default(),
PointerCapabilities::default(),
);
let url_data = crate::stylesheets::UrlExtraData::from(
url::Url::parse("https://example.test/").unwrap(),
);
let text_scale = crate::Atom::from("preferred-text-scale");
let value = |device: &Device| {
device
.environment()
.get(&text_scale, device, &url_data)
.unwrap()
.css
.parse::<f32>()
.unwrap()
};
assert_eq!(value(&device), 1.0);
device.set_preferred_text_scale(1.5);
assert_eq!(value(&device), 1.5);
device.set_preferred_text_scale(2.0);
assert_eq!(value(&device), 2.0);
assert!(device
.environment()
.get(&crate::Atom::from("unknown"), &device, &url_data)
.is_none());
for invalid in [0.0, -1.0, f32::NAN, f32::INFINITY, f32::NEG_INFINITY] {
assert!(std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
device.set_preferred_text_scale(invalid);
}))
.is_err());
assert_eq!(value(&device), 2.0);
}
}

#[test]
fn used_color_scheme_honors_supported_schemes_and_user_preference() {
assert!(!used_color_scheme_is_dark(
Expand Down
Loading