Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3584 | sourcerer | 1 | Using the LibCSS API |
2 | ==================== |
||
3 | |||
4 | This document explains how to use LibCSS. In addition to this document, please |
||
5 | see the examples and the headers (found in /usr/local/include/libcss or a |
||
6 | similar location). Experience with C is assumed. |
||
7 | |||
8 | Using the library consists of the following general steps: |
||
9 | |||
10 | 1. Initialize the library. |
||
11 | 2. Load one or more CSS files. |
||
12 | 3. Use the Selection API to determine styles. |
||
13 | 4. Use the computed styles. |
||
14 | 5. Shut down the library. |
||
15 | |||
16 | Please see example1.c for a demonstration of these steps. |
||
17 | |||
18 | |||
19 | Initialize the library |
||
20 | ---------------------- |
||
21 | |||
22 | The library is initialized using css_initialise(): |
||
23 | |||
24 | css_initialise("Aliases", myrealloc, 0); |
||
25 | |||
26 | The first argument is the pathname of an Aliases file, which maps character |
||
27 | encoding names to their canonical form. For an example, see test/data/Aliases. |
||
28 | |||
29 | The 2nd argument is an allocation function. All allocations required by library |
||
30 | initialization will be made by calling this function. It takes the same |
||
31 | arguments as realloc(); a pointer and a size. If pointer is NULL a new block is |
||
32 | being requested. If size is 0 the block should be freed. Otherwise an existing |
||
33 | block is being resized. In many cases this function can simply call realloc(). |
||
34 | |||
35 | The allocation function also takes a private data pointer, which is the third |
||
36 | argument to css_initialise(). This is not used by LibCSS but may be used to |
||
37 | communicate context to the allocation function. |
||
38 | |||
39 | The allocation function pointer and private data pointer are arguments to many |
||
40 | LibCSS functions and work in the same way. |
||
41 | |||
42 | css_initialise() returns a css_error value. It is CSS_OK if everything worked, |
||
43 | and an error code otherwise. The error codes are defined in libcss/errors.h. |
||
44 | |||
45 | Many LibCSS functions return a css_error value. Checking the return value of |
||
46 | every call that does is advised, for example: |
||
47 | |||
48 | css_error code; |
||
49 | code = css_initialise("../test/data/Aliases", myrealloc, 0); |
||
50 | if (code != CSS_OK) { |
||
51 | fprintf(stderr, "ERROR: css_initialise failed: %s\n", |
||
52 | css_error_to_string(code)); |
||
53 | exit(EXIT_FAILURE); |
||
54 | } |
||
55 | |||
56 | LibCSS depends on LibWapcaplet. This must be initialized before LibCSS. For |
||
57 | example: |
||
58 | |||
59 | lwc_code = lwc_initialise(myrealloc, NULL, 0); |
||
60 | if (lwc_code != lwc_error_ok) |
||
61 | ... |
||
62 | |||
63 | |||
64 | Load one or more CSS files |
||
65 | -------------------------- |
||
66 | |||
67 | A stylesheet is represented by the opaque type css_stylesheet. To create one, |
||
68 | use css_stylesheet_create(), for example: |
||
69 | |||
70 | css_stylesheet *sheet; |
||
71 | code = css_stylesheet_create(CSS_LEVEL_DEFAULT, "UTF-8", "", NULL, |
||
72 | false, false, myrealloc, 0, resolve_url, 0, &sheet); |
||
73 | if (code != CSS_OK) |
||
74 | ... |
||
75 | |||
76 | The arguments are as follows: |
||
77 | |||
78 | css_language_level level |
||
79 | Which version of CSS the stylesheet should be treated as. It currently has |
||
80 | no effect and is reserved for future use. The recommended value is |
||
81 | CSS_LEVEL_DEFAULT. |
||
82 | |||
83 | const char *charset |
||
84 | The encoding of the stylesheet data, or NULL if LibCSS should attempt to |
||
85 | detect it. If the encoding is known, for example from the Content-Type |
||
86 | header or a file attribute, then it should be supplied here. |
||
87 | |||
88 | const char *url |
||
89 | The URL that the stylesheet was retrieved from. LibCSS uses this along with |
||
90 | the resolve function (see below) to convert relative URLs in the stylesheet |
||
91 | (e.g. imports, background images) to absolute URLs. If the stylesheet has |
||
92 | no URL, use "". |
||
93 | |||
94 | const char *title |
||
95 | This is intended for the stylesheet title (for example from the tag). |
||
96 | The title is not used by LibCSS but may be retrieved using |
||
97 | css_stylesheet_get_title(). May be NULL if there is no title. |
||
98 | |||
99 | bool allow_quirks |
||
100 | |||
101 | |||
102 | bool inline_style |
||
103 | |||
104 | |||
105 | css_allocator_fn alloc |
||
106 | void *alloc_pw |
||
107 | |||
108 | |||
109 | css_url_resolution_fn resolve |
||
110 | void *resolve_pw |
||
111 | |||
112 | |||
113 | css_stylesheet **stylesheet |
||
114 | Updated with the newly created stylesheet object. |
||
115 | |||
116 | Once the stylesheet has been created, CSS source data can be added to it. LibCSS |
||
117 | parses the data into internal structures. Only data in memory is supported; you |
||
118 | must handle reading from files or the network if required. Data is added using |
||
119 | css_stylesheet_append_data(), for example: |
||
120 | |||
121 | code = css_stylesheet_append_data(sheet, data, length); |
||
122 | if (code != CSS_OK && code != CSS_NEEDDATA) |
||
123 | ... |
||
124 | |||
125 | The second argument is a pointer to a buffer containing some CSS to be parsed, |
||
126 | with length in bytes given in the 3rd argument. |
||
127 | |||
128 | This function may be called repeatedly with more data from the same stylesheet, |
||
129 | for example as data arrives over the network. |
||
130 | |||
131 | The return value may be CSS_NEEDDATA instead of CSS_OK. This indicates that more |
||
132 | data may be expected. The two states can be treated identically. |
||
133 | |||
134 | When all the data has been supplied, css_stylesheet_data_done() completes the |
||
135 | processing: |
||
136 | |||
137 | code = css_stylesheet_data_done(sheet); |
||
138 | if (code != CSS_OK) |
||
139 | ... |
||
140 | |||
141 | The stylesheet is now in memory and ready for further use. |
||
142 | |||
143 | |||
144 | Use the Selection API to determine styles |
||
145 | ----------------------------------------- |
||
146 | |||
147 | The Selection API is currently the only way to get information about styles from |
||
148 | stylesheets that have been loaded. It takes a document node as input and returns |
||
149 | the computed style that applies to that node. For example, it can be used to |
||
150 | answer the question "What style should this |
||
151 | |||
152 | CSS selectors can be complex and apply to certain arrangments of elements within |
||
153 | a document tree. Therefore LibCSS has to be able to navigate your document tree |
||
154 | and read attributes of it to determine if a style applies. It does this through |
||
155 | a series of functions that you supply. In this way LibCSS is independent of the |
||
156 | representation of the document. For example, with the style rule: |
||
157 | |||
158 | table h2 { color: red; } |
||
159 | |||
160 | when requesting the style for an h2 element node, LibCSS will search its |
||
161 | ancestors for a table element to determine if this style applies. |
||
162 | |||
163 | The first step in using the Selection API is creating a selection context. This |
||
164 | is a list of the stylesheets to be used. A context is created using |
||
165 | css_select_ctx_create(): |
||
166 | |||
167 | css_select_ctx *select_ctx; |
||
168 | code = css_select_ctx_create(myrealloc, 0, &select_ctx); |
||
169 | if (code != CSS_OK) |
||
170 | ... |
||
171 | |||
172 | Stylesheets are added to the context using css_select_ctx_append_sheet(): |
||
173 | |||
174 | code = css_select_ctx_append_sheet(select_ctx, sheet, CSS_ORIGIN_AUTHOR, |
||
175 | CSS_MEDIA_ALL); |
||
176 | if (code != CSS_OK) |
||
177 | ... |
||
178 | |||
179 | When adding a stylesheet, the origin and media can be specified. These are used |
||
180 | in the computation of styles as defined in the CSS specification. |
||
181 | |||
182 | Alternatively stylesheets may be added using css_select_ctx_insert_sheet(). |
||
183 | |||
184 | After the context has been prepared, an empty computed style is created: |
||
185 | |||
186 | css_computed_style *style; |
||
187 | code = css_computed_style_create(myrealloc, 0, &style); |
||
188 | if (code != CSS_OK) |
||
189 | ... |
||
190 | |||
191 | The style is then determined for a document node using css_select_style(): |
||
192 | |||
193 | code = css_select_style(select_ctx, element_node, 0, |
||
194 | CSS_MEDIA_SCREEN, NULL, style, |
||
195 | &select_handler, 0); |
||
196 | if (code != CSS_OK) |
||
197 | ... |
||
198 | |||
199 | The arguments are as follows: |
||
200 | |||
201 | css_select_ctx *ctx |
||
202 | The selection context, as described above. |
||
203 | |||
204 | void *node |
||
205 | A pointer to the document node for which the style is required. This is a |
||
206 | void pointer and may therefore be of any desired type. LibCSS can not use it |
||
207 | directly; instead it gets information about it through the functions given |
||
208 | in the handler argument, described below. Usually this will be a node in a |
||
209 | document tree. |
||
210 | |||
211 | uint32_t pseudo_element |
||
212 | |||
213 | uint64_t media |
||
214 | The media that the style should apply to. The computed style will only |
||
215 | consider stylesheets or @media blocks that include this media. See the CSS |
||
216 | specification for more details. |
||
217 | |||
218 | const css_stylesheet *inline_style |
||
219 | |||
220 | css_computed_style *result |
||
221 | Updated to the computed style for the node. |
||
222 | |||
223 | css_select_handler *handler |
||
224 | This is a table of functions that are used to get information from and to |
||
225 | navigate the document tree, in order to determine if a CSS selector matches |
||
226 | the document node. Further details are below. |
||
227 | |||
228 | void *pw |
||
229 | A private data pointer that is passed to each of the handler functions. |
||
230 | |||
231 | The types of the handler functions that need to be supplied and the definition |
||
232 | of css_select_handler are given in libcss/select.h. The functions all have the |
||
233 | following in common: |
||
234 | |||
235 | * the first argument is the private data pointer that was the last argument to |
||
236 | css_select_style() |
||
237 | |||
238 | * the second argument is the document node that is being queried is some way |
||
239 | |||
240 | * the last one or two arguments are pointers that must be updated with the |
||
241 | required information |
||
242 | |||
243 | * the return value is a css_error and should be CSS_OK if everything worked and |
||
244 | an error code otherwise |
||
245 | |||
246 | For example, the node_name function, which determines the element name of a |
||
247 | node, could be this: |
||
248 | |||
249 | css_error node_name(void *pw, void *n, lwc_string **name) |
||
250 | { |
||
251 | my_document_node *node = n; |
||
252 | *name = lwc_string_ref(node->name); |
||
253 | return CSS_OK; |
||
254 | } |
||
255 | |||
256 | where my_document_node is your document tree node type (e.g. a struct of some |
||
257 | sort). |
||
258 | |||
259 | |||
260 | Use the computed styles |
||
261 | ----------------------- |
||
262 | |||
263 | After the style has been computed by css_select_style() the CSS properties can |
||
264 | finally be retrieved. This is done using the property accessor functions |
||
265 | declared in libcss/computed.h. |
||
266 | |||
267 | Note that although struct css_computed_style is declared in computed.h, its |
||
268 | members must not be used directly. The accessors carry out various additional |
||
269 | work to read the properties correctly. |
||
270 | |||
271 | For example, the css_computed_color() accessor retrieves the color property: |
||
272 | |||
273 | uint8_t color_type; |
||
274 | css_color color_shade; |
||
275 | color_type = css_computed_color(style, &color_shade); |
||
276 | |||
277 | In this case color_type can be CSS_COLOR_INHERIT or CSS_COLOR_COLOR. In the |
||
278 | latter case, color_shade contains the actual color in RRGGBBAA format. Together |
||
279 | these two variables encode the possible values for the property given by the |
||
280 | CSS specification. |
||
281 |