<!DOCTYPE html>
<title>@scope - nesting (&)</title>
<link rel="help" href="https://drafts.csswg.org/css-cascade-6/#scope-atrule">
<link rel="help" href="https://drafts.csswg.org/css-nesting-1/#nest-selector">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/9740">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<main id=main></main>

<template id=test_nest_scope_end>
  <div>
    <style>
      /* (& > .b) behaves like (:where(:scope) > .b), due & mapping to :where(:scope).*/
      @scope (.a) to (& > .b) {
        :scope { z-index:1; }
      }

      /* Should not match, since <scope-end> refers to the scope itself. */
      @scope (.a) to (.b&) {
        :scope { z-index:42; }
      }
    </style>
    <div class="a b">
      <div class=b>
        <div id=below></div>
      </div>
    </div>
  </div>
  <div id=outside></div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_nest_scope_end.content.cloneNode(true));
  let a = document.querySelector('.a');
  let b = document.querySelector('.a > .b');
  assert_equals(getComputedStyle(a).zIndex, '1');
  assert_equals(getComputedStyle(b).zIndex, 'auto');
  assert_equals(getComputedStyle(below).zIndex, 'auto');
  assert_equals(getComputedStyle(outside).zIndex, 'auto');
}, 'Nesting-selector in <scope-end>');
</script>

<template id=test_nest_scope_end_implicit_scope>
  <div>
    <style>
      /* (.b) behaves like (:scope .b), due :scope being prepended
          implicitly. */
      @scope (.a) to (.b) {
        :scope { z-index:1; }
      }

      /* Should not match, since <scope-end> refers to the scope itself. */
      @scope (.a) to (.b:scope) {
        :scope { z-index:42; }
      }
    </style>
    <div class="a b">
      <div class=b>
        <div id=below></div>
      </div>
    </div>
  </div>
  <div id=outside></div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_nest_scope_end_implicit_scope.content.cloneNode(true));
  let a = document.querySelector('.a');
  let b = document.querySelector('.a > .b');
  assert_equals(getComputedStyle(a).zIndex, '1');
  assert_equals(getComputedStyle(b).zIndex, 'auto');
  assert_equals(getComputedStyle(below).zIndex, 'auto');
  assert_equals(getComputedStyle(outside).zIndex, 'auto');
}, 'Implicit :scope in <scope-end>');
</script>

<template id=test_relative_selector_scope_end>
  <div>
    <style>
      @scope (.a) to (> .b) {
        *, :scope { z-index:1; }
      }
    </style>
    <div class="a b">
      <div class=b>
        <div id=below></div>
      </div>
    </div>
  </div>
  <div id=outside></div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_relative_selector_scope_end.content.cloneNode(true));
  let a = document.querySelector('.a');
  let b = document.querySelector('.a > .b');
  assert_equals(getComputedStyle(a).zIndex, '1');
  assert_equals(getComputedStyle(b).zIndex, 'auto');
  assert_equals(getComputedStyle(below).zIndex, 'auto');
  assert_equals(getComputedStyle(outside).zIndex, 'auto');
}, 'Relative selectors in <scope-end>');
</script>

<template id=test_inner_nest>
  <div>
    <style>
      @scope (#div) {
        & {
          z-index: 1;
          & {
            z-index: 2;
          }
        }
      }
    </style>
    <div id=div></div>
  </div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_inner_nest.content.cloneNode(true));

  assert_equals(getComputedStyle(div).zIndex, '2');
}, 'Nested nesting-selectors within scope\'s <stylesheet> select inclusive descendants of the scope root');
</script>

<template id=test_parent_in_pseudo_scope>
  <div>
    <style>
      @scope (#div) {
        :scope {
          z-index: 1;
          & {
            z-index: 2;
          }
        }
      }
    </style>
    <div id=div></div>
  </div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_parent_in_pseudo_scope.content.cloneNode(true));

  assert_equals(getComputedStyle(div).zIndex, '2');
}, 'Nesting-selector within :scope rule');
</script>

<template id=test_parent_in_pseudo_scope_double>
  <div>
    <style>
      @scope (#div) {
        :scope {
          z-index: 1;
          & {
            & {
              z-index: 2;
            }
          }
        }
      }
    </style>
    <div id=div></div>
  </div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_parent_in_pseudo_scope_double.content.cloneNode(true));

  assert_equals(getComputedStyle(div).zIndex, '2');
}, 'Nesting-selector within :scope rule (double nested)');
</script>

