示例#1
0
 def __init__(self, content):
     self.content = content
     self.attrs = {}
     for declaration in parse_declaration_list(content,
                                               skip_comments=True,
                                               skip_whitespace=True):
         if isinstance(declaration, ast.AtRule):
             if declaration.at_keyword == 'bottom-right':
                 at_dec = Declarations(declaration.content)
                 self.attrs['page_bottom_right_content'] = at_dec.attrs[
                     'content']
             else:
                 raise NotImplementedError
         elif declaration.name == 'content':
             self.attrs[declaration.name.replace(
                 '-', '_')] = parse_content_value(declaration.value)
         else:
             attr = declaration.name.replace('-', '_')
             value_parts = parse_value_parts(declaration.value)
             if declaration.name in ('color', 'background-color'):
                 self.attrs[attr] = color3.parse_color(value_parts[0])
             elif declaration.name in ('margin', 'padding'):
                 apply_box_values(self.attrs, declaration.name + '_{}',
                                  list(map(convert, value_parts)))
             elif declaration.name == 'border-color':
                 apply_box_values(
                     self.attrs, 'border_{}_color',
                     list(map(color3.parse_color, value_parts)))
             elif declaration.name == 'border-width':
                 apply_box_values(self.attrs, 'border_{}_width',
                                  list(map(convert, value_parts)))
             elif declaration.name == 'border-collapse':
                 self.attrs[attr] = getattr(BorderCollapse,
                                            value_parts[0].value)
             elif declaration.name == 'border-style':
                 apply_box_values(
                     self.attrs, 'border_{}_style',
                     [getattr(BorderStyle, v.value) for v in value_parts])
             elif declaration.name == 'border-spacing':
                 if len(value_parts) == 1:
                     self.attrs['border_spacing_horizontal'] = value_parts[
                         0].value
                     self.attrs['border_spacing_vertical'] = value_parts[
                         0].value
                 else:
                     (self.attrs['border_spacing_horizontal'],
                      self.attrs['border_spacing_vertical']) = value_parts
             elif declaration.name.startswith('border-'):
                 if declaration.name.endswith('-style'):
                     self.attrs[attr] = getattr(BorderStyle,
                                                value_parts[0].value)
                 elif declaration.name.endswith('-color'):
                     self.attrs[attr] = color3.parse_color(value_parts[0])
                 elif declaration.name.endswith('-width'):
                     self.attrs[attr] = convert(value_parts[0])
             elif isinstance(value_parts[0], ast.DimensionToken):
                 self.attrs[attr] = convert(value_parts[0])
             else:
                 self.attrs[attr] = value_parts[0].value
示例#2
0
def parse_color_stop(tokens):
    if len(tokens) == 1:
        color = parse_color(tokens[0])
        if color is not None:
            return color, None
    elif len(tokens) == 2:
        color = parse_color(tokens[0])
        position = get_length(tokens[1], negative=True, percentage=True)
        if color is not None and position is not None:
            return color, position
    raise InvalidValues
示例#3
0
def parse_color_stop(tokens):
    if len(tokens) == 1:
        color = parse_color(tokens[0])
        if color is not None:
            return color, None
    elif len(tokens) == 2:
        color = parse_color(tokens[0])
        position = get_length(tokens[1], negative=True, percentage=True)
        if color is not None and position is not None:
            return color, position
    raise InvalidValues
示例#4
0
def parse_color_stop(tokens):
    if len(tokens) == 1:
        color = parse_color(tokens[0])
        if color == 'currentColor':
            # TODO: return the current color instead
            return parse_color('black'), None
        if color is not None:
            return color, None
    elif len(tokens) == 2:
        color = parse_color(tokens[0])
        position = get_length(tokens[1], negative=True, percentage=True)
        if color is not None and position is not None:
            return color, position
    raise InvalidValues
示例#5
0
def color(token):
    """``*-color`` and ``color`` properties validation."""
    result = parse_color(token)
    if result == 'currentColor':
        return 'inherit'
    else:
        return result
示例#6
0
def color(token):
    """``*-color`` and ``color`` properties validation."""
    result = parse_color(token)
    if result == 'currentColor':
        return 'inherit'
    else:
        return result
示例#7
0
def grey_from_style_frag(frag):
    color = color3.parse_color(frag)
    if color is None:
        return frag
    else:
        grey = int(255 * color.red * 0.3 + 255 * color.green * 0.59 + 255 * color.blue * 0.11)
        return "rgb({g}, {g}, {g})".format(g=grey)
