| // Copyright 2017 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <memory> |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "third_party/blink/renderer/core/css/properties/longhands.h" |
| #include "third_party/blink/renderer/core/css/style_engine.h" |
| #include "third_party/blink/renderer/core/dom/document.h" |
| #include "third_party/blink/renderer/core/dom/element.h" |
| #include "third_party/blink/renderer/core/dom/element_traversal.h" |
| #include "third_party/blink/renderer/core/dom/node_computed_style.h" |
| #include "third_party/blink/renderer/core/frame/local_frame_view.h" |
| #include "third_party/blink/renderer/core/html/html_div_element.h" |
| #include "third_party/blink/renderer/core/html/html_element.h" |
| #include "third_party/blink/renderer/core/html_names.h" |
| #include "third_party/blink/renderer/core/testing/page_test_base.h" |
| |
| namespace blink { |
| |
| class AffectedByPseudoTest : public PageTestBase { |
| protected: |
| struct ElementResult { |
| const blink::HTMLQualifiedName tag; |
| bool children_or_siblings_affected_by; |
| }; |
| |
| void SetHtmlInnerHTML(const char* html_content); |
| void CheckElementsForFocus(ElementResult expected[], |
| unsigned expected_count) const; |
| |
| enum AffectedByFlagName { |
| kAffectedBySubjectHas, |
| kAffectedByNonSubjectHas, |
| kAncestorsOrAncestorSiblingsAffectedByHas, |
| kSiblingsAffectedByHas, |
| kSiblingsAffectedByHasForSiblingRelationship, |
| kSiblingsAffectedByHasForSiblingDescendantRelationship, |
| kAffectedByPseudoInHas, |
| kAncestorsOrSiblingsAffectedByHoverInHas, |
| kAffectedByLogicalCombinationsInHas |
| }; |
| void CheckAffectedByFlagsForHas( |
| const char* element_id, |
| std::map<AffectedByFlagName, bool> expected) const; |
| }; |
| |
| void AffectedByPseudoTest::SetHtmlInnerHTML(const char* html_content) { |
| GetDocument().documentElement()->setInnerHTML(String::FromUTF8(html_content)); |
| UpdateAllLifecyclePhasesForTest(); |
| } |
| |
| void AffectedByPseudoTest::CheckElementsForFocus( |
| ElementResult expected[], |
| unsigned expected_count) const { |
| unsigned i = 0; |
| HTMLElement* element = GetDocument().body(); |
| |
| for (; element && i < expected_count; |
| element = Traversal<HTMLElement>::Next(*element), ++i) { |
| ASSERT_TRUE(element->HasTagName(expected[i].tag)); |
| DCHECK(element->GetComputedStyle()); |
| ASSERT_EQ(expected[i].children_or_siblings_affected_by, |
| element->ChildrenOrSiblingsAffectedByFocus()); |
| } |
| |
| DCHECK(!element); |
| DCHECK_EQ(i, expected_count); |
| } |
| |
| void AffectedByPseudoTest::CheckAffectedByFlagsForHas( |
| const char* element_id, |
| std::map<AffectedByFlagName, bool> expected) const { |
| bool actual; |
| const char* flag_name = nullptr; |
| for (auto iter : expected) { |
| switch (iter.first) { |
| case kAffectedBySubjectHas: |
| actual = GetElementById(element_id)->AffectedBySubjectHas(); |
| flag_name = "AffectedBySubjectHas"; |
| break; |
| case kAffectedByNonSubjectHas: |
| actual = GetElementById(element_id)->AffectedByNonSubjectHas(); |
| flag_name = "AffectedByNonSubjectHas"; |
| break; |
| case kAncestorsOrAncestorSiblingsAffectedByHas: |
| actual = GetElementById(element_id) |
| ->AncestorsOrAncestorSiblingsAffectedByHas(); |
| flag_name = "AncestorsOrAncestorSiblingsAffectedByHas"; |
| break; |
| case kSiblingsAffectedByHas: |
| actual = GetElementById(element_id)->GetSiblingsAffectedByHasFlags(); |
| flag_name = "SiblingsAffectedByHas"; |
| break; |
| case kSiblingsAffectedByHasForSiblingRelationship: |
| actual = |
| GetElementById(element_id) |
| ->HasSiblingsAffectedByHasFlags( |
| SiblingsAffectedByHasFlags::kFlagForSiblingRelationship); |
| flag_name = "SiblingsAffectedByHasForSiblingRelationship"; |
| break; |
| case kSiblingsAffectedByHasForSiblingDescendantRelationship: |
| actual = GetElementById(element_id) |
| ->HasSiblingsAffectedByHasFlags( |
| SiblingsAffectedByHasFlags:: |
| kFlagForSiblingDescendantRelationship); |
| flag_name = "SiblingsAffectedByHasForSiblingDescendantRelationship"; |
| break; |
| case kAffectedByPseudoInHas: |
| actual = GetElementById(element_id)->AffectedByPseudoInHas(); |
| flag_name = "AffectedByPseudoInHas"; |
| break; |
| case kAncestorsOrSiblingsAffectedByHoverInHas: |
| actual = GetElementById(element_id) |
| ->AncestorsOrSiblingsAffectedByHoverInHas(); |
| flag_name = "AncestorsOrSiblingsAffectedByHoverInHas"; |
| break; |
| case kAffectedByLogicalCombinationsInHas: |
| actual = |
| GetElementById(element_id)->AffectedByLogicalCombinationsInHas(); |
| flag_name = "AffectedByLogicalCombinationsInHas"; |
| break; |
| } |
| DCHECK(flag_name); |
| if (iter.second == actual) { |
| continue; |
| } |
| |
| ADD_FAILURE() << "#" << element_id << " : " << flag_name << " should be " |
| << (iter.second ? "true" : "false") << " but " |
| << (actual ? "true" : "false"); |
| } |
| } |
| |
| // ":focus div" will mark ascendants of all divs with |
| // childrenOrSiblingsAffectedByFocus. |
| TEST_F(AffectedByPseudoTest, FocusedAscendant) { |
| ElementResult expected[] = {{html_names::kBodyTag, true}, |
| {html_names::kDivTag, true}, |
| {html_names::kDivTag, false}, |
| {html_names::kDivTag, false}, |
| {html_names::kSpanTag, false}}; |
| |
| SetHtmlInnerHTML(R"HTML( |
| <head> |
| <style>:focus div { background-color: pink }</style> |
| </head> |
| <body> |
| <div><div></div></div> |
| <div><span></span></div> |
| </body> |
| )HTML"); |
| |
| CheckElementsForFocus(expected, sizeof(expected) / sizeof(ElementResult)); |
| } |
| |
| // "body:focus div" will mark the body element with |
| // childrenOrSiblingsAffectedByFocus. |
| TEST_F(AffectedByPseudoTest, FocusedAscendantWithType) { |
| ElementResult expected[] = {{html_names::kBodyTag, true}, |
| {html_names::kDivTag, false}, |
| {html_names::kDivTag, false}, |
| {html_names::kDivTag, false}, |
| {html_names::kSpanTag, false}}; |
| |
| SetHtmlInnerHTML(R"HTML( |
| <head> |
| <style>body:focus div { background-color: pink }</style> |
| </head> |
| <body> |
| <div><div></div></div> |
| <div><span></span></div> |
| </body> |
| )HTML"); |
| |
| CheckElementsForFocus(expected, sizeof(expected) / sizeof(ElementResult)); |
| } |
| |
| // ":not(body):focus div" should not mark the body element with |
| // childrenOrSiblingsAffectedByFocus. |
| // Note that currently ":focus:not(body)" does not do the same. Then the :focus |
| // is checked and the childrenOrSiblingsAffectedByFocus flag set before the |
| // negated type selector is found. |
| TEST_F(AffectedByPseudoTest, FocusedAscendantWithNegatedType) { |
| ElementResult expected[] = {{html_names::kBodyTag, false}, |
| {html_names::kDivTag, true}, |
| {html_names::kDivTag, false}, |
| {html_names::kDivTag, false}, |
| {html_names::kSpanTag, false}}; |
| |
| SetHtmlInnerHTML(R"HTML( |
| <head> |
| <style>:not(body):focus div { background-color: pink }</style> |
| </head> |
| <body> |
| <div><div></div></div> |
| <div><span></span></div> |
| </body> |
| )HTML"); |
| |
| CheckElementsForFocus(expected, sizeof(expected) / sizeof(ElementResult)); |
| } |
| |
| // Checking current behavior for ":focus + div", but this is a BUG or at best |
| // sub-optimal. The focused element will also in this case get |
| // childrenOrSiblingsAffectedByFocus even if it's really a sibling. Effectively, |
| // the whole sub-tree of the focused element will have styles recalculated even |
| // though none of the children are affected. There are other mechanisms that |
| // makes sure the sibling also gets its styles recalculated. |
| TEST_F(AffectedByPseudoTest, FocusedSibling) { |
| ElementResult expected[] = {{html_names::kBodyTag, false}, |
| {html_names::kDivTag, true}, |
| {html_names::kSpanTag, false}, |
| {html_names::kDivTag, false}}; |
| |
| SetHtmlInnerHTML(R"HTML( |
| <head> |
| <style>:focus + div { background-color: pink }</style> |
| </head> |
| <body> |
| <div> |
| <span></span> |
| </div> |
| <div></div> |
| </body> |
| )HTML"); |
| |
| CheckElementsForFocus(expected, sizeof(expected) / sizeof(ElementResult)); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByFocusUpdate) { |
| // Check that when focussing the outer div in the document below, you only |
| // get a single element style recalc. |
| |
| SetHtmlInnerHTML(R"HTML( |
| <style>:focus { border: 1px solid lime; }</style> |
| <div id=d tabIndex=1> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| |
| GetElementById("d")->Focus(); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| |
| ASSERT_EQ(1U, element_count); |
| } |
| |
| TEST_F(AffectedByPseudoTest, ChildrenOrSiblingsAffectedByFocusUpdate) { |
| // Check that when focussing the outer div in the document below, you get a |
| // style recalc for the whole subtree. |
| |
| SetHtmlInnerHTML(R"HTML( |
| <style>:focus div { border: 1px solid lime; }</style> |
| <div id=d tabIndex=1> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| |
| GetElementById("d")->Focus(); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| |
| ASSERT_EQ(11U, element_count); |
| } |
| |
| TEST_F(AffectedByPseudoTest, InvalidationSetFocusUpdate) { |
| // Check that when focussing the outer div in the document below, you get a |
| // style recalc for the outer div and the class=a div only. |
| |
| SetHtmlInnerHTML(R"HTML( |
| <style>:focus .a { border: 1px solid lime; }</style> |
| <div id=d tabIndex=1> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div class='a'></div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| |
| GetElementById("d")->Focus(); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| |
| ASSERT_EQ(2U, element_count); |
| } |
| |
| TEST_F(AffectedByPseudoTest, NoInvalidationSetFocusUpdate) { |
| // Check that when focussing the outer div in the document below, you get a |
| // style recalc for the outer div only. The invalidation set for :focus will |
| // include 'a', but the id=d div should be affectedByFocus, not |
| // childrenOrSiblingsAffectedByFocus. |
| |
| SetHtmlInnerHTML(R"HTML( |
| <style>#nomatch:focus .a { border: 1px solid lime; }</style> |
| <div id=d tabIndex=1> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div class='a'></div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| |
| GetElementById("d")->Focus(); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| |
| ASSERT_EQ(1U, element_count); |
| } |
| |
| TEST_F(AffectedByPseudoTest, FocusWithinCommonAncestor) { |
| // Check that when changing the focus between 2 elements we don't need a style |
| // recalc for all the ancestors affected by ":focus-within". |
| |
| SetHtmlInnerHTML(R"HTML( |
| <style>div:focus-within { background-color: lime; }</style> |
| <div> |
| <div> |
| <div id=focusme1 tabIndex=1></div> |
| <div id=focusme2 tabIndex=2></div> |
| <div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| |
| GetElementById("focusme1")->Focus(); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| |
| EXPECT_EQ(3U, element_count); |
| |
| start_count += element_count; |
| |
| GetElementById("focusme2")->Focus(); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| |
| // Only "focusme1" & "focusme2" elements need a recalc thanks to the common |
| // ancestor strategy. |
| EXPECT_EQ(2U, element_count); |
| } |
| |
| TEST_F(AffectedByPseudoTest, HoverScrollbar) { |
| SetHtmlInnerHTML( |
| "<style>div::-webkit-scrollbar:hover { color: pink; }</style>" |
| "<div id=div1></div>"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_FALSE(GetElementById("div1")->GetComputedStyle()->AffectedByHover()); |
| } |
| |
| TEST_F(AffectedByPseudoTest, |
| AffectedBySubjectHasAndAncestorsOrAncestorSiblingsAffectedByHas) { |
| SetHtmlInnerHTML(R"HTML( |
| <style>.a:has(.b) { background-color: lime; }</style> |
| <div id=div1> |
| <div id=div2 class='a'> |
| <div id=div3></div> |
| <div id=div4></div> |
| </div> |
| <div id=div5 class='a'> |
| <div id=div6></div> |
| <div id=div7 class='b'></div> |
| </div> |
| <div id=div8> |
| <div id=div9></div> |
| <div id=div10></div> |
| </div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedBySubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div8", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div9", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div10", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div10")->setAttribute(html_names::kClassAttr, |
| AtomicString("b")); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div4")->setAttribute(html_names::kClassAttr, |
| AtomicString("b")); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div6")->setAttribute(html_names::kClassAttr, |
| AtomicString("b")); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div6")->setAttribute(html_names::kClassAttr, g_empty_atom); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div7")->setAttribute(html_names::kClassAttr, g_empty_atom); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedBySubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, |
| AffectedByPseudoInHasAndAncestorsOrSiblingsAffectedByHoverInHas1) { |
| SetHtmlInnerHTML(R"HTML( |
| <style> |
| .a:has(.b:hover) { background-color: lime; } |
| .c:has(:hover) { background-color: green; } |
| .d:has(.e) { background-color: blue } |
| </style> |
| <div id=div1> |
| <div id=div2 class='a'> |
| <div id=div3></div> |
| <div id=div4></div> |
| </div> |
| <div id=div5 class='a'> |
| <div id=div6></div> |
| <div id=div7 class='b'></div> |
| </div> |
| <div id=div8 class='c'> |
| <div id=div9></div> |
| <div id=div10></div> |
| </div> |
| <div id=div11 class='d'> |
| <div id=div12></div> |
| <div id=div13></div> |
| </div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedByPseudoInHas, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedByPseudoInHas, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div8", {{kAffectedByPseudoInHas, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div9", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div10", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div12", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div13", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div3")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| GetElementById("div3")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div4")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| GetElementById("div4")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div4")->setAttribute(html_names::kClassAttr, |
| AtomicString("b")); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedByPseudoInHas, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div3")->setAttribute(html_names::kClassAttr, |
| AtomicString("b")); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedByPseudoInHas, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div3")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| GetElementById("div3")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div4")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| GetElementById("div4")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div3")->setAttribute(html_names::kClassAttr, g_empty_atom); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedByPseudoInHas, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div4")->setAttribute(html_names::kClassAttr, g_empty_atom); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedByPseudoInHas, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div6")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| GetElementById("div6")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div7")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| GetElementById("div7")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div9")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| GetElementById("div9")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div10")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| GetElementById("div10")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div12")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| GetElementById("div12")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div13")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| GetElementById("div13")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| } |
| |
| TEST_F(AffectedByPseudoTest, |
| AffectedByPseudoInHasAndAncestorsOrSiblingsAffectedByHoverInHas2) { |
| SetHtmlInnerHTML(R"HTML( |
| <style> |
| .a:has(.b:hover) .f { background-color: lime; } |
| .c:has(:hover) .g { background-color: green; } |
| .d:has(.e) .h { background-color: blue } |
| </style> |
| <div id=div1> |
| <div id=div2 class='a'> |
| <div id=div3></div> |
| <div id=div4></div> |
| <div><div class='f'></div></div> |
| </div> |
| <div id=div5 class='a'> |
| <div id=div6></div> |
| <div id=div7 class='b'></div> |
| <div><div class='f'></div></div> |
| </div> |
| <div id=div8 class='c'> |
| <div id=div9></div> |
| <div id=div10></div> |
| <div><div class='g'></div></div> |
| </div> |
| <div id=div11 class='d'> |
| <div id=div12></div> |
| <div id=div13></div> |
| <div><div class='h'></div></div> |
| </div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedByPseudoInHas, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedByPseudoInHas, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div8", {{kAffectedByPseudoInHas, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div9", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div10", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div12", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div13", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div3")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| GetElementById("div3")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div4")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| GetElementById("div4")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div4")->setAttribute(html_names::kClassAttr, |
| AtomicString("b")); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedByPseudoInHas, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div3")->setAttribute(html_names::kClassAttr, |
| AtomicString("b")); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedByPseudoInHas, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div3")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| GetElementById("div3")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div4")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| GetElementById("div4")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div3")->setAttribute(html_names::kClassAttr, g_empty_atom); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedByPseudoInHas, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div4")->setAttribute(html_names::kClassAttr, g_empty_atom); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedByPseudoInHas, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedByPseudoInHas, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div6")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| GetElementById("div6")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div7")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| GetElementById("div7")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div9")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| GetElementById("div9")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div10")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| GetElementById("div10")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div12")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| GetElementById("div12")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div13")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| GetElementById("div13")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| } |
| |
| TEST_F(AffectedByPseudoTest, |
| AffectedByNonSubjectHasHasAndAncestorsOrAncestorSiblingsAffectedByHas) { |
| SetHtmlInnerHTML(R"HTML( |
| <style>.a:has(.b) .c { background-color: lime; }</style> |
| <div id=div1> |
| <div id=div2 class='a'> |
| <div id=div3> |
| <div id=div4> |
| <div id=div5></div> |
| </div> |
| <div id=div6 class='b'></div> |
| </div> |
| <div id=div7></div> |
| </div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div7")->setAttribute(html_names::kClassAttr, |
| AtomicString("c")); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedByNonSubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div6")->setAttribute(html_names::kClassAttr, g_empty_atom); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedByNonSubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div5")->setAttribute(html_names::kClassAttr, |
| AtomicString("b")); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedByNonSubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, |
| AffectedByNonSubjectHasHasAndSiblingsAffectedByHas) { |
| SetHtmlInnerHTML(R"HTML( |
| <style>.a:has(~ .b) .c { background-color: lime; }</style> |
| <div id=div1> |
| <div id=div2 class='a'> |
| <div id=div3></div> |
| </div> |
| <div id=div4></div> |
| <div id=div5 class='b'></div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div3")->setAttribute(html_names::kClassAttr, |
| AtomicString("c")); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div5")->setAttribute(html_names::kClassAttr, g_empty_atom); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedBySubjectHasComplexCase1) { |
| SetHtmlInnerHTML(R"HTML( |
| <style>.a:has(.b ~ .c) { background-color: lime; }</style> |
| <div id=div1> |
| <div id=div2 class='a'> |
| <div id=div3></div> |
| <div id=div4> |
| <div id=div5></div> |
| <div id=div6 class='b'></div> |
| <div id=div7></div> |
| <div id=div8 class='c'></div> |
| <div id=div9></div> |
| </div> |
| </div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div2", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div4", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div5", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div6", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div7", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div8", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div9", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div8")->setAttribute(html_names::kClassAttr, g_empty_atom); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div2", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div3", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div4", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div5", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div6", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div7", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div8", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div9", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedBySubjectHasComplexCase2) { |
| SetHtmlInnerHTML(R"HTML( |
| <style>.a:has(~ .b .c) { background-color: lime; }</style> |
| <div id=div1> |
| <div id=div2 class='a'> |
| <div id=div3></div> |
| </div> |
| <div id=div4> |
| <div id=div5></div> |
| </div> |
| <div id=div6 class='b'> |
| <div id=div7></div> |
| <div id=div8> |
| <div id=div9></div> |
| <div id=div10 class='c'></div> |
| </div> |
| </div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div8", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div9", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div10", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div6")->setAttribute(html_names::kClassAttr, g_empty_atom); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div5", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div7", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div8", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div9", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div10", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedBySubjectHasComplexCase3) { |
| SetHtmlInnerHTML(R"HTML( |
| <style>.a:has(.b ~ .c .d) { background-color: lime; }</style> |
| <div id=div1> |
| <div id=div2 class='a'> |
| <div id=div3></div> |
| <div id=div4> |
| <div id=div5></div> |
| <div id=div6 class='b'></div> |
| <div id=div7></div> |
| <div id=div8 class='c'> |
| <div id=div9></div> |
| <div id=div10> |
| <div id=div11></div> |
| <div id=div12 class='d'></div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div2", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div3", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div4", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div5", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div6", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div7", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div8", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div9", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div10", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div12", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div8")->setAttribute(html_names::kClassAttr, g_empty_atom); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div2", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div3", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div4", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div5", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div6", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div7", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div8", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div9", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div10", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div11", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div12", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedBySubjectHasComplexCase4) { |
| SetHtmlInnerHTML(R"HTML( |
| <style>.a:has(~ .b .c ~ .d .e) { background-color: lime; }</style> |
| <div id=div1> |
| <div id=div2 class='a'> |
| <div id=div3></div> |
| </div> |
| <div id=div4> |
| <div id=div5></div> |
| </div> |
| <div id=div6 class='b'> |
| <div id=div7></div> |
| <div id=div8> |
| <div id=div9></div> |
| <div id=div10 class='c'></div> |
| <div id=div11></div> |
| <div id=div12 class='d'> |
| <div id=div13></div> |
| <div id=div14 class='e'></div> |
| </div> |
| </div> |
| </div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div7", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div8", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div9", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div10", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div11", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div12", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div13", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div14", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div6")->setAttribute(html_names::kClassAttr, g_empty_atom); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div5", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div7", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div8", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div9", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div10", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div11", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div12", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div13", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div14", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedBySubjectHasComplexCase5) { |
| SetHtmlInnerHTML(R"HTML( |
| <style>.a:has(~ .b .c) { background-color: lime; }</style> |
| <div id=div1> |
| <div id=div2 class='a'></div> |
| <div id=div3></div> |
| <div id=div4 class='b'> |
| <div id=div5 class='a'></div> |
| <div id=div6></div> |
| <div id=div7 class='b'> |
| <div id=div8 class='a'></div> |
| <div id=div9></div> |
| <div id=div10 class='b'> |
| <div id=div11 class='c'></div> |
| </div> |
| <div id=div12></div> |
| </div> |
| <div id=div13></div> |
| </div> |
| <div id=div14></div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div7", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div8", {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div9", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div10", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div11", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div12", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div13", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div14", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedBySubjectHasComplexCase6) { |
| SetHtmlInnerHTML(R"HTML( |
| <style>.a:has(~ .b .c) { background-color: lime; }</style> |
| <div id=div1> |
| <div id=div2 class='a'></div> |
| <div id=div3></div> |
| <div id=div4 class='b'> |
| <div id=div5 class='a'></div> |
| <div id=div6></div> |
| <div id=div7 class='b'> |
| <div id=div8 class='a'></div> |
| <div id=div9></div> |
| <div id=div10 class='b'> |
| <div id=div11></div> |
| </div> |
| <div id=div12></div> |
| </div> |
| <div id=div13></div> |
| </div> |
| <div id=div14></div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div5", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div6", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div7", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div8", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div9", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div10", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div11", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div12", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div13", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div14", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedBySubjectHasComplexCase7) { |
| SetHtmlInnerHTML(R"HTML( |
| <style>.a:has(+ .b .c) { background-color: lime; }</style> |
| <div id=div1> |
| <div id=div2></div> |
| <div id=div3 class='a'></div> |
| <div id=div4 class='b'> |
| <div id=div5></div> |
| <div id=div6 class='a'></div> |
| <div id=div7 class='b'> |
| <div id=div8></div> |
| <div id=div9 class='a'></div> |
| <div id=div10 class='b'> |
| <div id=div11></div> |
| </div> |
| <div id=div12></div> |
| </div> |
| <div id=div13></div> |
| </div> |
| <div id=div14></div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div5", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div6", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div7", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div8", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div9", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div10", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div11", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div12", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div13", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div14", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByNonSubjectHasComplexCase1) { |
| SetHtmlInnerHTML(R"HTML( |
| <style>.a:has(~ .b .c) .d { background-color: lime; }</style> |
| <div id=div1> |
| <div id=div2 class='a'> |
| <div id=div3></div> |
| </div> |
| <div id=div4> |
| <div id=div5> |
| <div id=div6></div> |
| </div> |
| </div> |
| <div id=div7 class='b'> |
| <div id=div8> |
| <div id=div9 class='c'></div> |
| </div> |
| </div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div8", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div9", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div3")->setAttribute(html_names::kClassAttr, |
| AtomicString("d")); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div8", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div9", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div9")->setAttribute(html_names::kClassAttr, g_empty_atom); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div5", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div6", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div8", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div9", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByNonSubjectHasComplexCase2) { |
| SetHtmlInnerHTML(R"HTML( |
| <style>.a:has(~ .b .c) ~ .d { background-color: lime; }</style> |
| <div id=div1> |
| <div id=div2 class='a'> |
| <div id=div3></div> |
| </div> |
| <div id=div4> |
| <div id=div5> |
| <div id=div6></div> |
| </div> |
| </div> |
| <div id=div7 class='b'> |
| <div id=div8> |
| <div id=div9 class='c'></div> |
| </div> |
| </div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div8", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div9", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div4")->setAttribute(html_names::kClassAttr, |
| AtomicString("d")); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div8", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div9", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div9")->setAttribute(html_names::kClassAttr, g_empty_atom); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div5", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div6", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div8", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div9", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByNonSubjectHasComplexCase3) { |
| SetHtmlInnerHTML(R"HTML( |
| <style>.a:has(~ .b > .c > .d) ~ .e { background-color: lime; }</style> |
| <div id=div1> |
| <div id=div2 class='a'> |
| <div id=div3></div> |
| </div> |
| <div id=div4> |
| <div id=div5> |
| <div id=div6></div> |
| </div> |
| </div> |
| <div id=div7 class='b'> |
| <div id=div8 class='c'> |
| <div id=div9 class='d'> |
| <div id=div10></div> |
| </div> |
| </div> |
| </div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div8", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div9", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div10", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div4")->setAttribute(html_names::kClassAttr, |
| AtomicString("e")); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div8", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div9", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div10", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div8")->setAttribute(html_names::kClassAttr, g_empty_atom); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div5", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div6", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas("div8", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div9", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div10", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedBySelectorQuery) { |
| SetHtmlInnerHTML(R"HTML( |
| <div id=div1> |
| <div id=div2 class='a'> |
| <div id=div3></div> |
| </div> |
| <div id=div4 class='e'> |
| <div id=div5> |
| <div id=div6></div> |
| </div> |
| </div> |
| <div id=div7 class='b'> |
| <div id=div8 class='c'> |
| <div id=div9 class='d'> |
| <div id=div10></div> |
| </div> |
| </div> |
| </div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div8", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div9", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div10", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| StaticElementList* result = GetDocument().QuerySelectorAll( |
| AtomicString(".a:has(~ .b > .c > .d) ~ .e")); |
| ASSERT_EQ(1U, result->length()); |
| EXPECT_EQ(result->item(0)->GetIdAttribute(), "div4"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div6", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div7", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div8", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div9", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div10", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByHasAfterInsertion1) { |
| SetHtmlInnerHTML(R"HTML( |
| <style> |
| .a:has(.b) { color: green; } |
| </style> |
| <div id=div1> |
| <div id=div11 class='a'></div> |
| </div> |
| <div id=div2> |
| <div id=div21> |
| <div id=div211> |
| <div id=div2111></div> |
| </div> |
| <div id=div212 class='b'> |
| <div id=div2121></div> |
| </div> |
| </div> |
| <div id=div22></div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div11", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div21", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div211", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2111", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div212", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2121", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div22", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div21")->setAttribute(html_names::kClassAttr, |
| AtomicString("a")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(1U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div11", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div21", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div211", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2111", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div212", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div2121", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div22", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| auto* subtree_root = MakeGarbageCollected<HTMLDivElement>(GetDocument()); |
| subtree_root->setAttribute(html_names::kIdAttr, AtomicString("div12")); |
| subtree_root->setInnerHTML( |
| String::FromUTF8(R"HTML(<div id=div121></div>)HTML")); |
| GetDocument().getElementById(AtomicString("div1"))->AppendChild(subtree_root); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(2U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div12", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div121", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div11")->setInnerHTML(String::FromUTF8( |
| R"HTML( |
| <div id=div111> |
| <div id=div1111></div> |
| <div id=div1112></div> |
| </div> |
| )HTML")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(3U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas("div111", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div1111", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div1112", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div1112")->setInnerHTML(String::FromUTF8( |
| R"HTML( |
| <div id=div11121> |
| <div id=div111211></div> |
| <div id=div111212 class='b'> |
| <div id=div1112121></div> |
| </div> |
| </div> |
| )HTML")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(5U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas("div11121", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div111211", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div111212", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div1112121", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div2111")->setInnerHTML(String::FromUTF8( |
| R"HTML( |
| <div id=div21111> |
| <div id=div211111></div> |
| </div> |
| )HTML")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(2U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div21111", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div211111", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div2121")->setInnerHTML(String::FromUTF8( |
| R"HTML( |
| <div id=div21211> |
| <div id=div212111></div> |
| </div> |
| )HTML")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(2U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas("div21211", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div212111", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByHasAfterInsertion2) { |
| SetHtmlInnerHTML(R"HTML( |
| <style> |
| .a:has(> .b > .c) { color: green; } |
| </style> |
| <div id=div1> |
| <div id=div11 class='a'></div> |
| </div> |
| <div id=div2> |
| <div id=div21> |
| <div id=div211 class='b'> |
| <div id=div2111 class='c'> |
| <div id=div21111></div> |
| </div> |
| </div> |
| <div id=div212></div> |
| </div> |
| <div id=div22></div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div11", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div21", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div211", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2111", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div21111", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div212", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div22", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div21")->setAttribute(html_names::kClassAttr, |
| AtomicString("a")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(1U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div11", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div21", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div211", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div2111", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div21111", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div212", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div22", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div11")->setInnerHTML(String::FromUTF8( |
| R"HTML( |
| <div id=div111 class='b'> |
| <div id=div1111> |
| <div id=div11111></div> |
| </div> |
| </div> |
| )HTML")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(4U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas("div111", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div1111", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div11111", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| EXPECT_EQ(Color::FromRGB(0, 0, 0), |
| GetElementById("div11")->GetComputedStyle()->VisitedDependentColor( |
| GetCSSPropertyColor())); |
| |
| // There can be some inefficiency for fixed depth :has() argument |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div11111") |
| ->setAttribute(html_names::kClassAttr, AtomicString("c")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(1U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| EXPECT_EQ(Color::FromRGB(0, 0, 0), |
| GetElementById("div11")->GetComputedStyle()->VisitedDependentColor( |
| GetCSSPropertyColor())); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div21111") |
| ->setInnerHTML(String::FromUTF8( |
| R"HTML( |
| <div id=div211111> |
| <div id=div2111111></div> |
| </div> |
| )HTML")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(2U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div211111", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2111111", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div212")->setInnerHTML(String::FromUTF8( |
| R"HTML( |
| <div id=div2121> |
| <div id=div21211> |
| <div id=div212111></div> |
| </div> |
| </div> |
| )HTML")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(3U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas("div2121", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div21211", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div212111", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByHasAfterInsertion3) { |
| SetHtmlInnerHTML(R"HTML( |
| <style> |
| .a:has(~ .b) { color: green; } |
| </style> |
| <div id=div1> |
| <div id=div11 class='a'> |
| <div id=div111></div> |
| </div> |
| </div> |
| <div id=div2> |
| <div id=div21></div> |
| <div id=div22></div> |
| <div id=div23></div> |
| <div id=div24 class='b'></div> |
| <div id=div25></div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div11", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div111", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div21", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div22", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div23", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div24", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div25", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div22")->setAttribute(html_names::kClassAttr, |
| AtomicString("a")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(1U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div11", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div111", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div21", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div22", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div23", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div24", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div25", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div111")->setInnerHTML(String::FromUTF8( |
| R"HTML( |
| <div id=div1111> |
| <div id=div11112 class='b'></div> |
| </div> |
| )HTML")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(2U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1111", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div11112", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| auto* subtree_root = MakeGarbageCollected<HTMLDivElement>(GetDocument()); |
| subtree_root->setAttribute(html_names::kIdAttr, AtomicString("div12")); |
| subtree_root->setInnerHTML(String::FromUTF8(R"HTML( |
| <div id=div121> |
| <div id=div1211></div> |
| <div id=div1212 class='a'> |
| <div id=div12121></div> |
| </div> |
| <div id=div1213></div> |
| <div id=div1214 class='b'></div> |
| <div id=div1215></div> |
| </div> |
| )HTML")); |
| GetDocument().getElementById(AtomicString("div1"))->AppendChild(subtree_root); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(8U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div12", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div121", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div1211", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div1212", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div12121", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div1213", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div1214", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div1215", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByHasAfterInsertion4) { |
| SetHtmlInnerHTML(R"HTML( |
| <style> |
| .a:has(+ .b + .c) { color: green; } |
| </style> |
| <div id=div1> |
| <div id=div11></div> |
| <div id=div13 class='b'></div> |
| <div id=div14></div> |
| <div id=div17></div> |
| <div id=div18></div> |
| <div id=div19></div> |
| </div> |
| <div id=div2> |
| <div id=div21></div> |
| <div id=div22></div> |
| <div id=div23 class='b'> |
| <div id=div231></div> |
| </div> |
| <div id=div24 class='c'></div> |
| <div id=div25></div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div13", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div14", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div17", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div18", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div19", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div21", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div22", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div23", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div24", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div25", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| auto* element = MakeGarbageCollected<HTMLDivElement>(GetDocument()); |
| element->setAttribute(html_names::kIdAttr, AtomicString("div12")); |
| element->setAttribute(html_names::kClassAttr, AtomicString("a")); |
| GetDocument() |
| .getElementById(AtomicString("div1")) |
| ->InsertBefore(element, |
| GetDocument().getElementById(AtomicString("div13"))); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(1U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div12", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div13", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div14", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div17", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| |
| EXPECT_EQ(Color::FromRGB(0, 0, 0), |
| GetElementById("div12")->GetComputedStyle()->VisitedDependentColor( |
| GetCSSPropertyColor())); |
| |
| // There can be some inefficiency for fixed adjacent distance :has() argument |
| start_count = GetStyleEngine().StyleForElementCount(); |
| element = MakeGarbageCollected<HTMLDivElement>(GetDocument()); |
| element->setAttribute(html_names::kIdAttr, AtomicString("div16")); |
| element->setAttribute(html_names::kClassAttr, AtomicString("b c")); |
| GetDocument() |
| .getElementById(AtomicString("div1")) |
| ->InsertBefore(element, |
| GetDocument().getElementById(AtomicString("div17"))); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(2U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| EXPECT_EQ(Color::FromRGB(0, 0, 0), |
| GetElementById("div12")->GetComputedStyle()->VisitedDependentColor( |
| GetCSSPropertyColor())); |
| |
| CheckAffectedByFlagsForHas( |
| "div16", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div17", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div14")->setAttribute(html_names::kClassAttr, |
| AtomicString("c")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(1U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| EXPECT_EQ(Color::FromRGB(0, 128, 0), |
| GetElementById("div12")->GetComputedStyle()->VisitedDependentColor( |
| GetCSSPropertyColor())); |
| |
| CheckAffectedByFlagsForHas( |
| "div16", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div17", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| element = MakeGarbageCollected<HTMLDivElement>(GetDocument()); |
| element->setAttribute(html_names::kIdAttr, AtomicString("div15")); |
| element->setAttribute(html_names::kClassAttr, AtomicString("a")); |
| GetDocument() |
| .getElementById(AtomicString("div1")) |
| ->InsertBefore(element, |
| GetDocument().getElementById(AtomicString("div16"))); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(2U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div12", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div15", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div16", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div17", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div18", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| element = MakeGarbageCollected<HTMLDivElement>(GetDocument()); |
| element->setAttribute(html_names::kIdAttr, AtomicString("div15.5")); |
| GetDocument() |
| .getElementById(AtomicString("div1")) |
| ->InsertBefore(element, |
| GetDocument().getElementById(AtomicString("div16"))); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(3U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div12", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div15", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div15.5", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div22")->setAttribute(html_names::kClassAttr, |
| AtomicString("a")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(1U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div21", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div22", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div23", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div231", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div24", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div25", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByHasAfterInsertion5) { |
| SetHtmlInnerHTML(R"HTML( |
| <style> |
| .a:has(~ .b .c) { color: green; } |
| </style> |
| <div id=div1> |
| <div id=div11 class='a'></div> |
| </div> |
| <div id=div2> |
| <div id=div21 class='a'></div> |
| <div id=div22 class='b'> |
| <div id=div221></div> |
| <div id=div222> |
| <div id=div2221></div> |
| <div id=div2223></div> |
| <div id=div2224 class='b'> |
| <div id=div22241 class='c'></div> |
| </div> |
| <div id=div2225></div> |
| </div> |
| </div> |
| <div id=div25></div> |
| </div> |
| <div id=div3> |
| <div id=div31></div> |
| <div id=div32></div> |
| <div id=div33> |
| <div id=div331></div> |
| </div> |
| <div id=div34></div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div11", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div21", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div22", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div221", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div222", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2221", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2223", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div2224", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div22241", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div2225", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div25", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div31", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div32", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div33", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div331", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div34", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| auto* subtree_root = MakeGarbageCollected<HTMLDivElement>(GetDocument()); |
| subtree_root->setAttribute(html_names::kIdAttr, AtomicString("div12")); |
| subtree_root->setInnerHTML(String::FromUTF8(R"HTML( |
| <div id=div121> |
| <div id=div1211></div> |
| <div id=div1212></div> |
| </div> |
| )HTML")); |
| GetDocument().getElementById(AtomicString("div1"))->AppendChild(subtree_root); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(4U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div12", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div121", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div1211", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div1212", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| |
| EXPECT_EQ(Color::FromRGB(0, 0, 0), |
| GetElementById("div11")->GetComputedStyle()->VisitedDependentColor( |
| GetCSSPropertyColor())); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| subtree_root = MakeGarbageCollected<HTMLDivElement>(GetDocument()); |
| subtree_root->setAttribute(html_names::kIdAttr, AtomicString("div13")); |
| subtree_root->setAttribute(html_names::kClassAttr, AtomicString("b")); |
| subtree_root->setInnerHTML(String::FromUTF8(R"HTML( |
| <div id=div131> |
| <div id=div1311 class='c'></div> |
| <div id=div1312></div> |
| </div> |
| )HTML")); |
| GetDocument().getElementById(AtomicString("div1"))->AppendChild(subtree_root); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(5U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| EXPECT_EQ(Color::FromRGB(0, 128, 0), |
| GetElementById("div11")->GetComputedStyle()->VisitedDependentColor( |
| GetCSSPropertyColor())); |
| |
| CheckAffectedByFlagsForHas( |
| "div12", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div121", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div1211", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div1212", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div13", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div131", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div1311", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div1312", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| subtree_root = MakeGarbageCollected<HTMLDivElement>(GetDocument()); |
| subtree_root->setAttribute(html_names::kIdAttr, AtomicString("div2222")); |
| subtree_root->setAttribute(html_names::kClassAttr, AtomicString("a")); |
| subtree_root->setInnerHTML( |
| String::FromUTF8(R"HTML(<div id=div22221></div>)HTML")); |
| GetDocument() |
| .getElementById(AtomicString("div222")) |
| ->InsertBefore(subtree_root, |
| GetDocument().getElementById(AtomicString("div2223"))); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(2U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div2221", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2222", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div22221", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2223", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div2224", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas("div22241", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2225", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByHasAfterInsertion6) { |
| SetHtmlInnerHTML(R"HTML( |
| <style> |
| .a:has(+ .b + .c .d) { color: green; } |
| </style> |
| <div id=div1> |
| <div id=div11 class='a'></div> |
| </div> |
| <div id=div2> |
| <div id=div21></div> |
| <div id=div22></div> |
| <div id=div23 class='b'></div> |
| <div id=div24 class='c'></div> |
| <div id=div25> |
| <div id=div251></div> |
| </div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div11", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div21", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div22", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div23", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div24", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div25", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div251", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| auto* subtree_root = MakeGarbageCollected<HTMLDivElement>(GetDocument()); |
| subtree_root->setAttribute(html_names::kIdAttr, AtomicString("div12")); |
| subtree_root->setInnerHTML(String::FromUTF8(R"HTML( |
| <div id=div121></div> |
| )HTML")); |
| GetDocument().getElementById(AtomicString("div1"))->AppendChild(subtree_root); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(3U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div12", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div121", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| subtree_root = MakeGarbageCollected<HTMLDivElement>(GetDocument()); |
| subtree_root->setAttribute(html_names::kIdAttr, AtomicString("div13")); |
| subtree_root->setInnerHTML(String::FromUTF8(R"HTML( |
| <div id=div131></div> |
| )HTML")); |
| GetDocument().getElementById(AtomicString("div1"))->AppendChild(subtree_root); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(3U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div13", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div131", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| |
| EXPECT_EQ(Color::FromRGB(0, 0, 0), |
| GetElementById("div11")->GetComputedStyle()->VisitedDependentColor( |
| GetCSSPropertyColor())); |
| |
| // There can be some inefficiency for fixed adjacent distance :has() argument |
| start_count = GetStyleEngine().StyleForElementCount(); |
| subtree_root = MakeGarbageCollected<HTMLDivElement>(GetDocument()); |
| subtree_root->setAttribute(html_names::kIdAttr, AtomicString("div14")); |
| subtree_root->setInnerHTML(String::FromUTF8(R"HTML( |
| <div id=div141 class='d'></div> |
| )HTML")); |
| GetDocument().getElementById(AtomicString("div1"))->AppendChild(subtree_root); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(3U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| EXPECT_EQ(Color::FromRGB(0, 0, 0), |
| GetElementById("div11")->GetComputedStyle()->VisitedDependentColor( |
| GetCSSPropertyColor())); |
| |
| CheckAffectedByFlagsForHas( |
| "div14", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div141", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div22")->setAttribute(html_names::kClassAttr, |
| AtomicString("a")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(1U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div21", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div22", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div23", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div24", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div25", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div251", {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| EXPECT_EQ(Color::FromRGB(0, 0, 0), |
| GetElementById("div22")->GetComputedStyle()->VisitedDependentColor( |
| GetCSSPropertyColor())); |
| |
| // There can be some inefficiency for fixed adjacent distance :has() argument |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div23")->setInnerHTML(String::FromUTF8( |
| R"HTML( |
| <div id=div231 class='d'></div> |
| )HTML")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(2U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div23", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div231", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| |
| EXPECT_EQ(Color::FromRGB(0, 0, 0), |
| GetElementById("div22")->GetComputedStyle()->VisitedDependentColor( |
| GetCSSPropertyColor())); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div24")->setInnerHTML(String::FromUTF8( |
| R"HTML( |
| <div id=div241> |
| <div id=div2411 class='d'></div> |
| </div> |
| )HTML")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(3U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div24", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div241", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2411", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| |
| EXPECT_EQ(Color::FromRGB(0, 128, 0), |
| GetElementById("div22")->GetComputedStyle()->VisitedDependentColor( |
| GetCSSPropertyColor())); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByHasAfterWiping) { |
| SetHtmlInnerHTML(R"HTML( |
| <style> |
| .a:has(.b) { color: green; } |
| </style> |
| <div id='div1' class='a'> |
| <div id='div11'> |
| div11 <div id='div111' class='b'></div> |
| </div> |
| <div id='div12'> |
| div12 <div id='div121' class='b'></div> |
| </div> |
| </div> |
| <div id='div2'> |
| div2 <div id='div21' class='b'></div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div111", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div12", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div121", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div21", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div11")) |
| ->setInnerHTML(String::FromUTF8(R"HTML(div11)HTML")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(0U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div12", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div121", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div21", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div12")) |
| ->setInnerHTML(String::FromUTF8(R"HTML(div12)HTML")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(1U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div12", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div21", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div2")) |
| ->setInnerHTML(String::FromUTF8(R"HTML(div2)HTML")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(0U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div12", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByLogicalCombinationsInHas) { |
| SetHtmlInnerHTML(R"HTML( |
| <style> |
| .a:has(:is(.b .c)) { color: green; } |
| .d:has(:is(.e)) { color: green; } |
| </style> |
| <div id=div1> |
| <div id=div11 class='a'> |
| <div id=div111> |
| <div id=div1111 class='c'></div> |
| </div> |
| </div> |
| <div id=div12 class='d'> |
| <div id=div121> |
| <div id=div1211></div> |
| </div> |
| </div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByLogicalCombinationsInHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div11", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByLogicalCombinationsInHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div111", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div1111", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div12", |
| {{kAffectedBySubjectHas, true}, |
| {kAffectedByLogicalCombinationsInHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div121", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas("div1211", |
| {{kAffectedBySubjectHas, false}, |
| {kAffectedByNonSubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div11")->setAttribute(html_names::kClassAttr, |
| AtomicString("a b")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(1U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div11")->setAttribute(html_names::kClassAttr, |
| AtomicString("a")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(1U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div11")->setAttribute(html_names::kClassAttr, |
| AtomicString("a invalid")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(0U, GetStyleEngine().StyleForElementCount() - start_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div12")->setAttribute(html_names::kClassAttr, |
| AtomicString("d e")); |
| UpdateAllLifecyclePhasesForTest(); |
| EXPECT_EQ(0U, GetStyleEngine().StyleForElementCount() - start_count); |
| } |
| |
| TEST_F(AffectedByPseudoTest, |
| AncestorsOrSiblingsAffectedByHoverInHasWithFastRejection) { |
| SetHtmlInnerHTML(R"HTML( |
| <style> |
| .a:has(nonexistent), .a:has(.b:hover) { color: green } |
| </style> |
| <div id=div1 class='a'> |
| <div id=div11></div> |
| <div id=div12 class='b'></div> |
| <div id=div13></div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, true}, |
| {kAffectedByPseudoInHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div12", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div13", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div13")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| GetElementById("div13")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div12")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| GetElementById("div12")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByHasAfterRemoval1) { |
| SetHtmlInnerHTML(R"HTML( |
| <style> |
| .a:has(.b) { color: green } |
| </style> |
| <div id=div1 class='a'> |
| <div id=div11></div> |
| <div id=div12 class='b'> |
| <div id=div121 class='b'></div> |
| </div> |
| <div id=div13 class='b'></div> |
| <div id=div14 class='b'></div> |
| <div id=div15></div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div12", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div121", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div13", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div14", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div15", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div12")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div121"))); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div12", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div13", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div14", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div1")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div12"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div13", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div14", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div1")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div14"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div13", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div1")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div13"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByHasAfterRemoval2) { |
| SetHtmlInnerHTML(R"HTML( |
| <style> |
| .a:has(> .b > .c) { color: green } |
| </style> |
| <div id=div1 class='a'> |
| <div id=div11></div> |
| <div id=div12 class='b'> |
| <div id=div121 class='c'></div> |
| <div id=div122 class='c'></div> |
| </div> |
| <div id=div13 class='b'> |
| <div id=div131 class='c'></div> |
| <div id=div132 class='c'></div> |
| <div id=div133 class='c'></div> |
| <div id=div134></div> |
| </div> |
| <div id=div14></div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div12", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div121", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div122", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div13", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div131", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div132", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div133", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div134", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div14", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div1")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div14"))); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div13")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div134"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div13")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div131"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div13")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div133"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div12", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div121", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div122", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div13", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div132", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div1")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div13"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div12", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div121", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div122", {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div12")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div121"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByHasAfterRemoval3) { |
| SetHtmlInnerHTML(R"HTML( |
| <style> |
| .a:has(~ .b) { color: green } |
| </style> |
| <div id=div1> |
| <div id=div11 class='a'> |
| <div id=div111 class='a'></div> |
| <div id=div112 class='b'></div> |
| <div id=div113 class='b'></div> |
| <div id=div114></div> |
| </div> |
| <div id=div12> |
| <div id=div121 class='b'></div> |
| <div id=div122 class='b'></div> |
| </div> |
| <div id=div13> |
| <div id=div131></div> |
| </div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedBySubjectHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div111", {{kAffectedBySubjectHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div112", {{kAffectedBySubjectHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div113", {{kAffectedBySubjectHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div114", {{kAffectedBySubjectHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div12", {{kAffectedBySubjectHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div121", {{kAffectedBySubjectHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div122", {{kAffectedBySubjectHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div13", {{kAffectedBySubjectHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div131", {{kAffectedBySubjectHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div11")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div114"))); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div11")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div112"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div11")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div113"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div12")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div122"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div1")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div13"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div1")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div12"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByHasAfterRemoval4) { |
| SetHtmlInnerHTML(R"HTML( |
| <style> |
| .a:has(+ .b + .c) { color: green } |
| </style> |
| <div id=div1> |
| <div id=div11 class='a'> |
| <div id=div111 class='a'></div> |
| <div id=div112 class='b'></div> |
| <div id=div113 class='c'></div> |
| <div id=div114 class='c'></div> |
| <div id=div115 class='c'></div> |
| <div id=div116></div> |
| </div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div11", {{kAffectedBySubjectHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div111", {{kAffectedBySubjectHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div112", {{kAffectedBySubjectHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div113", {{kAffectedBySubjectHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div114", {{kAffectedBySubjectHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div115", {{kAffectedBySubjectHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div116", {{kAffectedBySubjectHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div11")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div115"))); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div11")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div113"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div114", {{kAffectedBySubjectHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div116", {{kAffectedBySubjectHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div11")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div116"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div11")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div114"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByHasAfterRemoval5) { |
| SetHtmlInnerHTML(R"HTML( |
| <style> |
| .a:has(~ .b .c) { color: green } |
| </style> |
| <div id=div1> |
| <div id=div11 class='a'> |
| <div id=div111 class='c'></div> |
| </div> |
| <div id=div12> |
| <div id=div121></div> |
| <div id=div122 class='c'></div> |
| </div> |
| <div id=div13> |
| <div id=div131 class='c'></div> |
| </div> |
| <div id=div14 class='b'> |
| <div id=div141></div> |
| <div id=div142 class='c'></div> |
| <div id=div143 class='c'></div> |
| </div> |
| <div id=div15 class='b'> |
| <div id=div151 class='c'></div> |
| <div id=div152></div> |
| </div> |
| <div id=div16 class='b'> |
| <div id=div161 class='c'></div> |
| </div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div11", |
| {{kAffectedBySubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div111", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div12", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div121", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div122", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div13", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div131", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div14", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div141", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div142", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div143", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div15", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div151", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div152", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div16", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div161", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div11")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div111"))); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div12")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div122"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div1")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div12"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div1")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div13"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div11", |
| {{kAffectedBySubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div14", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div141", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div142", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div143", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div15", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div151", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div152", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div16", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div161", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div1")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div16"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div143", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div15", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div151", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div152", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div15")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div152"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div15")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div151"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div14", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div141", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div142", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div143", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div15", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div14")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div142"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByHasAfterRemoval6) { |
| SetHtmlInnerHTML(R"HTML( |
| <style> |
| .a:has(+ .b > .c) { color: green } |
| </style> |
| <div id=div1> |
| <div id=div11 class='a'></div> |
| <div id=div12 class='b'> |
| <div id=div121></div> |
| <div id=div122 class='c'> |
| <div id=div1221 class='c'></div> |
| </div> |
| </div> |
| <div id=div13 class='b'> |
| <div id=div131></div> |
| <div id=div132 class='c'></div> |
| </div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div11", |
| {{kAffectedBySubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div12", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div121", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div122", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div1221", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div13", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div131", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div132", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div122")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div1221"))); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetDocument() |
| .getElementById(AtomicString("div1")) |
| ->RemoveChild(GetDocument().getElementById(AtomicString("div12"))); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(1U, element_count); |
| |
| CheckAffectedByFlagsForHas( |
| "div1", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div11", |
| {{kAffectedBySubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div13", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, true}}); |
| CheckAffectedByFlagsForHas( |
| "div131", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, false}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| CheckAffectedByFlagsForHas( |
| "div132", |
| {{kAffectedBySubjectHas, false}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByHasWithoutNth) { |
| SetHtmlInnerHTML(R"HTML( |
| <style> |
| #root:has(.foo) { background-color: green } |
| :nth-child(1000) * { background-color: red } |
| </style> |
| <div id="root"> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div></div> |
| <div id="foo"></div> |
| </div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| |
| CheckAffectedByFlagsForHas( |
| "root", |
| {{kAffectedBySubjectHas, true}, |
| {kAncestorsOrAncestorSiblingsAffectedByHas, true}, |
| {kSiblingsAffectedByHasForSiblingDescendantRelationship, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| Element* foo = GetElementById("foo"); |
| foo->setAttribute(html_names::kClassAttr, AtomicString("foo")); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| |
| ASSERT_EQ(GetStyleEngine().StyleForElementCount() - start_count, 1U); |
| } |
| |
| TEST_F(AffectedByPseudoTest, AffectedByPseudoInHasWithNestingParent) { |
| SetHtmlInnerHTML(R"HTML( |
| <style> |
| .b:hover { |
| .a:has(~ &) { background-color: green; } |
| } |
| </style> |
| <div id=div1></div> |
| <div id=div2 class='a'></div> |
| <div id=div3></div> |
| <div id=div4 class='b'></div> |
| <div id=div5></div> |
| )HTML"); |
| |
| UpdateAllLifecyclePhasesForTest(); |
| CheckAffectedByFlagsForHas( |
| "div1", {{kAffectedBySubjectHas, false}, |
| {kAffectedByPseudoInHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, false}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div2", {{kAffectedBySubjectHas, true}, |
| {kAffectedByPseudoInHas, true}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div3", {{kAffectedBySubjectHas, false}, |
| {kAffectedByPseudoInHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| CheckAffectedByFlagsForHas( |
| "div4", {{kAffectedBySubjectHas, false}, |
| {kAffectedByPseudoInHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, true}}); |
| CheckAffectedByFlagsForHas( |
| "div5", {{kAffectedBySubjectHas, false}, |
| {kAffectedByPseudoInHas, false}, |
| {kSiblingsAffectedByHasForSiblingRelationship, true}, |
| {kAncestorsOrSiblingsAffectedByHoverInHas, false}}); |
| |
| unsigned start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div3")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| unsigned element_count = |
| GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(0U, element_count); |
| GetElementById("div3")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| |
| start_count = GetStyleEngine().StyleForElementCount(); |
| GetElementById("div4")->SetHovered(true); |
| UpdateAllLifecyclePhasesForTest(); |
| element_count = GetStyleEngine().StyleForElementCount() - start_count; |
| ASSERT_EQ(2U, element_count); |
| GetElementById("div4")->SetHovered(false); |
| UpdateAllLifecyclePhasesForTest(); |
| } |
| |
| } // namespace blink |