<template id=test_scope_within_style_rule>
  <div>
    <style>
      .a {
        @scope (.b) {
          .c { z-index: 1; }
        }
      }
    </style>
    <div class=a>
      <div class=b>
        <div class=c>
        </div>
      </div>
      <div id=out_of_scope class=c>
      </div>
    </div>
  </div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_scope_within_style_rule.content.cloneNode(true));

  let c = document.querySelector('.c');
  assert_equals(getComputedStyle(c).zIndex, '1');
  assert_equals(getComputedStyle(out_of_scope).zIndex, 'auto');
}, '@scope nested within style rule');
</script>

<template id=test_parent_pseudo_in_nested_scope_start>
  <div>
    <style>
      .a {
        @scope (&.b) {
          :scope { z-index: 1; }
        }
      }
    </style>
    <div class=a></div>
    <div class=b></div>
    <div class="a b"></div>
  </div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_parent_pseudo_in_nested_scope_start.content.cloneNode(true));

  let a = document.querySelector('.a:not(.b)');
  let b = document.querySelector('.b:not(.a)');
  let ab = document.querySelector('.a.b');
  assert_equals(getComputedStyle(a).zIndex, 'auto');
  assert_equals(getComputedStyle(b).zIndex, 'auto');
  assert_equals(getComputedStyle(ab).zIndex, '1');
}, 'Parent pseudo class within scope-start');
</script>


<template id=test_parent_pseudo_in_nested_scope_body>
  <div>
    <style>
      .a {
        @scope (.b) {
           /* The & points to <scope-start>, which contains an implicit &
              which points to .a. */
           &.c { z-index: 1; }
        }
      }
    </style>
    <div class=a>
      <div class=b>
        <div class="c"></div>
        <div class="a c"></div>
        <div class="a b c" matching></div>
      </div>
    </div>
    <div>
      <div class=a></div>
      <div class=b></div>
      <div class=c></div>
      <div class="a b"></div>
      <div class="a c"></div>
      <div class="b c"></div>
    </div>
  </div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_parent_pseudo_in_nested_scope_body.content.cloneNode(true));

  let matching = main.querySelectorAll("div[matching]");
  let non_matching = main.querySelectorAll("div:not([matching])");

  for (let m of matching) {
    assert_equals(getComputedStyle(m).zIndex, '1', `matching: ${m.nodeName}${m.className}`);
  }
  for (let m of non_matching) {
    assert_equals(getComputedStyle(m).zIndex, 'auto', `non-matching: ${m.nodeName}${m.className}`);
  }
}, 'Parent pseudo class within body of nested @scope');
</script>

<template id=test_direct_declarations_in_nested_scope>
  <div>
    <style>
      .a {
        @scope (.b) {
          z-index: 1;
        }
      }
    </style>
    <div class=a>
      <div class=b>
        <div class="c"></div>
      </div>
    </div>
  </div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_direct_declarations_in_nested_scope.content.cloneNode(true));

  let a = document.querySelector('.a');
  let b = document.querySelector('.b');
  let c = document.querySelector('.c');
  assert_equals(getComputedStyle(a).zIndex, 'auto');
  assert_equals(getComputedStyle(b).zIndex, '1');
  assert_equals(getComputedStyle(c).zIndex, 'auto');
}, 'Implicit rule within nested @scope ');
</script>

<template id=test_direct_declarations_in_nested_scope_proximity>
  <div>
    <style>
      .a {
        /* The '& .b' selector is wrapped in :where() to prevent a false
           positive when the implementation incorrectly wraps
           the z-index declaration in a rule with &-behavior
           rather than :where(:scope)-behavior. */
        @scope (:where(& .b)) {
          z-index: 1; /* Should win due to proximity */
        }
      }
      :where(.b) { z-index: 2; }
    </style>
    <div class=a>
      <div class="b x">
        <div class=c>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_direct_declarations_in_nested_scope_proximity.content.cloneNode(true));

  let a = document.querySelector('.a');
  let b = document.querySelector('.b');
  let c = document.querySelector('.c');
  assert_equals(getComputedStyle(a).zIndex, 'auto');
  assert_equals(getComputedStyle(b).zIndex, '1');
  assert_equals(getComputedStyle(c).zIndex, 'auto');
}, 'Implicit rule within nested @scope (proximity)');
</script>