示例#8
0
def test_color3_keywords():
    for css, expected in load_json('color3_keywords.json'):
        result = parse_color(css)
        if result is not None:
            r, g, b, a = result
            result = [r * 255, g * 255, b * 255, a]
        assert result == expected
示例#9
0
def expand_text_decoration(base_url, name, tokens):
    """Expand the ``text-decoration`` shorthand property."""
    text_decoration_line = set()
    text_decoration_color = None
    text_decoration_style = None

    for token in tokens:
        keyword = get_keyword(token)
        if keyword in ('none', 'underline', 'overline', 'line-through',
                       'blink'):
            text_decoration_line.add(keyword)
        elif keyword in ('solid', 'double', 'dotted', 'dashed', 'wavy'):
            if text_decoration_style is not None:
                raise InvalidValues
            else:
                text_decoration_style = keyword
        else:
            color = parse_color(token)
            if color is None:
                raise InvalidValues
            elif text_decoration_color is not None:
                raise InvalidValues
            else:
                text_decoration_color = color

    if 'none' in text_decoration_line:
        if len(text_decoration_line) != 1:
            raise InvalidValues
        text_decoration_line = 'none'
    elif not text_decoration_line:
        text_decoration_line = 'none'

    yield 'text_decoration_line', text_decoration_line
    yield 'text_decoration_color', text_decoration_color or 'currentColor'
    yield 'text_decoration_style', text_decoration_style or 'solid'
示例#10
0
def catColorAsRGBInt(category):
    if 'color' in category:
        rgb = parse_color(category['color'])
        if rgb is None:
            return None
        return (int(rgb.red * 255) << 16) + (int(rgb.green * 255) << 8) + int(
            rgb.blue * 255)
    return None
示例#11
0
def is_valid_css_color(css_color: str) -> bool:
    """Determines whether css color is valid.

    :param css_color: css color
    :type css_color: str
    :return: whether css color is valid
    :rtype: bool
    """
    return parse_color(css_color) is not None
示例#12
0
def expand_border_side(name, tokens):
    """Expand the ``border-*`` shorthand properties.

    See http://www.w3.org/TR/CSS21/box.html#propdef-border-top

    """
    for token in tokens:
        if parse_color(token) is not None:
            suffix = '-color'
        elif border_width([token]) is not None:
            suffix = '-width'
        elif border_style([token]) is not None:
            suffix = '-style'
        else:
            raise InvalidValues
        yield suffix, [token]
示例#13
0
def expand_border_side(name, tokens):
    """Expand the ``border-*`` shorthand properties.

    See http://www.w3.org/TR/CSS21/box.html#propdef-border-top

    """
    for token in tokens:
        if parse_color(token) is not None:
            suffix = '-color'
        elif border_width([token]) is not None:
            suffix = '-width'
        elif border_style([token]) is not None:
            suffix = '-style'
        else:
            raise InvalidValues
        yield suffix, [token]
示例#14
0
def compute_attr_function(computer, values):
    # TODO: use real token parsing instead of casting with Python types
    func_name, value = values
    assert func_name == 'attr()'
    attr_name, type_or_unit, fallback = value
    # computer.element sometimes is None
    # computer.element sometimes is a 'PageType' object without .get()
    # so wrapt the .get() into try and return None instead of crashing
    try:
        attr_value = computer.element.get(attr_name, fallback)
        if type_or_unit == 'string':
            pass  # Keep the string
        elif type_or_unit == 'url':
            if attr_value.startswith('#'):
                attr_value = ('internal', unquote(attr_value[1:]))
            else:
                attr_value = (
                    'external', safe_urljoin(computer.base_url, attr_value))
        elif type_or_unit == 'color':
            attr_value = parse_color(attr_value.strip())
        elif type_or_unit == 'integer':
            attr_value = int(attr_value.strip())
        elif type_or_unit == 'number':
            attr_value = float(attr_value.strip())
        elif type_or_unit == '%':
            attr_value = Dimension(float(attr_value.strip()), '%')
            type_or_unit = 'length'
        elif type_or_unit in LENGTH_UNITS:
            attr_value = Dimension(float(attr_value.strip()), type_or_unit)
            type_or_unit = 'length'
        elif type_or_unit in ANGLE_TO_RADIANS:
            attr_value = Dimension(float(attr_value.strip()), type_or_unit)
            type_or_unit = 'angle'
    except Exception:
        return
    return (type_or_unit, attr_value)
