From b5485da64c1f8086eb49a2c830ca75511f34abfd Mon Sep 17 00:00:00 2001
From: dec05eba <dec05eba@protonmail.com>
Date: Wed, 15 May 2024 22:28:05 +0200
Subject: Strip class attribute matching

---
 src/HtmlSearch.c | 117 ++++++++++++++++++++++++++++---------------------------
 1 file changed, 60 insertions(+), 57 deletions(-)

(limited to 'src')

diff --git a/src/HtmlSearch.c b/src/HtmlSearch.c
index 4ae27af..7d5c5c5 100644
--- a/src/HtmlSearch.c
+++ b/src/HtmlSearch.c
@@ -142,10 +142,65 @@ static char to_upper(char c) {
         return c;
 }
 
-static int string_views_equal_case_insensitive(const QuickMediaStringView str1, const QuickMediaStringView str2) {
+static int is_whitespace(int c) {
+    switch(c) {
+        case ' ':
+        case '\n':
+        case '\r':
+        case '\t':
+        case '\v':
+            return 1;
+        default:
+            return 0;
+    }
+}
+
+static int is_newline(int c) {
+    return c == '\n' || c == '\r';
+}
+
+static void lstrip(const char *str, size_t size, const char **output_str, size_t *output_size, int(*strip_filter_func)(int)) {
+    if(size == 0) {
+        *output_str = str;
+        *output_size = size;
+        return;
+    }
+
+    size_t i = 0;
+    while(i < size && strip_filter_func(str[i])) {
+        ++i;
+    }
+
+    *output_str = str + i;
+    *output_size = size - i;
+}
+
+static void rstrip(const char *str, size_t size, size_t *output_size, int(*strip_filter_func)(int)) {
+    if(size == 0) {
+        *output_size = size;
+        return;
+    }
+
+    ssize_t i = size - 1;
+    while(i >= 0 && strip_filter_func(str[i])) {
+        --i;
+    }
+
+    *output_size = i + 1;
+}
+
+static void strip(const char *str, size_t size, const char **output_str, size_t *output_size, int(*strip_filter_func)(int)) {
+    lstrip(str, size, output_str, output_size, strip_filter_func);
+    rstrip(*output_str, *output_size, output_size, strip_filter_func);
+}
+
+static int string_views_equal_case_insensitive_strip(QuickMediaStringView str1, QuickMediaStringView str2) {
     if(str2.size != str1.size)
         return 1;
 
+    strip(str1.data, str1.size, &str1.data, &str1.size, is_whitespace);
+    strip(str2.data, str2.size, &str2.data, &str2.size, is_whitespace);
+
     for(size_t i = 0; i < str1.size; ++i) {
         char c1 = str1.data[i];
         char c2 = str2.data[i];
@@ -158,7 +213,7 @@ static int string_views_equal_case_insensitive(const QuickMediaStringView str1,
 
 static QuickMediaHtmlAttribute* get_attribute_by_name(QuickMediaHtmlNode *node, QuickMediaStringView name) {
     for(QuickMediaHtmlAttribute *attr = node->first_attribute; attr; attr = attr->next) {
-        if(string_views_equal_case_insensitive(attr->key, name) == 0)
+        if(string_views_equal_case_insensitive_strip(attr->key, name) == 0)
             return attr;
     }
     return NULL;
@@ -177,7 +232,7 @@ static int find_child_nodes(QuickMediaHtmlChildNode *node, const QuickMediaNodeS
             continue;
 
         /* Match without node name or node name matches */
-        if(search_data->name.size == 0 || string_views_equal_case_insensitive(child->node.name, search_data->name) == 0) {
+        if(search_data->name.size == 0 || string_views_equal_case_insensitive_strip(child->node.name, search_data->name) == 0) {
             #define on_match() do { \
                 if(search_data->child) { \
                     if(find_child_nodes(child->node.first_child, search_data->child, result_callback, userdata) != 0) \
@@ -409,72 +464,20 @@ QuickMediaHtmlNode* quickmedia_html_node_find_child(QuickMediaHtmlNode *self, co
         if(!child->node.is_tag)
             continue;
 
-        if(string_views_equal_case_insensitive(child->node.name, tag) != 0)
+        if(string_views_equal_case_insensitive_strip(child->node.name, tag) != 0)
             continue;
 
         QuickMediaHtmlAttribute *attr = get_attribute_by_name(&child->node, attr_name);
         if(!attr)
             continue;
 
-        if(string_views_equal_case_insensitive(attr->value, attr_value) == 0)
+        if(string_views_equal_case_insensitive_strip(attr->value, attr_value) == 0)
             return &child->node;
     }
 
     return NULL;
 }
 
-static int is_whitespace(int c) {
-    switch(c) {
-        case ' ':
-        case '\n':
-        case '\r':
-        case '\t':
-        case '\v':
-            return 1;
-        default:
-            return 0;
-    }
-}
-
-static int is_newline(int c) {
-    return c == '\n' || c == '\r';
-}
-
-static void lstrip(const char *str, size_t size, const char **output_str, size_t *output_size, int(*strip_filter_func)(int)) {
-    if(size == 0) {
-        *output_str = str;
-        *output_size = size;
-        return;
-    }
-
-    size_t i = 0;
-    while(i < size && strip_filter_func(str[i])) {
-        ++i;
-    }
-
-    *output_str = str + i;
-    *output_size = size - i;
-}
-
-static void rstrip(const char *str, size_t size, size_t *output_size, int(*strip_filter_func)(int)) {
-    if(size == 0) {
-        *output_size = size;
-        return;
-    }
-
-    ssize_t i = size - 1;
-    while(i >= 0 && strip_filter_func(str[i])) {
-        --i;
-    }
-
-    *output_size = i + 1;
-}
-
-static void strip(const char *str, size_t size, const char **output_str, size_t *output_size, int(*strip_filter_func)(int)) {
-    lstrip(str, size, output_str, output_size, strip_filter_func);
-    rstrip(*output_str, *output_size, output_size, strip_filter_func);
-}
-
 static int merge_inner_text(QuickMediaHtmlNode *node, QuickMediaString *str) {
     if(node->is_tag) {
         int newline = 0;
-- 
cgit v1.2.3-70-g09d2