<template id=test_nested_scope_inside_an_is>
  <div>
    <style>
      @scope (.a) {
        .b {
          /* When nesting, because we’re  inside a defined scope,
             the `:scope` should reference the scoping root node properly, and
             check for the presence of an extra class on it, essentially
             being equal to `:scope.x .b { z-index: 1 }`. */
          &:is(:scope.x *) {
            z-index: 1;
          }
          /* This should not match, as we have a defined scope, and should
             not skip to the root. */
          &:is(:root:scope *) {
            z-index: 2;
          }
        }
        /* The nested case can be though of the following when expanded: */
        .c:is(:scope.x *) {
          z-index: 3;
        }
      }
    </style>
    <div class="b">
    </div>
    <div class="a x">
      <div class="b">
      </div>
      <div class="c">
      </div>
    </div>
</div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_nested_scope_inside_an_is.content.cloneNode(true));

  let b_outside = document.querySelector('.b');
  let b_inside = document.querySelector('.a .b');
  let c = document.querySelector('.c');
  assert_equals(getComputedStyle(b_outside).zIndex, 'auto');
  assert_equals(getComputedStyle(b_inside).zIndex, '1');
  assert_equals(getComputedStyle(c).zIndex, '3');
}, 'Nested :scope inside an :is');
</script>

<template id=test_nested_scope_pseudo>
  <div>
    <style>
      @scope (.b) {
        .a:not(:scope) {
          & :scope {
            z-index: 1;
          }
        }
      }
    </style>
    <div class="b">
    </div>
    <div class="a">
      <div class="b">
      </div>
    </div>
</div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_nested_scope_pseudo.content.cloneNode(true));

  let b_outside = document.querySelector('.b');
  let b_inside = document.querySelector('.a .b');
  assert_equals(getComputedStyle(b_outside).zIndex, 'auto');
  assert_equals(getComputedStyle(b_inside).zIndex, '1');
}, ':scope within nested and scoped rule');
</script>

<template id=test_nested_scope_pseudo_implied>
  <div>
    <style>
      @scope (.b) {
        .a:not(:scope) {
          :scope { /* & implied */
            z-index: 1;
          }
        }
      }
    </style>
    <div class="b">
    </div>
    <div class="a">
      <div class="b">
      </div>
    </div>
</div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_nested_scope_pseudo_implied.content.cloneNode(true));

  let b_outside = document.querySelector('.b');
  let b_inside = document.querySelector('.a .b');
  assert_equals(getComputedStyle(b_outside).zIndex, 'auto');
  assert_equals(getComputedStyle(b_inside).zIndex, '1');
}, ':scope within nested and scoped rule (implied &)');
</script>

<template id=test_nested_scope_pseudo_relative>
  <div>
    <style>
      @scope (.b) {
        .a:not(:scope) {
          > :scope { /* & implied */
            z-index: 1;
          }
        }
      }
    </style>
    <div class="b">
    </div>
    <div class="a">
      <div class="b">
      </div>
    </div>
</div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_nested_scope_pseudo_relative.content.cloneNode(true));

  let b_outside = document.querySelector('.b');
  let b_inside = document.querySelector('.a .b');
  assert_equals(getComputedStyle(b_outside).zIndex, 'auto');
  assert_equals(getComputedStyle(b_inside).zIndex, '1');
}, ':scope within nested and scoped rule (relative)');
</script>

<template id=test_scoped_nested_group_rule>
  <div>
    <style>
      @scope (.a) {
        .b:not(:scope) {
          @media (width) {
            z-index: 1;
          }
        }
      }
    </style>
    <div class="b">
    </div>
    <div class="a">
      <div class="b">
      </div>
    </div>
</div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_scoped_nested_group_rule.content.cloneNode(true));

  let b_outside = document.querySelector('.b');
  let b_inside = document.querySelector('.a .b');
  assert_equals(getComputedStyle(b_outside).zIndex, 'auto');
  assert_equals(getComputedStyle(b_inside).zIndex, '1');
}, 'Scoped nested group rule');
</script>

<template id=test_scoped_within_scoped>
  <div>
    <style>
      @scope (.a) {
        @scope(#descendant) {
          :scope {
            z-index: 1;
          }
        }
        @scope (> #child) {
          :scope {
            z-index: 1;
          }
        }
      }
    </style>
    <div class="a">
      <div id="descendant">
      </div>
      <div id="child">
      </div>
    </div>
