Port <style> element handling to Rust

parent 5fc3ca24
......@@ -95,14 +95,6 @@ struct RsvgSaxHandler {
void (*characters) (RsvgSaxHandler * self, const char *ch, gsize len);
};
typedef struct _RsvgSaxHandlerStyle {
RsvgSaxHandler super;
RsvgSaxHandler *parent;
RsvgLoad *load;
GString *style;
gboolean is_text_css;
} RsvgSaxHandlerStyle;
static xmlSAXHandler get_xml2_sax_handler (void);
RsvgLoad *
......@@ -170,90 +162,6 @@ rsvg_load_steal_tree (RsvgLoad *load)
return rsvg_xml_state_steal_tree (load->xml.rust_state);
}
static void
style_handler_free (RsvgSaxHandler * self)
{
RsvgSaxHandlerStyle *z = (RsvgSaxHandlerStyle *) self;
if (z->is_text_css)
rsvg_css_parse_into_handle (z->load->handle, z->style->str, z->style->len);
g_string_free (z->style, TRUE);
g_free (z);
}
static void
style_handler_characters (RsvgSaxHandler * self, const char *ch, gsize len)
{
RsvgSaxHandlerStyle *z = (RsvgSaxHandlerStyle *) self;
g_string_append_len (z->style, ch, len);
}
static void
style_handler_start (RsvgSaxHandler * self, const char *name, RsvgPropertyBag atts)
{
}
static void
style_handler_end (RsvgSaxHandler * self, const char *name)
{
RsvgSaxHandlerStyle *z = (RsvgSaxHandlerStyle *) self;
RsvgSaxHandler *previous = z->parent;
RsvgLoad *load = z->load;
if (!strcmp (name, "style")) {
if (load->xml.handler != NULL) {
load->xml.handler->free (load->xml.handler);
load->xml.handler = previous;
}
}
}
static void
start_style (RsvgLoad *load, RsvgPropertyBag *atts)
{
RsvgSaxHandlerStyle *handler = g_new0 (RsvgSaxHandlerStyle, 1);
RsvgPropertyBagIter *iter;
const char *key;
RsvgAttribute attr;
const char *value;
handler->super.free = style_handler_free;
handler->super.characters = style_handler_characters;
handler->super.start_element = style_handler_start;
handler->super.end_element = style_handler_end;
handler->load = load;
handler->style = g_string_new (NULL);
handler->parent = load->xml.handler;
load->xml.handler = &handler->super;
/* FIXME: See these:
*
* https://www.w3.org/TR/SVG/styling.html#StyleElementTypeAttribute
* https://www.w3.org/TR/SVG/styling.html#ContentStyleTypeAttribute
*
* If the "type" attribute is not present, we should fallback to the
* "contentStyleType" attribute of the svg element, which in turn
* defaults to "text/css".
*
* See where is_text_css is used to see where we parse the contents
* of the style element.
*/
handler->is_text_css = TRUE;
iter = rsvg_property_bag_iter_begin (atts);
while (rsvg_property_bag_iter_next (iter, &key, &attr, &value)) {
if (attr == RSVG_ATTRIBUTE_TYPE) {
handler->is_text_css = (g_ascii_strcasecmp (value, "text/css") == 0);
}
}
rsvg_property_bag_iter_end (iter);
}
/* start xinclude */
typedef struct _RsvgSaxHandlerXinclude {
......
......@@ -86,7 +86,7 @@ struct DocHandlerData {
selector: *mut CRSelector,
}
fn parse_into_handle(handle: *mut RsvgHandle, buf: &str) {
pub fn parse_into_handle(handle: *mut RsvgHandle, buf: &str) {
unsafe {
let handler_data = DocHandlerData {
handle,
......
use libc;
use std;
use std::cell::RefCell;
use std::ptr;
use std::rc::Rc;
use std::str;
use attributes::Attribute;
use css;
use handle::{self, RsvgHandle};
use load::rsvg_load_new_node;
use node::{node_new, Node, NodeType};
......@@ -55,7 +58,8 @@ impl XmlHandler for NodeCreationContext {
pbag: &PropertyBag,
) -> Box<XmlHandler> {
if name == "style" {
unimplemented!();
let ctx = StyleContext::empty();
StyleContext::start_element(&ctx, parent, handle, name, pbag)
} else {
let node = self.create_node(parent, handle, name, pbag);
......@@ -145,25 +149,65 @@ impl NodeCreationContext {
}
/// Handles the `<style>` element by parsing its character contents as CSS
struct StyleContext {}
struct StyleContext {
is_text_css: bool,
text: RefCell<String>,
}
impl XmlHandler for StyleContext {
fn start_element(
&self,
parent: Option<&Rc<Node>>,
handle: *mut RsvgHandle,
name: &str,
_parent: Option<&Rc<Node>>,
_handle: *mut RsvgHandle,
_name: &str,
pbag: &PropertyBag,
) -> Box<XmlHandler> {
Box::new(StyleContext {})
// FIXME: See these:
//
// https://www.w3.org/TR/SVG/styling.html#StyleElementTypeAttribute
// https://www.w3.org/TR/SVG/styling.html#ContentStyleTypeAttribute
//
// If the "type" attribute is not present, we should fallback to the
// "contentStyleType" attribute of the svg element, which in turn
// defaults to "text/css".
//
// See where is_text_css is used to see where we parse the contents
// of the style element.
let mut is_text_css = true;
for (_key, attr, value) in pbag.iter() {
if attr == Attribute::Type {
is_text_css = value == "text/css";
}
}
Box::new(StyleContext {
is_text_css,
text: RefCell::new(String::new()),
})
}
fn end_element(&self, handle: *mut RsvgHandle, _name: &str) -> Option<Rc<Node>> {
unimplemented!();
if self.is_text_css {
let text = self.text.borrow();
css::parse_into_handle(handle, &text);
}
None
}
fn characters(&self, text: &str) {
unimplemented!();
self.text.borrow_mut().push_str(text);
}
}
impl StyleContext {
fn empty() -> StyleContext {
StyleContext {
is_text_css: false,
text: RefCell::new(String::new()),
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment