The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

SelectorPattern.vala in libsvgbird

This file is a part of the Birdfont project.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git

Revisions

View the latest version of libsvgbird/SelectorPattern.vala.
Apply css styles
1 /* 2 Copyright (C) 2016 Johan Mattsson 3 4 This library is free software; you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 3 of the 7 License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 */ 14 15 using B; 16 using Math; 17 18 namespace SvgBird { 19 20 /** A CSS selector pattern. */ 21 public class SelectorPattern : GLib.Object { 22 Gee.ArrayList<SelectorTag> tags = new Gee.ArrayList<SelectorTag> (); 23 24 public SelectorPattern.empty () { 25 } 26 27 public SelectorPattern (string pattern) { 28 string p = pattern.strip (); 29 string[] elements = p.split (" "); 30 31 foreach (string element in elements) { 32 if (element != "") { 33 tags.add (new SelectorTag (element)); 34 } 35 } 36 } 37 38 public bool has_id () { 39 foreach (SelectorTag tag in tags) { 40 if (tag.id != null) { 41 return true; 42 } 43 } 44 45 return false; 46 } 47 48 public bool has_class () { 49 foreach (SelectorTag tag in tags) { 50 if (tag.css_class != null) { 51 return true; 52 } 53 } 54 55 return false; 56 } 57 58 public string to_string () { 59 StringBuilder s = new StringBuilder (); 60 61 foreach (SelectorTag tag in tags) { 62 if (s.str != "") { 63 s.append (" "); 64 } 65 66 s.append (tag.to_string ()); 67 } 68 69 return s.str; 70 } 71 public SelectorPattern copy () { 72 SelectorPattern pattern = new SelectorPattern.empty (); 73 74 foreach (SelectorTag tag in tags) { 75 pattern.tags.add (tag.copy ()); 76 } 77 78 return pattern; 79 } 80 81 public bool match (XmlElement tag, string? id, string? css_class) { 82 for (int i = tags.size - 1; i >= 0; i--) { 83 SelectorTag pattern = tags.get (i); 84 85 if (pattern.name == ">") { 86 if (i - 1 < 0) { 87 return false; 88 } 89 90 string parent = tags.get (i - 1).name; 91 92 if (!has_parent (tag, parent)) { 93 return false; 94 } 95 } else if (pattern.name == "+") { 96 if (i - 1 < 0) { 97 return false; 98 } 99 100 string previous = tags.get (i - 1).name; 101 102 if (!is_immediately_following (tag, previous)) { 103 return false; 104 } 105 } 106 107 if (!pattern.match (tag, id, css_class)) { 108 return false; 109 } 110 } 111 112 return true; 113 } 114 115 public bool is_immediately_following (XmlElement tag, string previous) { 116 return get_previous (tag) == tag; 117 } 118 119 XmlElement? get_previous (XmlElement? xml_parent) { 120 if (xml_parent == null) { 121 return null; 122 } 123 124 XmlElement element = (!) xml_parent; 125 XmlElement? parent = element.get_parent (); 126 127 if (parent != null) { 128 XmlElement? previous = null; 129 130 foreach (XmlElement e in (!) parent) { 131 if (e == xml_parent) { 132 return previous; 133 } 134 135 previous = e; 136 } 137 } 138 139 return null; 140 } 141 142 public bool has_parent (XmlElement tag, string parent) { 143 XmlElement? xml_parent = tag.get_parent (); 144 145 while (xml_parent != null) { 146 if (((!) xml_parent).get_name () == parent) { 147 return true; 148 } 149 150 xml_parent = tag.get_parent (); 151 } 152 153 return false; 154 } 155 } 156 157 } 158