Gitweb links:

...log 
http://git.netsurf-browser.org/libcss.git/shortlog/0eadfb721c47526c7af9f280f41a781e1bc3e3d0
...commit 
http://git.netsurf-browser.org/libcss.git/commit/0eadfb721c47526c7af9f280f41a781e1bc3e3d0
...tree 
http://git.netsurf-browser.org/libcss.git/tree/0eadfb721c47526c7af9f280f41a781e1bc3e3d0

The branch, master has been updated
       via  0eadfb721c47526c7af9f280f41a781e1bc3e3d0 (commit)
       via  d05d62752df773c8252dd10060188c35e8b6989a (commit)
       via  0e3a0b1ef42eb15d70a5307d340c38ab611eb64d (commit)
      from  c0af9cfa9adf8fdc94efa32a6847d7aebba0e107 (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/commit/?id=0eadfb721c47526c7af9f280f41a781e1bc3e3d0
commit 0eadfb721c47526c7af9f280f41a781e1bc3e3d0
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>

    Select: MQ: Use interned strings for media features
    
    Avoids some strcmps.

diff --git a/src/select/hash.c b/src/select/hash.c
index 0d85d6f..12e82aa 100644
--- a/src/select/hash.c
+++ b/src/select/hash.c
@@ -370,7 +370,8 @@ css_error css__selector_hash_find(css_selector_hash *hash,
                                                head->sel_chain_bloom,
                                                req->node_bloom) &&
                                    mq_rule_good_for_media(head->sel->rule,
-                                               req->unit_ctx, req->media)) {
+                                               req->unit_ctx, req->media,
+                                               req->str)) {
                                        /* Found a match */
                                        break;
                                }
@@ -446,11 +447,12 @@ css_error 
css__selector_hash_find_by_class(css_selector_hash *hash,
                                            _chain_good_for_element_name(
                                                        head->sel,
                                                        &(req->qname),
-                                                       req->uni) &&
+                                                       req->str->universal) &&
                                            mq_rule_good_for_media(
                                                        head->sel->rule,
                                                        req->unit_ctx,
-                                                       req->media)) {
+                                                       req->media,
+                                                       req->str)) {
                                                /* Found a match */
                                                break;
                                        }
@@ -527,11 +529,12 @@ css_error css__selector_hash_find_by_id(css_selector_hash 
*hash,
                                            _chain_good_for_element_name(
                                                        head->sel,
                                                        &req->qname,
-                                                       req->uni) &&
+                                                       req->str->universal) &&
                                            mq_rule_good_for_media(
                                                        head->sel->rule,
                                                        req->unit_ctx,
-                                                       req->media)) {
+                                                       req->media,
+                                                       req->str)) {
                                                /* Found a match */
                                                break;
                                        }
@@ -581,7 +584,8 @@ css_error 
css__selector_hash_find_universal(css_selector_hash *hash,
                                        head->sel_chain_bloom,
                                        req->node_bloom) &&
                            mq_rule_good_for_media(head->sel->rule,
-                                       req->unit_ctx, req->media)) {
+                                       req->unit_ctx, req->media,
+                                       req->str)) {
                                /* Found a match */
                                break;
                        }
@@ -924,7 +928,8 @@ css_error _iterate_elements(
                                                head->sel_chain_bloom,
                                                req->node_bloom) &&
                                    mq_rule_good_for_media(head->sel->rule,
-                                               req->unit_ctx, req->media)) {
+                                               req->unit_ctx, req->media,
+                                               req->str)) {
                                        /* Found a match */
                                        break;
                                }
@@ -981,11 +986,12 @@ css_error _iterate_classes(
                                            _chain_good_for_element_name(
                                                        head->sel,
                                                        &(req->qname),
-                                                       req->uni) &&
+                                                       req->str->universal) &&
                                            mq_rule_good_for_media(
                                                        head->sel->rule,
                                                        req->unit_ctx,
-                                                       req->media)) {
+                                                       req->media,
+                                                       req->str)) {
                                                /* Found a match */
                                                break;
                                        }
@@ -1043,11 +1049,12 @@ css_error _iterate_ids(
                                            _chain_good_for_element_name(
                                                        head->sel,
                                                        &req->qname,
-                                                       req->uni) &&
+                                                       req->str->universal) &&
                                            mq_rule_good_for_media(
                                                        head->sel->rule,
                                                        req->unit_ctx,
-                                                       req->media)) {
+                                                       req->media,
+                                                       req->str)) {
                                                /* Found a match */
                                                break;
                                        }
@@ -1090,7 +1097,8 @@ css_error _iterate_universal(
                                        head->sel_chain_bloom,
                                        req->node_bloom) &&
                            mq_rule_good_for_media(head->sel->rule,
-                                       req->unit_ctx, req->media)) {
+                                       req->unit_ctx, req->media,
+                                       req->str)) {
                                /* Found a match */
                                break;
                        }
diff --git a/src/select/hash.h b/src/select/hash.h
index df4102f..5f48a38 100644
--- a/src/select/hash.h
+++ b/src/select/hash.h
@@ -15,6 +15,7 @@
 #include <libcss/functypes.h>
 
 #include "select/bloom.h"
+#include "select/strings.h"
 
 /* Ugh. We need this to avoid circular includes. Happy! */
 struct css_selector;
