From a53a1df2610096920b92c10bcd6f43b65f6a33b9 Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Sat, 15 Mar 2008 19:14:43 +0000 Subject: [PATCH] Ideas for a new CSS engine svn path=/trunk/netsurf/; revision=3954 --- Docs/ideas/css-engine.txt | 162 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 Docs/ideas/css-engine.txt diff --git a/Docs/ideas/css-engine.txt b/Docs/ideas/css-engine.txt new file mode 100644 index 000000000..fb35e628e --- /dev/null +++ b/Docs/ideas/css-engine.txt @@ -0,0 +1,162 @@ +CSS engine +========== + +Requirements +------------ + + + Parse stylesheets conforming to the forward compatible CSS grammar + (Note that in the short term, the semantic analysis stage only need + support CSS2.1) + + Stylesheet management/merging (i.e. multiple stylesheets may be added + to a single engine context and thus affect style selection) + + Be able to select a style for a DOM node based upon the current stylesheets + in the engine context. + + Implemented as a standalone, reusable, library -- ideally MIT licensed. + +Suggested API +------------- + +struct css_context; +struct css_style; +struct css_stylesheet; + +typedef struct css_context css_context; +typedef struct css_style css_style; +typedef struct css_stylesheet css_stylesheet; + +typedef enum css_error { + CSS_OK, + CSS_NOMEM, + /* etc */ +} css_error; + +typedef enum css_origin { + CSS_ORIGIN_UA, + CSS_ORIGIN_AUTHOR, + CSS_ORIGIN_USER +} css_origin; + +#define CSS_MEDIA_SCREEN (1<<0) +#define CSS_MEDIA_PRINT (1<<1) +/* etc */ +#define CSS_MEDIA_ALL (0xffffffff) + +#define CSS_PSEUDO_CLASS_NONE (0) +#define CSS_PSEUDO_CLASS_LINK (1<<0) +#define CSS_PSEUDO_CLASS_VISITED (1<<1) +#define CSS_PSEUDO_CLASS_HOVER (1<<2) +#define CSS_PSEUDO_CLASS_ACTIVE (1<<3) +#define CSS_PSEUDO_CLASS_FOCUS (1<<4) + +typedef enum css_property { + CSS_BACKGROUND_ATTACHMENT, + /* etc */ +} css_property; + +typedef struct css_value { + css_property property; + + union { + css_background_attachment background_attachment; + /* etc */ + } value; +} css_value; + +typedef css_error (*css_import_handler)(void *pw, const char *url, + css_stylesheet *sheet); + +/* Initialise library */ +css_error css_init(void); +/* Finalise library */ +css_error css_fini(void); + +/* Create a stylesheet associated with the given URL, + * specifying the sheet's origin, the media type(s) it applies to and + * a callback routine for fetching imported sheets */ +css_stylesheet *css_stylesheet_create(const char *url, + css_origin origin, uint32_t media, + css_import_handler import_callback, void *pw); +/* Destroy a stylesheet */ +void css_stylesheet_destroy(css_stylesheet *sheet); + +/* Append data to a stylesheet, parsing progressively */ +css_error css_stylesheet_append_data(css_stylesheet *sheet, + const uint8_t *data, size_t len); +/* Tell stylesheet parser that there's no more data (will complete parsing) */ +css_error css_stylesheet_data_done(css_stylesheet *sheet); + +/* Retrieve the URL associated with a stylesheet */ +const char *css_stylesheet_get_url(css_stylesheet *sheet); +/* Retrieve the origin of a stylesheet */ +css_origin css_stylesheet_get_origin(css_stylesheet *sheet); +/* Retrieve the media type(s) applicable to a stylesheet */ +uint32_t css_stylesheet_get_media(css_stylesheet *sheet); + +/* Create a selection context */ +css_context *css_context_create(void); +/* Destroy a selection context */ +void css_context_destroy(css_context *context); + +/* Append a top-level stylesheet to a selection context */ +css_error css_context_append_sheet(css_context *context, + css_stylesheet *sheet); +/* Insert a top-level stylesheet into a selection context, at the given index */ +css_error css_context_insert_sheet(css_context *context, + css_stylesheet *sheet, uint32_t index); +/* Remove a top-level stylesheet from a selection context */ +css_error css_context_remove_sheet(css_context *context, + css_stylesheet *sheet); + +/* Retrieve the total number of sheets in a selection context + * (includes imported sheets) */ +uint32_t css_context_count_sheets(css_context *context); +/* Get a stylesheet from a selection context given an index [0, count) */ +const css_stylesheet *css_context_get_sheet(css_context *context, + uint32_t index); + +/* Select a style for a given DOM node with the given pseudo classes active + * and media type. + * + * If the document language contains non-CSS presentational hints (e.g. HTML + * presentational attributes etc), then these are passed in through + * property_list and treated as if they were encountered at the start of the + * author stylesheet with a specificity of 0. */ +css_style *css_style_select(css_context *context, + *node, uint32_t pseudo_classes, uint32_t media, + css_value **property_list, uint32_t property_list_length); +/* Destroy a selected style */ +void css_style_destroy(css_style *style); + +/* Retrieve a property value from a style */ +css_value *css_value_get(css_style *style, css_property property); +/* Destroy a property value */ +void css_value_destroy(css_value *value); + +Memory management +----------------- + + + Stylesheets are owned by their creator. Selection contexts reference them. + + Selection contexts are owned by the client. + + Selected styles are owned by the client. + + Property values are owned by the client. + + Therefore, the only difficulty lies within the handling of stylesheets + inserted into a selection context. The client code must ensure that a + stylesheet is destroyed after it has been removed from any selection + contexts which are using it. + +DOM node types & tree traversal +------------------------------- + + This is currently undecided. Either the CSS engine is tied to a DOM + implementation (and makes API calls directly), or it's more generic and + performs API calls through a vtable provided by the client. + +Imported stylesheets +-------------------- + + Imported stylesheets are handled by the CSS engine creating an appropriate + css_stylesheet object for the imported sheet and then asking the client + to fetch the data and append it to the sheet. The imported sheet is then + stored in the sheet that imported it. This effectively creates a tree of + stylesheets beneath the initial top-level sheet created by the client.