def __init__(self, href=None, media=None, title='', disabled=None, ownerNode=None, parentStyleSheet=None, readonly=False, ownerRule=None, validating=True): """ For parameters see :class:`~cssutils.stylesheets.StyleSheet` """ super(CSSStyleSheet, self).__init__('text/css', href, media, title, disabled, ownerNode, parentStyleSheet, validating=validating) self._ownerRule = ownerRule self.cssRules = cssutils.css.CSSRuleList() self._namespaces = _Namespaces(parentStyleSheet=self, log=self._log) self._variables = CSSVariablesDeclaration() self._readonly = readonly # used only during setting cssText by parse*() self.__encodingOverride = None self._fetcher = None
def __init__(self, href=None, media=None, title=u'', disabled=None, ownerNode=None, parentStyleSheet=None, readonly=False, ownerRule=None): """ For parameters see :class:`~cssutils.stylesheets.StyleSheet` """ super(CSSStyleSheet, self).__init__( 'text/css', href, media, title, disabled, ownerNode, parentStyleSheet) self._ownerRule = ownerRule self.cssRules = cssutils.css.CSSRuleList() self._namespaces = _Namespaces(parentStyleSheet=self, log=self._log) self._readonly = readonly # used only during setting cssText by parse*() self.__encodingOverride = None self._fetcher = None
def _setCssText(self, cssText): """Parse `cssText` and overwrites the whole stylesheet. :param cssText: a parseable string or a tuple of (cssText, dict-of-namespaces) :exceptions: - :exc:`~xml.dom.NamespaceErr`: If a namespace prefix is found which is not declared. - :exc:`~xml.dom.NoModificationAllowedErr`: Raised if the rule is readonly. - :exc:`~xml.dom.SyntaxErr`: Raised if the specified CSS string value has a syntax error and is unparsable. """ self._checkReadonly() cssText, namespaces = self._splitNamespacesOff(cssText) tokenizer = self._tokenize2(cssText) def S(expected, seq, token, tokenizer=None): # @charset must be at absolute beginning of style sheet # or 0 for py3 return max(1, expected or 0) def COMMENT(expected, seq, token, tokenizer=None): "special: sets parent*" self.insertRule( cssutils.css.CSSComment([token], parentStyleSheet=self)) # or 0 for py3 return max(1, expected or 0) def charsetrule(expected, seq, token, tokenizer): # parse and consume tokens in any case rule = cssutils.css.CSSCharsetRule(parentStyleSheet=self) rule.cssText = self._tokensupto2(tokenizer, token) if expected > 0: self._log.error( 'CSSStylesheet: CSSCharsetRule only allowed ' 'at beginning of stylesheet.', token, xml.dom.HierarchyRequestErr) return expected elif rule.wellformed: self.insertRule(rule) return 1 def importrule(expected, seq, token, tokenizer): # parse and consume tokens in any case rule = cssutils.css.CSSImportRule(parentStyleSheet=self) rule.cssText = self._tokensupto2(tokenizer, token) if expected > 1: self._log.error( 'CSSStylesheet: CSSImportRule not allowed ' 'here.', token, xml.dom.HierarchyRequestErr) return expected elif rule.wellformed: self.insertRule(rule) return 1 def namespacerule(expected, seq, token, tokenizer): # parse and consume tokens in any case rule = cssutils.css.CSSNamespaceRule(cssText=self._tokensupto2( tokenizer, token), parentStyleSheet=self) if expected > 2: self._log.error( 'CSSStylesheet: CSSNamespaceRule not allowed ' 'here.', token, xml.dom.HierarchyRequestErr) return expected elif rule.wellformed: if rule.prefix not in self.namespaces: # add new if not same prefix self.insertRule(rule, _clean=False) else: # same prefix => replace namespaceURI for r in self.cssRules.rulesOfType(rule.NAMESPACE_RULE): if r.prefix == rule.prefix: r._replaceNamespaceURI(rule.namespaceURI) self._namespaces[rule.prefix] = rule.namespaceURI return 2 def variablesrule(expected, seq, token, tokenizer): # parse and consume tokens in any case rule = cssutils.css.CSSVariablesRule(parentStyleSheet=self) rule.cssText = self._tokensupto2(tokenizer, token) if expected > 2: self._log.error( 'CSSStylesheet: CSSVariablesRule not allowed ' 'here.', token, xml.dom.HierarchyRequestErr) return expected elif rule.wellformed: self.insertRule(rule) self._updateVariables() return 2 def fontfacerule(expected, seq, token, tokenizer): # parse and consume tokens in any case rule = cssutils.css.CSSFontFaceRule(parentStyleSheet=self) rule.cssText = self._tokensupto2(tokenizer, token) if rule.wellformed: self.insertRule(rule) return 3 def mediarule(expected, seq, token, tokenizer): # parse and consume tokens in any case rule = cssutils.css.CSSMediaRule(parentStyleSheet=self) rule.cssText = self._tokensupto2(tokenizer, token) if rule.wellformed: self.insertRule(rule) return 3 def pagerule(expected, seq, token, tokenizer): # parse and consume tokens in any case rule = cssutils.css.CSSPageRule(parentStyleSheet=self) rule.cssText = self._tokensupto2(tokenizer, token) if rule.wellformed: self.insertRule(rule) return 3 def unknownrule(expected, seq, token, tokenizer): # parse and consume tokens in any case if token[1] in cssutils.css.MarginRule.margins: self._log.error('CSSStylesheet: MarginRule out CSSPageRule.', token, neverraise=True) rule = cssutils.css.MarginRule(parentStyleSheet=self) rule.cssText = self._tokensupto2(tokenizer, token) else: self._log.warn('CSSStylesheet: Unknown @rule found.', token, neverraise=True) rule = cssutils.css.CSSUnknownRule(parentStyleSheet=self) rule.cssText = self._tokensupto2(tokenizer, token) if rule.wellformed: self.insertRule(rule) # or 0 for py3 return max(1, expected or 0) def ruleset(expected, seq, token, tokenizer): # parse and consume tokens in any case rule = cssutils.css.CSSStyleRule(parentStyleSheet=self) rule.cssText = self._tokensupto2(tokenizer, token) if rule.wellformed: self.insertRule(rule) return 3 # save for possible reset oldCssRules = self.cssRules oldNamespaces = self._namespaces self.cssRules = cssutils.css.CSSRuleList() # simple during parse self._namespaces = namespaces self._variables = CSSVariablesDeclaration() # not used?! newseq = [] # ['CHARSET', 'IMPORT', ('VAR', NAMESPACE'), ('PAGE', 'MEDIA', ruleset)] wellformed, expected = self._parse(0, newseq, tokenizer, { 'S': S, 'COMMENT': COMMENT, 'CDO': lambda *ignored: None, 'CDC': lambda *ignored: None, 'CHARSET_SYM': charsetrule, 'FONT_FACE_SYM': fontfacerule, 'IMPORT_SYM': importrule, 'NAMESPACE_SYM': namespacerule, 'PAGE_SYM': pagerule, 'MEDIA_SYM': mediarule, 'VARIABLES_SYM': variablesrule, 'ATKEYWORD': unknownrule }, default=ruleset) if wellformed: # use proper namespace object self._namespaces = _Namespaces(parentStyleSheet=self, log=self._log) self._cleanNamespaces() else: # reset self._cssRules = oldCssRules self._namespaces = oldNamespaces self._updateVariables() self._cleanNamespaces()
def _setCssText(self, cssText): """Parse `cssText` and overwrites the whole stylesheet. :param cssText: a parseable string or a tuple of (cssText, dict-of-namespaces) :exceptions: - :exc:`~xml.dom.NamespaceErr`: If a namespace prefix is found which is not declared. - :exc:`~xml.dom.NoModificationAllowedErr`: Raised if the rule is readonly. - :exc:`~xml.dom.SyntaxErr`: Raised if the specified CSS string value has a syntax error and is unparsable. """ self._checkReadonly() cssText, namespaces = self._splitNamespacesOff(cssText) tokenizer = self._tokenize2(cssText) def S(expected, seq, token, tokenizer=None): # @charset must be at absolute beginning of style sheet # or 0 for py3 return max(1, expected or 0) def COMMENT(expected, seq, token, tokenizer=None): "special: sets parent*" self.insertRule(cssutils.css.CSSComment([token], parentStyleSheet=self)) # or 0 for py3 return max(1, expected or 0) def charsetrule(expected, seq, token, tokenizer): # parse and consume tokens in any case rule = cssutils.css.CSSCharsetRule(parentStyleSheet=self) rule.cssText = self._tokensupto2(tokenizer, token) if expected > 0: self._log.error(u'CSSStylesheet: CSSCharsetRule only allowed ' u'at beginning of stylesheet.', token, xml.dom.HierarchyRequestErr) return expected elif rule.wellformed: self.insertRule(rule) return 1 def importrule(expected, seq, token, tokenizer): # parse and consume tokens in any case rule = cssutils.css.CSSImportRule(parentStyleSheet=self) rule.cssText = self._tokensupto2(tokenizer, token) if expected > 1: self._log.error(u'CSSStylesheet: CSSImportRule not allowed ' u'here.', token, xml.dom.HierarchyRequestErr) return expected elif rule.wellformed: self.insertRule(rule) return 1 def namespacerule(expected, seq, token, tokenizer): # parse and consume tokens in any case rule = cssutils.css.CSSNamespaceRule(cssText=self._tokensupto2(tokenizer, token), parentStyleSheet=self) if expected > 2: self._log.error(u'CSSStylesheet: CSSNamespaceRule not allowed ' u'here.', token, xml.dom.HierarchyRequestErr) return expected elif rule.wellformed: if rule.prefix not in self.namespaces: # add new if not same prefix self.insertRule(rule, _clean=False) else: # same prefix => replace namespaceURI for r in self.cssRules.rulesOfType(rule.NAMESPACE_RULE): if r.prefix == rule.prefix: r._replaceNamespaceURI(rule.namespaceURI) self._namespaces[rule.prefix] = rule.namespaceURI return 2 def variablesrule(expected, seq, token, tokenizer): # parse and consume tokens in any case rule = cssutils.css.CSSVariablesRule(parentStyleSheet=self) rule.cssText = self._tokensupto2(tokenizer, token) if expected > 2: self._log.error(u'CSSStylesheet: CSSVariablesRule not allowed ' u'here.', token, xml.dom.HierarchyRequestErr) return expected elif rule.wellformed: self.insertRule(rule) self._updateVariables() return 2 def fontfacerule(expected, seq, token, tokenizer): # parse and consume tokens in any case rule = cssutils.css.CSSFontFaceRule(parentStyleSheet=self) rule.cssText = self._tokensupto2(tokenizer, token) if rule.wellformed: self.insertRule(rule) return 3 def mediarule(expected, seq, token, tokenizer): # parse and consume tokens in any case rule = cssutils.css.CSSMediaRule(parentStyleSheet=self) rule.cssText = self._tokensupto2(tokenizer, token) if rule.wellformed: self.insertRule(rule) return 3 def pagerule(expected, seq, token, tokenizer): # parse and consume tokens in any case rule = cssutils.css.CSSPageRule(parentStyleSheet=self) rule.cssText = self._tokensupto2(tokenizer, token) if rule.wellformed: self.insertRule(rule) return 3 def unknownrule(expected, seq, token, tokenizer): # parse and consume tokens in any case self._log.warn(u'CSSStylesheet: Unknown @rule found.', token, neverraise=True) rule = cssutils.css.CSSUnknownRule(self._tokensupto2(tokenizer, token), parentStyleSheet=self) if rule.wellformed: self.insertRule(rule) # or 0 for py3 return max(1, expected or 0) def ruleset(expected, seq, token, tokenizer): # parse and consume tokens in any case rule = cssutils.css.CSSStyleRule(parentStyleSheet=self) rule.cssText = self._tokensupto2(tokenizer, token) if rule.wellformed: self.insertRule(rule) return 3 # save for possible reset oldCssRules = self.cssRules oldNamespaces = self._namespaces self.cssRules = cssutils.css.CSSRuleList() # simple during parse self._namespaces = namespaces self._variables = CSSVariablesDeclaration() # not used?! newseq = [] # ['CHARSET', 'IMPORT', ('VAR', NAMESPACE'), ('PAGE', 'MEDIA', ruleset)] wellformed, expected = self._parse(0, newseq, tokenizer, {'S': S, 'COMMENT': COMMENT, 'CDO': lambda *ignored: None, 'CDC': lambda *ignored: None, 'CHARSET_SYM': charsetrule, 'FONT_FACE_SYM': fontfacerule, 'IMPORT_SYM': importrule, 'NAMESPACE_SYM': namespacerule, 'PAGE_SYM': pagerule, 'MEDIA_SYM': mediarule, 'VARIABLES_SYM': variablesrule, 'ATKEYWORD': unknownrule }, default=ruleset) if wellformed: # use proper namespace object self._namespaces = _Namespaces(parentStyleSheet=self, log=self._log) self._cleanNamespaces() else: # reset self._cssRules = oldCssRules self._namespaces = oldNamespaces self._updateVariables() self._cleanNamespaces()