@@ -25,7 +26,7 @@ struct css_hash_selection_requirments {
        css_qname qname;                /* Element name, or universal "*" */
        lwc_string *class;              /* Name of class, or NULL */
        lwc_string *id;                 /* Name of id, or NULL */
-       lwc_string *uni;                /* Universal element string "*" */
+       const css_select_strings *str;  /* Selection strings */
        const css_media *media;         /* Media spec we're selecting for */
        const css_unit_ctx *unit_ctx;   /* Document unit conversion context. */
        const css_bloom *node_bloom;    /* Node's bloom filter */
diff --git a/src/select/mq.h b/src/select/mq.h
index 014814b..dd3252e 100644
--- a/src/select/mq.h
+++ b/src/select/mq.h
@@ -10,6 +10,7 @@
 #define css_select_mq_h_
 
 #include "select/helpers.h"
+#include "select/strings.h"
 #include "select/unit.h"
 
 static inline bool mq_match_feature_range_length_op1(
@@ -114,10 +115,15 @@ static inline bool mq_match_feature_eq_ident_op1(
 static inline bool mq_match_feature(
                const css_mq_feature *feat,
                const css_unit_ctx *unit_ctx,
-               const css_media *media)
+               const css_media *media,
+               const css_select_strings *str)
 {
+       bool match;
+
        /* TODO: Use interned string for comparison. */
-       if (strcmp(lwc_string_data(feat->name), "width") == 0) {
+       if (lwc_string_isequal(feat->name,
+                       str->width, &match) == lwc_error_ok &&
+                       match == true) {
                if (!mq_match_feature_range_length_op1(feat->op, &feat->value,
                                        media->width, unit_ctx)) {
                        return false;
@@ -125,7 +131,9 @@ static inline bool mq_match_feature(
                return mq_match_feature_range_length_op2(feat->op2,
                                &feat->value2, media->width, unit_ctx);
 
-       } else if (strcmp(lwc_string_data(feat->name), "height") == 0) {
+       } else if (lwc_string_isequal(feat->name,
+                       str->height, &match) == lwc_error_ok &&
+                       match == true) {
                if (!mq_match_feature_range_length_op1(feat->op, &feat->value,
                                media->height, unit_ctx)) {
                        return false;
@@ -134,7 +142,9 @@ static inline bool mq_match_feature(
                return mq_match_feature_range_length_op2(feat->op2,
                                &feat->value2, media->height, unit_ctx);
 
-       } else if (strcmp(lwc_string_data(feat->name), "prefers-color-scheme") 
== 0) {
+       } else if (lwc_string_isequal(feat->name,
+                       str->prefers_color_scheme, &match) == lwc_error_ok &&
+                       match == true) {
                if (!mq_match_feature_eq_ident_op1(feat->op, &feat->value,
                                media->prefers_color_scheme)) {
                        return false;
@@ -159,7 +169,8 @@ static inline bool mq_match_feature(
 static inline bool mq_match_condition(
                const css_mq_cond *cond,
                const css_unit_ctx *unit_ctx,
-               const css_media *media)
+               const css_media *media,
+               const css_select_strings *str)
 {
        bool matched = !cond->op;
 
@@ -168,12 +179,12 @@ static inline bool mq_match_condition(
                if (cond->parts[i]->type == CSS_MQ_FEATURE) {
                        part_matched = mq_match_feature(
                                        cond->parts[i]->data.feat,
-                                       unit_ctx, media);
+                                       unit_ctx, media, str);
                } else {
                        assert(cond->parts[i]->type == CSS_MQ_COND);
                        part_matched = mq_match_condition(
                                        cond->parts[i]->data.cond,
-                                       unit_ctx, media);
+                                       unit_ctx, media, str);
                }
 
                if (cond->op) {
@@ -208,14 +219,15 @@ static inline bool mq_match_condition(
 static inline bool mq__list_match(
                const css_mq_query *m,
                const css_unit_ctx *unit_ctx,
-               const css_media *media)
+               const css_media *media,
+               const css_select_strings *str)
 {
        for (; m != NULL; m = m->next) {
                /* Check type */
                if (!!(m->type & media->type) != m->negate_type) {
                        if (m->cond == NULL ||
                                        mq_match_condition(m->cond,
-                                                       unit_ctx, media)) {
+                                                       unit_ctx, media, str)) {
                                /* We have a match, no need to look further. */
                                return true;
                        }
@@ -236,7 +248,8 @@ static inline bool mq__list_match(
 static inline bool mq_rule_good_for_media(
                const css_rule *rule,
                const css_unit_ctx *unit_ctx,
-               const css_media *media)
+               const css_media *media,
+               const css_select_strings *str)
 {
        bool applies = true;
        const css_rule *ancestor = rule;
@@ -245,7 +258,8 @@ static inline bool mq_rule_good_for_media(
                const css_rule_media *m = (const css_rule_media *) ancestor;
 
                if (ancestor->type == CSS_RULE_MEDIA) {
-                       applies = mq__list_match(m->media, unit_ctx, media);
+                       applies = mq__list_match(m->media,
+                                       unit_ctx, media, str);
                        if (applies == false) {
                                break;
                        }
diff --git a/src/select/select.c b/src/select/select.c
index ae98ec2..7d8195f 100644
--- a/src/select/select.c
+++ b/src/select/select.c
@@ -124,7 +124,8 @@ static css_error cascade_style(const css_style *style, 
css_select_state *state);
 static css_error select_font_faces_from_sheet(
                const css_stylesheet *sheet,
                css_origin origin,
-               css_select_font_faces_state *state);
+               css_select_font_faces_state *state,
+               const css_select_strings *str);
 
 #ifdef DEBUG_CHAIN_MATCHING
 static void dump_chain(const css_selector *selector);
@@ -1244,7 +1245,7 @@ css_error css_select_style(css_select_ctx *ctx, void 
*node,
        for (i = 0; i < ctx->n_sheets; i++) {
                const css_select_sheet s = ctx->sheets[i];
 
-               if (mq__list_match(s.media, unit_ctx, media) &&
+               if (mq__list_match(s.media, unit_ctx, media, &ctx->str) &&
                                s.sheet->disabled == false) {
                        error = select_from_sheet(ctx, s.sheet,
                                        s.origin, &state);
@@ -1425,10 +1426,10 @@ css_error css_select_font_faces(css_select_ctx *ctx,
        for (i = 0; i < ctx->n_sheets; i++) {
                const css_select_sheet s = ctx->sheets[i];
 
-               if (mq__list_match(s.media, unit_ctx, media) &&
+               if (mq__list_match(s.media, unit_ctx, media, &ctx->str) &&
                                s.sheet->disabled == false) {
                        error = select_font_faces_from_sheet(s.sheet,
-                                       s.origin, &state);
+                                       s.origin, &state, &ctx->str);
                        if (error != CSS_OK)
                                goto cleanup;
                }
@@ -1599,7 +1600,8 @@ css_error select_from_sheet(css_select_ctx *ctx, const 
css_stylesheet *sheet,
                        if (import->sheet != NULL &&
                                        mq__list_match(import->media,
                                                        state->unit_ctx,
-                                                       state->media)) {
+                                                       state->media,
+                                                       &ctx->str)) {
                                /* It's applicable, so process it */
                                if (sp >= IMPORT_STACK_SIZE)
                                        return CSS_NOMEM;
@@ -1640,10 +1642,11 @@ css_error select_from_sheet(css_select_ctx *ctx, const 
css_stylesheet *sheet,
 
 static css_error _select_font_face_from_rule(
                const css_rule_font_face *rule, css_origin origin,
-               css_select_font_faces_state *state)
+               css_select_font_faces_state *state,
+               const css_select_strings *str)
 {
        if (mq_rule_good_for_media((const css_rule *) rule,
-                       state->unit_ctx, state->media)) {
+                       state->unit_ctx, state->media, str)) {
                bool correct_family = false;
 
                if (lwc_string_isequal(
@@ -1687,7 +1690,8 @@ static css_error _select_font_face_from_rule(
 static css_error select_font_faces_from_sheet(
                const css_stylesheet *sheet,
                css_origin origin,
-               css_select_font_faces_state *state)
+               css_select_font_faces_state *state,
+               const css_select_strings *str)
 {
        const css_stylesheet *s = sheet;
        const css_rule *rule = s->rule_list;
@@ -1709,7 +1713,8 @@ static css_error select_font_faces_from_sheet(
                        if (import->sheet != NULL &&
                                        mq__list_match(import->media,
                                                        state->unit_ctx,
-                                                       state->media)) {
+                                                       state->media,
+                                                       str)) {
                                /* It's applicable, so process it */
                                if (sp >= IMPORT_STACK_SIZE)
                                        return CSS_NOMEM;
@@ -1727,8 +1732,7 @@ static css_error select_font_faces_from_sheet(
 
                        error = _select_font_face_from_rule(
                                        (const css_rule_font_face *) rule,
-                                       origin,
-                                       state);
+                                       origin, state, str);
 
                        if (error != CSS_OK)
                                return error;
@@ -1858,7 +1862,7 @@ css_error match_selectors_in_sheet(css_select_ctx *ctx,
        req.media = state->media;
        req.unit_ctx = state->unit_ctx;
        req.node_bloom = state->node_data->bloom;
-       req.uni = ctx->str.universal;
+       req.str = &ctx->str;
 
        /* Find hash chain that applies to current node */
        req.qname = state->element;


commitdiff 
http://git.netsurf-browser.org/libcss.git/commit/?id=d05d62752df773c8252dd10060188c35e8b6989a
commit d05d62752df773c8252dd10060188c35e8b6989a
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>

    Select: Add strings for media query features

diff --git a/src/select/strings.c b/src/select/strings.c
index 2eede49..6e9137d 100644
--- a/src/select/strings.c
+++ b/src/select/strings.c
@@ -177,6 +177,24 @@ css_error css_select_strings_intern(css_select_strings 
*str)
        if (error != lwc_error_ok)
                return css_error_from_lwc_error(error);
 
+       error = lwc_intern_string(
+                       "width", SLEN("width"),
+                       &str->width);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "height", SLEN("height"),
+                       &str->height);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "prefers-color-scheme", SLEN("prefers-color-scheme"),
+                       &str->prefers_color_scheme);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
        return CSS_OK;
 }
 
@@ -236,4 +254,11 @@ void css_select_strings_unref(css_select_strings *str)
                lwc_string_unref(str->before);
        if (str->after != NULL)
                lwc_string_unref(str->after);
+
+       if (str->width != NULL)
+               lwc_string_unref(str->width);
+       if (str->height != NULL)
+               lwc_string_unref(str->height);
+       if (str->prefers_color_scheme != NULL)
+               lwc_string_unref(str->prefers_color_scheme);
 }
diff --git a/src/select/strings.h b/src/select/strings.h
index 1861ff4..ff965e5 100644
--- a/src/select/strings.h
+++ b/src/select/strings.h
@@ -39,6 +39,10 @@ typedef struct {
        lwc_string *first_letter;
        lwc_string *before;
        lwc_string *after;
+
+       lwc_string *width;
+       lwc_string *height;
+       lwc_string *prefers_color_scheme;
 } css_select_strings;
 
 css_error css_select_strings_intern(css_select_strings *str);


commitdiff 
http://git.netsurf-browser.org/libcss.git/commit/?id=0e3a0b1ef42eb15d70a5307d340c38ab611eb64d
commit 0e3a0b1ef42eb15d70a5307d340c38ab611eb64d
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>

    Select: Split out useful strings

diff --git a/src/select/Makefile b/src/select/Makefile
index f5ddb18..b9e7390 100644
--- a/src/select/Makefile
+++ b/src/select/Makefile
@@ -2,6 +2,6 @@
 select_generator:
        python3 src/select/select_generator.py
 
-DIR_SOURCES := arena.c computed.c dispatch.c hash.c select.c font_face.c 
format_list_style.c unit.c
+DIR_SOURCES := arena.c computed.c dispatch.c hash.c select.c strings.c 
font_face.c format_list_style.c unit.c
 
 include $(NSBUILD)/Makefile.subdir
diff --git a/src/select/select.c b/src/select/select.c
index b050c0c..ae98ec2 100644
--- a/src/select/select.c
+++ b/src/select/select.c
@@ -23,6 +23,7 @@
 #include "select/propset.h"
 #include "select/font_face.h"
 #include "select/select.h"
+#include "select/strings.h"
 #include "select/unit.h"
 #include "utils/parserutilserror.h"
 #include "utils/utils.h"
@@ -52,34 +53,7 @@ struct css_select_ctx {
 
        void *pw;       /**< Client's private selection context */
 
-       /* Useful interned strings */
-       lwc_string *universal;
-       lwc_string *first_child;
-       lwc_string *link;
-       lwc_string *visited;
-       lwc_string *hover;
-       lwc_string *active;
-       lwc_string *focus;
-       lwc_string *nth_child;
-       lwc_string *nth_last_child;
-       lwc_string *nth_of_type;
-       lwc_string *nth_last_of_type;
-       lwc_string *last_child;
-       lwc_string *first_of_type;
-       lwc_string *last_of_type;
-       lwc_string *only_child;
-       lwc_string *only_of_type;
-       lwc_string *root;
-       lwc_string *empty;
-       lwc_string *target;
-       lwc_string *lang;
-       lwc_string *enabled;
-       lwc_string *disabled;
-       lwc_string *checked;
-       lwc_string *first_line;
-       lwc_string *first_letter;
-       lwc_string *before;
-       lwc_string *after;
+       css_select_strings str;
 
        /* Interned default style */
        css_computed_style *default_style;
@@ -125,9 +99,6 @@ static css_error set_initial(css_select_state *state,
                uint32_t prop, css_pseudo_element pseudo,
                void *parent);
 
-static css_error intern_strings(css_select_ctx *ctx);
-static void destroy_strings(css_select_ctx *ctx);
-
 static css_error select_from_sheet(css_select_ctx *ctx,
                const css_stylesheet *sheet, css_origin origin,
                css_select_state *state);
@@ -264,7 +235,7 @@ css_error css_select_ctx_create(css_select_ctx **result)
        if (c == NULL)
                return CSS_NOMEM;
 
-       error = intern_strings(c);
+       error = css_select_strings_intern(&c->str);
        if (error != CSS_OK) {
                free(c);
                return error;
@@ -286,7 +257,7 @@ css_error css_select_ctx_destroy(css_select_ctx *ctx)
        if (ctx == NULL)
                return CSS_BADPARM;
 
-       destroy_strings(ctx);
+       css_select_strings_unref(&ctx->str);
 
        if (ctx->default_style != NULL)
                css_computed_style_destroy(ctx->default_style);
@@ -1559,233 +1530,6 @@ css_error css_select_font_faces_results_destroy(
  * Selection engine internals below here                                      *
  
******************************************************************************/
 
-css_error intern_strings(css_select_ctx *ctx)
-{
-       lwc_error error;
-
-       /* Universal selector */
-       error = lwc_intern_string("*", SLEN("*"), &ctx->universal);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       /* Pseudo classes */
-       error = lwc_intern_string(
-                       "first-child", SLEN("first-child"),
-                       &ctx->first_child);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "link", SLEN("link"),
-                       &ctx->link);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "visited", SLEN("visited"),
-                       &ctx->visited);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "hover", SLEN("hover"),
-                       &ctx->hover);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "active", SLEN("active"),
-                       &ctx->active);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "focus", SLEN("focus"),
-                       &ctx->focus);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "nth-child", SLEN("nth-child"),
-                       &ctx->nth_child);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "nth-last-child", SLEN("nth-last-child"),
-                       &ctx->nth_last_child);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "nth-of-type", SLEN("nth-of-type"),
-                       &ctx->nth_of_type);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "nth-last-of-type", SLEN("nth-last-of-type"),
-                       &ctx->nth_last_of_type);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "last-child", SLEN("last-child"),
-                       &ctx->last_child);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "first-of-type", SLEN("first-of-type"),
-                       &ctx->first_of_type);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "last-of-type", SLEN("last-of-type"),
-                       &ctx->last_of_type);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "only-child", SLEN("only-child"),
-                       &ctx->only_child);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "only-of-type", SLEN("only-of-type"),
-                       &ctx->only_of_type);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "root", SLEN("root"),
-                       &ctx->root);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "empty", SLEN("empty"),
-                       &ctx->empty);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "target", SLEN("target"),
-                       &ctx->target);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "lang", SLEN("lang"),
-                       &ctx->lang);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "enabled", SLEN("enabled"),
-                       &ctx->enabled);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "disabled", SLEN("disabled"),
-                       &ctx->disabled);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "checked", SLEN("checked"),
-                       &ctx->checked);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       /* Pseudo elements */
-       error = lwc_intern_string(
-                       "first-line", SLEN("first-line"),
-                       &ctx->first_line);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "first_letter", SLEN("first-letter"),
-                       &ctx->first_letter);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "before", SLEN("before"),
-                       &ctx->before);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "after", SLEN("after"),
-                       &ctx->after);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       return CSS_OK;
-}
-
-void destroy_strings(css_select_ctx *ctx)
-{
-       if (ctx->universal != NULL)
-               lwc_string_unref(ctx->universal);
-       if (ctx->first_child != NULL)
-               lwc_string_unref(ctx->first_child);
-       if (ctx->link != NULL)
-               lwc_string_unref(ctx->link);
-       if (ctx->visited != NULL)
-               lwc_string_unref(ctx->visited);
-       if (ctx->hover != NULL)
-               lwc_string_unref(ctx->hover);
-       if (ctx->active != NULL)
-               lwc_string_unref(ctx->active);
-       if (ctx->focus != NULL)
-               lwc_string_unref(ctx->focus);
-       if (ctx->nth_child != NULL)
-               lwc_string_unref(ctx->nth_child);
-       if (ctx->nth_last_child != NULL)
-               lwc_string_unref(ctx->nth_last_child);
-       if (ctx->nth_of_type != NULL)
-               lwc_string_unref(ctx->nth_of_type);
-       if (ctx->nth_last_of_type != NULL)
-               lwc_string_unref(ctx->nth_last_of_type);
-       if (ctx->last_child != NULL)
-               lwc_string_unref(ctx->last_child);
-       if (ctx->first_of_type != NULL)
-               lwc_string_unref(ctx->first_of_type);
-       if (ctx->last_of_type != NULL)
-               lwc_string_unref(ctx->last_of_type);
-       if (ctx->only_child != NULL)
-               lwc_string_unref(ctx->only_child);
-       if (ctx->only_of_type != NULL)
-               lwc_string_unref(ctx->only_of_type);
-       if (ctx->root != NULL)
-               lwc_string_unref(ctx->root);
-       if (ctx->empty != NULL)
-               lwc_string_unref(ctx->empty);
-       if (ctx->target != NULL)
-               lwc_string_unref(ctx->target);
-       if (ctx->lang != NULL)
-               lwc_string_unref(ctx->lang);
-       if (ctx->enabled != NULL)
-               lwc_string_unref(ctx->enabled);
-       if (ctx->disabled != NULL)
-               lwc_string_unref(ctx->disabled);
-       if (ctx->checked != NULL)
-               lwc_string_unref(ctx->checked);
-       if (ctx->first_line != NULL)
-               lwc_string_unref(ctx->first_line);
-       if (ctx->first_letter != NULL)
-               lwc_string_unref(ctx->first_letter);
-       if (ctx->before != NULL)
-               lwc_string_unref(ctx->before);
-       if (ctx->after != NULL)
-               lwc_string_unref(ctx->after);
-}
 
 css_error set_hint(css_select_state *state, css_hint *hint)
 {
@@ -2114,7 +1858,7 @@ css_error match_selectors_in_sheet(css_select_ctx *ctx,
        req.media = state->media;
        req.unit_ctx = state->unit_ctx;
        req.node_bloom = state->node_data->bloom;
-       req.uni = ctx->universal;
+       req.uni = ctx->str.universal;
 
        /* Find hash chain that applies to current node */
        req.qname = state->element;
@@ -2279,7 +2023,7 @@ css_error match_selector_chain(css_select_ctx *ctx,
                /* Consider any combinator on this selector */
                if (s->data.comb != CSS_COMBINATOR_NONE &&
                                s->combinator->data.qname.name !=
-                                       ctx->universal) {
+                                       ctx->str.universal) {
                        /* Named combinator */
                        may_optimise &=
                                (s->data.comb == CSS_COMBINATOR_ANCESTOR ||
@@ -2614,7 +2358,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                        return error;
 
                if (is_root == false &&
-                               detail->qname.name == ctx->first_child) {
+                               detail->qname.name == ctx->str.first_child) {
                        int32_t num_before = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2622,7 +2366,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                        if (error == CSS_OK)
                                *match = (num_before == 0);
                } else if (is_root == false &&
-                               detail->qname.name == ctx->nth_child) {
+                               detail->qname.name == ctx->str.nth_child) {
                        int32_t num_before = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2634,7 +2378,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                                *match = match_nth(a, b, num_before + 1);
                        }
                } else if (is_root == false &&
-                               detail->qname.name == ctx->nth_last_child) {
+                               detail->qname.name == ctx->str.nth_last_child) {
                        int32_t num_after = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2646,7 +2390,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                                *match = match_nth(a, b, num_after + 1);
                        }
                } else if (is_root == false &&
-                               detail->qname.name == ctx->nth_of_type) {
+                               detail->qname.name == ctx->str.nth_of_type) {
                        int32_t num_before = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2658,7 +2402,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                                *match = match_nth(a, b, num_before + 1);
                        }
                } else if (is_root == false &&
-                               detail->qname.name == ctx->nth_last_of_type) {
+                               detail->qname.name == 
ctx->str.nth_last_of_type) {
                        int32_t num_after = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2670,7 +2414,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                                *match = match_nth(a, b, num_after + 1);
                        }
                } else if (is_root == false &&
-                               detail->qname.name == ctx->last_child) {
+                               detail->qname.name == ctx->str.last_child) {
                        int32_t num_after = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2678,7 +2422,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                        if (error == CSS_OK)
                                *match = (num_after == 0);
                } else if (is_root == false &&
-                               detail->qname.name == ctx->first_of_type) {
+                               detail->qname.name == ctx->str.first_of_type) {
                        int32_t num_before = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2686,7 +2430,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                        if (error == CSS_OK)
                                *match = (num_before == 0);
                } else if (is_root == false &&
-                               detail->qname.name == ctx->last_of_type) {
+                               detail->qname.name == ctx->str.last_of_type) {
                        int32_t num_after = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2694,7 +2438,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                        if (error == CSS_OK)
                                *match = (num_after == 0);
                } else if (is_root == false &&
-                               detail->qname.name == ctx->only_child) {
+                               detail->qname.name == ctx->str.only_child) {
                        int32_t num_before = 0, num_after = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2708,7 +2452,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                                                        (num_after == 0);
                        }
                } else if (is_root == false &&
-                               detail->qname.name == ctx->only_of_type) {
+                               detail->qname.name == ctx->str.only_of_type) {
                        int32_t num_before = 0, num_after = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2721,44 +2465,44 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                                        *match = (num_before == 0) &&
                                                        (num_after == 0);
                        }
-               } else if (detail->qname.name == ctx->root) {
+               } else if (detail->qname.name == ctx->str.root) {
                        *match = is_root;
-               } else if (detail->qname.name == ctx->empty) {
+               } else if (detail->qname.name == ctx->str.empty) {
                        error = state->handler->node_is_empty(state->pw,
                                        node, match);
-               } else if (detail->qname.name == ctx->link) {
+               } else if (detail->qname.name == ctx->str.link) {
                        error = state->handler->node_is_link(state->pw,
                                        node, match);
                        flags = CSS_NODE_FLAGS_NONE;
-               } else if (detail->qname.name == ctx->visited) {
+               } else if (detail->qname.name == ctx->str.visited) {
                        error = state->handler->node_is_visited(state->pw,
                                        node, match);
                        flags = CSS_NODE_FLAGS_NONE;
-               } else if (detail->qname.name == ctx->hover) {
+               } else if (detail->qname.name == ctx->str.hover) {
                        error = state->handler->node_is_hover(state->pw,
                                        node, match);
                        flags = CSS_NODE_FLAGS_NONE;
-               } else if (detail->qname.name == ctx->active) {
+               } else if (detail->qname.name == ctx->str.active) {
                        error = state->handler->node_is_active(state->pw,
                                        node, match);
                        flags = CSS_NODE_FLAGS_NONE;
-               } else if (detail->qname.name == ctx->focus) {
+               } else if (detail->qname.name == ctx->str.focus) {
                        error = state->handler->node_is_focus(state->pw,
                                        node, match);
                        flags = CSS_NODE_FLAGS_NONE;
-               } else if (detail->qname.name == ctx->target) {
+               } else if (detail->qname.name == ctx->str.target) {
                        error = state->handler->node_is_target(state->pw,
                                        node, match);
-               } else if (detail->qname.name == ctx->lang) {
+               } else if (detail->qname.name == ctx->str.lang) {
                        error = state->handler->node_is_lang(state->pw,
                                        node, detail->value.string, match);
-               } else if (detail->qname.name == ctx->enabled) {
+               } else if (detail->qname.name == ctx->str.enabled) {
                        error = state->handler->node_is_enabled(state->pw,
                                        node, match);
-               } else if (detail->qname.name == ctx->disabled) {
+               } else if (detail->qname.name == ctx->str.disabled) {
                        error = state->handler->node_is_disabled(state->pw,
                                        node, match);
-               } else if (detail->qname.name == ctx->checked) {
+               } else if (detail->qname.name == ctx->str.checked) {
                        error = state->handler->node_is_checked(state->pw,
                                        node, match);
                } else {
@@ -2769,13 +2513,13 @@ css_error match_detail(css_select_ctx *ctx, void *node,
        case CSS_SELECTOR_PSEUDO_ELEMENT:
                *match = true;
 
-               if (detail->qname.name == ctx->first_line) {
+               if (detail->qname.name == ctx->str.first_line) {
                        *pseudo_element = CSS_PSEUDO_ELEMENT_FIRST_LINE;
-               } else if (detail->qname.name == ctx->first_letter) {
+               } else if (detail->qname.name == ctx->str.first_letter) {
                        *pseudo_element = CSS_PSEUDO_ELEMENT_FIRST_LETTER;
-               } else if (detail->qname.name == ctx->before) {
+               } else if (detail->qname.name == ctx->str.before) {
                        *pseudo_element = CSS_PSEUDO_ELEMENT_BEFORE;
-               } else if (detail->qname.name == ctx->after) {
+               } else if (detail->qname.name == ctx->str.after) {
                        *pseudo_element = CSS_PSEUDO_ELEMENT_AFTER;
                } else
                        *match = false;
diff --git a/src/select/strings.c b/src/select/strings.c
new file mode 100644
index 0000000..2eede49
--- /dev/null
+++ b/src/select/strings.c
@@ -0,0 +1,239 @@
+/*
+ * This file is part of LibCSS
+ * Licensed under the MIT License,
+ *                http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2009 John-Mark Bell <[email protected]>
+ */
+
+#include <libwapcaplet/libwapcaplet.h>
+
+#include "select/strings.h"
+#include "utils/utils.h"
+
+css_error css_select_strings_intern(css_select_strings *str)
+{
+       lwc_error error;
+
+       /* Universal selector */
+       error = lwc_intern_string("*", SLEN("*"), &str->universal);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       /* Pseudo classes */
+       error = lwc_intern_string(
+                       "first-child", SLEN("first-child"),
+                       &str->first_child);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "link", SLEN("link"),
+                       &str->link);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "visited", SLEN("visited"),
+                       &str->visited);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "hover", SLEN("hover"),
+                       &str->hover);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "active", SLEN("active"),
+                       &str->active);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "focus", SLEN("focus"),
+                       &str->focus);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "nth-child", SLEN("nth-child"),
+                       &str->nth_child);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "nth-last-child", SLEN("nth-last-child"),
+                       &str->nth_last_child);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "nth-of-type", SLEN("nth-of-type"),
+                       &str->nth_of_type);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "nth-last-of-type", SLEN("nth-last-of-type"),
+                       &str->nth_last_of_type);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "last-child", SLEN("last-child"),
+                       &str->last_child);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "first-of-type", SLEN("first-of-type"),
+                       &str->first_of_type);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "last-of-type", SLEN("last-of-type"),
+                       &str->last_of_type);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "only-child", SLEN("only-child"),
+                       &str->only_child);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "only-of-type", SLEN("only-of-type"),
+                       &str->only_of_type);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "root", SLEN("root"),
+                       &str->root);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "empty", SLEN("empty"),
+                       &str->empty);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "target", SLEN("target"),
+                       &str->target);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "lang", SLEN("lang"),
+                       &str->lang);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "enabled", SLEN("enabled"),
+                       &str->enabled);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "disabled", SLEN("disabled"),
+                       &str->disabled);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "checked", SLEN("checked"),
+                       &str->checked);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       /* Pseudo elements */
+       error = lwc_intern_string(
+                       "first-line", SLEN("first-line"),
+                       &str->first_line);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "first_letter", SLEN("first-letter"),
+                       &str->first_letter);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "before", SLEN("before"),
+                       &str->before);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "after", SLEN("after"),
+                       &str->after);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       return CSS_OK;
+}
+
+void css_select_strings_unref(css_select_strings *str)
+{
+       if (str->universal != NULL)
+               lwc_string_unref(str->universal);
+       if (str->first_child != NULL)
+               lwc_string_unref(str->first_child);
+       if (str->link != NULL)
+               lwc_string_unref(str->link);
+       if (str->visited != NULL)
+               lwc_string_unref(str->visited);
+       if (str->hover != NULL)
+               lwc_string_unref(str->hover);
+       if (str->active != NULL)
+               lwc_string_unref(str->active);
+       if (str->focus != NULL)
+               lwc_string_unref(str->focus);
+       if (str->nth_child != NULL)
+               lwc_string_unref(str->nth_child);
+       if (str->nth_last_child != NULL)
+               lwc_string_unref(str->nth_last_child);
+       if (str->nth_of_type != NULL)
+               lwc_string_unref(str->nth_of_type);
+       if (str->nth_last_of_type != NULL)
+               lwc_string_unref(str->nth_last_of_type);
+       if (str->last_child != NULL)
+               lwc_string_unref(str->last_child);
+       if (str->first_of_type != NULL)
+               lwc_string_unref(str->first_of_type);
+       if (str->last_of_type != NULL)
+               lwc_string_unref(str->last_of_type);
+       if (str->only_child != NULL)
+               lwc_string_unref(str->only_child);
+       if (str->only_of_type != NULL)
+               lwc_string_unref(str->only_of_type);
+       if (str->root != NULL)
+               lwc_string_unref(str->root);
+       if (str->empty != NULL)
+               lwc_string_unref(str->empty);
+       if (str->target != NULL)
+               lwc_string_unref(str->target);
+       if (str->lang != NULL)
+               lwc_string_unref(str->lang);
+       if (str->enabled != NULL)
+               lwc_string_unref(str->enabled);
+       if (str->disabled != NULL)
+               lwc_string_unref(str->disabled);
+       if (str->checked != NULL)
+               lwc_string_unref(str->checked);
+       if (str->first_line != NULL)
+               lwc_string_unref(str->first_line);
+       if (str->first_letter != NULL)
+               lwc_string_unref(str->first_letter);
+       if (str->before != NULL)
+               lwc_string_unref(str->before);
+       if (str->after != NULL)
+               lwc_string_unref(str->after);
+}
diff --git a/src/select/strings.h b/src/select/strings.h
new file mode 100644
index 0000000..1861ff4
--- /dev/null
+++ b/src/select/strings.h
@@ -0,0 +1,48 @@
+/*
+ * This file is part of LibCSS
+ * Licensed under the MIT License,
+ *                http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2009 John-Mark Bell <[email protected]>
+ */
+
+#ifndef css_select_strings_h_
+#define css_select_strings_h_
+
+#include <libcss/errors.h>
+
+/** Useful interned strings */
+typedef struct {
+       lwc_string *universal;
+       lwc_string *first_child;
+       lwc_string *link;
+       lwc_string *visited;
+       lwc_string *hover;
+       lwc_string *active;
+       lwc_string *focus;
+       lwc_string *nth_child;
+       lwc_string *nth_last_child;
+       lwc_string *nth_of_type;
+       lwc_string *nth_last_of_type;
+       lwc_string *last_child;
+       lwc_string *first_of_type;
+       lwc_string *last_of_type;
+       lwc_string *only_child;
+       lwc_string *only_of_type;
+       lwc_string *root;
+       lwc_string *empty;
+       lwc_string *target;
+       lwc_string *lang;
+       lwc_string *enabled;
+       lwc_string *disabled;
+       lwc_string *checked;
+       lwc_string *first_line;
+       lwc_string *first_letter;
+       lwc_string *before;
+       lwc_string *after;
+} css_select_strings;
+
+css_error css_select_strings_intern(css_select_strings *str);
+void css_select_strings_unref(css_select_strings *str);
+
+#endif
+


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

