diff --git a/Cargo.lock b/Cargo.lock index 0b57ed93d3..b7967d6474 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4247,7 +4247,7 @@ dependencies = [ [[package]] name = "selectors" version = "0.40.0" -source = "git+https://github.com/ldm0/stylo?rev=713ba89c8e23dd76fd350c5bee68590bfdb885ae#713ba89c8e23dd76fd350c5bee68590bfdb885ae" +source = "git+https://github.com/ldm0/stylo?rev=32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6#32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6" dependencies = [ "bitflags", "cssparser", @@ -4379,7 +4379,7 @@ dependencies = [ [[package]] name = "servo_arc" version = "0.4.3" -source = "git+https://github.com/ldm0/stylo?rev=713ba89c8e23dd76fd350c5bee68590bfdb885ae#713ba89c8e23dd76fd350c5bee68590bfdb885ae" +source = "git+https://github.com/ldm0/stylo?rev=32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6#32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6" dependencies = [ "serde", "stable_deref_trait", @@ -4626,7 +4626,7 @@ dependencies = [ [[package]] name = "stylo" version = "0.20.0" -source = "git+https://github.com/ldm0/stylo?rev=713ba89c8e23dd76fd350c5bee68590bfdb885ae#713ba89c8e23dd76fd350c5bee68590bfdb885ae" +source = "git+https://github.com/ldm0/stylo?rev=32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6#32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6" dependencies = [ "app_units", "arrayvec", @@ -4682,7 +4682,7 @@ dependencies = [ [[package]] name = "stylo_atoms" version = "0.20.0" -source = "git+https://github.com/ldm0/stylo?rev=713ba89c8e23dd76fd350c5bee68590bfdb885ae#713ba89c8e23dd76fd350c5bee68590bfdb885ae" +source = "git+https://github.com/ldm0/stylo?rev=32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6#32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6" dependencies = [ "string_cache", "string_cache_codegen", @@ -4691,7 +4691,7 @@ dependencies = [ [[package]] name = "stylo_derive" version = "0.20.0" -source = "git+https://github.com/ldm0/stylo?rev=713ba89c8e23dd76fd350c5bee68590bfdb885ae#713ba89c8e23dd76fd350c5bee68590bfdb885ae" +source = "git+https://github.com/ldm0/stylo?rev=32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6#32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6" dependencies = [ "darling", "proc-macro2", @@ -4703,7 +4703,7 @@ dependencies = [ [[package]] name = "stylo_dom" version = "0.20.0" -source = "git+https://github.com/ldm0/stylo?rev=713ba89c8e23dd76fd350c5bee68590bfdb885ae#713ba89c8e23dd76fd350c5bee68590bfdb885ae" +source = "git+https://github.com/ldm0/stylo?rev=32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6#32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6" dependencies = [ "bitflags", "stylo_malloc_size_of", @@ -4712,7 +4712,7 @@ dependencies = [ [[package]] name = "stylo_malloc_size_of" version = "0.20.0" -source = "git+https://github.com/ldm0/stylo?rev=713ba89c8e23dd76fd350c5bee68590bfdb885ae#713ba89c8e23dd76fd350c5bee68590bfdb885ae" +source = "git+https://github.com/ldm0/stylo?rev=32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6#32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6" dependencies = [ "app_units", "cssparser", @@ -4729,7 +4729,7 @@ dependencies = [ [[package]] name = "stylo_static_prefs" version = "0.20.0" -source = "git+https://github.com/ldm0/stylo?rev=713ba89c8e23dd76fd350c5bee68590bfdb885ae#713ba89c8e23dd76fd350c5bee68590bfdb885ae" +source = "git+https://github.com/ldm0/stylo?rev=32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6#32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6" dependencies = [ "toml", ] @@ -4747,7 +4747,7 @@ dependencies = [ [[package]] name = "stylo_traits" version = "0.20.0" -source = "git+https://github.com/ldm0/stylo?rev=713ba89c8e23dd76fd350c5bee68590bfdb885ae#713ba89c8e23dd76fd350c5bee68590bfdb885ae" +source = "git+https://github.com/ldm0/stylo?rev=32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6#32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6" dependencies = [ "app_units", "bitflags", @@ -5033,7 +5033,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "to_shmem" version = "0.5.0" -source = "git+https://github.com/ldm0/stylo?rev=713ba89c8e23dd76fd350c5bee68590bfdb885ae#713ba89c8e23dd76fd350c5bee68590bfdb885ae" +source = "git+https://github.com/ldm0/stylo?rev=32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6#32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6" dependencies = [ "cssparser", "servo_arc", @@ -5046,7 +5046,7 @@ dependencies = [ [[package]] name = "to_shmem_derive" version = "0.1.0" -source = "git+https://github.com/ldm0/stylo?rev=713ba89c8e23dd76fd350c5bee68590bfdb885ae#713ba89c8e23dd76fd350c5bee68590bfdb885ae" +source = "git+https://github.com/ldm0/stylo?rev=32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6#32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6" dependencies = [ "darling", "proc-macro2", @@ -5653,7 +5653,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 39f559a53f..9158c3c628 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -92,12 +92,12 @@ curl = { git = "https://github.com/ldm0/curl-rust", branch = "moli" } curl-sys = { git = "https://github.com/ldm0/curl-rust", branch = "moli" } cookie = { git = "https://github.com/ldm0/cookie-rs", branch = "priority" } v8 = { path = "vendor/v8-146.9.0" } -selectors = { git = "https://github.com/ldm0/stylo", rev = "713ba89c8e23dd76fd350c5bee68590bfdb885ae" } -stylo = { git = "https://github.com/ldm0/stylo", rev = "713ba89c8e23dd76fd350c5bee68590bfdb885ae" } -stylo_atoms = { git = "https://github.com/ldm0/stylo", rev = "713ba89c8e23dd76fd350c5bee68590bfdb885ae" } -stylo_dom = { git = "https://github.com/ldm0/stylo", rev = "713ba89c8e23dd76fd350c5bee68590bfdb885ae" } -stylo_static_prefs = { git = "https://github.com/ldm0/stylo", rev = "713ba89c8e23dd76fd350c5bee68590bfdb885ae" } -stylo_traits = { git = "https://github.com/ldm0/stylo", rev = "713ba89c8e23dd76fd350c5bee68590bfdb885ae" } +selectors = { git = "https://github.com/ldm0/stylo", rev = "32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6" } +stylo = { git = "https://github.com/ldm0/stylo", rev = "32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6" } +stylo_atoms = { git = "https://github.com/ldm0/stylo", rev = "32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6" } +stylo_dom = { git = "https://github.com/ldm0/stylo", rev = "32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6" } +stylo_static_prefs = { git = "https://github.com/ldm0/stylo", rev = "32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6" } +stylo_traits = { git = "https://github.com/ldm0/stylo", rev = "32c3de3f2aab3340c51f03f2a0878d1e4eed7fd6" } taffy = { git = "https://github.com/ldm0/taffy", rev = "3305c7b51c4c88d698d5d3039cd6c8e828ff2086" } [workspace.lints.clippy] diff --git a/moli-renderer-v8/src/style_engine/tests/dependency.rs b/moli-renderer-v8/src/style_engine/tests/dependency.rs index 272ac43028..f7a787a2a4 100644 --- a/moli-renderer-v8/src/style_engine/tests/dependency.rs +++ b/moli-renderer-v8/src/style_engine/tests/dependency.rs @@ -1218,7 +1218,7 @@ fn source_dependency_request_translation_uses_context_roots_for_nth_of_dependenc } #[test] -fn source_dependency_request_translation_uses_context_roots_for_nested_relative_dependency() { +fn source_dependency_request_translation_tries_nested_relative_with_context_safety_roots() { let mut host = test_host(); let document = host.document_handle(); let parent = host.create_element("section"); @@ -1270,27 +1270,33 @@ fn source_dependency_request_translation_uses_context_roots_for_nested_relative_ assert_eq!(target_queries.len(), 1); assert_eq!( target_queries[0].kind(), - StyloRetainedSourceStyleInvalidationKind::ContextFallback + StyloRetainedSourceStyleInvalidationKind::RetainedQueries ); assert!( target_queries[0] - .fallback_reasons_for_test() - .contains(&StyloSourceInvalidationFallbackReason::NestedRelativeSelectorDependency) + .retained_queries_for_test() + .is_some_and(|queries| queries.contains(&query)) ); + assert!(target_queries[0].fallback_reasons_for_test().is_empty()); assert!( target_queries[0] .reasoned_fallback_root_set_for_test() + .is_empty() + ); + assert!( + target_queries[0] + .exact_safety_fallback_root_set_for_test() .contains(&target) ); assert!( !target_queries[0] - .reasoned_fallback_root_set_for_test() + .exact_safety_fallback_root_set_for_test() .contains(&document) ); } #[test] -fn source_dependency_request_translation_preserves_multiple_context_fallback_reasons() { +fn source_dependency_request_translation_keeps_nth_fallback_while_trying_nested_relative_exactly() { let mut host = test_host(); let document = host.document_handle(); let parent = host.create_element("section"); @@ -1337,18 +1343,28 @@ fn source_dependency_request_translation_preserves_multiple_context_fallback_rea assert_eq!(target_queries.len(), 1); assert_eq!( target_queries[0].kind(), - StyloRetainedSourceStyleInvalidationKind::ContextFallback + StyloRetainedSourceStyleInvalidationKind::RetainedQueries + ); + assert!( + target_queries[0] + .retained_queries_for_test() + .is_some_and(|queries| !queries.contains(&nth_query) && queries.contains(&nested_query)) ); let reasons = target_queries[0].fallback_reasons_for_test(); assert!(reasons.contains(&StyloSourceInvalidationFallbackReason::NthOfDependency)); assert!( - reasons.contains(&StyloSourceInvalidationFallbackReason::NestedRelativeSelectorDependency) + !reasons.contains(&StyloSourceInvalidationFallbackReason::NestedRelativeSelectorDependency) ); assert!( !target_queries[0] .reasoned_fallback_root_set_for_test() .contains(&document) ); + assert!( + !target_queries[0] + .exact_safety_fallback_root_set_for_test() + .contains(&document) + ); } #[test] diff --git a/moli-renderer-v8/src/style_engine/tests/invalidator.rs b/moli-renderer-v8/src/style_engine/tests/invalidator.rs index 1274a1ea69..4a05d8eb83 100644 --- a/moli-renderer-v8/src/style_engine/tests/invalidator.rs +++ b/moli-renderer-v8/src/style_engine/tests/invalidator.rs @@ -4928,6 +4928,155 @@ fn retained_stylo_invalidator_refreshes_nth_child_of_selector_list_on_class_chan ); } +#[test] +fn retained_stylo_invalidator_refreshes_nth_child_of_custom_state_with_context_fallback() { + let mut host = test_host(); + let document = host.document_handle(); + let body = host.create_element("body"); + let container = host.create_element("section"); + let first = host.create_element("x-stateful"); + let middle = host.create_element("x-stateful"); + let target = host.create_element("x-stateful"); + let unrelated = host.create_element("aside"); + + assert!(host.set_attribute(unrelated, "id", "unrelated")); + assert!(host.insert_custom_state(first, "--active")); + assert!(host.insert_custom_state(target, "--active")); + assert!(host.append_child(document, body)); + assert!(host.append_child(body, container)); + assert!(host.append_child(container, first)); + assert!(host.append_child(container, middle)); + assert!(host.append_child(container, target)); + assert!(host.append_child(body, unrelated)); + + let mut engine = MoliStyleEngine::new(); + let style_text = "section > x-stateful:nth-child(odd of :state(--active)) { + background-color: rgb(192, 192, 192); + } + #unrelated { color: rgb(1, 2, 3); }"; + let document_url = url::Url::parse("https://example.test/").unwrap(); + let source = StyloStylesheetSource::new(style_text.into(), document_url.clone()) + .with_source_id(Some(StyleSourceId::document_adopted_style_sheet( + document, 0, + ))); + engine.set_document_adopted_style_sheet_sources(document, vec![source.clone()]); + let mut inputs = FullStyleWorldSnapshot::default(); + inputs.document_stylesheet_sources.push(source); + assert_eq!( + engine.computed_style_property_value( + &host, + &document_url, + target, + "background-color", + None, + &inputs, + None, + ), + Some("rgba(0, 0, 0, 0)".into()) + ); + assert_eq!( + engine.computed_style_property_value( + &host, + &document_url, + unrelated, + "color", + None, + &inputs, + None, + ), + Some("rgb(1, 2, 3)".into()) + ); + + let media = crate::protocol_types::EmulatedMediaOverrides::default(); + let old_custom_states = host.custom_state_names(middle); + assert!(host.insert_custom_state(middle, "--active")); + let source_scope = crate::style_engine::scope::source_scope_for_custom_state_change( + &host, + middle, + &["--active".to_owned()], + ) + .expect("custom state scope"); + let target_queries = { + let world = engine.world_for_document(document); + let linked_sources = world.linked_stylesheet_sources.borrow(); + let document_adopted_sources = world.adopted_style_sheet_sources.borrow(); + super::planner::target_queries_for_pending_cause_with_document_adopted_sources( + &host, + &linked_sources, + &document_adopted_sources, + &engine.dom_adapter, + &media, + StyleViewport::default(), + document, + &PendingStyleInvalidationCause::CustomStateChange { + element: middle, + state_names: vec!["--active".to_owned()], + old_custom_states: old_custom_states.clone(), + }, + &source_scope, + ) + }; + assert_eq!(target_queries.len(), 1, "{target_queries:#?}"); + assert_eq!( + target_queries[0].kind(), + StyloRetainedSourceStyleInvalidationKind::ContextFallback, + "{target_queries:#?}" + ); + let application = engine + .with_retained_style_system_for_document_for_test(document, |retained| { + retained_source_invalidation_outcome_for_document_for_test( + &engine, + &host, + document, + StyleSourceDocumentContext::for_root_document(document), + Some(retained), + &target_queries, + false, + ) + }) + .finalize(&host); + assert_eq!( + application.cleanup_target_kind(), + StyleInvalidationCleanupTargetKind::SourceFallbackSubtreeRoots + ); + assert!(matches!( + application.cleanup_target(), + StyleInvalidationCleanupTarget::SourceFallbackSubtreeRoots(roots) + if roots.contains(&target) && !roots.contains(&unrelated) + )); + assert_eq!(application.diagnostic_target_results().len(), 1); + assert!(!application.diagnostic_target_results()[0].exact()); + assert!( + application.diagnostic_target_results()[0] + .fallback_reasons() + .contains(&StyloSourceInvalidationFallbackReason::NthOfDependency) + ); + + engine.invalidate_for_custom_state_change( + &host, + middle, + vec!["--active".to_owned()], + old_custom_states, + &media, + ); + engine.drain_pending_style_invalidations_for_document_for_test(&host, document); + + assert!(!engine.computed_style_cache_contains_handle_for_document_for_test(document, target)); + assert!(engine.computed_style_cache_contains_handle_for_document_for_test(document, unrelated)); + assert_eq!( + engine.computed_style_property_value( + &host, + &document_url, + target, + "background-color", + None, + &inputs, + None, + ), + Some("rgb(192, 192, 192)".into()) + ); +} + #[test] fn retained_stylo_invalidator_custom_state_snapshot_avoids_source_fallback() { let mut host = test_host(); @@ -5217,8 +5366,10 @@ fn retained_stylo_invalidator_refreshes_nested_is_sibling_has_on_child_removal() let first_child = host.create_element("span"); let second_child = host.create_element("span"); let third_child = host.create_element("span"); + let unrelated = host.create_element("aside"); assert!(host.set_attribute(target, "id", "target")); + assert!(host.set_attribute(unrelated, "id", "unrelated")); for item in [first_item, second_item, third_item] { assert!(host.set_attribute(item, "class", "item")); } @@ -5233,12 +5384,14 @@ fn retained_stylo_invalidator_refreshes_nested_is_sibling_has_on_child_removal() assert!(host.append_child(third_item, first_child)); assert!(host.append_child(third_item, second_child)); assert!(host.append_child(third_item, third_child)); + assert!(host.append_child(document, unrelated)); let mut engine = MoliStyleEngine::new(); let style_text = "#target { color: rgb(0, 128, 0); } #target:has(:is(.item + .item + .item > .child + .child + .child)) { color: rgb(192, 192, 192); - }"; + } + #unrelated { color: rgb(1, 2, 3); }"; let document_url = url::Url::parse("https://example.test/").unwrap(); let metadata = stylo_source_metadata_for_css_text(style_text, &document_url); assert!( @@ -5266,9 +5419,21 @@ fn retained_stylo_invalidator_refreshes_nested_is_sibling_has_on_child_removal() ), Some("rgb(192, 192, 192)".into()) ); + assert_eq!( + engine.computed_style_property_value( + &host, + &document_url, + unrelated, + "color", + None, + &inputs, + None, + ), + Some("rgb(1, 2, 3)".into()) + ); assert_eq!( engine.computed_style_cache_entry_count_for_document_for_test(document), - 1 + 2 ); let removed_snapshots = removed_element_dependency_snapshots(&host, &[first_item]); @@ -5289,6 +5454,7 @@ fn retained_stylo_invalidator_refreshes_nested_is_sibling_has_on_child_removal() engine.drain_pending_style_invalidations_for_document_for_test(&host, document); assert!(!engine.computed_style_cache_contains_handle_for_document_for_test(document, target)); + assert!(engine.computed_style_cache_contains_handle_for_document_for_test(document, unrelated)); assert_eq!( engine.computed_style_property_value( &host, @@ -5315,6 +5481,7 @@ fn retained_stylo_invalidator_refreshes_nested_is_sibling_has_on_middle_insertio let target = host.create_element("section"); let child = host.create_element("div"); let descendant = host.create_element("div"); + let unrelated = host.create_element("aside"); assert!(host.set_attribute(first, "class", "p")); assert!(host.set_attribute(previous, "id", "parent_previous")); @@ -5325,6 +5492,7 @@ fn retained_stylo_invalidator_refreshes_nested_is_sibling_has_on_middle_insertio assert!(host.set_attribute(child, "class", "d")); assert!(host.set_attribute(descendant, "id", "descendant")); assert!(host.set_attribute(descendant, "class", "e")); + assert!(host.set_attribute(unrelated, "id", "unrelated")); assert!(host.append_child(document, body)); assert!(host.append_child(body, outer)); assert!(host.append_child(outer, first)); @@ -5333,12 +5501,14 @@ fn retained_stylo_invalidator_refreshes_nested_is_sibling_has_on_middle_insertio assert!(host.append_child(parent, target)); assert!(host.append_child(target, child)); assert!(host.append_child(child, descendant)); + assert!(host.append_child(body, unrelated)); let mut engine = MoliStyleEngine::new(); let style_text = "#has_scope { color: rgb(128, 128, 128); } .green:has(#descendant:is(.p + .c_has_scope ~ .d .e)) { color: rgb(0, 128, 0); - }"; + } + #unrelated { color: rgb(1, 2, 3); }"; let document_url = url::Url::parse("https://example.test/").unwrap(); let metadata = stylo_source_metadata_for_css_text(style_text, &document_url); assert!( @@ -5366,9 +5536,21 @@ fn retained_stylo_invalidator_refreshes_nested_is_sibling_has_on_middle_insertio ), Some("rgb(0, 128, 0)".into()) ); + assert_eq!( + engine.computed_style_property_value( + &host, + &document_url, + unrelated, + "color", + None, + &inputs, + None, + ), + Some("rgb(1, 2, 3)".into()) + ); assert_eq!( engine.computed_style_cache_entry_count_for_document_for_test(document), - 1 + 2 ); let inserted = host.create_element("div"); @@ -5390,6 +5572,7 @@ fn retained_stylo_invalidator_refreshes_nested_is_sibling_has_on_middle_insertio engine.drain_pending_style_invalidations_for_document_for_test(&host, document); assert!(!engine.computed_style_cache_contains_handle_for_document_for_test(document, target)); + assert!(engine.computed_style_cache_contains_handle_for_document_for_test(document, unrelated)); assert_eq!( engine.computed_style_property_value( &host,