Example #1
0
    def _setCssText(self, cssText):
        self._checkReadonly()

        types = self._prods  # rename!

        _operator = Choice(Prod(name='Operator */',
                                match=lambda t, v: v in '*/',
                                toSeq=lambda t, tokens: (t[0], t[1])
                                ),
                           Sequence(
                               PreDef.S(),
                               Choice(
                                   Sequence(
                                       Prod(name='Operator */',
                                            match=lambda t, v: v in '*/',
                                            toSeq=lambda t, tokens: (t[0], t[1])
                                            ),
                                       PreDef.S(optional=True)
                                   ),
                                   Sequence(
                                       Prod(name='Operator +-',
                                            match=lambda t, v: v in '+-',
                                            toSeq=lambda t, tokens: (t[0], t[1])
                                            ),
                                       PreDef.S()
                                   ),
                                   PreDef.funcEnd(stop=True, mayEnd=True)
                               )
        )
        )

        def _operant(): return Choice(_DimensionProd(self),
                                      _CSSVariableProd(self))

        prods = Sequence(Prod(name='CALC',
                              match=lambda t, v: t == types.FUNCTION and
                              normalize(v) == 'calc('
                              ),
                         PreDef.S(optional=True),
                         _operant(),
                         Sequence(_operator,
                                  _operant(),
                                  minmax=lambda: (0, None)
                                  ),
                         PreDef.funcEnd(stop=True)
                         )

        # store: name of variable
        ok, seq, store, unused = ProdParser().parse(cssText,
                                                    'CSSCalc',
                                                    prods,
                                                    checkS=True)
        self.wellformed = ok
        if ok:
            self._setSeq(seq)
Example #2
0
    def _setCssText(self, cssText):
        self._checkReadonly()

        prods = Sequence(  # PreDef.unary(),
            Choice(PreDef.dimension(stop=True), PreDef.number(stop=True),
                   PreDef.percentage(stop=True)))
        ok, seq, store, unused = ProdParser().parse(cssText, 'DimensionValue',
                                                    prods)
        self.wellformed = ok
        if ok:
            item = seq[0]

            sign, v, d = self.__reUnNumDim.findall(normalize(item.value))[0]
            if '.' in v:
                val = float(sign + v)
            else:
                val = int(sign + v)

            dim = None
            if d:
                dim = d

            self._sign = sign
            self._value = val
            self._dimension = dim
            self._type = item.type

            self._setSeq(seq)
Example #3
0
    def _setCssText(self, cssText):
        self._checkReadonly()

        types = self._prods  # rename!
        prods = Sequence(
            Prod(name='var',
                 match=lambda t, v: t == types.FUNCTION and normalize(v) ==
                 'var('), PreDef.ident(toStore='ident'),
            Sequence(PreDef.comma(),
                     Choice(_ColorProd(self, toStore='fallback'),
                            _DimensionProd(self, toStore='fallback'),
                            _URIProd(self, toStore='fallback'),
                            _ValueProd(self, toStore='fallback'),
                            _CalcValueProd(self, toStore='fallback'),
                            _CSSVariableProd(self, toStore='fallback'),
                            _CSSFunctionProd(self, toStore='fallback')),
                     minmax=lambda: (0, 1)), PreDef.funcEnd(stop=True))

        # store: name of variable
        store = {'ident': None, 'fallback': None}
        ok, seq, store, unused = ProdParser().parse(cssText, 'CSSVariable',
                                                    prods)
        self.wellformed = ok

        if ok:
            self._name = store['ident'].value
            try:
                self._fallback = store['fallback'].value
            except KeyError:
                self._fallback = None

            self._setSeq(seq)
Example #4
0
    def _productions(self):
        """Return definition used for parsing."""
        types = self._prods  # rename!

        func = Prod(name='MSValue-Sub',
                    match=lambda t, v: t == self._prods.FUNCTION,
                    toSeq=lambda t, tokens:
                    (MSValue._functionName,
                     MSValue(pushtoken(t, tokens), parent=self)))

        funcProds = Sequence(
            Prod(name='FUNCTION',
                 match=lambda t, v: t == types.FUNCTION,
                 toSeq=lambda t, tokens: (t[0], t[1])),
            Sequence(
                Choice(
                    _ColorProd(self),
                    _DimensionProd(self),
                    _URIProd(self),
                    _ValueProd(self),
                    _MSValueProd(self),
                    # _CalcValueProd(self),
                    _CSSVariableProd(self),
                    func,
                    # _CSSFunctionProd(self),
                    Prod(name='MSValuePart',
                         match=lambda t, v: v != ')',
                         toSeq=lambda t, tokens: (t[0], t[1]))),
                minmax=lambda: (0, None)),
            PreDef.funcEnd(stop=True))
        return funcProds