</div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_scoped_within_scoped.content.cloneNode(true));

  assert_equals(getComputedStyle(descendant).zIndex, '1');
  assert_equals(getComputedStyle(child).zIndex, '1');
}, 'Scoped nested within another scope');
</script>

<template id=test_implicit_scope_nested_group_rule>
  <div class=nest>
    <style>
      .nest {
        @scope {
          #child {
            color: green;
          }
        }
      }
    </style>
    <div id=child>Foo</div>
</div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_implicit_scope_nested_group_rule.content.cloneNode(true));
  assert_equals(getComputedStyle(child).color, 'rgb(0, 128, 0)');
}, 'Implicit (prelude-less) @scope as a nested group rule');
</script>

<template id=test_insert_ampersand_rule_within_scope>
<style>
  .a {
    @scope (.b) {
      #child {
        color: red;
      }
    }
  }
</style>
<div class=a>
  <div class=b>
    <div id=child>Foo</div>
  </div>
</div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_insert_ampersand_rule_within_scope.content.cloneNode(true));
  assert_equals(getComputedStyle(child).color, 'rgb(255, 0, 0)');
  let scope_rule = main.querySelector('style').sheet.cssRules[0].cssRules[0];
  // & does not add specificity - inserting it up front does nothing...
  scope_rule.insertRule('& #child { color: green; }', 0);
  assert_equals(getComputedStyle(child).color, 'rgb(255, 0, 0)');
  scope_rule.deleteRule(0);
  // ... But inserting it at the end makes it win by order of appearance.
  scope_rule.insertRule('& #child { color: green; }', scope_rule.cssRules.length);
  assert_equals(getComputedStyle(child).color, 'rgb(0, 128, 0)');
}, 'Insert a nested style rule within @scope, &');
</script>

<template id=test_insert_pseudo_scope_rule_within_scope>
<style>
  .a {
    @scope (.b) {
      #child {
        color: red;
      }
    }
  }
</style>
<div class=a>
  <div class=b>
    <div id=child>Foo</div>
  </div>
</div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_insert_pseudo_scope_rule_within_scope.content.cloneNode(true));
  assert_equals(getComputedStyle(child).color, 'rgb(255, 0, 0)');
  let scope_rule = main.querySelector('style').sheet.cssRules[0].cssRules[0];
  scope_rule.insertRule(':scope #child { color: green; }');
  assert_equals(getComputedStyle(child).color, 'rgb(0, 128, 0)');
}, 'Insert a nested style rule within @scope, :scope');
</script>

<template id=test_insert_nested_declarations_directly>
<style>
  :where(.a) {
    color: red;
  }
  @scope (.a) {
  }
</style>
<div class=a>
  <div id=child>Foo</div>
</div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_insert_nested_declarations_directly.content.cloneNode(true));
  assert_equals(getComputedStyle(child).color, 'rgb(255, 0, 0)');
  let scope_rule = main.querySelector('style').sheet.cssRules[1];
  assert_true(scope_rule instanceof CSSScopeRule);
  scope_rule.insertRule('color: green');
  assert_true(scope_rule.cssRules[0] instanceof CSSNestedDeclarations);
  assert_equals(getComputedStyle(child).color, 'rgb(0, 128, 0)');
}, 'Insert a CSSNestedDeclarations rule directly in top-level @scope');
</script>

<template id=test_mutate_outer_selector_text_nested_declaration>
<style>
  #child {
    color: green; /* Specificity: (1, 0, 0) */
  }
  .b {
    #child {
      @scope (&) {
        --x: 1;
        color: red; /* Specificity: (0, 0, 0), effectively :where(:scope) */
      }
    }
  }
</style>
<div class=a>
  <div id=child>Foo</div>
</div>
</template>
<script>
test((t) => {
  t.add_cleanup(() => main.replaceChildren());
  main.append(test_mutate_outer_selector_text_nested_declaration.content.cloneNode(true));
  assert_equals(getComputedStyle(child).color, 'rgb(0, 128, 0)');
  assert_equals(getComputedStyle(child).getPropertyValue('--x'), '');

  let outer_rule = main.querySelector('style').sheet.cssRules[1];
  assert_equals(outer_rule.selectorText, '.b');
  outer_rule.selectorText = '.a';

  assert_equals(getComputedStyle(child).color, 'rgb(0, 128, 0)'); // Unchanged.
  assert_equals(getComputedStyle(child).getPropertyValue('--x'), '1'); // Changed.
}, 'Mutating selectorText on outer style rule causes correct inner specificity');
</script>
