Exemple #1
0
void
fz_match_css(fz_context *ctx, fz_css_match *match, fz_css_rule *css, fz_xml *node)
{
	fz_css_rule *rule;
	fz_css_selector *sel;
	fz_css_property *prop, *head, *tail;
	const char *s;

	for (rule = css; rule; rule = rule->next)
	{
		sel = rule->selector;
		while (sel)
		{
			if (match_selector(sel, node))
			{
				for (prop = rule->declaration; prop; prop = prop->next)
					add_property(match, prop->name, prop->value, selector_specificity(sel, prop->important));
				break;
			}
			sel = sel->next;
		}
	}

	s = fz_xml_att(node, "style");
	if (s)
	{
		fz_try(ctx)
		{
			head = tail = prop = fz_parse_css_properties(ctx, s);
			while (prop)
			{
				add_property(match, prop->name, prop->value, INLINE_SPECIFICITY);
				tail = prop;
				prop = prop->next;
			}
			if (tail)
				tail->next = css->garbage;
			css->garbage = head;
		}
		fz_catch(ctx)
		{
			fz_warn(ctx, "ignoring style attribute");
		}
	}

	sort_properties(match); /* speed up subsequent value_from_raw_property lookups */
}
Exemple #2
0
void
fz_match_css(fz_context *ctx, fz_css_match *match, fz_css_rule *css, fz_xml *node)
{
	fz_css_rule *rule;
	fz_css_selector *sel;
	fz_css_property *prop, *head, *tail;
	const char *s;

	for (rule = css; rule; rule = rule->next)
	{
		sel = rule->selector;
		while (sel)
		{
			if (match_selector(sel, node))
			{
				for (prop = rule->declaration; prop; prop = prop->next)
					add_property(match, prop->name, prop->value, selector_specificity(sel));
				break;
			}
			sel = sel->next;
		}
	}

	s = fz_xml_att(node, "style");
	if (s)
	{
		head = tail = prop = fz_parse_css_properties(ctx, s);
		while (prop)
		{
			add_property(match, prop->name, prop->value, INLINE_SPECIFICITY);
			tail = prop;
			prop = prop->next;
		}
		if (tail)
			tail->next = css->garbage;
		css->garbage = head;
	}
}
Exemple #3
0
static int
match_selector(fz_css_selector *sel, fz_xml *node)
{
	if (!node)
		return 0;

	if (sel->combine)
	{
		/* descendant */
		if (sel->combine == ' ')
		{
			fz_xml *parent = fz_xml_up(node);
			while (parent)
			{
				if (match_selector(sel->left, parent))
					if (match_selector(sel->right, node))
						return 1;
				parent = fz_xml_up(parent);
			}
			return 0;
		}

		/* child */
		if (sel->combine == '>')
		{
			fz_xml *parent = fz_xml_up(node);
			if (!parent)
				return 0;
			if (!match_selector(sel->left, parent))
				return 0;
			if (!match_selector(sel->right, node))
				return 0;
		}

		/* adjacent */
		if (sel->combine == '+')
		{
			fz_xml *prev = fz_xml_prev(node);
			while (prev && !fz_xml_tag(prev))
				prev = fz_xml_prev(prev);
			if (!prev)
				return 0;
			if (!fz_xml_tag(prev))
				return 0;
			if (!match_selector(sel->left, prev))
				return 0;
			if (!match_selector(sel->right, node))
				return 0;
		}
	}

	if (sel->name)
	{
		if (strcmp(sel->name, fz_xml_tag(node)))
			return 0;
	}

	if (sel->cond)
	{
		if (!match_condition(sel->cond, node))
			return 0;
	}

	return 1;
}