Summary of changes:
 src/select/Makefile  |    2 +-
 src/select/hash.c    |   32 +++--
 src/select/hash.h    |    3 +-
 src/select/mq.h      |   36 ++++--
 src/select/select.c  |  346 +++++++-------------------------------------------
 src/select/strings.c |  264 ++++++++++++++++++++++++++++++++++++++
 src/select/strings.h |   52 ++++++++
 7 files changed, 411 insertions(+), 324 deletions(-)
 create mode 100644 src/select/strings.c
 create mode 100644 src/select/strings.h

diff --git a/src/select/Makefile b/src/select/Makefile
index f5ddb18..b9e7390 100644
--- a/src/select/Makefile
+++ b/src/select/Makefile
@@ -2,6 +2,6 @@
 select_generator:
        python3 src/select/select_generator.py
 
-DIR_SOURCES := arena.c computed.c dispatch.c hash.c select.c font_face.c 
format_list_style.c unit.c
+DIR_SOURCES := arena.c computed.c dispatch.c hash.c select.c strings.c 
font_face.c format_list_style.c unit.c
 
 include $(NSBUILD)/Makefile.subdir
diff --git a/src/select/hash.c b/src/select/hash.c
index 0d85d6f..12e82aa 100644
--- a/src/select/hash.c
+++ b/src/select/hash.c
@@ -370,7 +370,8 @@ css_error css__selector_hash_find(css_selector_hash *hash,
                                                head->sel_chain_bloom,
                                                req->node_bloom) &&
                                    mq_rule_good_for_media(head->sel->rule,
-                                               req->unit_ctx, req->media)) {
+                                               req->unit_ctx, req->media,
+                                               req->str)) {
                                        /* Found a match */
                                        break;
                                }