示例#15
0
def compute_attr_function(computer, values):
    # TODO: use real token parsing instead of casting with Python types
    func_name, value = values
    assert func_name == 'attr()'
    attr_name, type_or_unit, fallback = value
    # computer['element'] sometimes is None
    # computer['element'] sometimes is a 'PageType' object without .get()
    # so wrapt the .get() into try and return None instead of crashing
    try:
        attr_value = computer['element'].get(attr_name, fallback)
        if type_or_unit == 'string':
            pass  # Keep the string
        elif type_or_unit == 'url':
            if attr_value.startswith('#'):
                attr_value = ('internal', unquote(attr_value[1:]))
            else:
                attr_value = ('external',
                              safe_urljoin(computer['base_url'], attr_value))
        elif type_or_unit == 'color':
            attr_value = parse_color(attr_value.strip())
        elif type_or_unit == 'integer':
            attr_value = int(attr_value.strip())
        elif type_or_unit == 'number':
            attr_value = float(attr_value.strip())
        elif type_or_unit == '%':
            attr_value = Dimension(float(attr_value.strip()), '%')
            type_or_unit = 'length'
        elif type_or_unit in LENGTH_UNITS:
            attr_value = Dimension(float(attr_value.strip()), type_or_unit)
            type_or_unit = 'length'
        elif type_or_unit in ANGLE_TO_RADIANS:
            attr_value = Dimension(float(attr_value.strip()), type_or_unit)
            type_or_unit = 'angle'
    except Exception:
        return
    return (type_or_unit, attr_value)
示例#16
0
def test_color3_hsl():
    for css, expected in load_json('color3_hsl.json'):
        assert to_json(parse_color(css)) == expected
示例#17
0
def color(string):
    """Safely parse a color string and return a RGBA tuple."""
    return parse_color(string or '') or (0, 0, 0, 1)
示例#18
0
def other_colors(token):
    return parse_color(token)
示例#19
0
def other_colors(token):
    return parse_color(token)
示例#20
0
def outline_color(token):
    if get_keyword(token) == 'invert':
        return 'currentColor'
    else:
        return parse_color(token)
示例#21
0
from __future__ import division, unicode_literals

import collections

from tinycss2.color3 import parse_color

Dimension = collections.namedtuple('Dimension', ['value', 'unit'])


# See http://www.w3.org/TR/CSS21/propidx.html
INITIAL_VALUES = {
    'bottom': 'auto',
    'caption_side': 'top',
    'clear': 'none',
    'clip': (),  # computed value for 'auto'
    'color': parse_color('black'),  # chosen by the user agent
    'content': 'normal',
    # Means 'none', but allow `display: list-item` to increment the
    # list-item counter. If we ever have a way for authors to query
    # computed values (JavaScript?), this value should serialize to 'none'.
    'counter_increment': 'auto',
    'counter_reset': (),  # parsed value for 'none'
    # 'counter_set': (),  # parsed value for 'none'
    'direction': 'ltr',
    'display': 'inline',
    'empty_cells': 'show',
    'float': 'none',
    'height': 'auto',
    'left': 'auto',
    'line_height': 'normal',
    'list_style_image': ('none', None),
示例#22
0
"""

import collections

from tinycss2.color3 import parse_color

Dimension = collections.namedtuple('Dimension', ['value', 'unit'])


# See http://www.w3.org/TR/CSS21/propidx.html
INITIAL_VALUES = {
    'bottom': 'auto',
    'caption_side': 'top',
    'clear': 'none',
    'clip': (),  # computed value for 'auto'
    'color': parse_color('black'),  # chosen by the user agent
    # Means 'none', but allow `display: list-item` to increment the
    # list-item counter. If we ever have a way for authors to query
    # computed values (JavaScript?), this value should serialize to 'none'.
    'counter_increment': 'auto',
    'counter_reset': (),  # parsed value for 'none'
    # 'counter_set': (),  # parsed value for 'none'
    'direction': 'ltr',
    'display': 'inline',
    'empty_cells': 'show',
    'float': 'none',
    'height': 'auto',
    'left': 'auto',
    'line_height': 'normal',
    'list_style_image': ('none', None),
    'list_style_position': 'outside',
示例#23
0
def outline_color(token):
    if get_keyword(token) == 'invert':
        return 'currentColor'
    else:
        return parse_color(token)
示例#24
0
def test_color3(input):
    return parse_color(input)
示例#25
0
def test_parse_declaration_value_color():
    source = 'color:#369'
    declaration = parse_one_declaration(source)
    (value_token,) = declaration.value
    assert parse_color(value_token) == (.2, .4, .6, 1)
    assert declaration.serialize() == source