[gxml: 1/4] CSS Selectors : Improve and fix selection. - add ', ' to invalid char array for identifiers, so AND



commit 4c3de37613bc969ab2d7a0803892990fd08d4586
Author: BZHDeveloper <inizan yannick gmail com>
Date:   Mon Jun 24 01:19:25 2019 +0200

    CSS Selectors : Improve and fix selection.
            - add ',' to invalid char array for identifiers, so AND combiner is valid without space
            - AND combiner must combine elements from root/provided element, and not last matched element
            - fix PRECEDED combiner (formerly known as BEFORE), select all previous sibling elements if they 
match
            - remove debug lines

 gxml/CssSelectorParser.vala | 36 +++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)
---
diff --git a/gxml/CssSelectorParser.vala b/gxml/CssSelectorParser.vala
index 228c711..9eb3188 100644
--- a/gxml/CssSelectorParser.vala
+++ b/gxml/CssSelectorParser.vala
@@ -29,7 +29,7 @@ public enum GXml.CssCombiner {
        AND,
        PARENT,
        AFTER,
-       BEFORE
+       PRECEDED
 }
 
 public enum GXml.CssSelectorType {
@@ -185,7 +185,7 @@ public class GXml.CssSelectorParser : GLib.Object {
                        '$', '&', '#', '|', '`',
                        '^', '@', '+', '~', '*',
                        '%', '!', '?', '<', '>', 
-                       ':', '.', '"', '\''
+                       ':', '.', '"', '\'', ','
                };
                return !(u in array);
        }
@@ -386,7 +386,7 @@ public class GXml.CssSelectorParser : GLib.Object {
                        else if (str.peek() == '+')
                                combiner = GXml.CssCombiner.AFTER;
                        else if (str.peek() == '~')
-                               combiner = GXml.CssCombiner.BEFORE;
+                               combiner = GXml.CssCombiner.PRECEDED;
                        else if (combiner == 0)
                                combiner = GXml.CssCombiner.NONE;
                        if (combiner != GXml.CssCombiner.NONE && combiner != GXml.CssCombiner.INSIDE)
@@ -397,8 +397,6 @@ public class GXml.CssSelectorParser : GLib.Object {
                }
                if (list.size == 0)
                        throw new GXml.CssSelectorError.NULL (_("No selectors found"));
-//             foreach (var sel in list)
-//                     print ("%s %s %s\n", sel.selector_type.to_string(), sel.name, sel.value);
                if (list[list.size - 1].combiner == GXml.CssCombiner.NONE)
                        list[list.size - 1].combiner = GXml.CssCombiner.NULL;
                if (list[list.size - 1].combiner != GXml.CssCombiner.NULL)
@@ -638,39 +636,43 @@ public class GXml.CssSelectorParser : GLib.Object {
                        return sel.local_name == element.local_name && sel.prefix == element.prefix;
                }
                if (selector is GXml.CssNotSelector)
-                       return !match_element (element, (selector as GXml.CssNotSelector).selectors);
+                       return !match_element (element, element, (selector as GXml.CssNotSelector).selectors);
                if (selector.selector_type == GXml.CssSelectorType.PSEUDO_CLASS)
                        return match_pseudo (element, selector);
                return false;
        }
        
-       static bool match_element (GXml.DomElement element, Gee.Collection<GXml.CssSelector> selectors) 
throws GLib.Error {
+       static bool match_element (GXml.DomElement root, GXml.DomElement element, 
Gee.Collection<GXml.CssSelector> selectors) throws GLib.Error {
                var list = new Gee.ArrayList<GXml.CssSelector>();
                list.add_all (selectors);
                var selector = list.remove_at (list.size - 1);
                if (list.size == 0)
                        return match_node (element, selector);
                if (list[list.size - 1].combiner == GXml.CssCombiner.AND)
-                       return match_node (element, selector) || match_element (element, list);
+                       return match_node (element, selector) || match_element (root, root, list);
                if (list[list.size - 1].combiner == GXml.CssCombiner.NONE)
-                       return match_node (element, selector) && match_element (element, list);
+                       return match_node (element, selector) && match_element (root, element, list);
                if (list[list.size - 1].combiner == GXml.CssCombiner.AFTER) {
                        if (element.previous_element_sibling == null)
                                return false;
-                       return match_node (element, selector) && match_element 
(element.previous_element_sibling, list);
+                       return match_node (element, selector) && match_element (root, 
element.previous_element_sibling, list);
                }
-               if (list[list.size - 1].combiner == GXml.CssCombiner.BEFORE) {
-                       if (element.next_element_sibling == null)
-                               return false;
-                       return match_node (element, selector) && match_element (element.next_element_sibling, 
list);
+               if (list[list.size - 1].combiner == GXml.CssCombiner.PRECEDED) {
+                       bool res = match_node (element, selector);
+                       var prev = element.previous_element_sibling;
+                       while (prev != null) {
+                               if (res && match_element (root, prev, list))
+                                       return true;
+                               prev = prev.previous_element_sibling;
+                       }
                }
                if (list[list.size - 1].combiner == GXml.CssCombiner.PARENT)
-                       return match_node (element, selector) && match_element (element.parent_element, list);
+                       return match_node (element, selector) && match_element (root, element.parent_element, 
list);
                if (list[list.size - 1].combiner == GXml.CssCombiner.INSIDE) {
                        var parent = element.parent_element;
                        bool res = match_node (element, selector);
                        while (parent != null) {
-                               if (res && match_element (parent, list))
+                               if (res && match_element (root, parent, list))
                                        return true;
                                parent = parent.parent_element;
                        }
@@ -679,7 +681,7 @@ public class GXml.CssSelectorParser : GLib.Object {
        }
 
        public bool match (GXml.DomElement element) throws GLib.Error {
-               return match_element (element, this.list);
+               return match_element (element, element, this.list);
        }
        
        public GXml.DomNodeList query_selector_all (GXml.DomElement element) throws GLib.Error {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]