Changeset 292466 in webkit


Ignore:
Timestamp:
Apr 6, 2022 8:07:06 AM (4 months ago)
Author:
ntim@apple.com
Message:

[:has() pseudo-class] Support invalidation for more input pseudo classes
https://bugs.webkit.org/show_bug.cgi?id=238451

Reviewed by Antti Koivisto.

  • :indeterminate
  • :read-only
  • :read-write
  • :required
  • :optional

LayoutTests/imported/w3c:

Split the test in multiple subtests.

  • web-platform-tests/css/selectors/invalidation/input-pseudo-classes-in-has-expected.txt:
  • web-platform-tests/css/selectors/invalidation/input-pseudo-classes-in-has.html:

Source/WebCore:

  • html/HTMLFormControlElement.cpp:

(WebCore::HTMLFormControlElement::parseAttribute):
(WebCore::HTMLFormControlElement::readOnlyStateChanged):
(WebCore::HTMLFormControlElement::requiredStateChanged):

  • html/HTMLInputElement.cpp:

(WebCore::HTMLInputElement::setIndeterminate):

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r292459 r292466  
     12022-04-06  Tim Nguyen  <ntim@apple.com>
     2
     3        [:has() pseudo-class] Support invalidation for more input pseudo classes
     4        https://bugs.webkit.org/show_bug.cgi?id=238451
     5
     6        Reviewed by Antti Koivisto.
     7
     8        - :indeterminate
     9        - :read-only
     10        - :read-write
     11        - :required
     12        - :optional
     13
     14        Split the test in multiple subtests.
     15
     16        * web-platform-tests/css/selectors/invalidation/input-pseudo-classes-in-has-expected.txt:
     17        * web-platform-tests/css/selectors/invalidation/input-pseudo-classes-in-has.html:
     18
    1192022-04-06  Youenn Fablet  <youenn@apple.com>
    220
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/input-pseudo-classes-in-has-expected.txt

    r292419 r292466  
    11 Check me!
    22
    3 FAIL CSS Selectors Invalidation: input pseudo classes in :has() argument assert_equals: ancestor should be yellowgreen expected "rgb(154, 205, 50)" but got "rgb(0, 128, 0)"
     3PASS :checked & :indeterminate invalidation
     4PASS :disabled invalidation
     5PASS :read-only invalidation
     6PASS :valid invalidation
     7FAIL :default invalidation with input[type=radio] assert_equals: ancestor should be lightblue expected "rgb(173, 216, 230)" but got "rgb(0, 0, 0)"
     8PASS :required invalidation
     9FAIL :out-of-range invalidation assert_equals: ancestor should be darkgreen expected "rgb(0, 100, 0)" but got "rgb(0, 0, 0)"
     10FAIL :placeholder-shown invalidation assert_equals: ancestor should be navy expected "rgb(0, 0, 128)" but got "rgb(0, 0, 0)"
    411
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/input-pseudo-classes-in-has.html

    r292419 r292466  
    66<script src="/resources/testharness.js"></script>
    77<script src="/resources/testharnessreport.js"></script>
    8 <script src="/resources/testdriver.js"></script>
    9 <script src="/resources/testdriver-actions.js"></script>
    10 <script src="/resources/testdriver-vendor.js"></script>
    118<style>
    129  .ancestor:has(#checkme:checked) { color: green }
     
    2825</div>
    2926<script>
    30   test(() => {
     27  test(function() {
     28    this.add_cleanup(() => {
     29      checkme.checked = false;
     30    });
    3131    checkme.checked = false;
    3232    assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)",
     
    3838    assert_equals(getComputedStyle(subject).color, "rgb(154, 205, 50)",
    3939                  "ancestor should be yellowgreen");
     40    const input = checkme;
    4041    checkme.remove();
     42    input.indeterminate = false;
    4143    assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)",
    4244                  "ancestor should be black");
    4345
    44     {
    45       const input = document.createElement('input');
    46       input.id = 'checkme';
    47       input.setAttribute('type', 'checkbox');
    48       input.setAttribute('name', 'my-checkbox');
    49       input.checked = true;
    50       assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)",
    51                     "ancestor should be black");
    52       subject.prepend(input);
    53       assert_equals(getComputedStyle(subject).color, "rgb(0, 128, 0)",
    54                     "ancestor should be green");
    55     }
     46    subject.prepend(input);
     47    checkme.checked = true;
     48    assert_equals(getComputedStyle(subject).color, "rgb(0, 128, 0)",
     49                  "ancestor should be green");
     50  }, ":checked & :indeterminate invalidation");
    5651
     52  test(function() {
     53    this.add_cleanup(() => {
     54      checkme.disabled = false;
     55    });
     56    assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)",
     57                  "ancestor should be black");
    5758    checkme.disabled = true;
    5859    assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 255)",
    5960                  "ancestor should be blue");
     61  }, ":disabled invalidation");
    6062
     63  test(function() {
     64    this.add_cleanup(() => {
     65      textinput.readOnly = false;
     66    });
     67    assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)",
     68                  "ancestor should be black");
    6169    textinput.readOnly = true;
    6270    assert_equals(getComputedStyle(subject).color, "rgb(135, 206, 235)",
    6371                  "ancestor should be skyblue");
    64     textinput.readOnly = false;
     72  }, ":read-only invalidation");
    6573
     74  test(function() {
     75    this.add_cleanup(() => {
     76      textinput.value = "";
     77    });
     78    assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)",
     79                  "ancestor should be black");
     80    textinput.value = "text input";
     81    assert_equals(getComputedStyle(subject).color, "rgb(144, 238, 144)",
     82                  "ancestor should be lightgreen");
     83  }, ":valid invalidation");
     84
     85  test(function() {
     86    this.add_cleanup(() => {
     87      radioinput.removeAttribute("type");
     88    });
     89    assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)",
     90                  "ancestor should be black");
     91    radioinput.type = 'radio';
     92    assert_equals(getComputedStyle(subject).color, "rgb(173, 216, 230)",
     93                  "ancestor should be lightblue");
     94  }, ":default invalidation with input[type=radio]");
     95
     96  test(function() {
     97    this.add_cleanup(() => {
     98      numberinput.required = false;
     99    });
     100    assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)",
     101                  "ancestor should be black");
     102    numberinput.required = true;
     103    assert_equals(getComputedStyle(subject).color, "rgb(255, 192, 203)",
     104                  "ancestor should be pink");
     105  }, ":required invalidation");
     106
     107  test(function() {
     108    this.add_cleanup(() => {
     109      numberinput.value = 5;
     110    });
     111    assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)",
     112                  "ancestor should be black");
     113    numberinput.value = 12;
     114    assert_equals(getComputedStyle(subject).color, "rgb(0, 100, 0)",
     115                  "ancestor should be darkgreen");
     116  }, ":out-of-range invalidation");
     117
     118  test(function() {
     119    this.add_cleanup(() => {
     120      textinput.removeAttribute("placeholder");
     121    });
     122    assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 0)",
     123                  "ancestor should be black");
    66124    textinput.placeholder = 'placeholder text';
    67125    assert_equals(getComputedStyle(subject).color, "rgb(0, 0, 128)",
    68126                  "ancestor should be navy");
    69 
    70     radioinput.type = 'radio';
    71     assert_equals(getComputedStyle(subject).color, "rgb(173, 216, 230)",
    72                   "ancestor should be lightblue");
    73 
    74     textinput.value = "text input";
    75     assert_equals(getComputedStyle(subject).color, "rgb(144, 238, 144)",
    76                   "ancestor should be lightgreen");
    77 
    78     numberinput.value = 12;
    79     assert_equals(getComputedStyle(subject).color, "rgb(0, 100, 0)",
    80                   "ancestor should be darkgreen");
    81 
    82     numberinput.required = true;
    83     assert_equals(getComputedStyle(subject).color, "rgb(255, 192, 203)",
    84                   "ancestor should be pink");
    85 
    86   });
     127  }, ":placeholder-shown invalidation");
    87128</script>
  • trunk/Source/WebCore/ChangeLog

    r292465 r292466  
     12022-04-06  Tim Nguyen  <ntim@apple.com>
     2
     3        [:has() pseudo-class] Support invalidation for more input pseudo classes
     4        https://bugs.webkit.org/show_bug.cgi?id=238451
     5
     6        Reviewed by Antti Koivisto.
     7
     8        - :indeterminate
     9        - :read-only
     10        - :read-write
     11        - :required
     12        - :optional
     13
     14        * html/HTMLFormControlElement.cpp:
     15        (WebCore::HTMLFormControlElement::parseAttribute):
     16        (WebCore::HTMLFormControlElement::readOnlyStateChanged):
     17        (WebCore::HTMLFormControlElement::requiredStateChanged):
     18        * html/HTMLInputElement.cpp:
     19        (WebCore::HTMLInputElement::setIndeterminate):
     20
    1212022-04-06  Alan Bujtas  <zalan@apple.com>
    222
  • trunk/Source/WebCore/html/HTMLFormControlElement.cpp

    r290575 r292466  
    168168        }
    169169    } else if (name == readonlyAttr) {
    170         bool wasReadOnly = m_isReadOnly;
    171         m_isReadOnly = !value.isNull();
    172         if (wasReadOnly != m_isReadOnly)
     170        bool newReadOnly = !value.isNull();
     171        if (m_isReadOnly != newReadOnly) {
     172            Style::PseudoClassChangeInvalidation readOnlyInvalidation(*this, { { CSSSelector::PseudoClassReadOnly, newReadOnly }, { CSSSelector::PseudoClassReadWrite, !newReadOnly } });
     173            m_isReadOnly = newReadOnly;
    173174            readOnlyStateChanged();
     175        }
    174176    } else if (name == requiredAttr) {
    175         bool wasRequired = m_isRequired;
    176         m_isRequired = !value.isNull();
    177         if (wasRequired != m_isRequired)
     177        bool newRequired = !value.isNull();
     178        if (m_isRequired != newRequired) {
     179            Style::PseudoClassChangeInvalidation requiredInvalidation(*this, { { CSSSelector::PseudoClassRequired, newRequired }, { CSSSelector::PseudoClassOptional, !newRequired } });
     180            m_isRequired = newRequired;
    178181            requiredStateChanged();
     182        }
    179183    } else
    180184        HTMLElement::parseAttribute(name, value);
     
    196200{
    197201    updateWillValidateAndValidity();
     202
     203    // Some input pseudo classes like :in-range/out-of-range change based on the readonly state.
     204    // FIXME: Use PseudoClassChangeInvalidation instead for :has() support and more efficiency.
    198205    invalidateStyleForSubtree();
    199206}
     
    202209{
    203210    updateValidity();
    204     // Style recalculation is needed because style selectors may include
    205     // :required and :optional pseudo-classes.
    206     invalidateStyleForSubtree();
    207211}
    208212
  • trunk/Source/WebCore/html/HTMLInputElement.cpp

    r292370 r292466  
    993993        return;
    994994
     995    Style::PseudoClassChangeInvalidation indeterminateInvalidation(*this, CSSSelector::PseudoClassIndeterminate, newValue);
    995996    m_isIndeterminate = newValue;
    996 
    997     invalidateStyleForSubtree();
    998997
    999998    if (renderer() && renderer()->style().hasEffectiveAppearance())
Note: See TracChangeset for help on using the changeset viewer.