Example #5
0
def MediaQueryValueProd(parent):
    return Choice(
        _ColorProd(parent),
        _DimensionProd(parent),
        _ValueProd(parent),
        PreDef.ratio(),
    )
Example #6
0
    def _productions(self):
        """Return definition used for parsing."""
        types = self._prods  # rename!

        itemProd = Choice(_ColorProd(self), _DimensionProd(self),
                          _URIProd(self), _ValueProd(self),
                          _CalcValueProd(self), _CSSVariableProd(self),
                          _CSSFunctionProd(self))
        funcProds = Sequence(
            Prod(name='FUNCTION',
                 match=lambda t, v: t == types.FUNCTION,
                 toSeq=lambda t, tokens: (t[0], normalize(t[1]))),
            Choice(
                Sequence(
                    itemProd,
                    Sequence(PreDef.comma(optional=True),
                             itemProd,
                             minmax=lambda: (0, None)),
                    PreDef.funcEnd(stop=True)), PreDef.funcEnd(stop=True)))
        return funcProds
Example #7
0
    def _setCssText(self, cssText):
        self._checkReadonly()

        prods = Choice(PreDef.hexcolor(stop=True),
                       PreDef.ident(stop=True),
                       PreDef.string(stop=True),
                       PreDef.unicode_range(stop=True),
                       )
        ok, seq, store, unused = ProdParser().parse(cssText, 'Value', prods)
        self.wellformed = ok
        if ok:
            # only 1 value anyway!
            self._type = seq[0].type
            self._value = seq[0].value

            self._setSeq(seq)
Example #8
0
    def test_matches(self):
        "Choice.matches()"
        p1 = Prod('p1', lambda t, v: t == 1)
        p2 = Prod('p2', lambda t, v: t == 2, optional=True)

        t1 = (1, 0, 0, 0)
        t2 = (2, 0, 0, 0)
        t3 = (3, 0, 0, 0)

        c = Choice(p1, p2)
        self.assertEqual(True, c.matches(t1))
        self.assertEqual(True, c.matches(t2))
        self.assertEqual(False, c.matches(t3))

        c = Choice(Sequence(p1), Sequence(p2))
        self.assertEqual(True, c.matches(t1))
        self.assertEqual(True, c.matches(t2))
        self.assertEqual(False, c.matches(t3))
Example #9
0
    def test_reset(self):
        "Choice.reset()"
        p1 = Prod('p1', lambda t, v: t == 1)
        p2 = Prod('p2', lambda t, v: t == 2)
        t1 = (1, 0, 0, 0)
        t2 = (2, 0, 0, 0)

        ch = Choice(p1, p2)
        self.assertEqual(p1, ch.nextProd(t1))
        self.assertRaises(Exhausted, ch.nextProd, t1)
        ch.reset()
        self.assertEqual(p2, ch.nextProd(t2))
Example #10
0
    def test_nested(self):
        "Choice with nested Sequence"
        p1 = Prod('p1', lambda t, v: t == 1)
        p2 = Prod('p2', lambda t, v: t == 2)
        s1 = Sequence(p1, p1)
        s2 = Sequence(p2, p2)
        t0 = (0, 0, 0, 0)
        t1 = (1, 0, 0, 0)
        t2 = (2, 0, 0, 0)

        ch = Choice(s1, s2)
        self.assertRaisesMsg(
            ParseError,
            'No match for (0, 0, 0, 0) in Choice(Sequence(p1, p1), Sequence(p2, p2))',
            ch.nextProd, t0)
        self.assertEqual(s1, ch.nextProd(t1))
        self.assertRaisesMsg(Exhausted, 'Extra token', ch.nextProd, t1)

        ch = Choice(s1, s2)
        self.assertEqual(s2, ch.nextProd(t2))
        self.assertRaisesMsg(Exhausted, 'Extra token', ch.nextProd, t1)
Example #11
0
    def _setCssText(self, cssText):
        """
        :exceptions:
            - :exc:`~xml.dom.SyntaxErr`:
              Raised if the specified CSS string value has a syntax error and
              is unparsable.
            - :exc:`~xml.dom.InvalidModificationErr`:
              Raised if the specified CSS string value represents a different
              type of rule than the current one.
            - :exc:`~xml.dom.HierarchyRequestErr`:
              Raised if the rule cannot be inserted at this point in the
              style sheet.
            - :exc:`~xml.dom.NoModificationAllowedErr`:
              Raised if the rule is readonly.
        """
        super(MarginRule, self)._setCssText(cssText)

        # TEMP: all style tokens are saved in store to fill styledeclaration
        # TODO: resolve when all generators
        styletokens = Prod(name='styletokens',
                           match=lambda t, v: v != '}',
                           # toSeq=False,
                           toStore='styletokens',
                           storeToken=True
                           )

        prods = Sequence(Prod(name='@ margin',
                              match=lambda t, v:
                              t == 'ATKEYWORD' and
                              self._normalize(v) in MarginRule.margins,
                              toStore='margin'
                              # TODO?
                              # , exception=xml.dom.InvalidModificationErr
                              ),
                         PreDef.char('OPEN', '{'),
                         Sequence(Choice(PreDef.unknownrule(toStore='@'),
                                         styletokens),
                                  minmax=lambda: (0, None)
                                  ),
                         PreDef.char('CLOSE', '}', stopAndKeep=True)
                         )
        # parse
        ok, seq, store, unused = ProdParser().parse(cssText,
                                                    'MarginRule',
                                                    prods)

        if ok:
            # TODO: use seq for serializing instead of fixed stuff?
            self._setSeq(seq)

            if 'margin' in store:
                # may raise:
                self.margin = store['margin'].value
            else:
                self._log.error('No margin @keyword for this %s rule' %
                                self.margin,
                                error=xml.dom.InvalidModificationErr)

            # new empty style
            self.style = CSSStyleDeclaration(parentRule=self)

            if 'styletokens' in store:
                # may raise:
                self.style.cssText = store['styletokens']
Example #12
0
    def _setMediaText(self, mediaText):
        """
        :param mediaText:
            a single media query string, e.g. ``print and (min-width: 25cm)``

        :exceptions:
            - :exc:`~xml.dom.SyntaxErr`:
              Raised if the specified string value has a syntax error and is
              unparsable.
            - :exc:`~xml.dom.InvalidCharacterErr`:
              Raised if the given mediaType is unknown.
            - :exc:`~xml.dom.NoModificationAllowedErr`:
              Raised if this media query is readonly.

        media_query
         : [ONLY | NOT]? S* media_type S* [ AND S* expression ]*
         | expression [ AND S* expression ]*
         ;
        media_type
         : IDENT
         ;
        expression
         : '(' S* media_feature S* [ ':' S* expr ]? ')' S*
         ;
        media_feature
         : IDENT
         ;

        """
        self._checkReadonly()

        def expression():
            return Sequence(
                PreDef.char(name='expression', char='('),
                Prod(name='media_feature',
                     match=lambda t, v: t == PreDef.types.IDENT),
                Sequence(
                    PreDef.char(name='colon', char=':'),
                    css_parser.css.value.MediaQueryValueProd(self),
                    minmax=lambda: (0, 1)  # optional
                ),
                PreDef.char(name='expression END',
                            char=')',
                            stopIfNoMoreMatch=self._partof))

        prods = Choice(
            Sequence(
                Prod(
                    name='ONLY|NOT',  # media_query
                    match=lambda t, v: t == PreDef.types.IDENT and normalize(v)
                    in ('only', 'not'),
                    optional=True,
                    toStore='not simple'),
                Prod(name='media_type',
                     match=lambda t, v: t == PreDef.types.IDENT and normalize(
                         v) in self.MEDIA_TYPES,
                     stopIfNoMoreMatch=True,
                     toStore='media_type'),
                Sequence(Prod(name='AND',
                              match=lambda t, v: t == PreDef.types.IDENT and
                              normalize(v) == 'and',
                              toStore='not simple'),
                         expression(),
                         minmax=lambda: (0, None))),
            Sequence(
                expression(),
                Sequence(Prod(name='AND',
                              match=lambda t, v: t == PreDef.types.IDENT and
                              normalize(v) == 'and'),
                         expression(),
                         minmax=lambda: (0, None))),
            Sequence(
                Prod(
                    name='ONLY|NOT',  # media_query
                    match=lambda t, v: t == PreDef.types.IDENT and normalize(v)
                    in ('only', 'not'),
                    optional=True,
                    toStore='not simple'),
                Prod(name='media_type',
                     match=lambda t, v: t == PreDef.types.IDENT,
                     toStore='media_type'),
                Sequence(Prod(name='AND',
                              match=lambda t, v: t == PreDef.types.IDENT and
                              normalize(v) == 'and',
                              toStore='not simple'),
                         expression(),
                         minmax=lambda: (0, None))))

        # parse
        ok, seq, store, unused = ProdParser().parse(mediaText, 'MediaQuery',
                                                    prods)
        self._wellformed = ok
        if ok:
            try:
                media_type = store['media_type']
            except KeyError:
                pass
            else:
                if 'not simple' not in store:
                    self.mediaType = media_type.value

            # TODO: filter doubles!
            self._setSeq(seq)
Example #13
0
    def test_combi(self):
        "ProdParser.parse() 2"
        p1 = Prod('p1', lambda t, v: v == '1')
        p2 = Prod('p2', lambda t, v: v == '2')
        p3 = Prod('p3', lambda t, v: v == '3')

        tests = {
            '1 2': True,
            '1 2 1 2': True,
            '3': True,
            # '': 'No match in Choice(Sequence(p1, p2), p3)',
            '1': 'Missing token for production p2',
            '1 2 1': 'Missing token for production p2',
            '1 2 1 2 x': "No match: ('IDENT', 'x', 1, 9)",
            '1 2 1 2 1': "No match: ('NUMBER', '1', 1, 9)",
            '3 x': "No match: ('IDENT', 'x', 1, 3)",
            '3 3': "No match: ('NUMBER', '3', 1, 3)",
        }
        for text, exp in tests.items():
            if sys.version_info.major == 2 and hasattr(exp, 'replace'):
                exp = exp.replace("('", "(u'").replace(" '", " u'")
            prods = Choice(Sequence(p1, p2, minmax=lambda: (1, 2)), p3)
            if exp is True:
                wellformed, seq, store, unused = ProdParser().parse(
                    text, 'T', prods)
                self.assertEqual(wellformed, exp)
            else:
                self.assertRaisesMsg(xml.dom.SyntaxErr, 'T: %s' % exp,
                                     ProdParser().parse, text, 'T', prods)

        tests = {
            '1 3':
            True,
            '1 1 3':
            True,
            '2 3':
            True,
            '1':
            'Missing token for production p3',
            '1 1':
            'Missing token for production p3',
            '1 3 3':
            "No match: ('NUMBER', '3', 1, 5)",
            '1 1 3 3':
            "No match: ('NUMBER', '3', 1, 7)",
            '2 3 3':
            "No match: ('NUMBER', '3', 1, 5)",
            '2':
            'Missing token for production p3',
            '3':
            "Missing token for production Choice(Sequence(p1), p2): ('NUMBER', '3', 1, 1)",
        }
        for text, exp in tests.items():
            if sys.version_info.major == 2 and hasattr(exp, 'replace'):
                exp = exp.replace("('", "(u'").replace(" '", " u'")
            prods = Sequence(Choice(Sequence(p1, minmax=lambda: (1, 2)), p2),
                             p3)
            if exp is True:
                wellformed, seq, store, unused = ProdParser().parse(
                    text, 'T', prods)
                self.assertEqual(wellformed, exp)
            else:
                self.assertRaisesMsg(xml.dom.SyntaxErr, 'T: %s' % exp,
                                     ProdParser().parse, text, 'T', prods)
