Honor print media in PDF export
This commit is contained in:
1 parent
c1dbec078b
commit
703d334df7
12 files changed
+856
-181
No files matched your search
@@ -15,6 +15,18 @@ use std::sync::Arc;
|
||||
|
||||
use crate::LayoutStyle;
|
||||
|
||||
/// CSS media type used while selecting conditional author rules.
|
||||
///
|
||||
/// Screen is the normal live-page mode. PDF export temporarily selects Print
|
||||
/// so `@media print` and media-gated stylesheet blocks can participate without
|
||||
/// mutating the document or changing JavaScript's live screen environment.
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||
pub enum CssMediaType {
|
||||
#[default]
|
||||
Screen,
|
||||
Print,
|
||||
}
|
||||
|
||||
/// The part of the tree whose selector match may change when a dependency on
|
||||
/// one element changes. Multiple bits can be present for selectors which use
|
||||
/// the same key in more than one compound.
|
||||
@@ -2320,7 +2332,8 @@ const MAX_STYLESHEET_CACHE_RULES: usize = 100_000;
|
||||
///
|
||||
/// DOM mutations still run the complete cascade and layout against the live
|
||||
/// tree. This cache retains only source parsing, selector compilation, and
|
||||
/// candidate indexing, whose inputs are the ordered CSS text and viewport.
|
||||
/// candidate indexing, whose inputs are the ordered CSS text, viewport, and
|
||||
/// selected CSS media type.
|
||||
/// Keeping a single exact-key entry prevents cross-document growth and avoids
|
||||
/// hash-collision correctness risks. Pathological source sets above the byte
|
||||
/// bound are parsed normally but never retained.
|
||||
@@ -2334,6 +2347,7 @@ pub struct StylesheetCache {
|
||||
struct CachedStylesheet {
|
||||
sources: Vec<String>,
|
||||
viewport_bits: (u32, u32),
|
||||
media_type: CssMediaType,
|
||||
source_bytes: usize,
|
||||
sheet: Arc<Stylesheet>,
|
||||
}
|
||||
@@ -2344,17 +2358,26 @@ impl StylesheetCache {
|
||||
tree: &DomTree,
|
||||
sources: &[String],
|
||||
viewport: (f32, f32),
|
||||
media_type: CssMediaType,
|
||||
) -> (Arc<Stylesheet>, bool) {
|
||||
let viewport_bits = (viewport.0.to_bits(), viewport.1.to_bits());
|
||||
if let Some(entry) = self.entry.as_ref() {
|
||||
if entry.viewport_bits == viewport_bits && entry.sources == sources {
|
||||
if entry.viewport_bits == viewport_bits
|
||||
&& entry.media_type == media_type
|
||||
&& entry.sources == sources
|
||||
{
|
||||
self.hits = self.hits.saturating_add(1);
|
||||
return (Arc::clone(&entry.sheet), true);
|
||||
}
|
||||
}
|
||||
|
||||
self.misses = self.misses.saturating_add(1);
|
||||
let sheet = Arc::new(Stylesheet::parse_for_viewport(tree, sources, viewport));
|
||||
let sheet = Arc::new(Stylesheet::parse_for_viewport_and_media(
|
||||
tree,
|
||||
sources,
|
||||
viewport,
|
||||
media_type,
|
||||
));
|
||||
let source_bytes = sources
|
||||
.iter()
|
||||
.try_fold(0usize, |total, source| total.checked_add(source.len()));
|
||||
@@ -2369,6 +2392,7 @@ impl StylesheetCache {
|
||||
self.entry = Some(CachedStylesheet {
|
||||
sources: sources.to_vec(),
|
||||
viewport_bits,
|
||||
media_type,
|
||||
source_bytes,
|
||||
sheet: Arc::clone(&sheet),
|
||||
});
|
||||
@@ -2556,10 +2580,25 @@ impl Stylesheet {
|
||||
/// fixed desktop width made responsive frameworks build one DOM while the
|
||||
/// renderer applied another breakpoint.
|
||||
pub fn parse_for_viewport(tree: &DomTree, sources: &[String], viewport: (f32, f32)) -> Self {
|
||||
Self::parse_for_viewport_at_animation_time(
|
||||
Self::parse_for_viewport_and_media(
|
||||
tree,
|
||||
sources,
|
||||
viewport,
|
||||
CssMediaType::Screen,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn parse_for_viewport_and_media(
|
||||
tree: &DomTree,
|
||||
sources: &[String],
|
||||
viewport: (f32, f32),
|
||||
media_type: CssMediaType,
|
||||
) -> Self {
|
||||
Self::parse_for_viewport_and_media_at_animation_time(
|
||||
tree,
|
||||
sources,
|
||||
viewport,
|
||||
media_type,
|
||||
crate::AnimationSampleTime::default(),
|
||||
)
|
||||
}
|
||||
@@ -2569,6 +2608,22 @@ impl Stylesheet {
|
||||
sources: &[String],
|
||||
viewport: (f32, f32),
|
||||
animation_sample_time: crate::AnimationSampleTime,
|
||||
) -> Self {
|
||||
Self::parse_for_viewport_and_media_at_animation_time(
|
||||
tree,
|
||||
sources,
|
||||
viewport,
|
||||
CssMediaType::Screen,
|
||||
animation_sample_time,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn parse_for_viewport_and_media_at_animation_time(
|
||||
tree: &DomTree,
|
||||
sources: &[String],
|
||||
viewport: (f32, f32),
|
||||
media_type: CssMediaType,
|
||||
animation_sample_time: crate::AnimationSampleTime,
|
||||
) -> Self {
|
||||
let mut sheet = Stylesheet {
|
||||
rules: Vec::new(),
|
||||
@@ -2598,6 +2653,7 @@ impl Stylesheet {
|
||||
let parsed = parse_stylesheet_for_viewport_preserving_containers_in_layer(
|
||||
src,
|
||||
viewport,
|
||||
media_type,
|
||||
&mut sheet.container_conditions,
|
||||
ContainerConditionId::NONE,
|
||||
&mut layers,
|
||||
@@ -3919,6 +3975,7 @@ fn extract_keyframes(css: &str) -> Vec<(String, Keyframes)> {
|
||||
let parsed = parse_stylesheet_for_viewport_preserving_containers(
|
||||
css,
|
||||
(1280.0, 720.0),
|
||||
CssMediaType::Screen,
|
||||
&mut conditions,
|
||||
ContainerConditionId::NONE,
|
||||
);
|
||||
@@ -5413,6 +5470,7 @@ fn parse_stylesheet_for_viewport(css: &str, viewport: (f32, f32)) -> Vec<(String
|
||||
parse_stylesheet_for_viewport_preserving_containers(
|
||||
css,
|
||||
viewport,
|
||||
CssMediaType::Screen,
|
||||
&mut conditions,
|
||||
ContainerConditionId::NONE,
|
||||
)
|
||||
@@ -5432,6 +5490,7 @@ fn parse_stylesheet_for_viewport(css: &str, viewport: (f32, f32)) -> Vec<(String
|
||||
fn parse_stylesheet_for_viewport_preserving_containers(
|
||||
css: &str,
|
||||
viewport: (f32, f32),
|
||||
media_type: CssMediaType,
|
||||
container_conditions: &mut Vec<ContainerConditionNode>,
|
||||
container_condition_id: ContainerConditionId,
|
||||
) -> Vec<ParsedRule> {
|
||||
@@ -5439,6 +5498,7 @@ fn parse_stylesheet_for_viewport_preserving_containers(
|
||||
parse_stylesheet_for_viewport_preserving_containers_in_layer(
|
||||
css,
|
||||
viewport,
|
||||
media_type,
|
||||
container_conditions,
|
||||
container_condition_id,
|
||||
&mut layers,
|
||||
@@ -5449,6 +5509,7 @@ fn parse_stylesheet_for_viewport_preserving_containers(
|
||||
fn parse_stylesheet_for_viewport_preserving_containers_in_layer(
|
||||
css: &str,
|
||||
viewport: (f32, f32),
|
||||
media_type: CssMediaType,
|
||||
container_conditions: &mut Vec<ContainerConditionNode>,
|
||||
container_condition_id: ContainerConditionId,
|
||||
layers: &mut LayerRegistry,
|
||||
@@ -5498,6 +5559,7 @@ fn parse_stylesheet_for_viewport_preserving_containers_in_layer(
|
||||
decls,
|
||||
&mut rules,
|
||||
viewport,
|
||||
media_type,
|
||||
container_conditions,
|
||||
container_condition_id,
|
||||
layers,
|
||||
@@ -5513,6 +5575,7 @@ fn parse_stylesheet_for_viewport_preserving_containers_in_layer(
|
||||
decls,
|
||||
&mut rules,
|
||||
viewport,
|
||||
media_type,
|
||||
container_conditions,
|
||||
container_condition_id,
|
||||
layers,
|
||||
@@ -5551,17 +5614,19 @@ fn flush_at_rule(
|
||||
inner: &str,
|
||||
rules: &mut Vec<ParsedRule>,
|
||||
viewport: (f32, f32),
|
||||
media_type: CssMediaType,
|
||||
container_conditions: &mut Vec<ContainerConditionNode>,
|
||||
container_condition_id: ContainerConditionId,
|
||||
layers: &mut LayerRegistry,
|
||||
current_layer: Option<&LayerOrder>,
|
||||
) {
|
||||
if let Some(prelude) = at_rule_prelude(at, "media") {
|
||||
if media_query_applies_for_viewport(prelude, viewport) {
|
||||
if media_query_applies_for_viewport_and_type(prelude, viewport, media_type) {
|
||||
rules.extend(
|
||||
parse_stylesheet_for_viewport_preserving_containers_in_layer(
|
||||
inner,
|
||||
viewport,
|
||||
media_type,
|
||||
container_conditions,
|
||||
container_condition_id,
|
||||
layers,
|
||||
@@ -5575,6 +5640,7 @@ fn flush_at_rule(
|
||||
parse_stylesheet_for_viewport_preserving_containers_in_layer(
|
||||
inner,
|
||||
viewport,
|
||||
media_type,
|
||||
container_conditions,
|
||||
container_condition_id,
|
||||
layers,
|
||||
@@ -5596,6 +5662,7 @@ fn flush_at_rule(
|
||||
parse_stylesheet_for_viewport_preserving_containers_in_layer(
|
||||
inner,
|
||||
viewport,
|
||||
media_type,
|
||||
container_conditions,
|
||||
id,
|
||||
layers,
|
||||
@@ -5647,6 +5714,7 @@ fn flush_at_rule(
|
||||
parse_stylesheet_for_viewport_preserving_containers_in_layer(
|
||||
inner,
|
||||
viewport,
|
||||
media_type,
|
||||
container_conditions,
|
||||
container_condition_id,
|
||||
layers,
|
||||
@@ -6276,16 +6344,28 @@ fn split_supports_operator<'a>(condition: &'a str, operator: &str) -> Option<Vec
|
||||
/// inside `(feature: value)`, so it's safe to discard them wholesale rather
|
||||
/// than special-case every formatting variant a site might use.
|
||||
pub(crate) fn media_query_applies_for_viewport(query: &str, viewport: (f32, f32)) -> bool {
|
||||
media_query_applies_for_viewport_and_type(query, viewport, CssMediaType::Screen)
|
||||
}
|
||||
|
||||
pub(crate) fn media_query_applies_for_viewport_and_type(
|
||||
query: &str,
|
||||
viewport: (f32, f32),
|
||||
media_type: CssMediaType,
|
||||
) -> bool {
|
||||
// A media-query list is an OR, not an AND. Evaluate each top-level comma
|
||||
// arm independently (commas inside functions such as rgb() / calc() are
|
||||
// not list separators). This also keeps an inapplicable `print` arm from
|
||||
// suppressing a later screen/feature arm.
|
||||
split_media_query_list(query)
|
||||
.into_iter()
|
||||
.any(|query| single_media_query_applies_for_viewport(query, viewport))
|
||||
.any(|query| single_media_query_applies_for_viewport(query, viewport, media_type))
|
||||
}
|
||||
|
||||
fn single_media_query_applies_for_viewport(query: &str, viewport: (f32, f32)) -> bool {
|
||||
fn single_media_query_applies_for_viewport(
|
||||
query: &str,
|
||||
viewport: (f32, f32),
|
||||
media_type: CssMediaType,
|
||||
) -> bool {
|
||||
let viewport_w = viewport.0;
|
||||
let viewport_h = viewport.1;
|
||||
let query = query.trim().strip_prefix("@media").unwrap_or(query).trim();
|
||||
@@ -6295,19 +6375,26 @@ fn single_media_query_applies_for_viewport(query: &str, viewport: (f32, f32)) ->
|
||||
.flat_map(|c| c.to_lowercase())
|
||||
.collect();
|
||||
|
||||
// Tailwind expresses every `max-*` breakpoint as the negation of a
|
||||
// min-width query (`not all and (min-width:40rem)`). Evaluate the inner
|
||||
// condition and invert it; treating all `not all` queries as permanently
|
||||
// false makes mutually exclusive responsive utilities apply together at
|
||||
// desktop widths. Unknown browser-targeting features still conservatively
|
||||
// evaluate true inside and therefore false after negation.
|
||||
if let Some(inner) = compact.strip_prefix("notalland") {
|
||||
return !single_media_query_applies_for_viewport(inner, viewport);
|
||||
// A leading `not` negates the complete media query. This covers both
|
||||
// Tailwind's `not all and (...)` breakpoints and ordinary `not print` /
|
||||
// `not screen` selection without treating a word inside a feature as a
|
||||
// media type.
|
||||
if let Some(inner) = compact.strip_prefix("not") {
|
||||
return !single_media_query_applies_for_viewport(inner, viewport, media_type);
|
||||
}
|
||||
if compact == "notall" {
|
||||
return false;
|
||||
}
|
||||
if compact.contains("print") {
|
||||
let compact = compact.strip_prefix("only").unwrap_or(&compact);
|
||||
|
||||
let medium = compact.split_once("and").map_or(compact, |(medium, _)| medium);
|
||||
let medium_matches = match medium {
|
||||
"all" => true,
|
||||
"screen" => media_type == CssMediaType::Screen,
|
||||
"print" => media_type == CssMediaType::Print,
|
||||
medium if medium.starts_with('(') => true,
|
||||
// Unknown named media such as `speech` do not match either visual
|
||||
// rendering mode.
|
||||
_ => false,
|
||||
};
|
||||
if !medium_matches {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -6478,6 +6565,7 @@ fn denest(
|
||||
body: &str,
|
||||
rules: &mut Vec<ParsedRule>,
|
||||
viewport: (f32, f32),
|
||||
media_type: CssMediaType,
|
||||
container_conditions: &mut Vec<ContainerConditionNode>,
|
||||
container_condition_id: ContainerConditionId,
|
||||
layers: &mut LayerRegistry,
|
||||
@@ -6556,12 +6644,17 @@ fn denest(
|
||||
if let Some(at) = pre.strip_prefix('@') {
|
||||
// A nested at-rule keeps the enclosing selector for its body.
|
||||
if let Some(prelude) = at_rule_prelude(at, "media") {
|
||||
if media_query_applies_for_viewport(prelude, viewport) {
|
||||
if media_query_applies_for_viewport_and_type(
|
||||
prelude,
|
||||
viewport,
|
||||
media_type,
|
||||
) {
|
||||
denest(
|
||||
sel,
|
||||
&inner,
|
||||
rules,
|
||||
viewport,
|
||||
media_type,
|
||||
container_conditions,
|
||||
container_condition_id,
|
||||
layers,
|
||||
@@ -6575,6 +6668,7 @@ fn denest(
|
||||
&inner,
|
||||
rules,
|
||||
viewport,
|
||||
media_type,
|
||||
container_conditions,
|
||||
container_condition_id,
|
||||
layers,
|
||||
@@ -6594,6 +6688,7 @@ fn denest(
|
||||
&inner,
|
||||
rules,
|
||||
viewport,
|
||||
media_type,
|
||||
container_conditions,
|
||||
id,
|
||||
layers,
|
||||
@@ -6613,6 +6708,7 @@ fn denest(
|
||||
&inner,
|
||||
rules,
|
||||
viewport,
|
||||
media_type,
|
||||
container_conditions,
|
||||
container_condition_id,
|
||||
layers,
|
||||
@@ -6627,6 +6723,7 @@ fn denest(
|
||||
&inner,
|
||||
rules,
|
||||
viewport,
|
||||
media_type,
|
||||
container_conditions,
|
||||
container_condition_id,
|
||||
layers,
|
||||
@@ -8365,6 +8462,7 @@ mod tests {
|
||||
let parsed = parse_stylesheet_for_viewport_preserving_containers(
|
||||
css,
|
||||
(1280.0, 720.0),
|
||||
CssMediaType::Screen,
|
||||
&mut conditions,
|
||||
ContainerConditionId::NONE,
|
||||
);
|
||||
@@ -8420,6 +8518,7 @@ mod tests {
|
||||
let parsed = parse_stylesheet_for_viewport_preserving_containers(
|
||||
css,
|
||||
(1280.0, 720.0),
|
||||
CssMediaType::Screen,
|
||||
&mut conditions,
|
||||
ContainerConditionId::NONE,
|
||||
);
|
||||
@@ -8453,6 +8552,7 @@ mod tests {
|
||||
let parsed = parse_stylesheet_for_viewport_preserving_containers(
|
||||
css,
|
||||
(1280.0, 720.0),
|
||||
CssMediaType::Screen,
|
||||
&mut conditions,
|
||||
ContainerConditionId::NONE,
|
||||
);
|
||||
@@ -8894,6 +8994,7 @@ mod tests {
|
||||
let parsed = parse_stylesheet_for_viewport_preserving_containers(
|
||||
"@container (future(foo)), main (min-width:1px) {.card{display:grid}}",
|
||||
(1280.0, 720.0),
|
||||
CssMediaType::Screen,
|
||||
&mut conditions,
|
||||
ContainerConditionId::NONE,
|
||||
);
|
||||
@@ -9320,6 +9421,7 @@ mod tests {
|
||||
let parsed = parse_stylesheet_for_viewport_preserving_containers(
|
||||
css,
|
||||
(1280.0, 720.0),
|
||||
CssMediaType::Screen,
|
||||
&mut conditions,
|
||||
ContainerConditionId::NONE,
|
||||
);
|
||||
@@ -9386,6 +9488,7 @@ mod tests {
|
||||
let rich = parse_stylesheet_for_viewport_preserving_containers(
|
||||
css,
|
||||
(1280.0, 720.0),
|
||||
CssMediaType::Screen,
|
||||
&mut conditions,
|
||||
ContainerConditionId::NONE,
|
||||
);
|
||||
@@ -9518,6 +9621,37 @@ mod tests {
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn media_type_selects_screen_print_negation_and_query_lists() {
|
||||
let viewport = (800.0, 600.0);
|
||||
let applies = |query, media| {
|
||||
media_query_applies_for_viewport_and_type(query, viewport, media)
|
||||
};
|
||||
|
||||
assert!(applies("screen", CssMediaType::Screen));
|
||||
assert!(!applies("screen", CssMediaType::Print));
|
||||
assert!(applies("print", CssMediaType::Print));
|
||||
assert!(!applies("print", CssMediaType::Screen));
|
||||
assert!(applies("not print", CssMediaType::Screen));
|
||||
assert!(!applies("not print", CssMediaType::Print));
|
||||
assert!(applies("not screen", CssMediaType::Print));
|
||||
assert!(!applies("not screen", CssMediaType::Screen));
|
||||
assert!(applies("speech, print", CssMediaType::Print));
|
||||
assert!(!applies("speech, print", CssMediaType::Screen));
|
||||
assert!(applies(
|
||||
"print and (min-width: 700px)",
|
||||
CssMediaType::Print
|
||||
));
|
||||
assert!(!applies(
|
||||
"print and (min-width: 900px)",
|
||||
CssMediaType::Print
|
||||
));
|
||||
assert!(applies(
|
||||
"not all and (min-width: 900px)",
|
||||
CssMediaType::Screen
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn negated_min_width_queries_form_max_breakpoints() {
|
||||
assert!(media_query_applies_for_viewport(
|
||||
|
||||
@@ -3435,6 +3435,28 @@ pub(crate) fn layout_dom_with_web_fonts_and_stylesheet_cache_with_animation_stat
|
||||
stylesheet_cache: &mut crate::css::StylesheetCache,
|
||||
animation_sample: crate::AnimationSample,
|
||||
animation_timeline: &mut crate::AnimationTimelineState,
|
||||
) -> DomLayout {
|
||||
layout_dom_with_web_fonts_and_stylesheet_cache_for_media_with_animation_state(
|
||||
tree,
|
||||
viewport,
|
||||
intrinsic,
|
||||
fonts,
|
||||
stylesheet_cache,
|
||||
crate::CssMediaType::Screen,
|
||||
animation_sample,
|
||||
animation_timeline,
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn layout_dom_with_web_fonts_and_stylesheet_cache_for_media_with_animation_state(
|
||||
tree: &DomTree,
|
||||
viewport: (f32, f32),
|
||||
intrinsic: &ReplacedIntrinsicMap,
|
||||
fonts: &[crate::inline::WebFont],
|
||||
stylesheet_cache: &mut crate::css::StylesheetCache,
|
||||
media_type: crate::CssMediaType,
|
||||
animation_sample: crate::AnimationSample,
|
||||
animation_timeline: &mut crate::AnimationTimelineState,
|
||||
) -> DomLayout {
|
||||
layout_dom_with_web_fonts_pass_limit_at_animation_time(
|
||||
tree,
|
||||
@@ -3445,6 +3467,7 @@ pub(crate) fn layout_dom_with_web_fonts_and_stylesheet_cache_with_animation_stat
|
||||
Some(stylesheet_cache),
|
||||
None,
|
||||
&[],
|
||||
media_type,
|
||||
animation_sample,
|
||||
animation_timeline,
|
||||
)
|
||||
@@ -3520,6 +3543,7 @@ pub(crate) fn layout_dom_with_web_fonts_and_retained_styles_with_animation_state
|
||||
Some(stylesheet_cache),
|
||||
Some(retained),
|
||||
mutations,
|
||||
crate::CssMediaType::Screen,
|
||||
animation_sample,
|
||||
animation_timeline,
|
||||
)
|
||||
@@ -3555,6 +3579,7 @@ fn layout_dom_with_web_fonts_pass_limit(
|
||||
stylesheet_cache,
|
||||
retained,
|
||||
mutations,
|
||||
crate::CssMediaType::Screen,
|
||||
crate::AnimationSample::default(),
|
||||
&mut animation_timeline,
|
||||
)
|
||||
@@ -3569,6 +3594,7 @@ fn layout_dom_with_web_fonts_pass_limit_at_animation_time(
|
||||
stylesheet_cache: Option<&mut crate::css::StylesheetCache>,
|
||||
retained: Option<RetainedStyleMaps>,
|
||||
mutations: &[RetainedStyleMutation],
|
||||
media_type: crate::CssMediaType,
|
||||
animation_sample: crate::AnimationSample,
|
||||
animation_timeline: &mut crate::AnimationTimelineState,
|
||||
) -> (DomLayout, ContainerLayoutTelemetry) {
|
||||
@@ -3579,7 +3605,16 @@ fn layout_dom_with_web_fonts_pass_limit_at_animation_time(
|
||||
for nid in tree.descendants(tree.document()) {
|
||||
if let Some(node) = tree.get_node(nid) {
|
||||
if let Some(elem) = node.as_element() {
|
||||
if elem.local.as_ref() == "style" {
|
||||
if elem.local.as_ref() == "style"
|
||||
&& node.get_attribute("media").is_none_or(|media| {
|
||||
media.trim().is_empty()
|
||||
|| crate::css::media_query_applies_for_viewport_and_type(
|
||||
media,
|
||||
viewport,
|
||||
media_type,
|
||||
)
|
||||
})
|
||||
{
|
||||
css_sources.push(tree.text_content(nid));
|
||||
}
|
||||
}
|
||||
@@ -3588,12 +3623,13 @@ fn layout_dom_with_web_fonts_pass_limit_at_animation_time(
|
||||
|
||||
let t0 = std::time::Instant::now();
|
||||
let (sheet, stylesheet_cache_hit) = match stylesheet_cache {
|
||||
Some(cache) => cache.get_or_parse(tree, &css_sources, viewport),
|
||||
Some(cache) => cache.get_or_parse(tree, &css_sources, viewport, media_type),
|
||||
None => (
|
||||
std::sync::Arc::new(crate::css::Stylesheet::parse_for_viewport(
|
||||
std::sync::Arc::new(crate::css::Stylesheet::parse_for_viewport_and_media(
|
||||
tree,
|
||||
&css_sources,
|
||||
viewport,
|
||||
media_type,
|
||||
)),
|
||||
false,
|
||||
),
|
||||
@@ -14866,6 +14902,7 @@ mod tests {
|
||||
Some(&mut cache),
|
||||
None,
|
||||
&[],
|
||||
crate::CssMediaType::Screen,
|
||||
crate::AnimationSample::document(0.0),
|
||||
&mut timeline,
|
||||
);
|
||||
@@ -14883,6 +14920,7 @@ mod tests {
|
||||
Some(&mut cache),
|
||||
Some(retained),
|
||||
&[RetainedStyleMutation::Animation { node: animated }],
|
||||
crate::CssMediaType::Screen,
|
||||
crate::AnimationSample::document(500.0),
|
||||
&mut timeline,
|
||||
);
|
||||
@@ -14896,6 +14934,7 @@ mod tests {
|
||||
Some(&mut cache),
|
||||
None,
|
||||
&[],
|
||||
crate::CssMediaType::Screen,
|
||||
crate::AnimationSample::document(500.0),
|
||||
&mut full_timeline,
|
||||
);
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
use taffy::prelude::*;
|
||||
|
||||
pub mod css;
|
||||
pub use css::{Stylesheet, StylesheetCache};
|
||||
pub use css::{CssMediaType, Stylesheet, StylesheetCache};
|
||||
|
||||
pub mod style;
|
||||
pub use style::compute_style;
|
||||
@@ -106,6 +106,7 @@ pub use paint::{
|
||||
prepare_dom_with_dynamic_fonts, prepare_dom_with_dynamic_fonts_at_animation_time,
|
||||
prepare_dom_with_dynamic_fonts_and_stylesheet_cache,
|
||||
prepare_dom_with_dynamic_fonts_and_stylesheet_cache_at_animation_time,
|
||||
prepare_dom_with_dynamic_fonts_and_stylesheet_cache_for_media_with_animation_state,
|
||||
prepare_dom_with_dynamic_fonts_and_stylesheet_cache_with_animation_state,
|
||||
screenshot_png, screenshot_png_scrolled, screenshot_png_scrolled_at_animation_time,
|
||||
screenshot_png_scrolled_at_animation_time_with_surface_color,
|
||||
|
||||
@@ -24,7 +24,8 @@ static FONT_BOLD_OBLIQUE_BYTES: &[u8] = include_bytes!("../assets/liberation-san
|
||||
|
||||
use crate::dom::{
|
||||
layout_dom_with_web_fonts_and_retained_styles_with_animation_state,
|
||||
layout_dom_with_web_fonts_and_stylesheet_cache_with_animation_state, RetainedStyleMaps,
|
||||
layout_dom_with_web_fonts_and_stylesheet_cache_for_media_with_animation_state,
|
||||
RetainedStyleMaps,
|
||||
};
|
||||
|
||||
const DEFAULT_RESOURCE_CACHE_ENTRIES: usize = 512;
|
||||
@@ -2006,6 +2007,30 @@ pub fn prepare_dom_with_dynamic_fonts_and_stylesheet_cache_with_animation_state(
|
||||
stylesheet_cache: &mut crate::css::StylesheetCache,
|
||||
animation_sample: crate::AnimationSample,
|
||||
animation_timeline: &mut crate::AnimationTimelineState,
|
||||
) -> Option<PreparedRender> {
|
||||
prepare_dom_with_dynamic_fonts_and_stylesheet_cache_for_media_with_animation_state(
|
||||
tree,
|
||||
viewport,
|
||||
base_url,
|
||||
resources,
|
||||
dynamic_fonts,
|
||||
stylesheet_cache,
|
||||
crate::CssMediaType::Screen,
|
||||
animation_sample,
|
||||
animation_timeline,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn prepare_dom_with_dynamic_fonts_and_stylesheet_cache_for_media_with_animation_state(
|
||||
tree: &DomTree,
|
||||
viewport: (f32, f32),
|
||||
base_url: Option<&str>,
|
||||
resources: &mut RenderResourceCache,
|
||||
dynamic_fonts: &[DynamicFontFace],
|
||||
stylesheet_cache: &mut crate::css::StylesheetCache,
|
||||
media_type: crate::CssMediaType,
|
||||
animation_sample: crate::AnimationSample,
|
||||
animation_timeline: &mut crate::AnimationTimelineState,
|
||||
) -> Option<PreparedRender> {
|
||||
prepare_dom_with_dynamic_fonts_and_stylesheet_cache_internal(
|
||||
tree,
|
||||
@@ -2015,6 +2040,7 @@ pub fn prepare_dom_with_dynamic_fonts_and_stylesheet_cache_with_animation_state(
|
||||
dynamic_fonts,
|
||||
stylesheet_cache,
|
||||
None,
|
||||
media_type,
|
||||
animation_sample,
|
||||
animation_timeline,
|
||||
)
|
||||
@@ -2166,6 +2192,7 @@ pub fn prepare_dom_with_retained_styles_with_animation_state(
|
||||
dynamic_fonts,
|
||||
stylesheet_cache,
|
||||
Some((retained, mutations)),
|
||||
crate::CssMediaType::Screen,
|
||||
animation_sample,
|
||||
animation_timeline,
|
||||
)
|
||||
@@ -2199,6 +2226,7 @@ fn prepare_dom_with_dynamic_fonts_and_stylesheet_cache_internal(
|
||||
dynamic_fonts: &[DynamicFontFace],
|
||||
stylesheet_cache: &mut crate::css::StylesheetCache,
|
||||
retained: Option<(RetainedStyleMaps, &[crate::dom::RetainedStyleMutation])>,
|
||||
media_type: crate::CssMediaType,
|
||||
animation_sample: crate::AnimationSample,
|
||||
animation_timeline: &mut crate::AnimationTimelineState,
|
||||
) -> Option<PreparedRender> {
|
||||
@@ -2253,12 +2281,13 @@ fn prepare_dom_with_dynamic_fonts_and_stylesheet_cache_internal(
|
||||
animation_sample,
|
||||
animation_timeline,
|
||||
),
|
||||
None => layout_dom_with_web_fonts_and_stylesheet_cache_with_animation_state(
|
||||
None => layout_dom_with_web_fonts_and_stylesheet_cache_for_media_with_animation_state(
|
||||
tree,
|
||||
viewport,
|
||||
&intrinsic,
|
||||
&fonts,
|
||||
stylesheet_cache,
|
||||
media_type,
|
||||
animation_sample,
|
||||
animation_timeline,
|
||||
),
|
||||
@@ -2282,12 +2311,13 @@ fn prepare_dom_with_dynamic_fonts_and_stylesheet_cache_internal(
|
||||
{
|
||||
resources.content_image_layout_retries += 1;
|
||||
}
|
||||
laid = layout_dom_with_web_fonts_and_stylesheet_cache_with_animation_state(
|
||||
laid = layout_dom_with_web_fonts_and_stylesheet_cache_for_media_with_animation_state(
|
||||
tree,
|
||||
viewport,
|
||||
&intrinsic,
|
||||
&fonts,
|
||||
stylesheet_cache,
|
||||
media_type,
|
||||
animation_sample,
|
||||
animation_timeline,
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user