The Birdfont Source Code


All Repositories / birdfont.git / commitdiff – RSS feed

CSS pseudo classes in SVG files

These changes was commited to the Birdfont repository Mon, 04 Jul 2016 14:45:41 +0000.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
[Mon, 04 Jul 2016 14:45:41 +0000]

Updated Files

libbirdfont/SvgParser.vala
libsvgbird/Selector.vala
libsvgbird/SelectorPattern.vala
libsvgbird/SelectorTag.vala
libsvgbird/StyleSheet.vala
libsvgbird/SvgFile.vala
libsvgbird/SvgStyle.vala
--- a/libbirdfont/SvgParser.vala +++ b/libbirdfont/SvgParser.vala @@ -557,7 +557,7 @@ } } - style = SvgStyle.parse (null, style, tag); + style = SvgStyle.parse (null, style, tag, null); if (hidden) { return; @@ -625,7 +625,7 @@ } } - style = SvgStyle.parse (null, style, tag); + style = SvgStyle.parse (null, style, tag, null); if (hidden) { return; @@ -691,7 +691,7 @@ } } - style = SvgStyle.parse (null, style, tag); + style = SvgStyle.parse (null, style, tag, null); if (hidden) { return; @@ -769,7 +769,7 @@ } } - style = SvgStyle.parse (null, style, tag); + style = SvgStyle.parse (null, style, tag, null); if (hidden) { return; @@ -867,7 +867,7 @@ } } - style = SvgStyle.parse (null, style, tag); + style = SvgStyle.parse (null, style, tag, null); if (hidden) { return path_list; @@ -907,7 +907,7 @@ } } - style = SvgStyle.parse (null, style, tag); + style = SvgStyle.parse (null, style, tag, null); if (hidden) { return;
--- a/libsvgbird/Selector.vala +++ b/libsvgbird/Selector.vala @@ -21,6 +21,7 @@ Gee.ArrayList<SelectorPattern> tag_patterns = new Gee.ArrayList<SelectorPattern> (); Gee.ArrayList<SelectorPattern> class_patterns = new Gee.ArrayList<SelectorPattern> (); + Gee.ArrayList<SelectorPattern> pseudo_class_patterns = new Gee.ArrayList<SelectorPattern> (); Gee.ArrayList<SelectorPattern> id_patterns = new Gee.ArrayList<SelectorPattern> (); public SvgStyle style { get; set; } @@ -32,13 +33,20 @@ SelectorPattern p = new SelectorPattern (selector_patterns[i]); if (p.has_id ()) { - id_patterns.add (p); + SelectorPattern id = p.get_id_patterns (); + id_patterns.add (id); } if (p.has_class ()) { - class_patterns.add (p); + SelectorPattern css_class = p.get_class_patterns (); + class_patterns.add (css_class); } + if (p.has_pseudo_class ()) { + SelectorPattern pseudo_class = p.get_pseudo_class_patterns (); + pseudo_class_patterns.add (pseudo_class); + } + tag_patterns.add (p); } @@ -58,6 +66,10 @@ foreach (SelectorPattern pattern in selector.id_patterns) { id_patterns.add (pattern.copy ()); + } + + foreach (SelectorPattern pattern in selector.pseudo_class_patterns) { + pseudo_class_patterns.add (pattern.copy ()); } } @@ -79,9 +91,9 @@ return new Selector.copy_constructor (this); } - public bool match_tag (XmlElement tag, string? id, string? css_class) { + public bool match_tag (XmlElement tag, string? id, string? css_class, string? psedo_class) { foreach (SelectorPattern pattern in tag_patterns) { - if (pattern.match (tag, id, css_class)) { + if (pattern.match (tag, id, css_class, psedo_class)) { return true; } } @@ -89,9 +101,9 @@ return false; } - public bool match_id (XmlElement tag, string? id, string? css_class) { + public bool match_id (XmlElement tag, string? id, string? css_class, string? psedo_class) { foreach (SelectorPattern pattern in id_patterns) { - if (pattern.match (tag, id, css_class)) { + if (pattern.match (tag, id, css_class, psedo_class)) { return true; } } @@ -99,9 +111,19 @@ return false; } - public bool match_class (XmlElement tag, string? id, string? css_class) { + public bool match_class (XmlElement tag, string? id, string? css_class, string? psedo_class) { foreach (SelectorPattern pattern in class_patterns) { - if (pattern.match (tag, id, css_class)) { + if (pattern.match (tag, id, css_class, psedo_class)) { + return true; + } + } + + return false; + } + + public bool match_pseudo_class (XmlElement tag, string? id, string? css_class, string? psedo_class) { + foreach (SelectorPattern pattern in pseudo_class_patterns) { + if (pattern.match (tag, id, css_class, psedo_class)) { return true; } }
--- a/libsvgbird/SelectorPattern.vala +++ b/libsvgbird/SelectorPattern.vala @@ -23,7 +23,7 @@ public SelectorPattern.empty () { } - + public SelectorPattern (string pattern) { string p = pattern.strip (); string[] elements = p.split (" "); @@ -33,6 +33,36 @@ tags.add (new SelectorTag (element)); } } + } + + public SelectorPattern get_id_patterns () { + SelectorPattern pattern = new SelectorPattern.empty (); + foreach (SelectorTag tag in tags) { + if (tag.id != null) { + pattern.tags.add (tag); + } + } + return pattern; + } + + public SelectorPattern get_class_patterns () { + SelectorPattern pattern = new SelectorPattern.empty (); + foreach (SelectorTag tag in tags) { + if (tag.css_class != null) { + pattern.tags.add (tag); + } + } + return pattern; + } + + public SelectorPattern get_pseudo_class_patterns () { + SelectorPattern pattern = new SelectorPattern.empty (); + foreach (SelectorTag tag in tags) { + if (tag.pseudo_class != null) { + pattern.tags.add (tag); + } + } + return pattern; } public bool has_id () { @@ -55,6 +85,16 @@ return false; } + public bool has_pseudo_class () { + foreach (SelectorTag tag in tags) { + if (tag.pseudo_class != null) { + return true; + } + } + + return false; + } + public string to_string () { StringBuilder s = new StringBuilder (); @@ -78,7 +118,11 @@ return pattern; } - public bool match (XmlElement tag, string? id, string? css_class) { + public bool match (XmlElement tag, string? id, string? css_class, string? pseudo_class) { + if (tag.get_name () == "") { + return false; + } + for (int i = tags.size - 1; i >= 0; i--) { SelectorTag pattern = tags.get (i); @@ -104,7 +148,7 @@ } } - if (!pattern.match (tag, id, css_class)) { + if (!pattern.match (tag, id, css_class, pseudo_class)) { return false; } }
--- a/libsvgbird/SelectorTag.vala +++ b/libsvgbird/SelectorTag.vala @@ -22,6 +22,7 @@ public string name; public string? id = null; public string? css_class = null; + public string? pseudo_class = null; Gee.ArrayList<AttributePattern>? attribute_patterns = null; public SelectorTag.empty () { @@ -29,39 +30,38 @@ public SelectorTag (string pattern) { string tag_pattern = pattern.strip (); - int id_separator = tag_pattern.index_of ("#"); - int class_separator = tag_pattern.index_of ("."); int attribute_separator = tag_pattern.index_of ("["); if (attribute_separator != -1) { parse_attributes (tag_pattern.substring (attribute_separator)); + tag_pattern = tag_pattern.substring (0, attribute_separator - "[".length); } - - if (id_separator != -1) { - name = tag_pattern.substring (0, id_separator); - - id_separator += "#".length; - if (attribute_separator == -1) { - id = tag_pattern.substring (id_separator); - } else { - id = tag_pattern.substring (id_separator, attribute_separator - id_separator); - } - } else if (class_separator != -1) { - name = tag_pattern.substring (0, class_separator); - - class_separator += ".".length; - if (attribute_separator == -1) { - css_class = tag_pattern.substring (class_separator); - } else { - css_class = tag_pattern.substring (class_separator, attribute_separator - class_separator); - } - } else { - if (attribute_separator == -1) { - name = tag_pattern; - } else { - css_class = tag_pattern.substring (0, attribute_separator); - } + + tag_pattern = create_part (tag_pattern, ":", out pseudo_class); + tag_pattern = create_part (tag_pattern, ".", out css_class); + tag_pattern = create_part (tag_pattern, "#", out id); + name = tag_pattern; + } + + string create_part (string tag_pattern, string separator, out string? part) { + int separator_index = tag_pattern.index_of (separator); + int separator_length = separator.length; + + part = null; + + if (separator_index == -1) { + return tag_pattern; } + + if (separator_index > -1 && separator_index + separator_length < tag_pattern.length) { + part = tag_pattern.substring (separator_index + separator_length); + } + + if (separator_index > separator_length) { + return tag_pattern.substring (0, separator_index); + } + + return ""; } public SelectorTag copy () { @@ -70,6 +70,7 @@ tag.name = name; tag.id = id; tag.css_class = css_class; + tag.pseudo_class = pseudo_class; if (attribute_patterns != null) { foreach (AttributePattern p in (!) attribute_patterns) { @@ -133,7 +134,7 @@ return pattern; } - public bool match (XmlElement tag, string? id, string? css_class) { + public bool match (XmlElement tag, string? id, string? css_class, string? pseudo_class) { string tag_name = tag.get_name (); if (this.name != "*" && this.name != "" && tag_name != "") { @@ -158,6 +159,16 @@ } if (((!) this.css_class) != ((!) css_class)) { + return false; + } + } + + if (this.pseudo_class != null) { + if (pseudo_class == null) { + return false; + } + + if (((!) this.pseudo_class) != ((!) pseudo_class)) { return false; } } @@ -185,6 +196,11 @@ if (css_class != null) { s.append ("."); s.append ((!) css_class); + } + + if (pseudo_class != null) { + s.append (":"); + s.append ((!) pseudo_class); } if (attribute_patterns != null) {
--- a/libsvgbird/StyleSheet.vala +++ b/libsvgbird/StyleSheet.vala @@ -47,7 +47,7 @@ return style_sheet; } - public void apply_style (XmlElement tag, SvgStyle style) { + public void apply_style (XmlElement tag, SvgStyle style, string? pseudo_class) { string? id = null; string? css_class = null; @@ -62,20 +62,32 @@ } foreach (Selector selector in styles) { - if (selector.match_tag (tag, id, css_class)) { + if (selector.match_tag (tag, id, css_class, pseudo_class)) { style.apply (selector.style); + } + } + + if (css_class != null) { + foreach (Selector selector in styles) { + if (selector.match_class (tag, id, css_class, pseudo_class)) { + style.apply (selector.style); + } } } - foreach (Selector selector in styles) { - if (selector.match_class (tag, id, css_class)) { - style.apply (selector.style); + if (id != null) { + foreach (Selector selector in styles) { + if (selector.match_id (tag, id, css_class, pseudo_class)) { + style.apply (selector.style); + } } } - - foreach (Selector selector in styles) { - if (selector.match_id (tag, id, css_class)) { - style.apply (selector.style); + + if (pseudo_class != null) { + foreach (Selector selector in styles) { + if (selector.match_pseudo_class (tag, id, css_class, pseudo_class)) { + style.apply (selector.style); + } } }
--- a/libsvgbird/SvgFile.vala +++ b/libsvgbird/SvgFile.vala @@ -34,7 +34,7 @@ drawing = new SvgDrawing (); SvgStyle style = new SvgStyle (); - SvgStyle.parse (drawing.defs, style, svg_tag); + SvgStyle.parse (drawing.defs, style, svg_tag, null); foreach (Attribute attr in svg_tag.get_attributes ()) { if (attr.get_name () == "width") { @@ -315,7 +315,7 @@ void parse_stop (Gradient gradient, XmlElement tag) { SvgStyle parent_style = new SvgStyle (); // not inherited - SvgStyle style = SvgStyle.parse (drawing.defs, parent_style, tag); + SvgStyle style = SvgStyle.parse (drawing.defs, parent_style, tag, null); Stop stop = new Stop (); gradient.stops.add (stop); @@ -428,7 +428,7 @@ object.clip_path = get_clip_path (attributes); object.transforms = get_transform (attributes); - object.style = SvgStyle.parse (drawing.defs, parent_style, tag); + object.style = SvgStyle.parse (drawing.defs, parent_style, tag, null); object.visible = is_visible (tag); // FIXME: add style fill none }
--- a/libsvgbird/SvgStyle.vala +++ b/libsvgbird/SvgStyle.vala @@ -236,7 +236,7 @@ } } - public static SvgStyle parse (Defs? d, SvgStyle inherited, XmlElement tag) { + public static SvgStyle parse (Defs? d, SvgStyle inherited, XmlElement tag, string? psedo_class) { SvgStyle s = new SvgStyle (); Attributes attributes = tag.get_attributes (); @@ -245,7 +245,7 @@ if (d != null) { StyleSheet style_sheet = ((!) d).style_sheet; - style_sheet.apply_style (tag, s); + style_sheet.apply_style (tag, s, psedo_class); } foreach (Attribute a in attributes) {