summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEevee (Alex Munroe) <eevee.git@veekun.com>2014-08-26 17:24:05 -0700
committerEevee (Alex Munroe) <eevee.git@veekun.com>2014-08-26 17:24:05 -0700
commit9f0c60e02e76d0fb06538160eb0b36df72abca1a (patch)
tree5bb12c4ea432a73a34cf6f8d6c7cb46e3d14bbd7
parent8c8d728cb3b375d85b9d5776b0fc598fc39efa88 (diff)
downloadpyscss-9f0c60e02e76d0fb06538160eb0b36df72abca1a.tar.gz
Make a best-effort to patch up some gradient stuff. Fixes #277, #292.
-rw-r--r--scss/functions/compass/gradients.py76
-rw-r--r--scss/tests/files/compass/gradients.css26
-rw-r--r--scss/tests/files/compass/gradients.scss14
3 files changed, 93 insertions, 23 deletions
diff --git a/scss/functions/compass/gradients.py b/scss/functions/compass/gradients.py
index 769953b..2d92ba5 100644
--- a/scss/functions/compass/gradients.py
+++ b/scss/functions/compass/gradients.py
@@ -2,6 +2,7 @@
the same.
"""
from __future__ import absolute_import
+from __future__ import print_function
from __future__ import unicode_literals
import base64
@@ -91,7 +92,7 @@ def __color_stops(percentages, *args):
else:
stops = [s if s.is_simple_unit('%') else s * max_stops for s in stops]
- return list(zip(stops, colors))
+ return List(List(pair) for pair in zip(stops, colors))
def _render_standard_color_stops(color_stops):
@@ -214,32 +215,65 @@ def _get_gradient_color_stops(args):
return color_stops or None
+# TODO these functions need to be
+# 1. well-defined
+# 2. guaranteed to never wreck css3 syntax
+# 3. updated to whatever current compass does
+# 4. fixed to use a custom type instead of monkeypatching
+
+
@register('radial-gradient')
def radial_gradient(*args):
args = List.from_maybe_starargs(args)
- position_and_angle = _get_gradient_position_and_angle(args)
- shape_and_size = _get_gradient_shape_and_size(args)
+ try:
+ # Do a rough check for standard syntax first -- `shape at position`
+ at_position = list(args[0]).index(String('at'))
+ except (IndexError, ValueError):
+ shape_and_size = _get_gradient_shape_and_size(args)
+ position_and_angle = _get_gradient_position_and_angle(args)
+ else:
+ shape_and_size = List.maybe_new(args[0][:at_position])
+ position_and_angle = List.maybe_new(args[0][at_position + 1:])
+
color_stops = _get_gradient_color_stops(args)
if color_stops is None:
raise Exception('No color stops provided to radial-gradient function')
color_stops = __color_stops(False, *color_stops)
- args = [
- position(position_and_angle) if position_and_angle is not None else None,
- shape_and_size if shape_and_size is not None else None,
- ]
- args.extend(_render_standard_color_stops(color_stops))
-
- to__s = 'radial-gradient(' + ', '.join(to_str(a) for a in args or [] if a is not None) + ')'
- ret = String.unquoted(to__s)
+ if position_and_angle:
+ rendered_position = position(position_and_angle)
+ else:
+ rendered_position = None
+ rendered_color_stops = _render_standard_color_stops(color_stops)
+
+ args = []
+ if shape_and_size and rendered_position:
+ args.append(List([shape_and_size, String.unquoted('at'), rendered_position], use_comma=False))
+ elif rendered_position:
+ args.append(rendered_position)
+ elif shape_and_size:
+ args.append(shape_and_size)
+ args.extend(rendered_color_stops)
+
+ legacy_args = []
+ if rendered_position:
+ legacy_args.append(rendered_position)
+ if shape_and_size:
+ legacy_args.append(shape_and_size)
+ legacy_args.extend(rendered_color_stops)
+
+ ret = String.unquoted(
+ 'radial-gradient(' + ', '.join(a.render() for a in args) + ')')
+
+ legacy_ret = 'radial-gradient(' + ', '.join(a.render() for a in legacy_args) + ')'
def to__css2():
return String.unquoted('')
ret.to__css2 = to__css2
def to__moz():
- return String.unquoted('-moz-' + to__s)
+ return String.unquoted('-moz-' + legacy_ret)
ret.to__moz = to__moz
def to__pie():
@@ -248,15 +282,15 @@ def radial_gradient(*args):
ret.to__pie = to__pie
def to__webkit():
- return String.unquoted('-webkit-' + to__s)
+ return String.unquoted('-webkit-' + legacy_ret)
ret.to__webkit = to__webkit
def to__owg():
args = [
'radial',
- grad_point(position_and_angle) if position_and_angle is not None else 'center',
+ grad_point(*position_and_angle) if position_and_angle is not None else 'center',
'0',
- grad_point(position_and_angle) if position_and_angle is not None else 'center',
+ grad_point(*position_and_angle) if position_and_angle is not None else 'center',
__grad_end_position(True, color_stops),
]
args.extend('color-stop(%s, %s)' % (s.render(), c.render()) for s, c in color_stops)
@@ -265,7 +299,7 @@ def radial_gradient(*args):
ret.to__owg = to__owg
def to__svg():
- return radial_svg_gradient(color_stops, position_and_angle or 'center')
+ return radial_svg_gradient(*(list(color_stops) + list(position_and_angle or [String('center')])))
ret.to__svg = to__svg
return ret
@@ -336,11 +370,11 @@ def radial_svg_gradient(*args):
args = List.from_maybe_starargs(args)
color_stops = args
center = None
- if isinstance(args[-1], (String, Number, six.string_types)):
+ if isinstance(args[-1], (String, Number)):
center = args[-1]
color_stops = args[:-1]
color_stops = __color_stops(False, *color_stops)
- cx, cy = zip(*grad_point(center).items())[1]
+ cx, cy = grad_point(center)
r = __grad_end_position(True, color_stops)
svg = __radial_svg(color_stops, cx, cy, r)
url = 'data:' + 'image/svg+xml' + ';base64,' + base64.b64encode(svg)
@@ -353,12 +387,12 @@ def linear_svg_gradient(*args):
args = List.from_maybe_starargs(args)
color_stops = args
start = None
- if isinstance(args[-1], (String, Number, six.string_types)):
+ if isinstance(args[-1], (String, Number)):
start = args[-1]
color_stops = args[:-1]
color_stops = __color_stops(False, *color_stops)
- x1, y1 = zip(*grad_point(start).items())[1]
- x2, y2 = zip(*grad_point(opposite_position(start)).items())[1]
+ x1, y1 = grad_point(start)
+ x2, y2 = grad_point(opposite_position(start))
svg = _linear_svg(color_stops, x1, y1, x2, y2)
url = 'data:' + 'image/svg+xml' + ';base64,' + base64.b64encode(svg)
inline = 'url("%s")' % escape(url)
diff --git a/scss/tests/files/compass/gradients.css b/scss/tests/files/compass/gradients.css
index 9a99ca1..f26dc7f 100644
--- a/scss/tests/files/compass/gradients.css
+++ b/scss/tests/files/compass/gradients.css
@@ -1,58 +1,84 @@
.bg-shortcut-linear-gradient {
background: #fff linear-gradient(top left, #ddd, #aaa);
}
+
.bg-shortcut-radial-gradient {
background: #fff radial-gradient(center center, #ddd, #aaa 100px);
}
+
.bg-linear-gradient-angle-svg {
background-image: linear-gradient(-45deg, blue, black);
}
+
.bg-linear-gradient-angle2-svg {
background-image: linear-gradient(top left, blue, black);
}
+
.bg-linear-gradient {
background-image: linear-gradient(top left, #ddd, #aaa);
}
+
.bg-linear-gradient-pixel-stop-from-top {
background-image: linear-gradient(top, #ddd 10px, #aaa 40px);
}
+
.bg-linear-gradient-pixel-stop-from-left {
background-image: linear-gradient(left, #ddd 10px, #aaa 40px);
}
+
.transparent-in-linear-gradient {
background-image: #fff linear-gradient(top left, transparent, #aaa);
}
+
.bg-radial-gradient {
background-image: radial-gradient(center center, #ddd, transparent 100px);
}
+
.bg-linear-gradient-with-angle {
background-image: linear-gradient(-45deg, #ddd, #aaa);
}
+
.bg-radial-gradient-with-angle-and-shape {
background-image: radial-gradient(ellipse cover, #ddd, #aaa 100px);
}
+
.bg-all-gradient-types {
background-image: linear-gradient(top left, #ddd, #aaa);
background-image: radial-gradient(center center, #ddd, #aaa 100px);
}
+
.border-image-gradient {
border-image: radial-gradient(#0f0, #f00 100px) 100 stretch;
}
+
.direct-list-image-with-gradient {
list-style-image: radial-gradient(lime, red 10px);
}
+
.shorthand-list-image-with-gradient {
list-style: outside radial-gradient(lime, red 10px);
}
+
.content-with-gradient {
content: radial-gradient(lime, red 10px);
}
+
.bg-linear-gradient-no-position {
background-image: linear-gradient(#ddd, #aaa);
}
+
.bg-radial-gradient-no-position {
background-image: radial-gradient(#ddd, #aaa 100px);
}
+
.cross-fade {
background-image: cross-fade(radial-gradient(#ddd, #aaa 100px), url("4x6.png"));
}
+
+.bg-radial-gradient-at {
+ background: radial-gradient(circle at center, red, green);
+}
+
+.bg-linear-gradient-to {
+ background: linear-gradient(to right, red, green);
+}
diff --git a/scss/tests/files/compass/gradients.scss b/scss/tests/files/compass/gradients.scss
index 9951e75..1eba785 100644
--- a/scss/tests/files/compass/gradients.scss
+++ b/scss/tests/files/compass/gradients.scss
@@ -1,5 +1,3 @@
-@option style:legacy;
-
// Borrowed from Compass's actual test suite, but cut down to just the gradient
// calls, and with some editing to e.g. preserve color formatting:
// https://github.com/chriseppstein/compass/blob/stable/test/fixtures/stylesheets/compass/sass/gradients.sass
@@ -83,3 +81,15 @@
.cross-fade {
background-image: cross-fade(radial-gradient(#ddd, #aaa 100px), url("4x6.png"));
}
+
+
+/* New tests of our own */
+
+// Valid CSS3, used to come out with the first argument doubled
+.bg-radial-gradient-at {
+ background: radial-gradient(circle at center, red 0%, green 100%);
+}
+
+.bg-linear-gradient-to {
+ background: linear-gradient(to right, red 0%, green 100%);
+}