Subversion Repositories Kolibri OS

Rev

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 

element have?"

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