summaryrefslogtreecommitdiff
path: root/source/html/css-apply.c
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2016-04-14 13:26:05 +0200
committerTor Andersson <tor.andersson@artifex.com>2016-04-26 15:12:57 +0200
commitb935334975d13548379b58d1883eea98dc0f4eda (patch)
tree4bccf4e34edcb1b8f59a157f0a4296dee00de750 /source/html/css-apply.c
parent1c7e4d15c16908b8591a856504008a10b7418a9a (diff)
downloadmupdf-b935334975d13548379b58d1883eea98dc0f4eda.tar.xz
epub: Add matching for [att], [att=val] and [att~=val] css selectors.
Diffstat (limited to 'source/html/css-apply.c')
-rw-r--r--source/html/css-apply.c37
1 files changed, 23 insertions, 14 deletions
diff --git a/source/html/css-apply.c b/source/html/css-apply.c
index 7fbe81e6..3daff6b4 100644
--- a/source/html/css-apply.c
+++ b/source/html/css-apply.c
@@ -217,29 +217,34 @@ selector_specificity(fz_css_selector *sel, int important)
*/
static int
-match_id_condition(fz_xml *node, const char *p)
+match_att_exists_condition(fz_xml *node, const char *key)
{
- const char *s = fz_xml_att(node, "id");
- if (s && !strcmp(s, p))
- return 1;
- return 0;
+ const char *s = fz_xml_att(node, key);
+ return s != NULL;
+}
+
+static int
+match_att_is_condition(fz_xml *node, const char *key, const char *val)
+{
+ const char *att = fz_xml_att(node, key);
+ return att && !strcmp(val, att);
}
static int
-match_class_condition(fz_xml *node, const char *p)
+match_att_has_condition(fz_xml *node, const char *att, const char *needle)
{
- const char *s = fz_xml_att(node, "class");
+ const char *haystack = fz_xml_att(node, att);
const char *ss;
int n;
- if (s) {
+ if (haystack) {
/* Try matching whole property first. */
- if (!strcmp(s, p))
+ if (!strcmp(haystack, needle))
return 1;
/* Look for matching words. */
- n = strlen(p);
- ss = strstr(s, p);
- if (ss && (ss[n] == ' ' || ss[n] == 0) && (ss == s || ss[-1] == ' '))
+ n = strlen(needle);
+ ss = strstr(haystack, needle);
+ if (ss && (ss[n] == ' ' || ss[n] == 0) && (ss == haystack || ss[-1] == ' '))
return 1;
}
return 0;
@@ -254,8 +259,12 @@ match_condition(fz_css_condition *cond, fz_xml *node)
switch (cond->type) {
default: return 0;
case ':': return 0; /* don't support pseudo-classes */
- case '#': if (!match_id_condition(node, cond->val)) return 0; break;
- case '.': if (!match_class_condition(node, cond->val)) return 0; break;
+ case '#': if (!match_att_is_condition(node, "id", cond->val)) return 0; break;
+ case '.': if (!match_att_has_condition(node, "class", cond->val)) return 0; break;
+ case '[': if (!match_att_exists_condition(node, cond->key)) return 0; break;
+ case '=': if (!match_att_is_condition(node, cond->key, cond->val)) return 0; break;
+ case '~': if (!match_att_has_condition(node, cond->key, cond->val)) return 0; break;
+ case '|': if (!match_att_is_condition(node, cond->key, cond->val)) return 0; break;
}
return match_condition(cond->next, node);