@@ -446,11 +447,12 @@ css_error 
css__selector_hash_find_by_class(css_selector_hash *hash,
                                            _chain_good_for_element_name(
                                                        head->sel,
                                                        &(req->qname),
-                                                       req->uni) &&
+                                                       req->str->universal) &&
                                            mq_rule_good_for_media(
                                                        head->sel->rule,
                                                        req->unit_ctx,
-                                                       req->media)) {
+                                                       req->media,
+                                                       req->str)) {
                                                /* Found a match */
                                                break;
                                        }
@@ -527,11 +529,12 @@ css_error css__selector_hash_find_by_id(css_selector_hash 
*hash,
                                            _chain_good_for_element_name(
                                                        head->sel,
                                                        &req->qname,
-                                                       req->uni) &&
+                                                       req->str->universal) &&
                                            mq_rule_good_for_media(
                                                        head->sel->rule,
                                                        req->unit_ctx,
-                                                       req->media)) {
+                                                       req->media,
+                                                       req->str)) {
                                                /* Found a match */
                                                break;
                                        }
@@ -581,7 +584,8 @@ css_error 
css__selector_hash_find_universal(css_selector_hash *hash,
                                        head->sel_chain_bloom,
                                        req->node_bloom) &&
                            mq_rule_good_for_media(head->sel->rule,
-                                       req->unit_ctx, req->media)) {
+                                       req->unit_ctx, req->media,
+                                       req->str)) {
                                /* Found a match */
                                break;
                        }
