Пример #1
0
    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
Пример #2
0
    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
Пример #3
0
    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()
Пример #4
0
    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()