From 82bf6780ee66e71940e8c1da1c3573acab831e7d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Wed, 18 Jan 2023 18:30:26 +0100
Subject: [PATCH] WIP: Nesting

---
 .cargo/config.in                                    |  6 ------
 Cargo.lock                                          |  4 +++-
 Cargo.toml                                          |  3 ++-
 servo/components/style/gecko/data.rs                |  6 ++++++
 .../style/properties/declaration_block.rs           |  6 +++++-
 servo/components/style/stylesheets/rule_list.rs     |  2 +-
 servo/components/style/stylesheets/rule_parser.rs   |  2 ++
 servo/components/style/stylesheets/style_rule.rs    | 13 ++++++++++---
 third_party/rust/cssparser/Cargo.toml               |  2 +-
 .../rust/cssparser/src/rules_and_declarations.rs    |  8 ++++----
 10 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/.cargo/config.in b/.cargo/config.in
index c7dc00c8ccc7e..19c3bd34fd861 100644
--- a/.cargo/config.in
+++ b/.cargo/config.in
@@ -120,12 +120,6 @@ git = "https://github.com/rust-minidump/minidump-writer.git"
 rev = "7d76616d27b9dc87fe3a94639b8b4f947d52a6aa"
 replace-with = "vendored-sources"
 
-[source."https://github.com/servo/rust-cssparser"]
-git = "https://github.com/servo/rust-cssparser"
-rev = "b196a164dcbb317016d4aa6c58c13147e6045ebb"
-replace-with = "vendored-sources"
-
-
 # Take advantage of the fact that cargo will treat lines starting with #
 # as comments to add preprocessing directives. This file can thus by copied
 # as-is to $topsrcdir/.cargo/config with no preprocessing to be used there