@@ -924,7 +928,8 @@ css_error _iterate_elements(
                                                head->sel_chain_bloom,
                                                req->node_bloom) &&
                                    mq_rule_good_for_media(head->sel->rule,
-                                               req->unit_ctx, req->media)) {
+                                               req->unit_ctx, req->media,
+                                               req->str)) {
                                        /* Found a match */
                                        break;
                                }
@@ -981,11 +986,12 @@ css_error _iterate_classes(
                                            _chain_good_for_element_name(
                                                        head->sel,
                                                        &(req->qname),
-                                                       req->uni) &&
+                                                       req->str->universal) &&
                                            mq_rule_good_for_media(
                                                        head->sel->rule,
                                                        req->unit_ctx,
-                                                       req->media)) {
+                                                       req->media,
+                                                       req->str)) {
                                                /* Found a match */
                                                break;
                                        }
@@ -1043,11 +1049,12 @@ css_error _iterate_ids(
                                            _chain_good_for_element_name(
                                                        head->sel,
                                                        &req->qname,
-                                                       req->uni) &&
+                                                       req->str->universal) &&
                                            mq_rule_good_for_media(
                                                        head->sel->rule,
                                                        req->unit_ctx,
-                                                       req->media)) {
+                                                       req->media,
+                                                       req->str)) {
                                                /* Found a match */
                                                break;
                                        }
@@ -1090,7 +1097,8 @@ css_error _iterate_universal(
                                        head->sel_chain_bloom,
                                        req->node_bloom) &&
                            mq_rule_good_for_media(head->sel->rule,
-                                       req->unit_ctx, req->media)) {
+                                       req->unit_ctx, req->media,
+                                       req->str)) {
                                /* Found a match */
                                break;
                        }
diff --git a/src/select/hash.h b/src/select/hash.h
index df4102f..5f48a38 100644
--- a/src/select/hash.h
+++ b/src/select/hash.h
@@ -15,6 +15,7 @@
 #include <libcss/functypes.h>
 
 #include "select/bloom.h"
+#include "select/strings.h"
 
 /* Ugh. We need this to avoid circular includes. Happy! */
 struct css_selector;
