forked from KolibriOS/kolibrios
Netsurf initial port (still needs native ui and cURL)
git-svn-id: svn://kolibrios.org@3584 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
@@ -0,0 +1,281 @@
|
||||
Using the LibCSS API
|
||||
====================
|
||||
|
||||
This document explains how to use LibCSS. In addition to this document, please
|
||||
see the examples and the headers (found in /usr/local/include/libcss or a
|
||||
similar location). Experience with C is assumed.
|
||||
|
||||
Using the library consists of the following general steps:
|
||||
|
||||
1. Initialize the library.
|
||||
2. Load one or more CSS files.
|
||||
3. Use the Selection API to determine styles.
|
||||
4. Use the computed styles.
|
||||
5. Shut down the library.
|
||||
|
||||
Please see example1.c for a demonstration of these steps.
|
||||
|
||||
|
||||
Initialize the library
|
||||
----------------------
|
||||
|
||||
The library is initialized using css_initialise():
|
||||
|
||||
css_initialise("Aliases", myrealloc, 0);
|
||||
|
||||
The first argument is the pathname of an Aliases file, which maps character
|
||||
encoding names to their canonical form. For an example, see test/data/Aliases.
|
||||
|
||||
The 2nd argument is an allocation function. All allocations required by library
|
||||
initialization will be made by calling this function. It takes the same
|
||||
arguments as realloc(); a pointer and a size. If pointer is NULL a new block is
|
||||
being requested. If size is 0 the block should be freed. Otherwise an existing
|
||||
block is being resized. In many cases this function can simply call realloc().
|
||||
|
||||
The allocation function also takes a private data pointer, which is the third
|
||||
argument to css_initialise(). This is not used by LibCSS but may be used to
|
||||
communicate context to the allocation function.
|
||||
|
||||
The allocation function pointer and private data pointer are arguments to many
|
||||
LibCSS functions and work in the same way.
|
||||
|
||||
css_initialise() returns a css_error value. It is CSS_OK if everything worked,
|
||||
and an error code otherwise. The error codes are defined in libcss/errors.h.
|
||||
|
||||
Many LibCSS functions return a css_error value. Checking the return value of
|
||||
every call that does is advised, for example:
|
||||
|
||||
css_error code;
|
||||
code = css_initialise("../test/data/Aliases", myrealloc, 0);
|
||||
if (code != CSS_OK) {
|
||||
fprintf(stderr, "ERROR: css_initialise failed: %s\n",
|
||||
css_error_to_string(code));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
LibCSS depends on LibWapcaplet. This must be initialized before LibCSS. For
|
||||
example:
|
||||
|
||||
lwc_code = lwc_initialise(myrealloc, NULL, 0);
|
||||
if (lwc_code != lwc_error_ok)
|
||||
...
|
||||
|
||||
|
||||
Load one or more CSS files
|
||||
--------------------------
|
||||
|
||||
A stylesheet is represented by the opaque type css_stylesheet. To create one,
|
||||
use css_stylesheet_create(), for example:
|
||||
|
||||
css_stylesheet *sheet;
|
||||
code = css_stylesheet_create(CSS_LEVEL_DEFAULT, "UTF-8", "", NULL,
|
||||
false, false, myrealloc, 0, resolve_url, 0, &sheet);
|
||||
if (code != CSS_OK)
|
||||
...
|
||||
|
||||
The arguments are as follows:
|
||||
|
||||
css_language_level level
|
||||
Which version of CSS the stylesheet should be treated as. It currently has
|
||||
no effect and is reserved for future use. The recommended value is
|
||||
CSS_LEVEL_DEFAULT.
|
||||
|
||||
const char *charset
|
||||
The encoding of the stylesheet data, or NULL if LibCSS should attempt to
|
||||
detect it. If the encoding is known, for example from the Content-Type
|
||||
header or a file attribute, then it should be supplied here.
|
||||
|
||||
const char *url
|
||||
The URL that the stylesheet was retrieved from. LibCSS uses this along with
|
||||
the resolve function (see below) to convert relative URLs in the stylesheet
|
||||
(e.g. imports, background images) to absolute URLs. If the stylesheet has
|
||||
no URL, use "".
|
||||
|
||||
const char *title
|
||||
This is intended for the stylesheet title (for example from the <link> tag).
|
||||
The title is not used by LibCSS but may be retrieved using
|
||||
css_stylesheet_get_title(). May be NULL if there is no title.
|
||||
|
||||
bool allow_quirks
|
||||
|
||||
|
||||
bool inline_style
|
||||
|
||||
|
||||
css_allocator_fn alloc
|
||||
void *alloc_pw
|
||||
|
||||
|
||||
css_url_resolution_fn resolve
|
||||
void *resolve_pw
|
||||
|
||||
|
||||
css_stylesheet **stylesheet
|
||||
Updated with the newly created stylesheet object.
|
||||
|
||||
Once the stylesheet has been created, CSS source data can be added to it. LibCSS
|
||||
parses the data into internal structures. Only data in memory is supported; you
|
||||
must handle reading from files or the network if required. Data is added using
|
||||
css_stylesheet_append_data(), for example:
|
||||
|
||||
code = css_stylesheet_append_data(sheet, data, length);
|
||||
if (code != CSS_OK && code != CSS_NEEDDATA)
|
||||
...
|
||||
|
||||
The second argument is a pointer to a buffer containing some CSS to be parsed,
|
||||
with length in bytes given in the 3rd argument.
|
||||
|
||||
This function may be called repeatedly with more data from the same stylesheet,
|
||||
for example as data arrives over the network.
|
||||
|
||||
The return value may be CSS_NEEDDATA instead of CSS_OK. This indicates that more
|
||||
data may be expected. The two states can be treated identically.
|
||||
|
||||
When all the data has been supplied, css_stylesheet_data_done() completes the
|
||||
processing:
|
||||
|
||||
code = css_stylesheet_data_done(sheet);
|
||||
if (code != CSS_OK)
|
||||
...
|
||||
|
||||
The stylesheet is now in memory and ready for further use.
|
||||
|
||||
|
||||
Use the Selection API to determine styles
|
||||
-----------------------------------------
|
||||
|
||||
The Selection API is currently the only way to get information about styles from
|
||||
stylesheets that have been loaded. It takes a document node as input and returns
|
||||
the computed style that applies to that node. For example, it can be used to
|
||||
answer the question "What style should this <h1> element have?"
|
||||
|
||||
CSS selectors can be complex and apply to certain arrangments of elements within
|
||||
a document tree. Therefore LibCSS has to be able to navigate your document tree
|
||||
and read attributes of it to determine if a style applies. It does this through
|
||||
a series of functions that you supply. In this way LibCSS is independent of the
|
||||
representation of the document. For example, with the style rule:
|
||||
|
||||
table h2 { color: red; }
|
||||
|
||||
when requesting the style for an h2 element node, LibCSS will search its
|
||||
ancestors for a table element to determine if this style applies.
|
||||
|
||||
The first step in using the Selection API is creating a selection context. This
|
||||
is a list of the stylesheets to be used. A context is created using
|
||||
css_select_ctx_create():
|
||||
|
||||
css_select_ctx *select_ctx;
|
||||
code = css_select_ctx_create(myrealloc, 0, &select_ctx);
|
||||
if (code != CSS_OK)
|
||||
...
|
||||
|
||||
Stylesheets are added to the context using css_select_ctx_append_sheet():
|
||||
|
||||
code = css_select_ctx_append_sheet(select_ctx, sheet, CSS_ORIGIN_AUTHOR,
|
||||
CSS_MEDIA_ALL);
|
||||
if (code != CSS_OK)
|
||||
...
|
||||
|
||||
When adding a stylesheet, the origin and media can be specified. These are used
|
||||
in the computation of styles as defined in the CSS specification.
|
||||
|
||||
Alternatively stylesheets may be added using css_select_ctx_insert_sheet().
|
||||
|
||||
After the context has been prepared, an empty computed style is created:
|
||||
|
||||
css_computed_style *style;
|
||||
code = css_computed_style_create(myrealloc, 0, &style);
|
||||
if (code != CSS_OK)
|
||||
...
|
||||
|
||||
The style is then determined for a document node using css_select_style():
|
||||
|
||||
code = css_select_style(select_ctx, element_node, 0,
|
||||
CSS_MEDIA_SCREEN, NULL, style,
|
||||
&select_handler, 0);
|
||||
if (code != CSS_OK)
|
||||
...
|
||||
|
||||
The arguments are as follows:
|
||||
|
||||
css_select_ctx *ctx
|
||||
The selection context, as described above.
|
||||
|
||||
void *node
|
||||
A pointer to the document node for which the style is required. This is a
|
||||
void pointer and may therefore be of any desired type. LibCSS can not use it
|
||||
directly; instead it gets information about it through the functions given
|
||||
in the handler argument, described below. Usually this will be a node in a
|
||||
document tree.
|
||||
|
||||
uint32_t pseudo_element
|
||||
|
||||
uint64_t media
|
||||
The media that the style should apply to. The computed style will only
|
||||
consider stylesheets or @media blocks that include this media. See the CSS
|
||||
specification for more details.
|
||||
|
||||
const css_stylesheet *inline_style
|
||||
|
||||
css_computed_style *result
|
||||
Updated to the computed style for the node.
|
||||
|
||||
css_select_handler *handler
|
||||
This is a table of functions that are used to get information from and to
|
||||
navigate the document tree, in order to determine if a CSS selector matches
|
||||
the document node. Further details are below.
|
||||
|
||||
void *pw
|
||||
A private data pointer that is passed to each of the handler functions.
|
||||
|
||||
The types of the handler functions that need to be supplied and the definition
|
||||
of css_select_handler are given in libcss/select.h. The functions all have the
|
||||
following in common:
|
||||
|
||||
* the first argument is the private data pointer that was the last argument to
|
||||
css_select_style()
|
||||
|
||||
* the second argument is the document node that is being queried is some way
|
||||
|
||||
* the last one or two arguments are pointers that must be updated with the
|
||||
required information
|
||||
|
||||
* the return value is a css_error and should be CSS_OK if everything worked and
|
||||
an error code otherwise
|
||||
|
||||
For example, the node_name function, which determines the element name of a
|
||||
node, could be this:
|
||||
|
||||
css_error node_name(void *pw, void *n, lwc_string **name)
|
||||
{
|
||||
my_document_node *node = n;
|
||||
*name = lwc_string_ref(node->name);
|
||||
return CSS_OK;
|
||||
}
|
||||
|
||||
where my_document_node is your document tree node type (e.g. a struct of some
|
||||
sort).
|
||||
|
||||
|
||||
Use the computed styles
|
||||
-----------------------
|
||||
|
||||
After the style has been computed by css_select_style() the CSS properties can
|
||||
finally be retrieved. This is done using the property accessor functions
|
||||
declared in libcss/computed.h.
|
||||
|
||||
Note that although struct css_computed_style is declared in computed.h, its
|
||||
members must not be used directly. The accessors carry out various additional
|
||||
work to read the properties correctly.
|
||||
|
||||
For example, the css_computed_color() accessor retrieves the color property:
|
||||
|
||||
uint8_t color_type;
|
||||
css_color color_shade;
|
||||
color_type = css_computed_color(style, &color_shade);
|
||||
|
||||
In this case color_type can be CSS_COLOR_INHERIT or CSS_COLOR_COLOR. In the
|
||||
latter case, color_shade contains the actual color in RRGGBBAA format. Together
|
||||
these two variables encode the possible values for the property given by the
|
||||
CSS specification.
|
||||
|
||||
Reference in New Issue
Block a user