Repository: ProjectEvergreen/greenwood (js)

Issue:
add support for optimizing the CSS `:has` / `:is` pseudo-selectora
## Type of Change
Feature

## Summary
The [CSS `:has` psuedo-selector](https://developer.mozilla.org/en-US/docs/Web/CSS/:has) is neat new CSS feature (almost*) available in all browsers and can [come in pretty handy]
(https://twitter.com/wesbos/status/1653401308022607874?s=43&t=23JfvPjOIJyZ9W8iFiZYyg).
https://www.smashingmagazine.com/2023/01/level-up-css-skills-has-selector/
```css
/* Selects an h1 heading with a
paragraph element that immediately follows
the h1 and applies the style to h1 */
h1:has(+ p) {
  margin-bottom: 0;
}
```

It is still outstanding in FF but will be [coming soon]() but it is a standard now, so no harm in supporting it in Greenwood
https://caniuse.com/css-has
![Screen Shot 2023-05-05 at 7 44 48 PM](https://user-images.githubusercontent.com/895923/236585522-8defb58a-999e-48a5-b43f-252fcacb1415.png)

## Details
So will just need to add support for this in our CSS resource plugin and add a test case.

Pull request:
add support for optimizing CSS `:has` / `:is` pseudo-selectors
<!--
## Submitting a Pull Request
We love contributions and appreciate any help you can offer!
-->

## Related Issue
resolves #1106 

So for example, with this HTML
```html
<h1>Heading for :has (should be red)</h1>
<p>Testing :has!</p>

<h1>Heading for :is (should not be red)</h1>
<ol>
  <li>Saturn</li>
  <li>
    <ul>
      <li>Mimas</li>
      <li>Enceladus</li>
      <li>
        <ol>
          <li>Voyager</li>
          <li>Cassini</li>
        </ol>
      </li>
      <li>Tethys</li>
    </ul>
  </li>
  <li>Uranus</li>
  <li>
    <ol>
      <li>Titania</li>
      <li>Oberon</li>
    </ol>
  </li>
</ol>
```

And this CSS (from the MDN page)
```css
h1:has(+ p) {
  color: red;
}

ol {
  list-style-type: upper-alpha;
  color: darkblue;
}

:is(ol, ul, menu:unsupported) :is(ol, ul) {
  color: green;
}

:is(ol, ul) :is(ol, ul) ol {
  list-style-type: lower-greek;
  color: chocolate;
}
```

The styles work as expected in dev and production builds
![Screenshot 2023-11-03 at 7 37 48 PM](https://github.com/ProjectEvergreen/greenwood/assets/895923/471c2bd4-567c-43ae-a26d-5de511399870)
![Screenshot 2023-11-03 at 7 51 25 PM](https://github.com/ProjectEvergreen/greenwood/assets/895923/a612eefb-6ed0-47a9-8948-6fd313598aec)

## Summary of Changes
1. Add support for optimizing [`:has`](https://developer.mozilla.org/en-US/docs/Web/CSS/:has)
1. Add support for optimizing [`:is`](https://developer.mozilla.org/en-US/docs/Web/CSS/:is)
1. Add test case

## TODO
1. [x] Demo / test
1. [x] also need `:is` support?

Patch:
diff --git a/packages/cli/src/plugins/resource/plugin-standard-css.js b/packages/cli/src/plugins/resource/plugin-standard-css.js
index 22b3801f..d52c723e 100644
--- a/packages/cli/src/plugins/resource/plugin-standard-css.js
+++ b/packages/cli/src/plugins/resource/plugin-standard-css.js
@@ -46,6 +46,8 @@ function bundleCss(body, url, projectDirectory) {
 
         switch (name) {
 
+          case 'is':
+          case 'has':
           case 'lang':
           case 'not':
           case 'nth-child':
@@ -153,6 +155,8 @@ function bundleCss(body, url, projectDirectory) {
         case 'PseudoClassSelector':
           switch (node.name) {
 
+            case 'is':
+            case 'has':
             case 'lang':
             case 'not':
             case 'nth-child':


Test patch:
diff --git a/packages/cli/test/cases/build.config.optimization-default/fixtures/expected.css b/packages/cli/test/cases/build.config.optimization-default/fixtures/expected.css
index 5c565df5..5b1bb6ad 100644
--- a/packages/cli/test/cases/build.config.optimization-default/fixtures/expected.css
+++ b/packages/cli/test/cases/build.config.optimization-default/fixtures/expected.css
@@ -54,4 +54,8 @@ a[href*='greenwood'],a[href$='.pdf']{color:orange}
 
 @page {size:8.5in 9in;margin-top:4in;}
 
-@font-feature-values Font One{@styleset {nice-style:12}}
\ No newline at end of file
+@font-feature-values Font One{@styleset {nice-style:12}}
+
+h1:has(+h2){margin:0 0 0.25rem 0}
+
+:is(ol,ul,menu:unsupported) :is(ol,ul){color:green}
\ No newline at end of file
diff --git a/packages/cli/test/cases/build.config.optimization-default/src/styles/main.css b/packages/cli/test/cases/build.config.optimization-default/src/styles/main.css
index 2689da7c..d2836cee 100644
--- a/packages/cli/test/cases/build.config.optimization-default/src/styles/main.css
+++ b/packages/cli/test/cases/build.config.optimization-default/src/styles/main.css
@@ -121,4 +121,12 @@ a[href*="greenwood"], a[href$=".pdf"] {
   @styleset {
     nice-style: 12;
   }
+}
+
+h1:has(+ h2) {
+  margin: 0 0 0.25rem 0;
+}
+
+:is(ol, ul, menu:unsupported) :is(ol, ul) {
+  color: green;
 }
\ No newline at end of file