Example #14
0
    def test_init(self):
        "Choice.__init__()"
        p1 = Prod('p1', lambda t, v: t == 1)
        p2 = Prod('p2', lambda t, v: t == 2)
        t0 = (0, 0, 0, 0)
        t1 = (1, 0, 0, 0)
        t2 = (2, 0, 0, 0)

        ch = Choice(p1, p2)
        self.assertRaisesMsg(ParseError,
                             'No match for (0, 0, 0, 0) in Choice(p1, p2)',
                             ch.nextProd, t0)
        self.assertEqual(p1, ch.nextProd(t1))
        self.assertRaisesMsg(Exhausted, 'Extra token', ch.nextProd, t1)

        ch = Choice(p1, p2)
        self.assertEqual(p2, ch.nextProd(t2))
        self.assertRaisesMsg(Exhausted, 'Extra token', ch.nextProd, t2)

        ch = Choice(p2, p1)
        self.assertRaisesMsg(ParseError,
                             'No match for (0, 0, 0, 0) in Choice(p2, p1)',
                             ch.nextProd, t0)
        self.assertEqual(p1, ch.nextProd(t1))
        self.assertRaisesMsg(Exhausted, 'Extra token', ch.nextProd, t1)

        ch = Choice(p2, p1)
        self.assertEqual(p2, ch.nextProd(t2))
        self.assertRaisesMsg(Exhausted, 'Extra token', ch.nextProd, t2)
Example #15
0
    def _setCssText(self, cssText):
        if isinstance(cssText, (int, float)):
            cssText = text_type(cssText)  # if it is a number
        """
        Format::

            unary_operator
              : '-' | '+'
              ;
            operator
              : '/' S* | ',' S* | /* empty */
              ;
            expr
              : term [ operator term ]*
              ;
            term
              : unary_operator?
                [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* |
                  ANGLE S* | TIME S* | FREQ S* ]
              | STRING S* | IDENT S* | URI S* | hexcolor | function
              | UNICODE-RANGE S*
              ;
            function
              : FUNCTION S* expr ')' S*
              ;
            /*
             * There is a constraint on the color that it must
             * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F])
             * after the "#"; e.g., "#000" is OK, but "#abcd" is not.
             */
            hexcolor
              : HASH S*
              ;

        :exceptions:
            - :exc:`~xml.dom.SyntaxErr`:
              Raised if the specified CSS string value has a syntax error
              (according to the attached property) or is unparsable.
            - :exc:`~xml.dom.InvalidModificationErr`:
              TODO: Raised if the specified CSS string value represents a
              different type of values than the values allowed by the CSS
              property.
            - :exc:`~xml.dom.NoModificationAllowedErr`:
              Raised if this value is readonly.
        """
        self._checkReadonly()

        # used as operator is , / or S
        nextSor = ',/'
        term = Choice(
            _ColorProd(self, nextSor),
            _DimensionProd(self, nextSor),
            _URIProd(self, nextSor),
            _ValueProd(self, nextSor),
            #                      _Rect(self, nextSor),
            # all other functions
            _CSSVariableProd(self, nextSor),
            _MSValueProd(self, nextSor),
            _CalcValueProd(self, nextSor),
            _CSSFunctionProd(self, nextSor))
        operator = Choice(PreDef.S(toSeq=False),
                          PreDef.char('comma',
                                      ',',
                                      toSeq=lambda t, tokens:
                                      ('operator', t[1]),
                                      optional=True),
                          PreDef.char('slash',
                                      '/',
                                      toSeq=lambda t, tokens:
                                      ('operator', t[1]),
                                      optional=True),
                          optional=True)
        prods = Sequence(
            term,
            Sequence(  # mayEnd this Sequence if whitespace
                operator,
                # TODO: only when setting via other class
                # used by variabledeclaration currently
                PreDef.char('END', ';', stopAndKeep=True, optional=True),
                # TODO: } and !important ends too!
                term,
                minmax=lambda: (0, None)))
        # parse
        ok, seq, store, unused = ProdParser().parse(cssText, 'PropertyValue',
                                                    prods)
        # must be at least one value!
        ok = ok and len(as_list(self.__items(seq))) > 0

        for item in seq:
            if hasattr(item.value, 'wellformed') and not item.value.wellformed:
                ok = False
                break

        self.wellformed = ok
        if ok:
            self._setSeq(seq)
        else:
            self._log.error('PropertyValue: Unknown syntax or no value: %s' %
                            self._valuestr(cssText))