diff --git a/Cargo.lock b/Cargo.lock
index b8978b048aadd..b10bb7cb8b98a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1104,7 +1104,6 @@ dependencies = [
 [[package]]
 name = "cssparser"
 version = "0.30.0"
-source = "git+https://github.com/servo/rust-cssparser?rev=b196a164dcbb317016d4aa6c58c13147e6045ebb#b196a164dcbb317016d4aa6c58c13147e6045ebb"
 dependencies = [
  "cssparser-macros",
  "dtoa-short",
@@ -1119,7 +1118,10 @@ dependencies = [
 [[package]]
 name = "cssparser-macros"
 version = "0.6.0"
+<<<<<<< HEAD
 source = "git+https://github.com/servo/rust-cssparser?rev=b196a164dcbb317016d4aa6c58c13147e6045ebb#b196a164dcbb317016d4aa6c58c13147e6045ebb"
+=======
+>>>>>>> b61aaf04e9463 (WIP: Nesting)
 dependencies = [
  "quote",
  "syn",
diff --git a/Cargo.toml b/Cargo.toml
index 5fb7c20535adc..11d72bfa7f4d8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -167,7 +167,8 @@ minidump-writer = { git = "https://github.com/rust-minidump/minidump-writer.git"
 # warp 0.3.3 + https://github.com/seanmonstar/warp/pull/1007
 warp = { git = "https://github.com/glandium/warp", rev = "4af45fae95bc98b0eba1ef0db17e1dac471bb23d" }
 
-cssparser = { git = "https://github.com/servo/rust-cssparser", rev = "b196a164dcbb317016d4aa6c58c13147e6045ebb" }
+cssparser = { path = "third_party/rust/cssparser" }
+cssparser-macros = { path = "third_party/rust/cssparser-macros" }
 
 # application-services overrides to make updating them all simpler.
 interrupt-support = { git = "https://github.com/bendk/application-services", rev = "ecb35df5fc40357c49922f90e86bf4147fa52953" }
diff --git a/servo/components/style/gecko/data.rs b/servo/components/style/gecko/data.rs
index cabae61d563bd..ef7e9c730982f 100644
--- a/servo/components/style/gecko/data.rs
+++ b/servo/components/style/gecko/data.rs
@@ -25,6 +25,12 @@ use std::fmt;
 #[derive(Eq, PartialEq)]
 pub struct GeckoStyleSheet(*const DomStyleSheet);
 
+// FIXME(emilio): These are not quite real! GeckoStyleSheet should probably be thread-safe
+// ref-counted. We don't _use_ it off the main thread but need this because StyleRule contains
+// nested rules. FIX BEFORE LANDING / ENABLING NESTING BY DEFAULT
+unsafe impl Send for GeckoStyleSheet {}
+unsafe impl Sync for GeckoStyleSheet {}
+
 impl fmt::Debug for GeckoStyleSheet {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         let contents = self.contents();
diff --git a/servo/components/style/properties/declaration_block.rs b/servo/components/style/properties/declaration_block.rs
index 1b7c18e345d00..00fe85b5b1117 100644
--- a/servo/components/style/properties/declaration_block.rs
+++ b/servo/components/style/properties/declaration_block.rs
@@ -1256,7 +1256,11 @@ pub fn parse_style_attribute(
     );
 
     let mut input = ParserInput::new(input);
-    parse_property_declaration_list(&context, &mut Parser::new(&mut input), None)
+    parse_property_declaration_list(
+        &context,
+        &mut Parser::new(&mut input),
+        None,
+    )
 }
 
 /// Parse a given property declaration. Can result in multiple
diff --git a/servo/components/style/stylesheets/rule_list.rs b/servo/components/style/stylesheets/rule_list.rs
index c246d7ae6bbab..33f9efaa0959c 100644
--- a/servo/components/style/stylesheets/rule_list.rs
+++ b/servo/components/style/stylesheets/rule_list.rs
@@ -17,7 +17,7 @@ use servo_arc::{Arc, RawOffsetArc};
 use std::fmt::{self, Write};
 
 /// A list of CSS rules.
-#[derive(Debug, ToShmem)]
+#[derive(Debug, ToShmem, Default)]
 pub struct CssRules(pub Vec<CssRule>);
 
 impl CssRules {
diff --git a/servo/components/style/stylesheets/rule_parser.rs b/servo/components/style/stylesheets/rule_parser.rs
index b86e31aead9c4..e518d8c468624 100644
--- a/servo/components/style/stylesheets/rule_parser.rs
+++ b/servo/components/style/stylesheets/rule_parser.rs
@@ -790,6 +790,8 @@ impl<'a, 'b, 'i> QualifiedRuleParser<'i> for NestedRuleParser<'a, 'b> {
         Ok(CssRule::Style(Arc::new(self.shared_lock.wrap(StyleRule {
             selectors,
             block,
+            // TODO
+            rules: Arc::new(self.shared_lock.wrap(Default::default())),
             source_location: start.source_location(),
         }))))
     }
diff --git a/servo/components/style/stylesheets/style_rule.rs b/servo/components/style/stylesheets/style_rule.rs
index 1d4a2e273163b..a0e73ff96dddd 100644
--- a/servo/components/style/stylesheets/style_rule.rs
+++ b/servo/components/style/stylesheets/style_rule.rs
@@ -9,6 +9,7 @@ use crate::selector_parser::SelectorImpl;
 use crate::shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked};
 use crate::shared_lock::{SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
 use crate::str::CssStringWriter;
+use crate::stylesheets::CssRules;
 use cssparser::SourceLocation;
 #[cfg(feature = "gecko")]
 use malloc_size_of::MallocUnconditionalShallowSizeOf;
@@ -25,6 +26,8 @@ pub struct StyleRule {
     pub selectors: SelectorList<SelectorImpl>,
     /// The declaration block with the properties it contains.
     pub block: Arc<Locked<PropertyDeclarationBlock>>,
+    /// The nested rules to this style rule.
+    pub rules: Arc<Locked<CssRules>>,
     /// The location in the sheet where it was found.
     pub source_location: SourceLocation,
 }
@@ -35,11 +38,13 @@ impl DeepCloneWithLock for StyleRule {
         &self,
         lock: &SharedRwLock,
         guard: &SharedRwLockReadGuard,
-        _params: &DeepCloneParams,
-    ) -> StyleRule {
-        StyleRule {
+        params: &DeepCloneParams,
+    ) -> Self {
+        let rules = self.rules.read_with(guard);
+        Self {
             selectors: self.selectors.clone(),
             block: Arc::new(lock.wrap(self.block.read_with(guard).clone())),
+            rules: Arc::new(lock.wrap(rules.deep_clone_with_lock(lock, guard, params))),
             source_location: self.source_location.clone(),
         }
     }
@@ -53,6 +58,8 @@ impl StyleRule {
         n += self.selectors.0.size_of(ops);
         n += self.block.unconditional_shallow_size_of(ops) +
             self.block.read_with(guard).size_of(ops);
+        n += self.rules.unconditional_shallow_size_of(ops) +
+            self.rules.read_with(guard).size_of(guard, ops);
         n
     }
 }
diff --git a/third_party/rust/cssparser/Cargo.toml b/third_party/rust/cssparser/Cargo.toml
index 23695b79b693b..27ec906c41c07 100644
--- a/third_party/rust/cssparser/Cargo.toml
+++ b/third_party/rust/cssparser/Cargo.toml
@@ -21,7 +21,7 @@ difference = "2.0"
 encoding_rs = "0.8"
 
 [dependencies]
-cssparser-macros = {path = "./macros", version = "0.6"}
+cssparser-macros = {path = "../cssparser-macros", version = "0.6"}
 dtoa-short = "0.3"
 itoa = "1.0"
 phf = {version = ">=0.8,<=0.11", features = ["macros"]}
diff --git a/third_party/rust/cssparser/src/rules_and_declarations.rs b/third_party/rust/cssparser/src/rules_and_declarations.rs
index 3224bb964b1f6..832a4861c8294 100644
--- a/third_party/rust/cssparser/src/rules_and_declarations.rs
+++ b/third_party/rust/cssparser/src/rules_and_declarations.rs
@@ -304,8 +304,8 @@ where
     /// It could be a custom enum.
     pub fn new_for_stylesheet(input: &'a mut Parser<'i, 't>, parser: P) -> Self {
         RuleListParser {
-            input: input,
-            parser: parser,
+            input,
+            parser,
             is_stylesheet: true,
             any_rule_so_far: false,
         }
@@ -319,8 +319,8 @@ where
     /// (This is to deal with legacy workarounds for `<style>` HTML element parsing.)
     pub fn new_for_nested_rule(input: &'a mut Parser<'i, 't>, parser: P) -> Self {
         RuleListParser {
-            input: input,
-            parser: parser,
+            input,
+            parser,
             is_stylesheet: false,
             any_rule_so_far: false,
         }
-- 
2.39.2