@@ -25,7 +26,7 @@ struct css_hash_selection_requirments {
        css_qname qname;                /* Element name, or universal "*" */
        lwc_string *class;              /* Name of class, or NULL */
        lwc_string *id;                 /* Name of id, or NULL */
-       lwc_string *uni;                /* Universal element string "*" */
+       const css_select_strings *str;  /* Selection strings */
        const css_media *media;         /* Media spec we're selecting for */
        const css_unit_ctx *unit_ctx;   /* Document unit conversion context. */
        const css_bloom *node_bloom;    /* Node's bloom filter */
diff --git a/src/select/mq.h b/src/select/mq.h
index 014814b..dd3252e 100644
--- a/src/select/mq.h
+++ b/src/select/mq.h
@@ -10,6 +10,7 @@
 #define css_select_mq_h_
 
 #include "select/helpers.h"
+#include "select/strings.h"
 #include "select/unit.h"
 
 static inline bool mq_match_feature_range_length_op1(
@@ -114,10 +115,15 @@ static inline bool mq_match_feature_eq_ident_op1(
 static inline bool mq_match_feature(
                const css_mq_feature *feat,
                const css_unit_ctx *unit_ctx,
-               const css_media *media)
+               const css_media *media,
+               const css_select_strings *str)
 {
+       bool match;
+
        /* TODO: Use interned string for comparison. */
-       if (strcmp(lwc_string_data(feat->name), "width") == 0) {
+       if (lwc_string_isequal(feat->name,
+                       str->width, &match) == lwc_error_ok &&
+                       match == true) {
                if (!mq_match_feature_range_length_op1(feat->op, &feat->value,
                                        media->width, unit_ctx)) {
                        return false;
@@ -125,7 +131,9 @@ static inline bool mq_match_feature(
                return mq_match_feature_range_length_op2(feat->op2,
                                &feat->value2, media->width, unit_ctx);
 
-       } else if (strcmp(lwc_string_data(feat->name), "height") == 0) {
+       } else if (lwc_string_isequal(feat->name,
+                       str->height, &match) == lwc_error_ok &&
+                       match == true) {
                if (!mq_match_feature_range_length_op1(feat->op, &feat->value,
                                media->height, unit_ctx)) {
                        return false;
@@ -134,7 +142,9 @@ static inline bool mq_match_feature(
                return mq_match_feature_range_length_op2(feat->op2,
                                &feat->value2, media->height, unit_ctx);
 
-       } else if (strcmp(lwc_string_data(feat->name), "prefers-color-scheme") 
== 0) {
+       } else if (lwc_string_isequal(feat->name,
+                       str->prefers_color_scheme, &match) == lwc_error_ok &&
+                       match == true) {
                if (!mq_match_feature_eq_ident_op1(feat->op, &feat->value,
                                media->prefers_color_scheme)) {
                        return false;
@@ -159,7 +169,8 @@ static inline bool mq_match_feature(
 static inline bool mq_match_condition(
                const css_mq_cond *cond,
                const css_unit_ctx *unit_ctx,
-               const css_media *media)
+               const css_media *media,
+               const css_select_strings *str)
 {
        bool matched = !cond->op;
 
@@ -168,12 +179,12 @@ static inline bool mq_match_condition(
                if (cond->parts[i]->type == CSS_MQ_FEATURE) {
                        part_matched = mq_match_feature(
                                        cond->parts[i]->data.feat,
-                                       unit_ctx, media);
+                                       unit_ctx, media, str);
                } else {
                        assert(cond->parts[i]->type == CSS_MQ_COND);
                        part_matched = mq_match_condition(
                                        cond->parts[i]->data.cond,
-                                       unit_ctx, media);
+                                       unit_ctx, media, str);
                }
 
                if (cond->op) {
@@ -208,14 +219,15 @@ static inline bool mq_match_condition(
 static inline bool mq__list_match(
                const css_mq_query *m,
                const css_unit_ctx *unit_ctx,
-               const css_media *media)
+               const css_media *media,
+               const css_select_strings *str)
 {
        for (; m != NULL; m = m->next) {
                /* Check type */
                if (!!(m->type & media->type) != m->negate_type) {
                        if (m->cond == NULL ||
                                        mq_match_condition(m->cond,
-                                                       unit_ctx, media)) {
+                                                       unit_ctx, media, str)) {
                                /* We have a match, no need to look further. */
                                return true;
                        }
@@ -236,7 +248,8 @@ static inline bool mq__list_match(
 static inline bool mq_rule_good_for_media(
                const css_rule *rule,
                const css_unit_ctx *unit_ctx,
-               const css_media *media)
+               const css_media *media,
+               const css_select_strings *str)
 {
        bool applies = true;
        const css_rule *ancestor = rule;
@@ -245,7 +258,8 @@ static inline bool mq_rule_good_for_media(
                const css_rule_media *m = (const css_rule_media *) ancestor;
 
                if (ancestor->type == CSS_RULE_MEDIA) {
-                       applies = mq__list_match(m->media, unit_ctx, media);
+                       applies = mq__list_match(m->media,
+                                       unit_ctx, media, str);
                        if (applies == false) {
                                break;
                        }
diff --git a/src/select/select.c b/src/select/select.c
index b050c0c..7d8195f 100644
--- a/src/select/select.c
+++ b/src/select/select.c
@@ -23,6 +23,7 @@
 #include "select/propset.h"
 #include "select/font_face.h"
 #include "select/select.h"
+#include "select/strings.h"
 #include "select/unit.h"
 #include "utils/parserutilserror.h"
 #include "utils/utils.h"
@@ -52,34 +53,7 @@ struct css_select_ctx {
 
        void *pw;       /**< Client's private selection context */
 
-       /* Useful interned strings */
-       lwc_string *universal;
-       lwc_string *first_child;
-       lwc_string *link;
-       lwc_string *visited;
-       lwc_string *hover;
-       lwc_string *active;
-       lwc_string *focus;
-       lwc_string *nth_child;
-       lwc_string *nth_last_child;
-       lwc_string *nth_of_type;
-       lwc_string *nth_last_of_type;
-       lwc_string *last_child;
-       lwc_string *first_of_type;
-       lwc_string *last_of_type;
-       lwc_string *only_child;
-       lwc_string *only_of_type;
-       lwc_string *root;
-       lwc_string *empty;
-       lwc_string *target;
-       lwc_string *lang;
-       lwc_string *enabled;
-       lwc_string *disabled;
-       lwc_string *checked;
-       lwc_string *first_line;
-       lwc_string *first_letter;
-       lwc_string *before;
-       lwc_string *after;
+       css_select_strings str;
 
        /* Interned default style */
        css_computed_style *default_style;
@@ -125,9 +99,6 @@ static css_error set_initial(css_select_state *state,
                uint32_t prop, css_pseudo_element pseudo,
                void *parent);
 
-static css_error intern_strings(css_select_ctx *ctx);
-static void destroy_strings(css_select_ctx *ctx);
-
 static css_error select_from_sheet(css_select_ctx *ctx,
                const css_stylesheet *sheet, css_origin origin,
                css_select_state *state);
@@ -153,7 +124,8 @@ static css_error cascade_style(const css_style *style, 
css_select_state *state);
 static css_error select_font_faces_from_sheet(
                const css_stylesheet *sheet,
                css_origin origin,
-               css_select_font_faces_state *state);
+               css_select_font_faces_state *state,
+               const css_select_strings *str);
 
 #ifdef DEBUG_CHAIN_MATCHING
 static void dump_chain(const css_selector *selector);
@@ -264,7 +236,7 @@ css_error css_select_ctx_create(css_select_ctx **result)
        if (c == NULL)
                return CSS_NOMEM;
 
-       error = intern_strings(c);
+       error = css_select_strings_intern(&c->str);
        if (error != CSS_OK) {
                free(c);
                return error;
@@ -286,7 +258,7 @@ css_error css_select_ctx_destroy(css_select_ctx *ctx)
        if (ctx == NULL)
                return CSS_BADPARM;
 
-       destroy_strings(ctx);
+       css_select_strings_unref(&ctx->str);
 
        if (ctx->default_style != NULL)
                css_computed_style_destroy(ctx->default_style);
@@ -1273,7 +1245,7 @@ css_error css_select_style(css_select_ctx *ctx, void 
*node,
        for (i = 0; i < ctx->n_sheets; i++) {
                const css_select_sheet s = ctx->sheets[i];
 
-               if (mq__list_match(s.media, unit_ctx, media) &&
+               if (mq__list_match(s.media, unit_ctx, media, &ctx->str) &&
                                s.sheet->disabled == false) {
                        error = select_from_sheet(ctx, s.sheet,
                                        s.origin, &state);
@@ -1454,10 +1426,10 @@ css_error css_select_font_faces(css_select_ctx *ctx,
        for (i = 0; i < ctx->n_sheets; i++) {
                const css_select_sheet s = ctx->sheets[i];
 
-               if (mq__list_match(s.media, unit_ctx, media) &&
+               if (mq__list_match(s.media, unit_ctx, media, &ctx->str) &&
                                s.sheet->disabled == false) {
                        error = select_font_faces_from_sheet(s.sheet,
-                                       s.origin, &state);
+                                       s.origin, &state, &ctx->str);
                        if (error != CSS_OK)
                                goto cleanup;
                }
@@ -1559,233 +1531,6 @@ css_error css_select_font_faces_results_destroy(
  * Selection engine internals below here                                      *
  
******************************************************************************/
 
-css_error intern_strings(css_select_ctx *ctx)
-{
-       lwc_error error;
-
-       /* Universal selector */
-       error = lwc_intern_string("*", SLEN("*"), &ctx->universal);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       /* Pseudo classes */
-       error = lwc_intern_string(
-                       "first-child", SLEN("first-child"),
-                       &ctx->first_child);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "link", SLEN("link"),
-                       &ctx->link);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "visited", SLEN("visited"),
-                       &ctx->visited);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "hover", SLEN("hover"),
-                       &ctx->hover);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "active", SLEN("active"),
-                       &ctx->active);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "focus", SLEN("focus"),
-                       &ctx->focus);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "nth-child", SLEN("nth-child"),
-                       &ctx->nth_child);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "nth-last-child", SLEN("nth-last-child"),
-                       &ctx->nth_last_child);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "nth-of-type", SLEN("nth-of-type"),
-                       &ctx->nth_of_type);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "nth-last-of-type", SLEN("nth-last-of-type"),
-                       &ctx->nth_last_of_type);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "last-child", SLEN("last-child"),
-                       &ctx->last_child);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "first-of-type", SLEN("first-of-type"),
-                       &ctx->first_of_type);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "last-of-type", SLEN("last-of-type"),
-                       &ctx->last_of_type);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "only-child", SLEN("only-child"),
-                       &ctx->only_child);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "only-of-type", SLEN("only-of-type"),
-                       &ctx->only_of_type);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "root", SLEN("root"),
-                       &ctx->root);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "empty", SLEN("empty"),
-                       &ctx->empty);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "target", SLEN("target"),
-                       &ctx->target);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "lang", SLEN("lang"),
-                       &ctx->lang);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "enabled", SLEN("enabled"),
-                       &ctx->enabled);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "disabled", SLEN("disabled"),
-                       &ctx->disabled);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "checked", SLEN("checked"),
-                       &ctx->checked);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       /* Pseudo elements */
-       error = lwc_intern_string(
-                       "first-line", SLEN("first-line"),
-                       &ctx->first_line);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "first_letter", SLEN("first-letter"),
-                       &ctx->first_letter);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "before", SLEN("before"),
-                       &ctx->before);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       error = lwc_intern_string(
-                       "after", SLEN("after"),
-                       &ctx->after);
-       if (error != lwc_error_ok)
-               return css_error_from_lwc_error(error);
-
-       return CSS_OK;
-}
-
-void destroy_strings(css_select_ctx *ctx)
-{
-       if (ctx->universal != NULL)
-               lwc_string_unref(ctx->universal);
-       if (ctx->first_child != NULL)
-               lwc_string_unref(ctx->first_child);
-       if (ctx->link != NULL)
-               lwc_string_unref(ctx->link);
-       if (ctx->visited != NULL)
-               lwc_string_unref(ctx->visited);
-       if (ctx->hover != NULL)
-               lwc_string_unref(ctx->hover);
-       if (ctx->active != NULL)
-               lwc_string_unref(ctx->active);
-       if (ctx->focus != NULL)
-               lwc_string_unref(ctx->focus);
-       if (ctx->nth_child != NULL)
-               lwc_string_unref(ctx->nth_child);
-       if (ctx->nth_last_child != NULL)
-               lwc_string_unref(ctx->nth_last_child);
-       if (ctx->nth_of_type != NULL)
-               lwc_string_unref(ctx->nth_of_type);
-       if (ctx->nth_last_of_type != NULL)
-               lwc_string_unref(ctx->nth_last_of_type);
-       if (ctx->last_child != NULL)
-               lwc_string_unref(ctx->last_child);
-       if (ctx->first_of_type != NULL)
-               lwc_string_unref(ctx->first_of_type);
-       if (ctx->last_of_type != NULL)
-               lwc_string_unref(ctx->last_of_type);
-       if (ctx->only_child != NULL)
-               lwc_string_unref(ctx->only_child);
-       if (ctx->only_of_type != NULL)
-               lwc_string_unref(ctx->only_of_type);
-       if (ctx->root != NULL)
-               lwc_string_unref(ctx->root);
-       if (ctx->empty != NULL)
-               lwc_string_unref(ctx->empty);
-       if (ctx->target != NULL)
-               lwc_string_unref(ctx->target);
-       if (ctx->lang != NULL)
-               lwc_string_unref(ctx->lang);
-       if (ctx->enabled != NULL)
-               lwc_string_unref(ctx->enabled);
-       if (ctx->disabled != NULL)
-               lwc_string_unref(ctx->disabled);
-       if (ctx->checked != NULL)
-               lwc_string_unref(ctx->checked);
-       if (ctx->first_line != NULL)
-               lwc_string_unref(ctx->first_line);
-       if (ctx->first_letter != NULL)
-               lwc_string_unref(ctx->first_letter);
-       if (ctx->before != NULL)
-               lwc_string_unref(ctx->before);
-       if (ctx->after != NULL)
-               lwc_string_unref(ctx->after);
-}
 
 css_error set_hint(css_select_state *state, css_hint *hint)
 {
@@ -1855,7 +1600,8 @@ css_error select_from_sheet(css_select_ctx *ctx, const 
css_stylesheet *sheet,
                        if (import->sheet != NULL &&
                                        mq__list_match(import->media,
                                                        state->unit_ctx,
-                                                       state->media)) {
+                                                       state->media,
+                                                       &ctx->str)) {
                                /* It's applicable, so process it */
                                if (sp >= IMPORT_STACK_SIZE)
                                        return CSS_NOMEM;
@@ -1896,10 +1642,11 @@ css_error select_from_sheet(css_select_ctx *ctx, const 
css_stylesheet *sheet,
 
 static css_error _select_font_face_from_rule(
                const css_rule_font_face *rule, css_origin origin,
-               css_select_font_faces_state *state)
+               css_select_font_faces_state *state,
+               const css_select_strings *str)
 {
        if (mq_rule_good_for_media((const css_rule *) rule,
-                       state->unit_ctx, state->media)) {
+                       state->unit_ctx, state->media, str)) {
                bool correct_family = false;
 
                if (lwc_string_isequal(
@@ -1943,7 +1690,8 @@ static css_error _select_font_face_from_rule(
 static css_error select_font_faces_from_sheet(
                const css_stylesheet *sheet,
                css_origin origin,
-               css_select_font_faces_state *state)
+               css_select_font_faces_state *state,
+               const css_select_strings *str)
 {
        const css_stylesheet *s = sheet;
        const css_rule *rule = s->rule_list;
@@ -1965,7 +1713,8 @@ static css_error select_font_faces_from_sheet(
                        if (import->sheet != NULL &&
                                        mq__list_match(import->media,
                                                        state->unit_ctx,
-                                                       state->media)) {
+                                                       state->media,
+                                                       str)) {
                                /* It's applicable, so process it */
                                if (sp >= IMPORT_STACK_SIZE)
                                        return CSS_NOMEM;
@@ -1983,8 +1732,7 @@ static css_error select_font_faces_from_sheet(
 
                        error = _select_font_face_from_rule(
                                        (const css_rule_font_face *) rule,
-                                       origin,
-                                       state);
+                                       origin, state, str);
 
                        if (error != CSS_OK)
                                return error;
@@ -2114,7 +1862,7 @@ css_error match_selectors_in_sheet(css_select_ctx *ctx,
        req.media = state->media;
        req.unit_ctx = state->unit_ctx;
        req.node_bloom = state->node_data->bloom;
-       req.uni = ctx->universal;
+       req.str = &ctx->str;
 
        /* Find hash chain that applies to current node */
        req.qname = state->element;
@@ -2279,7 +2027,7 @@ css_error match_selector_chain(css_select_ctx *ctx,
                /* Consider any combinator on this selector */
                if (s->data.comb != CSS_COMBINATOR_NONE &&
                                s->combinator->data.qname.name !=
-                                       ctx->universal) {
+                                       ctx->str.universal) {
                        /* Named combinator */
                        may_optimise &=
                                (s->data.comb == CSS_COMBINATOR_ANCESTOR ||
@@ -2614,7 +2362,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                        return error;
 
                if (is_root == false &&
-                               detail->qname.name == ctx->first_child) {
+                               detail->qname.name == ctx->str.first_child) {
                        int32_t num_before = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2622,7 +2370,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                        if (error == CSS_OK)
                                *match = (num_before == 0);
                } else if (is_root == false &&
-                               detail->qname.name == ctx->nth_child) {
+                               detail->qname.name == ctx->str.nth_child) {
                        int32_t num_before = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2634,7 +2382,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                                *match = match_nth(a, b, num_before + 1);
                        }
                } else if (is_root == false &&
-                               detail->qname.name == ctx->nth_last_child) {
+                               detail->qname.name == ctx->str.nth_last_child) {
                        int32_t num_after = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2646,7 +2394,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                                *match = match_nth(a, b, num_after + 1);
                        }
                } else if (is_root == false &&
-                               detail->qname.name == ctx->nth_of_type) {
+                               detail->qname.name == ctx->str.nth_of_type) {
                        int32_t num_before = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2658,7 +2406,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                                *match = match_nth(a, b, num_before + 1);
                        }
                } else if (is_root == false &&
-                               detail->qname.name == ctx->nth_last_of_type) {
+                               detail->qname.name == 
ctx->str.nth_last_of_type) {
                        int32_t num_after = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2670,7 +2418,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                                *match = match_nth(a, b, num_after + 1);
                        }
                } else if (is_root == false &&
-                               detail->qname.name == ctx->last_child) {
+                               detail->qname.name == ctx->str.last_child) {
                        int32_t num_after = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2678,7 +2426,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                        if (error == CSS_OK)
                                *match = (num_after == 0);
                } else if (is_root == false &&
-                               detail->qname.name == ctx->first_of_type) {
+                               detail->qname.name == ctx->str.first_of_type) {
                        int32_t num_before = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2686,7 +2434,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                        if (error == CSS_OK)
                                *match = (num_before == 0);
                } else if (is_root == false &&
-                               detail->qname.name == ctx->last_of_type) {
+                               detail->qname.name == ctx->str.last_of_type) {
                        int32_t num_after = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2694,7 +2442,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                        if (error == CSS_OK)
                                *match = (num_after == 0);
                } else if (is_root == false &&
-                               detail->qname.name == ctx->only_child) {
+                               detail->qname.name == ctx->str.only_child) {
                        int32_t num_before = 0, num_after = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2708,7 +2456,7 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                                                        (num_after == 0);
                        }
                } else if (is_root == false &&
-                               detail->qname.name == ctx->only_of_type) {
+                               detail->qname.name == ctx->str.only_of_type) {
                        int32_t num_before = 0, num_after = 0;
 
                        error = state->handler->node_count_siblings(state->pw,
@@ -2721,44 +2469,44 @@ css_error match_detail(css_select_ctx *ctx, void *node,
                                        *match = (num_before == 0) &&
                                                        (num_after == 0);
                        }
-               } else if (detail->qname.name == ctx->root) {
+               } else if (detail->qname.name == ctx->str.root) {
                        *match = is_root;
-               } else if (detail->qname.name == ctx->empty) {
+               } else if (detail->qname.name == ctx->str.empty) {
                        error = state->handler->node_is_empty(state->pw,
                                        node, match);
-               } else if (detail->qname.name == ctx->link) {
+               } else if (detail->qname.name == ctx->str.link) {
                        error = state->handler->node_is_link(state->pw,
                                        node, match);
                        flags = CSS_NODE_FLAGS_NONE;
-               } else if (detail->qname.name == ctx->visited) {
+               } else if (detail->qname.name == ctx->str.visited) {
                        error = state->handler->node_is_visited(state->pw,
                                        node, match);
                        flags = CSS_NODE_FLAGS_NONE;
-               } else if (detail->qname.name == ctx->hover) {
+               } else if (detail->qname.name == ctx->str.hover) {
                        error = state->handler->node_is_hover(state->pw,
                                        node, match);
                        flags = CSS_NODE_FLAGS_NONE;
-               } else if (detail->qname.name == ctx->active) {
+               } else if (detail->qname.name == ctx->str.active) {
                        error = state->handler->node_is_active(state->pw,
                                        node, match);
                        flags = CSS_NODE_FLAGS_NONE;
-               } else if (detail->qname.name == ctx->focus) {
+               } else if (detail->qname.name == ctx->str.focus) {
                        error = state->handler->node_is_focus(state->pw,
                                        node, match);
                        flags = CSS_NODE_FLAGS_NONE;
-               } else if (detail->qname.name == ctx->target) {
+               } else if (detail->qname.name == ctx->str.target) {
                        error = state->handler->node_is_target(state->pw,
                                        node, match);
-               } else if (detail->qname.name == ctx->lang) {
+               } else if (detail->qname.name == ctx->str.lang) {
                        error = state->handler->node_is_lang(state->pw,
                                        node, detail->value.string, match);
-               } else if (detail->qname.name == ctx->enabled) {
+               } else if (detail->qname.name == ctx->str.enabled) {
                        error = state->handler->node_is_enabled(state->pw,
                                        node, match);
-               } else if (detail->qname.name == ctx->disabled) {
+               } else if (detail->qname.name == ctx->str.disabled) {
                        error = state->handler->node_is_disabled(state->pw,
                                        node, match);
-               } else if (detail->qname.name == ctx->checked) {
+               } else if (detail->qname.name == ctx->str.checked) {
                        error = state->handler->node_is_checked(state->pw,
                                        node, match);
                } else {
@@ -2769,13 +2517,13 @@ css_error match_detail(css_select_ctx *ctx, void *node,
        case CSS_SELECTOR_PSEUDO_ELEMENT:
                *match = true;
 
-               if (detail->qname.name == ctx->first_line) {
+               if (detail->qname.name == ctx->str.first_line) {
                        *pseudo_element = CSS_PSEUDO_ELEMENT_FIRST_LINE;
-               } else if (detail->qname.name == ctx->first_letter) {
+               } else if (detail->qname.name == ctx->str.first_letter) {
                        *pseudo_element = CSS_PSEUDO_ELEMENT_FIRST_LETTER;
-               } else if (detail->qname.name == ctx->before) {
+               } else if (detail->qname.name == ctx->str.before) {
                        *pseudo_element = CSS_PSEUDO_ELEMENT_BEFORE;
-               } else if (detail->qname.name == ctx->after) {
+               } else if (detail->qname.name == ctx->str.after) {
                        *pseudo_element = CSS_PSEUDO_ELEMENT_AFTER;
                } else
                        *match = false;
diff --git a/src/select/strings.c b/src/select/strings.c
new file mode 100644
index 0000000..6e9137d
--- /dev/null
+++ b/src/select/strings.c
@@ -0,0 +1,264 @@
+/*
+ * This file is part of LibCSS
+ * Licensed under the MIT License,
+ *                http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2009 John-Mark Bell <[email protected]>
+ */
+
+#include <libwapcaplet/libwapcaplet.h>
+
+#include "select/strings.h"
+#include "utils/utils.h"
+
+css_error css_select_strings_intern(css_select_strings *str)
+{
+       lwc_error error;
+
+       /* Universal selector */
+       error = lwc_intern_string("*", SLEN("*"), &str->universal);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       /* Pseudo classes */
+       error = lwc_intern_string(
+                       "first-child", SLEN("first-child"),
+                       &str->first_child);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "link", SLEN("link"),
+                       &str->link);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "visited", SLEN("visited"),
+                       &str->visited);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "hover", SLEN("hover"),
+                       &str->hover);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "active", SLEN("active"),
+                       &str->active);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "focus", SLEN("focus"),
+                       &str->focus);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "nth-child", SLEN("nth-child"),
+                       &str->nth_child);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "nth-last-child", SLEN("nth-last-child"),
+                       &str->nth_last_child);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "nth-of-type", SLEN("nth-of-type"),
+                       &str->nth_of_type);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "nth-last-of-type", SLEN("nth-last-of-type"),
+                       &str->nth_last_of_type);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "last-child", SLEN("last-child"),
+                       &str->last_child);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "first-of-type", SLEN("first-of-type"),
+                       &str->first_of_type);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "last-of-type", SLEN("last-of-type"),
+                       &str->last_of_type);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "only-child", SLEN("only-child"),
+                       &str->only_child);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "only-of-type", SLEN("only-of-type"),
+                       &str->only_of_type);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "root", SLEN("root"),
+                       &str->root);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "empty", SLEN("empty"),
+                       &str->empty);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "target", SLEN("target"),
+                       &str->target);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "lang", SLEN("lang"),
+                       &str->lang);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "enabled", SLEN("enabled"),
+                       &str->enabled);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "disabled", SLEN("disabled"),
+                       &str->disabled);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "checked", SLEN("checked"),
+                       &str->checked);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       /* Pseudo elements */
+       error = lwc_intern_string(
+                       "first-line", SLEN("first-line"),
+                       &str->first_line);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "first_letter", SLEN("first-letter"),
+                       &str->first_letter);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "before", SLEN("before"),
+                       &str->before);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "after", SLEN("after"),
+                       &str->after);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "width", SLEN("width"),
+                       &str->width);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "height", SLEN("height"),
+                       &str->height);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       error = lwc_intern_string(
+                       "prefers-color-scheme", SLEN("prefers-color-scheme"),
+                       &str->prefers_color_scheme);
+       if (error != lwc_error_ok)
+               return css_error_from_lwc_error(error);
+
+       return CSS_OK;
+}
+
+void css_select_strings_unref(css_select_strings *str)
+{
+       if (str->universal != NULL)
+               lwc_string_unref(str->universal);
+       if (str->first_child != NULL)
+               lwc_string_unref(str->first_child);
+       if (str->link != NULL)
+               lwc_string_unref(str->link);
+       if (str->visited != NULL)
+               lwc_string_unref(str->visited);
+       if (str->hover != NULL)
+               lwc_string_unref(str->hover);
+       if (str->active != NULL)
+               lwc_string_unref(str->active);
+       if (str->focus != NULL)
+               lwc_string_unref(str->focus);
+       if (str->nth_child != NULL)
+               lwc_string_unref(str->nth_child);
+       if (str->nth_last_child != NULL)
+               lwc_string_unref(str->nth_last_child);
+       if (str->nth_of_type != NULL)
+               lwc_string_unref(str->nth_of_type);
+       if (str->nth_last_of_type != NULL)
+               lwc_string_unref(str->nth_last_of_type);
+       if (str->last_child != NULL)
+               lwc_string_unref(str->last_child);
+       if (str->first_of_type != NULL)
+               lwc_string_unref(str->first_of_type);
+       if (str->last_of_type != NULL)
+               lwc_string_unref(str->last_of_type);
+       if (str->only_child != NULL)
+               lwc_string_unref(str->only_child);
+       if (str->only_of_type != NULL)
+               lwc_string_unref(str->only_of_type);
+       if (str->root != NULL)
+               lwc_string_unref(str->root);
+       if (str->empty != NULL)
+               lwc_string_unref(str->empty);
+       if (str->target != NULL)
+               lwc_string_unref(str->target);
+       if (str->lang != NULL)
+               lwc_string_unref(str->lang);
+       if (str->enabled != NULL)
+               lwc_string_unref(str->enabled);
+       if (str->disabled != NULL)
+               lwc_string_unref(str->disabled);
+       if (str->checked != NULL)
+               lwc_string_unref(str->checked);
+       if (str->first_line != NULL)
+               lwc_string_unref(str->first_line);
+       if (str->first_letter != NULL)
+               lwc_string_unref(str->first_letter);
+       if (str->before != NULL)
+               lwc_string_unref(str->before);
+       if (str->after != NULL)
+               lwc_string_unref(str->after);
+
+       if (str->width != NULL)
+               lwc_string_unref(str->width);
+       if (str->height != NULL)
+               lwc_string_unref(str->height);
+       if (str->prefers_color_scheme != NULL)
+               lwc_string_unref(str->prefers_color_scheme);
+}
diff --git a/src/select/strings.h b/src/select/strings.h
new file mode 100644
index 0000000..ff965e5
--- /dev/null
+++ b/src/select/strings.h
@@ -0,0 +1,52 @@
+/*
+ * This file is part of LibCSS
+ * Licensed under the MIT License,
+ *                http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2009 John-Mark Bell <[email protected]>
+ */
+
+#ifndef css_select_strings_h_
+#define css_select_strings_h_
+
+#include <libcss/errors.h>
+
+/** Useful interned strings */
+typedef struct {
+       lwc_string *universal;
+       lwc_string *first_child;
+       lwc_string *link;
+       lwc_string *visited;
+       lwc_string *hover;
+       lwc_string *active;
+       lwc_string *focus;
+       lwc_string *nth_child;
+       lwc_string *nth_last_child;
+       lwc_string *nth_of_type;
+       lwc_string *nth_last_of_type;
+       lwc_string *last_child;
+       lwc_string *first_of_type;
+       lwc_string *last_of_type;
+       lwc_string *only_child;
+       lwc_string *only_of_type;
+       lwc_string *root;
+       lwc_string *empty;
+       lwc_string *target;
+       lwc_string *lang;
+       lwc_string *enabled;
+       lwc_string *disabled;
+       lwc_string *checked;
+       lwc_string *first_line;
+       lwc_string *first_letter;
+       lwc_string *before;
+       lwc_string *after;
+
+       lwc_string *width;
+       lwc_string *height;
+       lwc_string *prefers_color_scheme;
+} css_select_strings;
+
+css_error css_select_strings_intern(css_select_strings *str);
+void css_select_strings_unref(css_select_strings *str);
+
+#endif
+


-- 
Cascading Style Sheets library
_______________________________________________
netsurf-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to