An initial implementation is now in SVN. Limitations:
- Allows a single <style> element in the document. Doesn't allow external stylesheets, doesn't allow more than one <style> element.
- (Or rather it ignores all but one of the <style> elements, possibly changing which one it respects based on which was most recently re-read.)
- No editing interface other than the XML editor.
- There are a number of aspects of editing:
- The most basic level: allow editing using the XML editor. (See Update section below.)
- Editing a stylesheet.
- Specifying what classes each object belongs to.
- Doesn't respect media restrictions (e.g. ignores "this rule applies only to non-visual media" directives, and doesn't allow having one style for print and another style for on-screen).
- @font-face hints are ignored.
- Doesn't handle any other at-rules (@media, @import, @page, ...).
An incomplete list of work needed:
- Ensure that this single stylesheet is updated whenever any of the <style> elements change (or are deleted or created etc.).
- Similarly, ensure that the picture is refreshed when the stylesheet is changed.
- Convert the simple user agent style sheet given at http://www.w3.org/TR/SVG11/styling.html#UAStyleSheet to libcroco structures (perhaps by passing strings to libcroco parsing functions) and store in desktop->style_cascade.
- Modify style.cpp to query the stylesheet. (Done but not checked in.)
- There may be some work needed for "shorthand properties", e.g. `marker' is shorthand for modifying marker-start, marker-mid and marker-end properties (http://www.w3.org/TR/SVG11/painting.html#MarkerProperty). A non-SVG CSS example is `margin'.
Updating for changes to <style> content
State so far: Every keystroke in the xml editor in the content of the <style> element gets sp_style_elem_read_content to be re-read. One can force an object to get the revised stylesheet info by e.g. <Up> <Down> (forcing an update) then deleting its style attribute. So one change is that we shouldn't be so keen to put things in the style attribute. Currently, the stylesheet info gets merged into SPStyle, and set the style attribute to contain everything in SPStyle (and clear any styling attributes like fill=...). One existing problem with this behaviour (other than how it interacts with stylesheets) is that we discard any style properties we don't know about. Whereas we ought to remember the content of the style attribute and only replace the properties we've changed, and add to if necessary.
One implementation would be to keep SPStyle but indicate which properties came from where, and hence which ones need to be written to the style attribute and which ones don't. Apart from not writing if src==stylesheet, we can also avoid writing if src==attribute: i.e. don't gratuitously break SVG Tiny conformance of a document (or more generally break compatibility with implementations that don't honour CSS style attributes). Not to say that we can't choose to use the style attribute for properties that the user changes during an inkscape session, but currently we change from attributes to style=... even for shapes that the user just changes the position of without changing any styling stuff.
Why can't we use libcroco-0.6's existing libxml interface to cr-sel-eng.c ?
Some CSS selectors (http://www.w3.org/TR/REC-CSS2/selector.html) can express "is preceded by X" or "is a descendent of X" (where X can itself be similarly constrained recursively), so we'd pretty much need to maintain the entire document in libxml form if we want to use libcroco for CSS selectors.
Suppose we want to find the style of node N. We pass libcroco a stylesheet and ask it what rules apply to N. If the stylesheet says "nodes that are preceded by a node that is preceded by a node that's a descendent of (... etc. ...) have red stroking" then libcroco needs to be able to navigate through the tree. So we can't pass libcroco just a libxml version of node N, we need to fill in its parent and sibling links, providing a libxml node for a significant proportion of all nodes in the tree. (Short of using hardware watchpoints to check access to the sibling/parent links and supply them lazily.)