iconv: Bail out of the loop when an illegal sequence of bytes occurs.
[elinks/elinks-j605.git] / src / document / css / stylesheet.h
blob01f0e9e5b9d29aa87ceae00aebaefe1dad4e90e0
2 #ifndef EL__DOCUMENT_CSS_STYLESHEET_H
3 #define EL__DOCUMENT_CSS_STYLESHEET_H
5 #include "protocol/uri.h"
6 #include "util/lists.h"
8 /* #define DEBUG_CSS */
10 /** @file
11 * @todo TODO: We need a memory efficient and fast way to define how
12 * properties cascade. What we are interested in is making it fast and
13 * easy to find all properties we need.
15 * @code
16 * struct css_cascade {
17 * struct css_cascade *parent;
18 * struct list_head properties;
20 * - Can later be turned into a table to not waste memory:
21 * struct css_property properties[1];
22 * };
23 * @endcode
25 * And the selector should then only map a document element into this
26 * data structure.
28 * All the CSS applier has to do is require the css_cascade of the current
29 * element and it should nicely inherit any style from parent cascades.
30 * Question is in what direction to apply. It should be possible for the user
31 * to overwrite any document provided stylesheet using "!important" so we need
32 * to keep track in some table what properties was already applied so we only
33 * overwrite when we have to. --jonas
35 * XXX: This is one of the TODOs where I have no clue what is it talking about
36 * in particular. Is it obsolete now when we grok 'td.foo p#x>a:hover' without
37 * hesitation? --pasky */
39 /** A set of struct css_selector. This is currently represented as a
40 * list but that may be changed later. Therefore please try not to
41 * access the contents directly; instead define new wrapper macros.
43 * According to CSS2 section 7.1 "Cascading order", if two rules have
44 * the same weight, then the latter specified wins. Regardless, the
45 * order of rules need not be represented in struct css_selector_set,
46 * because all rules for the same selector have already been merged
47 * into one struct css_selector. */
48 struct css_selector_set {
49 unsigned char may_contain_rel_ancestor_or_parent;
51 /** The list of selectors in this set.
53 * Sets are currently represented as lists that
54 * find_css_selector() then has to search linearly.
55 * Hashing was also tested but did not help in practice:
56 * each find_css_selector() call runs approximately one
57 * strcasecmp(), and a hash function is unlikely to be
58 * faster than that. See ELinks bug 789 for details.
60 * Keep this away from the beginning of the structure,
61 * so that nobody can cast the struct css_selector_set *
62 * to LIST_OF(struct css_selector) * and get away with it. */
63 LIST_OF(struct css_selector) list;
65 #define INIT_CSS_SELECTOR_SET(set) { 0, { D_LIST_HEAD(set.list) } }
67 /** The struct css_selector is used for mapping elements (or nodes) in the
68 * document structure to properties. See README for some hints about how the
69 * trees of these span. */
70 struct css_selector {
71 LIST_HEAD(struct css_selector);
73 /** This defines relation between this selector fragment and its
74 * parent in the selector tree.
75 * Update with set_css_selector_relation(). */
76 enum css_selector_relation {
77 CSR_ROOT, /**< First class stylesheet member. */
78 CSR_SPECIFITY, /**< Narrowing-down, i.e. the "x" in "foo#x". */
79 CSR_ANCESTOR, /**< Ancestor, i.e. the "p" in "p a". */
80 CSR_PARENT, /**< Direct parent, i.e. the "div" in "div>img". */
81 } relation;
82 struct css_selector_set leaves;
84 enum css_selector_type {
85 CST_ELEMENT,
86 CST_ID,
87 CST_CLASS,
88 CST_PSEUDO,
89 CST_INVALID, /**< Auxiliary for the parser */
90 } type;
91 unsigned char *name;
93 LIST_OF(struct css_property) properties;
97 struct css_stylesheet;
98 typedef void (*css_stylesheet_importer_T)(struct css_stylesheet *, struct uri *,
99 const unsigned char *url, int urllen);
101 /** The struct css_stylesheet describes all the useful data that was extracted
102 * from the CSS source. Currently we don't cache anything but the default user
103 * stylesheet so it can contain stuff from both @<style> tags and @@import'ed
104 * CSS documents. */
105 struct css_stylesheet {
106 /** The import callback function. The caller must check the
107 * media types first. */
108 css_stylesheet_importer_T import;
110 /** The import callback's data. */
111 void *import_data;
113 /** The set of basic element selectors (which can then somehow
114 * tree up on inside). */
115 struct css_selector_set selectors;
117 /** How deeply nested are we. Limited by MAX_REDIRECTS. */
118 int import_level;
121 #define INIT_CSS_STYLESHEET(css, import) \
122 { import, NULL, INIT_CSS_SELECTOR_SET(css.selectors) }
124 /** Dynamically allocates a stylesheet. */
125 struct css_stylesheet *init_css_stylesheet(css_stylesheet_importer_T importer,
126 void *import_data);
128 /** Mirror given CSS stylesheet @a css1 to an identical copy of itself
129 * (including all the selectors), @a css2. */
130 void mirror_css_stylesheet(struct css_stylesheet *css1,
131 struct css_stylesheet *css2);
133 /** Releases all the content of the stylesheet (but not the stylesheet
134 * itself). */
135 void done_css_stylesheet(struct css_stylesheet *css);
138 /** Returns a new freshly made selector adding it to the given selector
139 * set, or NULL. */
140 struct css_selector *get_css_selector(struct css_selector_set *set,
141 enum css_selector_type type,
142 enum css_selector_relation rel,
143 const unsigned char *name, int namelen);
145 #define get_css_base_selector(stylesheet, type, rel, name, namelen) \
146 get_css_selector((stylesheet) ? &(stylesheet)->selectors : NULL, \
147 type, rel, name, namelen)
149 /** Looks up the selector of the name @a name and length @a namelen in
150 * the given set of selectors. */
151 struct css_selector *find_css_selector(struct css_selector_set *set,
152 enum css_selector_type type,
153 enum css_selector_relation rel,
154 const unsigned char *name, int namelen);
156 #define find_css_base_selector(stylesheet, type, rel, name, namelen) \
157 find_css_selector(&stylesheet->selectors, rel, type, name, namelen)
159 /** Initialize the selector structure. This is a rather low-level
160 * function from your POV. */
161 struct css_selector *init_css_selector(struct css_selector_set *set,
162 enum css_selector_type type,
163 enum css_selector_relation relation,
164 const unsigned char *name, int namelen);
166 /** Add all properties from the list to the given @a selector. */
167 void add_selector_properties(struct css_selector *selector,
168 LIST_OF(struct css_property) *properties);
170 /** Join @a sel2 to @a sel1, @a sel1 taking precedence in all conflicts. */
171 void merge_css_selectors(struct css_selector *sel1, struct css_selector *sel2);
173 /** Use this function instead of modifying css_selector.relation directly. */
174 void set_css_selector_relation(struct css_selector *,
175 enum css_selector_relation);
177 /** Destroy a selector. done_css_stylesheet() normally does that for you. */
178 void done_css_selector(struct css_selector *selector);
180 void init_css_selector_set(struct css_selector_set *set);
181 void done_css_selector_set(struct css_selector_set *set);
182 #define css_selector_set_empty(set) list_empty((set)->list)
183 #define css_selector_set_front(set) ((struct css_selector *) ((set)->list.next))
184 void add_css_selector_to_set(struct css_selector *, struct css_selector_set *);
185 void del_css_selector_from_set(struct css_selector *);
186 #define css_selector_is_in_set(selector) ((selector)->next != NULL)
187 #define foreach_css_selector(selector, set) foreach (selector, (set)->list)
189 #ifdef DEBUG_CSS
190 /** Dumps the selector tree to stderr. */
191 void dump_css_selector_tree(struct css_selector_set *set);
192 #endif
194 #endif