1# Copyright (c) 2017-2021 Cedric Bellegarde <cedric.bellegarde@adishatz.org> 2# This program is free software: you can redistribute it and/or modify 3# it under the terms of the GNU General Public License as published by 4# the Free Software Foundation, either version 3 of the License, or 5# (at your option) any later version. 6# This program is distributed in the hope that it will be useful, 7# but WITHOUT ANY WARRANTY; without even the implied warranty of 8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9# GNU General Public License for more details. 10# You should have received a copy of the GNU General Public License 11# along with this program. If not, see <http://www.gnu.org/licenses/>. 12 13import re 14 15from eolie.css_rule_style import CSSStyleRule 16from eolie.css_rule_media import CSSMediaRule 17from eolie.css_rule_import import CSSImportRule 18from eolie.css_rule_supports import CSSSupportsRule 19 20 21class CSSRuleList: 22 """ 23 Represent a list of rules 24 """ 25 26 def __init__(self, css, uri, cancellable): 27 """ 28 Init rule 29 @param css as str 30 @param uri as str 31 @param cancellable as Gio.Cancellable 32 """ 33 self.__uri = uri 34 self.__rules = [] 35 for child in self.__get_children(css): 36 child = child.strip() 37 # Remove any comment 38 child = re.sub("\/\*[^*]*[^/]*\*\/", "", child) 39 if child.startswith("@media"): 40 rule = CSSMediaRule(child, uri, cancellable) 41 elif child.startswith("@supports"): 42 rule = CSSSupportsRule(child, uri, cancellable) 43 elif child.startswith("@import"): 44 rule = CSSImportRule(child, uri, cancellable) 45 elif child.startswith("@"): 46 # Ignore others at-rules 47 continue 48 else: 49 rule = CSSStyleRule(child) 50 self.__rules.append(rule) 51 52 @property 53 def css_text(self): 54 """ 55 Get css text for rules 56 """ 57 css = [rule.css_text for rule in self.__rules] 58 return "".join(css) 59 60 @property 61 def populated(self): 62 """ 63 True if rule is populated 64 @return bool 65 """ 66 for rule in self.__rules: 67 if not rule.populated: 68 return False 69 return True 70 71####################### 72# PRIVATE # 73####################### 74 def __get_children(self, css): 75 """ 76 Get children for css 77 @param css as str 78 @return [str] 79 """ 80 children = [] 81 css = css.replace("\n", "").strip() 82 css_split = css.split("}") 83 bracket_count = 0 84 children = [] 85 subcss = [] 86 while css_split: 87 item = css_split.pop(0) 88 for import_css in re.findall("@import[^;]*;", item): 89 children.append(import_css) 90 item.replace(import_css, "") 91 bracket_count += item.count("{") - 1 92 subcss.append(item) 93 if bracket_count == 0: 94 children.append("%s}" % "}".join(subcss)) 95 subcss = [] 96 return children 97