Ver Fonte

LibHTML: Implement immediate-child selectors (#foo > #bar)

Andreas Kling há 5 anos atrás
pai
commit
cad326f323

+ 17 - 0
Base/home/anon/www/selectors.html

@@ -11,6 +11,10 @@
     border-width: 1;
     border-width: 1;
     border-color: #00ff00;
     border-color: #00ff00;
 }
 }
+div > .boo > .bee {
+    background-color: #000000;
+    color: #ff00ff;
+}
 </style>
 </style>
 </head>
 </head>
 <body>
 <body>
@@ -28,5 +32,18 @@
             <div>hello</div>
             <div>hello</div>
         </div>
         </div>
     </div>
     </div>
+    <div>
+        <div class="boo">
+            <div class="bee">Spooky!</div>
+        </div>
+    </div>
+    <div>
+        <div class="boo">
+            <div>
+                <div class="bee">
+                    Not spooky!
+                </div>
+            </div>
+        </div>
 </body>
 </body>
 </html>
 </html>

+ 8 - 2
Libraries/LibHTML/CSS/StyleResolver.cpp

@@ -34,9 +34,10 @@ static bool matches(const Selector& selector, int component_index, const Element
     auto& component = selector.components()[component_index];
     auto& component = selector.components()[component_index];
     if (!matches(component, element))
     if (!matches(component, element))
         return false;
         return false;
-    if (component.relation == Selector::Component::Relation::None)
+    switch (component.relation) {
+    case Selector::Component::Relation::None:
         return true;
         return true;
-    if (component.relation == Selector::Component::Relation::Descendant) {
+    case Selector::Component::Relation::Descendant:
         ASSERT(component_index != 0);
         ASSERT(component_index != 0);
         for (auto* ancestor = element.parent(); ancestor; ancestor = ancestor->parent()) {
         for (auto* ancestor = element.parent(); ancestor; ancestor = ancestor->parent()) {
             if (!ancestor->is_element())
             if (!ancestor->is_element())
@@ -45,6 +46,11 @@ static bool matches(const Selector& selector, int component_index, const Element
                 return true;
                 return true;
         }
         }
         return false;
         return false;
+    case Selector::Component::Relation::ImmediateChild:
+        ASSERT(component_index != 0);
+        if (!element.parent() || !element.parent()->is_element())
+            return false;
+        return matches(selector, component_index - 1, static_cast<const Element&>(*element.parent()));
     }
     }
     ASSERT_NOT_REACHED();
     ASSERT_NOT_REACHED();
 }
 }