Gitweb links:

...log 
http://git.netsurf-browser.org/libcss.git/shortlog/3c973e0136779959d95f3ff578fbd5d46bc53530
...commit 
http://git.netsurf-browser.org/libcss.git/commit/3c973e0136779959d95f3ff578fbd5d46bc53530
...tree 
http://git.netsurf-browser.org/libcss.git/tree/3c973e0136779959d95f3ff578fbd5d46bc53530

The branch, master has been updated
       via  3c973e0136779959d95f3ff578fbd5d46bc53530 (commit)
      from  71d28981207beb72b3ca68a9fa24948615a6a9bd (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commitdiff 
http://git.netsurf-browser.org/libcss.git/commitdiff/3c973e0136779959d95f3ff578fbd5d46bc53530
commit 3c973e0136779959d95f3ff578fbd5d46bc53530
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>

    Prioritise id and class hashes over element hash when inserting rules.

diff --git a/src/select/hash.c b/src/select/hash.c
index 2cc6f4a..37492c1 100644
--- a/src/select/hash.c
+++ b/src/select/hash.c
@@ -198,27 +198,27 @@ css_error css__selector_hash_insert(css_selector_hash 
*hash,
                return CSS_BADPARM;
 
        /* Work out which hash to insert into */
-       if (lwc_string_length(selector->data.qname.name) != 1 ||
-                       lwc_string_data(selector->data.qname.name)[0] != '*') {
-               /* Named element */
-               mask = hash->elements.n_slots - 1;
-               index = _hash_name(selector->data.qname.name) & mask;
+       if ((name = _id_name(selector)) != NULL) {
+               /* Named ID */
+               mask = hash->ids.n_slots - 1;
+               index = _hash_name(name) & mask;
 
-               error = _insert_into_chain(hash, &hash->elements.slots[index], 
+               error = _insert_into_chain(hash, &hash->ids.slots[index],
                                selector);
        } else if ((name = _class_name(selector)) != NULL) {
                /* Named class */
                mask = hash->classes.n_slots - 1;
                index = _hash_name(name) & mask;
 
-               error = _insert_into_chain(hash, &hash->classes.slots[index], 
+               error = _insert_into_chain(hash, &hash->classes.slots[index],
                                selector);
-       } else if ((name = _id_name(selector)) != NULL) {
-               /* Named ID */
-               mask = hash->ids.n_slots - 1;
-               index = _hash_name(name) & mask;
+       } else if (lwc_string_length(selector->data.qname.name) != 1 ||
+                       lwc_string_data(selector->data.qname.name)[0] != '*') {
+               /* Named element */
+               mask = hash->elements.n_slots - 1;
+               index = _hash_name(selector->data.qname.name) & mask;
 
-               error = _insert_into_chain(hash, &hash->ids.slots[index], 
+               error = _insert_into_chain(hash, &hash->elements.slots[index],
                                selector);
        } else {
                /* Universal chain */
@@ -245,28 +245,28 @@ css_error css__selector_hash_remove(css_selector_hash 
*hash,
        if (hash == NULL || selector == NULL)
                return CSS_BADPARM;
 
-       /* Work out which hash to insert into */
-       if (lwc_string_length(selector->data.qname.name) != 1 ||
-                       lwc_string_data(selector->data.qname.name)[0] != '*') {
-               /* Named element */
-               mask = hash->elements.n_slots - 1;
-               index = _hash_name(selector->data.qname.name) & mask;
+       /* Work out which hash to remove from */
+       if ((name = _id_name(selector)) != NULL) {
+               /* Named ID */
+               mask = hash->ids.n_slots - 1;
+               index = _hash_name(name) & mask;
 
-               error = _remove_from_chain(hash, &hash->elements.slots[index], 
+               error = _remove_from_chain(hash, &hash->ids.slots[index],
                                selector);
        } else if ((name = _class_name(selector)) != NULL) {
                /* Named class */
                mask = hash->classes.n_slots - 1;
                index = _hash_name(name) & mask;
 
-               error = _remove_from_chain(hash, &hash->classes.slots[index], 
+               error = _remove_from_chain(hash, &hash->classes.slots[index],
                                selector);
-       } else if ((name = _id_name(selector)) != NULL) {
-               /* Named ID */
-               mask = hash->ids.n_slots - 1;
-               index = _hash_name(name) & mask;
+       } else if (lwc_string_length(selector->data.qname.name) != 1 ||
+                       lwc_string_data(selector->data.qname.name)[0] != '*') {
+               /* Named element */
+               mask = hash->elements.n_slots - 1;
+               index = _hash_name(selector->data.qname.name) & mask;
 
-               error = _remove_from_chain(hash, &hash->ids.slots[index], 
+               error = _remove_from_chain(hash, &hash->elements.slots[index],
                                selector);
        } else {
                /* Universal chain */
diff --git a/src/select/select.c b/src/select/select.c
index ba35262..5c007af 100644
--- a/src/select/select.c
+++ b/src/select/select.c
@@ -97,6 +97,19 @@ typedef struct css_select_font_faces_state {
        css_select_font_faces_list author_font_faces;
 } css_select_font_faces_state;
 
+/**
+ * CSS rule source
+ */
+typedef struct css_select_rule_source {
+       enum {
+               CSS_SELECT_RULE_SRC_ELEMENT,
+               CSS_SELECT_RULE_SRC_CLASS,
+               CSS_SELECT_RULE_SRC_ID,
+               CSS_SELECT_RULE_SRC_UNIVERSAL
+       } source;
+       uint32_t class;
+} css_select_rule_source;
+
 
 static css_error set_hint(css_select_state *state, uint32_t prop);
 static css_error set_initial(css_select_state *state, 
@@ -1285,31 +1298,66 @@ static inline bool _selector_less_specific(const 
css_selector *ref,
 
 static const css_selector *_selector_next(const css_selector **node,
                const css_selector **id, const css_selector ***classes,
-               uint32_t n_classes, const css_selector **univ)
+               uint32_t n_classes, const css_selector **univ,
+               css_select_rule_source *src)
 {
        const css_selector *ret = NULL;
 
-       if (_selector_less_specific(ret, *node))
+       if (_selector_less_specific(ret, *node)) {
                ret = *node;
+               src->source = CSS_SELECT_RULE_SRC_ELEMENT;
+       }
 
-       if (_selector_less_specific(ret, *id))
+       if (_selector_less_specific(ret, *id)) {
                ret = *id;
+               src->source = CSS_SELECT_RULE_SRC_ID;
+       }
 
-       if (_selector_less_specific(ret, *univ))
+       if (_selector_less_specific(ret, *univ)) {
                ret = *univ;
+               src->source = CSS_SELECT_RULE_SRC_UNIVERSAL;
+       }
 
        if (classes != NULL && n_classes > 0) {
                uint32_t i;
 
                for (i = 0; i < n_classes; i++) {
-                       if (_selector_less_specific(ret, *(classes[i])))
+                       if (_selector_less_specific(ret, *(classes[i]))) {
                                ret = *(classes[i]);
+                               src->source = CSS_SELECT_RULE_SRC_CLASS;
+                               src->class = i;
+                       }
                }
        }
 
        return ret;
 }
 
+static bool _rule_good_for_element_name(const css_selector *selector,
+               css_select_rule_source *src, css_select_state *state)
+{
+       /* If source of rule is element or universal hash, we know the
+        * element name is a match.  If it comes from the class or id hash,
+        * we have to test for a match */
+       if (src->source == CSS_SELECT_RULE_SRC_ID ||
+                       src->source == CSS_SELECT_RULE_SRC_CLASS) {
+               if (lwc_string_length(selector->data.qname.name) != 1 ||
+                               lwc_string_data(
+                                       selector->data.qname.name)[0] != '*') {
+                       bool match;
+                       if (lwc_string_caseless_isequal(
+                                       selector->data.qname.name,
+                                       state->element.name,
+                                       &match) == lwc_error_ok &&
+                                       match == false) {
+                               return false;
+                       }
+               }
+       }
+
+       return true;
+}
+
 css_error match_selectors_in_sheet(css_select_ctx *ctx, 
                const css_stylesheet *sheet, css_select_state *state)
 {
@@ -1324,6 +1372,7 @@ css_error match_selectors_in_sheet(css_select_ctx *ctx,
        css_selector_hash_iterator class_iterator;
        const css_selector **univ_selectors = &empty_selector;
        css_selector_hash_iterator univ_iterator;
+       css_select_rule_source src = { CSS_SELECT_RULE_SRC_ELEMENT, 0 };
        css_error error;
 
        /* Find hash chain that applies to current node */
@@ -1377,7 +1426,12 @@ css_error match_selectors_in_sheet(css_select_ctx *ctx,
                 * Pick the least specific/earliest occurring selector.
                 */
                selector = _selector_next(node_selectors, id_selectors,
-                               class_selectors, n_classes, univ_selectors);
+                               class_selectors, n_classes, univ_selectors,
+                               &src);
+
+               /* We know there are selectors pending, so should have a
+                * selector here */
+               assert(selector != NULL);
 
                /* No bytecode if rule body is empty or wholly invalid --
                 * Only interested in rules with bytecode */
@@ -1387,33 +1441,40 @@ css_error match_selectors_in_sheet(css_select_ctx *ctx,
                         * current media requirements. */
                        if (_rule_applies_to_media(selector->rule,
                                        state->media)) {
-                               error = match_selector_chain(ctx, selector,
-                                               state);
-                               if (error != CSS_OK)
-                                       goto cleanup;
+                               if (_rule_good_for_element_name(selector, &src,
+                                               state)) {
+                                       error = match_selector_chain(
+                                                       ctx, selector,
+                                                       state);
+                                       if (error != CSS_OK)
+                                               goto cleanup;
+                               }
                        }
                }
 
                /* Advance to next selector in whichever chain we extracted 
                 * the processed selector from. */
-               if (selector == *node_selectors) {
+               switch (src.source) {
+               case CSS_SELECT_RULE_SRC_ELEMENT:
                        error = node_iterator(
                                        node_selectors, &node_selectors);
-               } else if (selector == *id_selectors) {
+                       break;
+
+               case CSS_SELECT_RULE_SRC_ID:
                        error = id_iterator(
                                        id_selectors, &id_selectors);
-               } else if (selector == *univ_selectors) {
+                       break;
+
+               case CSS_SELECT_RULE_SRC_UNIVERSAL:
                        error = univ_iterator(
                                        univ_selectors, &univ_selectors);
-               } else {
-                       for (i = 0; i < n_classes; i++) {
-                               if (selector == *(class_selectors[i])) {
-                                       error = class_iterator(
-                                                       class_selectors[i], 
-                                                       &class_selectors[i]);
-                                       break;
-                               }
-                       }
+                       break;
+
+               case CSS_SELECT_RULE_SRC_CLASS:
+                       error = class_iterator(
+                                       class_selectors[src.class],
+                                       &class_selectors[src.class]);
+                       break;
                }
 
                if (error != CSS_OK)


-----------------------------------------------------------------------

Summary of changes:
 src/select/hash.c   |   50 ++++++++++++------------
 src/select/select.c |  105 ++++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 108 insertions(+), 47 deletions(-)

diff --git a/src/select/hash.c b/src/select/hash.c
index 2cc6f4a..37492c1 100644
--- a/src/select/hash.c
+++ b/src/select/hash.c
@@ -198,27 +198,27 @@ css_error css__selector_hash_insert(css_selector_hash 
*hash,
                return CSS_BADPARM;
 
        /* Work out which hash to insert into */
-       if (lwc_string_length(selector->data.qname.name) != 1 ||
-                       lwc_string_data(selector->data.qname.name)[0] != '*') {
-               /* Named element */
-               mask = hash->elements.n_slots - 1;
-               index = _hash_name(selector->data.qname.name) & mask;
+       if ((name = _id_name(selector)) != NULL) {
+               /* Named ID */
+               mask = hash->ids.n_slots - 1;
+               index = _hash_name(name) & mask;
 
-               error = _insert_into_chain(hash, &hash->elements.slots[index], 
+               error = _insert_into_chain(hash, &hash->ids.slots[index],
                                selector);
        } else if ((name = _class_name(selector)) != NULL) {
                /* Named class */
                mask = hash->classes.n_slots - 1;
                index = _hash_name(name) & mask;
 
-               error = _insert_into_chain(hash, &hash->classes.slots[index], 
+               error = _insert_into_chain(hash, &hash->classes.slots[index],
                                selector);
-       } else if ((name = _id_name(selector)) != NULL) {
-               /* Named ID */
-               mask = hash->ids.n_slots - 1;
-               index = _hash_name(name) & mask;
+       } else if (lwc_string_length(selector->data.qname.name) != 1 ||
+                       lwc_string_data(selector->data.qname.name)[0] != '*') {
+               /* Named element */
+               mask = hash->elements.n_slots - 1;
+               index = _hash_name(selector->data.qname.name) & mask;
 
-               error = _insert_into_chain(hash, &hash->ids.slots[index], 
+               error = _insert_into_chain(hash, &hash->elements.slots[index],
                                selector);
        } else {
                /* Universal chain */
@@ -245,28 +245,28 @@ css_error css__selector_hash_remove(css_selector_hash 
*hash,
        if (hash == NULL || selector == NULL)
                return CSS_BADPARM;
 
-       /* Work out which hash to insert into */
-       if (lwc_string_length(selector->data.qname.name) != 1 ||
-                       lwc_string_data(selector->data.qname.name)[0] != '*') {
-               /* Named element */
-               mask = hash->elements.n_slots - 1;
-               index = _hash_name(selector->data.qname.name) & mask;
+       /* Work out which hash to remove from */
+       if ((name = _id_name(selector)) != NULL) {
+               /* Named ID */
+               mask = hash->ids.n_slots - 1;
+               index = _hash_name(name) & mask;
 
-               error = _remove_from_chain(hash, &hash->elements.slots[index], 
+               error = _remove_from_chain(hash, &hash->ids.slots[index],
                                selector);
        } else if ((name = _class_name(selector)) != NULL) {
                /* Named class */
                mask = hash->classes.n_slots - 1;
                index = _hash_name(name) & mask;
 
-               error = _remove_from_chain(hash, &hash->classes.slots[index], 
+               error = _remove_from_chain(hash, &hash->classes.slots[index],
                                selector);
-       } else if ((name = _id_name(selector)) != NULL) {
-               /* Named ID */
-               mask = hash->ids.n_slots - 1;
-               index = _hash_name(name) & mask;
+       } else if (lwc_string_length(selector->data.qname.name) != 1 ||
+                       lwc_string_data(selector->data.qname.name)[0] != '*') {
+               /* Named element */
+               mask = hash->elements.n_slots - 1;
+               index = _hash_name(selector->data.qname.name) & mask;
 
-               error = _remove_from_chain(hash, &hash->ids.slots[index], 
+               error = _remove_from_chain(hash, &hash->elements.slots[index],
                                selector);
        } else {
                /* Universal chain */
diff --git a/src/select/select.c b/src/select/select.c
index ba35262..5c007af 100644
--- a/src/select/select.c
+++ b/src/select/select.c
@@ -97,6 +97,19 @@ typedef struct css_select_font_faces_state {
        css_select_font_faces_list author_font_faces;
 } css_select_font_faces_state;
 
+/**
+ * CSS rule source
+ */
+typedef struct css_select_rule_source {
+       enum {
+               CSS_SELECT_RULE_SRC_ELEMENT,
+               CSS_SELECT_RULE_SRC_CLASS,
+               CSS_SELECT_RULE_SRC_ID,
+               CSS_SELECT_RULE_SRC_UNIVERSAL
+       } source;
+       uint32_t class;
+} css_select_rule_source;
+
 
 static css_error set_hint(css_select_state *state, uint32_t prop);
 static css_error set_initial(css_select_state *state, 
@@ -1285,31 +1298,66 @@ static inline bool _selector_less_specific(const 
css_selector *ref,
 
 static const css_selector *_selector_next(const css_selector **node,
                const css_selector **id, const css_selector ***classes,
-               uint32_t n_classes, const css_selector **univ)
+               uint32_t n_classes, const css_selector **univ,
+               css_select_rule_source *src)
 {
        const css_selector *ret = NULL;
 
-       if (_selector_less_specific(ret, *node))
+       if (_selector_less_specific(ret, *node)) {
                ret = *node;
+               src->source = CSS_SELECT_RULE_SRC_ELEMENT;
+       }
 
-       if (_selector_less_specific(ret, *id))
+       if (_selector_less_specific(ret, *id)) {
                ret = *id;
+               src->source = CSS_SELECT_RULE_SRC_ID;
+       }
 
-       if (_selector_less_specific(ret, *univ))
+       if (_selector_less_specific(ret, *univ)) {
                ret = *univ;
+               src->source = CSS_SELECT_RULE_SRC_UNIVERSAL;
+       }
 
        if (classes != NULL && n_classes > 0) {
                uint32_t i;
 
                for (i = 0; i < n_classes; i++) {
-                       if (_selector_less_specific(ret, *(classes[i])))
+                       if (_selector_less_specific(ret, *(classes[i]))) {
                                ret = *(classes[i]);
+                               src->source = CSS_SELECT_RULE_SRC_CLASS;
+                               src->class = i;
+                       }
                }
        }
 
        return ret;
 }
 
+static bool _rule_good_for_element_name(const css_selector *selector,
+               css_select_rule_source *src, css_select_state *state)
+{
+       /* If source of rule is element or universal hash, we know the
+        * element name is a match.  If it comes from the class or id hash,
+        * we have to test for a match */
+       if (src->source == CSS_SELECT_RULE_SRC_ID ||
+                       src->source == CSS_SELECT_RULE_SRC_CLASS) {
+               if (lwc_string_length(selector->data.qname.name) != 1 ||
+                               lwc_string_data(
+                                       selector->data.qname.name)[0] != '*') {
+                       bool match;
+                       if (lwc_string_caseless_isequal(
+                                       selector->data.qname.name,
+                                       state->element.name,
+                                       &match) == lwc_error_ok &&
+                                       match == false) {
+                               return false;
+                       }
+               }
+       }
+
+       return true;
+}
+
 css_error match_selectors_in_sheet(css_select_ctx *ctx, 
                const css_stylesheet *sheet, css_select_state *state)
 {
@@ -1324,6 +1372,7 @@ css_error match_selectors_in_sheet(css_select_ctx *ctx,
        css_selector_hash_iterator class_iterator;
        const css_selector **univ_selectors = &empty_selector;
        css_selector_hash_iterator univ_iterator;
+       css_select_rule_source src = { CSS_SELECT_RULE_SRC_ELEMENT, 0 };
        css_error error;
 
        /* Find hash chain that applies to current node */
@@ -1377,7 +1426,12 @@ css_error match_selectors_in_sheet(css_select_ctx *ctx,
                 * Pick the least specific/earliest occurring selector.
                 */
                selector = _selector_next(node_selectors, id_selectors,
-                               class_selectors, n_classes, univ_selectors);
+                               class_selectors, n_classes, univ_selectors,
+                               &src);
+
+               /* We know there are selectors pending, so should have a
+                * selector here */
+               assert(selector != NULL);
 
                /* No bytecode if rule body is empty or wholly invalid --
                 * Only interested in rules with bytecode */
@@ -1387,33 +1441,40 @@ css_error match_selectors_in_sheet(css_select_ctx *ctx,
                         * current media requirements. */
                        if (_rule_applies_to_media(selector->rule,
                                        state->media)) {
-                               error = match_selector_chain(ctx, selector,
-                                               state);
-                               if (error != CSS_OK)
-                                       goto cleanup;
+                               if (_rule_good_for_element_name(selector, &src,
+                                               state)) {
+                                       error = match_selector_chain(
+                                                       ctx, selector,
+                                                       state);
+                                       if (error != CSS_OK)
+                                               goto cleanup;
+                               }
                        }
                }
 
                /* Advance to next selector in whichever chain we extracted 
                 * the processed selector from. */
-               if (selector == *node_selectors) {
+               switch (src.source) {
+               case CSS_SELECT_RULE_SRC_ELEMENT:
                        error = node_iterator(
                                        node_selectors, &node_selectors);
-               } else if (selector == *id_selectors) {
+                       break;
+
+               case CSS_SELECT_RULE_SRC_ID:
                        error = id_iterator(
                                        id_selectors, &id_selectors);
-               } else if (selector == *univ_selectors) {
+                       break;
+
+               case CSS_SELECT_RULE_SRC_UNIVERSAL:
                        error = univ_iterator(
                                        univ_selectors, &univ_selectors);
-               } else {
-                       for (i = 0; i < n_classes; i++) {
-                               if (selector == *(class_selectors[i])) {
-                                       error = class_iterator(
-                                                       class_selectors[i], 
-                                                       &class_selectors[i]);
-                                       break;
-                               }
-                       }
+                       break;
+
+               case CSS_SELECT_RULE_SRC_CLASS:
+                       error = class_iterator(
+                                       class_selectors[src.class],
+                                       &class_selectors[src.class]);
+                       break;
                }
 
                if (error != CSS_OK)


-- 
Cascading Style Sheets library

_______________________________________________
netsurf-commits mailing list
[email protected]
http://vlists.pepperfish.net/cgi-bin/mailman/listinfo/netsurf-commits-netsurf-browser.org

Reply via email to