Example #16
0
        def _operant(): return Choice(_DimensionProd(self),
                                      _CSSVariableProd(self))

        prods = Sequence(Prod(name='CALC',
Example #17
0
    def _setCssText(self, cssText):
        self._checkReadonly()
        types = self._prods  # rename!

        component = Choice(
            PreDef.unary(toSeq=lambda t, tokens: (t[
                0], DimensionValue(pushtoken(t, tokens), parent=self))),
            PreDef.number(toSeq=lambda t, tokens: (t[
                0], DimensionValue(pushtoken(t, tokens), parent=self))),
            PreDef.percentage(toSeq=lambda t, tokens: (t[
                0], DimensionValue(pushtoken(t, tokens), parent=self))))
        noalp = Sequence(
            Prod(name='FUNCTION',
                 match=lambda t, v: t == types.FUNCTION and v.lower() in
                 ('rgb(', 'hsl('),
                 toSeq=lambda t, tokens: (t[0], normalize(t[1]))), component,
            Sequence(PreDef.comma(optional=True),
                     component,
                     minmax=lambda: (2, 2)), PreDef.funcEnd(stop=True))
        witha = Sequence(
            Prod(name='FUNCTION',
                 match=lambda t, v: t == types.FUNCTION and v.lower() in
                 ('rgba(', 'hsla('),
                 toSeq=lambda t, tokens: (t[0], normalize(t[1]))), component,
            Sequence(PreDef.comma(optional=True),
                     component,
                     minmax=lambda: (3, 3)), PreDef.funcEnd(stop=True))
        namedcolor = Prod(name='Named Color',
                          match=lambda t, v: t == 'IDENT' and
                          (normalize(v) in as_list(self.COLORS.keys())),
                          stop=True)

        prods = Choice(PreDef.hexcolor(stop=True), namedcolor, noalp, witha)

        ok, seq, store, unused = ProdParser().parse(cssText, self.type, prods)
        self.wellformed = ok
        if ok:
            t, v = seq[0].type, seq[0].value
            if 'IDENT' == t:
                rgba = self.COLORS[normalize(v)]
            if 'HASH' == t:
                if len(v) == 4:
                    # HASH #rgb
                    rgba = (int(2 * v[1], 16), int(2 * v[2],
                                                   16), int(2 * v[3], 16), 1.0)
                else:
                    # HASH #rrggbb
                    rgba = (int(v[1:3], 16), int(v[3:5], 16), int(v[5:7],
                                                                  16), 1.0)

            elif 'FUNCTION' == t:
                functiontype, raw, check = None, [], ''
                HSL = False

                for item in seq:
                    try:
                        type_ = item.value.type
                    except AttributeError:
                        # type of function, e.g. rgb(
                        if item.type == 'FUNCTION':
                            functiontype = item.value
                            HSL = functiontype in ('hsl(', 'hsla(')
                        continue

                    # save components
                    if type_ == Value.NUMBER:
                        raw.append(item.value.value)
                        check += 'N'
                    elif type_ == Value.PERCENTAGE:
                        if HSL:
                            # save as percentage fraction
                            raw.append(item.value.value / 100.0)
                        else:
                            # save as real value of percentage of 255
                            raw.append(int(255 * item.value.value / 100))
                        check += 'P'

                if HSL:
                    # convert to rgb
                    # h is 360 based (circle)
                    h, s, l_ = raw[0] / 360.0, raw[1], raw[2]
                    # ORDER h l_ s !!!
                    r, g, b = colorsys.hls_to_rgb(h, l_, s)
                    # back to 255 based
                    rgba = [
                        int(round(r * 255)),
                        int(round(g * 255)),
                        int(round(b * 255))
                    ]

                    if len(raw) > 3:
                        rgba.append(raw[3])

                else:
                    # rgb, rgba
                    rgba = raw

                if len(rgba) < 4:
                    rgba.append(1.0)

                # validate
                checks = {
                    'rgb(': ('NNN', 'PPP'),
                    'rgba(': ('NNNN', 'PPPN'),
                    'hsl(': ('NPP', ),
                    'hsla(': ('NPPN', )
                }
                if check not in checks[functiontype]:
                    self._log.error('ColorValue has invalid %s) parameters: '
                                    '%s (N=Number, P=Percentage)' %
                                    (functiontype, check))

            self._colorType = t
            self._red, self._green, self._blue, self._alpha = tuple(rgba)
            self._setSeq(seq)
Example #18
0
 def _operant():
     return Choice(_DimensionProd(self), _CSSVariableProd(self))