compass-core 1.0.0.alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +22 -0
- data/VERSION +1 -0
- data/data/caniuse.json +1 -0
- data/data/caniuse_extras/css-placeholder.json +171 -0
- data/lib/compass-core.rb +1 -0
- data/lib/compass/browser_support.rb +62 -0
- data/lib/compass/configuration.rb +168 -0
- data/lib/compass/configuration/data.rb +178 -0
- data/lib/compass/configuration/defaults.rb +197 -0
- data/lib/compass/configuration/inheritance.rb +304 -0
- data/lib/compass/configuration/paths.rb +19 -0
- data/lib/compass/core.rb +64 -0
- data/lib/compass/core/caniuse.rb +282 -0
- data/lib/compass/core/sass_extensions.rb +10 -0
- data/lib/compass/core/sass_extensions/functions.rb +39 -0
- data/lib/compass/core/sass_extensions/functions/colors.rb +67 -0
- data/lib/compass/core/sass_extensions/functions/configuration.rb +162 -0
- data/lib/compass/core/sass_extensions/functions/constants.rb +74 -0
- data/lib/compass/core/sass_extensions/functions/cross_browser_support.rb +269 -0
- data/lib/compass/core/sass_extensions/functions/display.rb +32 -0
- data/lib/compass/core/sass_extensions/functions/enumerate.rb +7 -0
- data/lib/compass/core/sass_extensions/functions/env.rb +60 -0
- data/lib/compass/core/sass_extensions/functions/font_files.rb +41 -0
- data/lib/compass/core/sass_extensions/functions/gradient_support.rb +616 -0
- data/lib/compass/core/sass_extensions/functions/image_size.rb +117 -0
- data/lib/compass/core/sass_extensions/functions/inline_image.rb +64 -0
- data/lib/compass/core/sass_extensions/functions/lists.rb +101 -0
- data/lib/compass/core/sass_extensions/functions/math.rb +92 -0
- data/lib/compass/core/sass_extensions/functions/selectors.rb +64 -0
- data/lib/compass/core/sass_extensions/functions/urls.rb +297 -0
- data/lib/compass/core/sass_extensions/monkey_patches.rb +3 -0
- data/lib/compass/core/sass_extensions/monkey_patches/browser_support.rb +118 -0
- data/lib/compass/core/sass_extensions/monkey_patches/traversal.rb +23 -0
- data/lib/compass/core/version.rb +5 -0
- data/lib/compass/error.rb +5 -0
- data/stylesheets/_compass.scss +3 -0
- data/stylesheets/_lemonade.scss +38 -0
- data/stylesheets/compass/_configuration.scss +54 -0
- data/stylesheets/compass/_css3.scss +21 -0
- data/stylesheets/compass/_layout.scss +3 -0
- data/stylesheets/compass/_reset-legacy.scss +3 -0
- data/stylesheets/compass/_reset.scss +3 -0
- data/stylesheets/compass/_support.scss +441 -0
- data/stylesheets/compass/_typography.scss +4 -0
- data/stylesheets/compass/_utilities.scss +9 -0
- data/stylesheets/compass/css3/_animation.scss +122 -0
- data/stylesheets/compass/css3/_appearance.scss +17 -0
- data/stylesheets/compass/css3/_background-clip.scss +35 -0
- data/stylesheets/compass/css3/_background-origin.scss +37 -0
- data/stylesheets/compass/css3/_background-size.scss +19 -0
- data/stylesheets/compass/css3/_border-radius.scss +107 -0
- data/stylesheets/compass/css3/_box-shadow.scss +88 -0
- data/stylesheets/compass/css3/_box-sizing.scss +15 -0
- data/stylesheets/compass/css3/_box.scss +85 -0
- data/stylesheets/compass/css3/_columns.scss +210 -0
- data/stylesheets/compass/css3/_deprecated-support.scss +272 -0
- data/stylesheets/compass/css3/_filter.scss +50 -0
- data/stylesheets/compass/css3/_flexbox.scss +156 -0
- data/stylesheets/compass/css3/_font-face.scss +48 -0
- data/stylesheets/compass/css3/_hyphenation.scss +71 -0
- data/stylesheets/compass/css3/_images.scss +139 -0
- data/stylesheets/compass/css3/_inline-block.scss +31 -0
- data/stylesheets/compass/css3/_opacity.scss +23 -0
- data/stylesheets/compass/css3/_pie.scss +1 -0
- data/stylesheets/compass/css3/_regions.scss +27 -0
- data/stylesheets/compass/css3/_selection.scss +59 -0
- data/stylesheets/compass/css3/_shared.scss +5 -0
- data/stylesheets/compass/css3/_text-shadow.scss +82 -0
- data/stylesheets/compass/css3/_transform.scss +590 -0
- data/stylesheets/compass/css3/_transition.scss +171 -0
- data/stylesheets/compass/css3/_user-interface.scss +71 -0
- data/stylesheets/compass/layout/_grid-background.scss +178 -0
- data/stylesheets/compass/layout/_sticky-footer.scss +23 -0
- data/stylesheets/compass/layout/_stretching.scss +24 -0
- data/stylesheets/compass/reset/_utilities-legacy.scss +135 -0
- data/stylesheets/compass/reset/_utilities.scss +142 -0
- data/stylesheets/compass/typography/_links.scss +3 -0
- data/stylesheets/compass/typography/_lists.scss +4 -0
- data/stylesheets/compass/typography/_text.scss +4 -0
- data/stylesheets/compass/typography/_units.scss +152 -0
- data/stylesheets/compass/typography/_vertical_rhythm.scss +300 -0
- data/stylesheets/compass/typography/links/_hover-link.scss +5 -0
- data/stylesheets/compass/typography/links/_link-colors.scss +28 -0
- data/stylesheets/compass/typography/links/_unstyled-link.scss +7 -0
- data/stylesheets/compass/typography/lists/_bullets.scss +34 -0
- data/stylesheets/compass/typography/lists/_horizontal-list.scss +63 -0
- data/stylesheets/compass/typography/lists/_inline-block-list.scss +50 -0
- data/stylesheets/compass/typography/lists/_inline-list.scss +47 -0
- data/stylesheets/compass/typography/text/_ellipsis.scss +25 -0
- data/stylesheets/compass/typography/text/_force-wrap.scss +12 -0
- data/stylesheets/compass/typography/text/_nowrap.scss +2 -0
- data/stylesheets/compass/typography/text/_replacement.scss +68 -0
- data/stylesheets/compass/utilities/_color.scss +1 -0
- data/stylesheets/compass/utilities/_general.scss +6 -0
- data/stylesheets/compass/utilities/_links.scss +5 -0
- data/stylesheets/compass/utilities/_lists.scss +6 -0
- data/stylesheets/compass/utilities/_print.scss +17 -0
- data/stylesheets/compass/utilities/_sass.scss +2 -0
- data/stylesheets/compass/utilities/_sprites.scss +2 -0
- data/stylesheets/compass/utilities/_tables.scss +3 -0
- data/stylesheets/compass/utilities/_text.scss +5 -0
- data/stylesheets/compass/utilities/color/_brightness.scss +12 -0
- data/stylesheets/compass/utilities/color/_contrast.scss +52 -0
- data/stylesheets/compass/utilities/general/_clearfix.scss +44 -0
- data/stylesheets/compass/utilities/general/_float.scss +38 -0
- data/stylesheets/compass/utilities/general/_hacks.scss +65 -0
- data/stylesheets/compass/utilities/general/_min.scss +16 -0
- data/stylesheets/compass/utilities/general/_reset.scss +2 -0
- data/stylesheets/compass/utilities/general/_tabs.scss +1 -0
- data/stylesheets/compass/utilities/general/_tag-cloud.scss +18 -0
- data/stylesheets/compass/utilities/links/_hover-link.scss +3 -0
- data/stylesheets/compass/utilities/links/_link-colors.scss +3 -0
- data/stylesheets/compass/utilities/links/_unstyled-link.scss +3 -0
- data/stylesheets/compass/utilities/lists/_bullets.scss +3 -0
- data/stylesheets/compass/utilities/lists/_horizontal-list.scss +3 -0
- data/stylesheets/compass/utilities/lists/_inline-block-list.scss +3 -0
- data/stylesheets/compass/utilities/lists/_inline-list.scss +3 -0
- data/stylesheets/compass/utilities/sass/_lists.scss +16 -0
- data/stylesheets/compass/utilities/sass/_maps.scss +19 -0
- data/stylesheets/compass/utilities/sprites/_base.scss +92 -0
- data/stylesheets/compass/utilities/sprites/_sprite-img.scss +81 -0
- data/stylesheets/compass/utilities/tables/_alternating-rows-and-columns.scss +22 -0
- data/stylesheets/compass/utilities/tables/_borders.scss +38 -0
- data/stylesheets/compass/utilities/tables/_scaffolding.scss +9 -0
- data/stylesheets/compass/utilities/text/_ellipsis.scss +3 -0
- data/stylesheets/compass/utilities/text/_nowrap.scss +3 -0
- data/stylesheets/compass/utilities/text/_replacement.scss +3 -0
- data/templates/ellipsis/ellipsis.sass +9 -0
- data/templates/ellipsis/manifest.rb +27 -0
- data/templates/ellipsis/xml/ellipsis.xml +14 -0
- data/templates/extension/manifest.rb +26 -0
- data/templates/extension/stylesheets/main.sass +1 -0
- data/templates/extension/templates/project/manifest.rb +2 -0
- data/templates/extension/templates/project/screen.sass +2 -0
- data/templates/project/USAGE.markdown +32 -0
- data/templates/project/ie.sass +6 -0
- data/templates/project/manifest.rb +4 -0
- data/templates/project/print.sass +6 -0
- data/templates/project/screen.sass +7 -0
- metadata +241 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Compass::Core::SassExtensions::Functions::Display
|
|
2
|
+
DEFAULT_DISPLAY = {
|
|
3
|
+
"block" => %w{address article aside blockquote center dir div dd details dl dt fieldset
|
|
4
|
+
figcaption figure form footer frameset h1 h2 h3 h4 h5 h6 hr header hgroup
|
|
5
|
+
isindex menu nav noframes noscript ol p pre section summary ul},
|
|
6
|
+
"inline" => %w{a abbr acronym audio b basefont bdo big br canvas cite code command
|
|
7
|
+
datalist dfn em embed font i img input keygen kbd label mark meter output
|
|
8
|
+
progress q rp rt ruby s samp select small span strike strong sub
|
|
9
|
+
sup textarea time tt u var video wbr},
|
|
10
|
+
"inline-block" => %w{img},
|
|
11
|
+
"table" => %w{table},
|
|
12
|
+
"list-item" => %w{li},
|
|
13
|
+
"table-row-group" => %w{tbody},
|
|
14
|
+
"table-header-group" => %w{thead},
|
|
15
|
+
"table-footer-group" => %w{tfoot},
|
|
16
|
+
"table-row" => %w{tr},
|
|
17
|
+
"table-cell" => %w{th td},
|
|
18
|
+
"html5-block" => %w{article aside details figcaption figure footer header hgroup menu nav
|
|
19
|
+
section summary},
|
|
20
|
+
"html5-inline" => %w{audio canvas command datalist embed keygen mark meter output progress rp
|
|
21
|
+
rt ruby time video wbr},
|
|
22
|
+
"text-input" => %w{input textarea}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
DEFAULT_DISPLAY["html5"] = (DEFAULT_DISPLAY["html5-block"] + DEFAULT_DISPLAY["html5-inline"]).sort.uniq
|
|
26
|
+
|
|
27
|
+
# returns a comma delimited string for all the
|
|
28
|
+
# elements according to their default css3 display value.
|
|
29
|
+
def elements_of_type(display)
|
|
30
|
+
Sass::Script::String.new(DEFAULT_DISPLAY.fetch(display.value.to_s).join(", "))
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
module Compass::Core::SassExtensions::Functions::Enumerate
|
|
2
|
+
def enumerate(prefix, from, through, separator = nil)
|
|
3
|
+
separator ||= Sass::Script::String.new("-", :string)
|
|
4
|
+
selectors = (from.value..through.value).map{|i| "#{prefix.value}#{separator.value}#{i}"}.join(", ")
|
|
5
|
+
Sass::Script::String.new(selectors)
|
|
6
|
+
end
|
|
7
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module Compass::Core::SassExtensions::Functions::Env
|
|
2
|
+
extend Compass::Core::SassExtensions::Functions::SassDeclarationHelper
|
|
3
|
+
|
|
4
|
+
def compass_env
|
|
5
|
+
compass_opts = options[:compass] || {}
|
|
6
|
+
Sass::Script::String.new((compass_opts[:environment] || "development").to_s)
|
|
7
|
+
end
|
|
8
|
+
declare :compass_env, []
|
|
9
|
+
|
|
10
|
+
DEFAULT_TIME = Sass::Script::String.new("%T%:z")
|
|
11
|
+
def current_time(format = DEFAULT_TIME)
|
|
12
|
+
assert_type format, :String
|
|
13
|
+
Sass::Script::String.new(Time.now.strftime(format.value))
|
|
14
|
+
end
|
|
15
|
+
declare :current_time, []
|
|
16
|
+
declare :current_time, [:format]
|
|
17
|
+
|
|
18
|
+
DEFAULT_DATE = Sass::Script::String.new("%F")
|
|
19
|
+
def current_date(format = DEFAULT_DATE)
|
|
20
|
+
current_time(format)
|
|
21
|
+
end
|
|
22
|
+
declare :current_date, []
|
|
23
|
+
declare :current_date, [:format]
|
|
24
|
+
|
|
25
|
+
NOT_ABSOLUTE = Sass::Script::Bool.new(false)
|
|
26
|
+
def current_source_file(absolute = NOT_ABSOLUTE)
|
|
27
|
+
if absolute.to_bool
|
|
28
|
+
Sass::Script::String.new(options[:original_filename].to_s)
|
|
29
|
+
else
|
|
30
|
+
filename = Pathname.new(options[:original_filename].to_s)
|
|
31
|
+
sass_path = Pathname.new(Compass.configuration.sass_path)
|
|
32
|
+
relative_filename = filename.relative_path_from(sass_path).to_s rescue filename
|
|
33
|
+
Sass::Script::String.new(relative_filename.to_s)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
declare :current_source_file, []
|
|
37
|
+
declare :current_source_file, [:absolute]
|
|
38
|
+
|
|
39
|
+
def current_output_file(absolute = NOT_ABSOLUTE)
|
|
40
|
+
Sass::Script::String.new(options[:css_filename].to_s)
|
|
41
|
+
if absolute.to_bool
|
|
42
|
+
Sass::Script::String.new(options[:css_filename].to_s)
|
|
43
|
+
else
|
|
44
|
+
filename = Pathname.new(options[:css_filename].to_s)
|
|
45
|
+
css_path = Pathname.new(Compass.configuration.css_path)
|
|
46
|
+
relative_filename = filename.relative_path_from(css_path).to_s rescue filename
|
|
47
|
+
Sass::Script::String.new(relative_filename.to_s)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
declare :current_output_file, []
|
|
51
|
+
declare :current_output_file, [:absolute]
|
|
52
|
+
|
|
53
|
+
unless Sass::Util.has?(:public_instance_method, Sass::Script::Functions, :inspect)
|
|
54
|
+
# This is going to be in sass 3.3, just here temporarily.
|
|
55
|
+
def inspect(value)
|
|
56
|
+
unquoted_string(value.to_sass)
|
|
57
|
+
end
|
|
58
|
+
declare :inspect, [:value]
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Compass::Core::SassExtensions::Functions::FontFiles
|
|
2
|
+
FONT_TYPES = {
|
|
3
|
+
:woff => 'woff',
|
|
4
|
+
:otf => 'opentype',
|
|
5
|
+
:opentype => 'opentype',
|
|
6
|
+
:ttf => 'truetype',
|
|
7
|
+
:truetype => 'truetype',
|
|
8
|
+
:svg => 'svg',
|
|
9
|
+
:eot => 'embedded-opentype'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
def font_files(*args)
|
|
13
|
+
files = []
|
|
14
|
+
args_length = args.length
|
|
15
|
+
skip_next = false
|
|
16
|
+
|
|
17
|
+
args.each_with_index do |arg, index|
|
|
18
|
+
if skip_next
|
|
19
|
+
skip_next = false
|
|
20
|
+
next
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
type = (args_length > (index + 1)) ? args[index + 1].value.to_sym : :wrong
|
|
24
|
+
|
|
25
|
+
if FONT_TYPES.key? type
|
|
26
|
+
skip_next = true
|
|
27
|
+
else
|
|
28
|
+
# let pass url like font.type?thing#stuff
|
|
29
|
+
type = arg.to_s.split('.').last.gsub(/(\?(.*))?(#(.*))?"/, '').to_sym
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
if FONT_TYPES.key? type
|
|
33
|
+
files << "#{font_url(arg)} format('#{FONT_TYPES[type]}')"
|
|
34
|
+
else
|
|
35
|
+
raise Sass::SyntaxError, "Could not determine font type for #{arg}"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
Sass::Script::String.new(files.join(", "))
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,616 @@
|
|
|
1
|
+
module Compass::Core::SassExtensions::Functions::GradientSupport
|
|
2
|
+
|
|
3
|
+
GRADIENT_ASPECTS = %w(webkit moz svg css2 o owg).freeze
|
|
4
|
+
|
|
5
|
+
class ColorStop < Sass::Script::Literal
|
|
6
|
+
attr_accessor :color, :stop
|
|
7
|
+
def children
|
|
8
|
+
[color, stop].compact
|
|
9
|
+
end
|
|
10
|
+
def initialize(color, stop = nil)
|
|
11
|
+
unless Sass::Script::Color === color ||
|
|
12
|
+
Sass::Script::Funcall === color ||
|
|
13
|
+
(Sass::Script::String === color && color.value == "currentColor")||
|
|
14
|
+
(Sass::Script::String === color && color.value == "transparent")
|
|
15
|
+
raise Sass::SyntaxError, "Expected a color. Got: #{color}"
|
|
16
|
+
end
|
|
17
|
+
if stop && !stop.is_a?(Sass::Script::Number)
|
|
18
|
+
raise Sass::SyntaxError, "Expected a number. Got: #{stop}"
|
|
19
|
+
end
|
|
20
|
+
self.color, self.stop = color, stop
|
|
21
|
+
end
|
|
22
|
+
def inspect
|
|
23
|
+
to_s
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.color_to_svg_s(c)
|
|
27
|
+
# svg doesn't support the "transparent" keyword; we need to manually
|
|
28
|
+
# refactor it into "transparent black"
|
|
29
|
+
if c.is_a?(Sass::Script::String) && c.value == "transparent"
|
|
30
|
+
"black"
|
|
31
|
+
elsif c.is_a?(Sass::Script::String)
|
|
32
|
+
c.value.dup
|
|
33
|
+
else
|
|
34
|
+
self.color_to_s(c.with(:alpha => 1))
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.color_to_svg_alpha(c)
|
|
39
|
+
# svg doesn't support the "transparent" keyword; we need to manually
|
|
40
|
+
# refactor it into "transparent black"
|
|
41
|
+
if c.is_a?(Sass::Script::String) && c.value == "transparent"
|
|
42
|
+
0
|
|
43
|
+
elsif c.is_a?(Sass::Script::String) && c.value == "currentColor"
|
|
44
|
+
1
|
|
45
|
+
else
|
|
46
|
+
c.alpha
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def self.color_to_s(c)
|
|
51
|
+
if c.is_a?(Sass::Script::String)
|
|
52
|
+
c.value.dup
|
|
53
|
+
else
|
|
54
|
+
c.inspect.dup
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def to_s(options = self.options)
|
|
59
|
+
s = self.class.color_to_s(color)
|
|
60
|
+
if stop
|
|
61
|
+
s << " "
|
|
62
|
+
if stop.unitless?
|
|
63
|
+
s << stop.times(Sass::Script::Number.new(100, ["%"])).inspect
|
|
64
|
+
else
|
|
65
|
+
s << stop.inspect
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
s
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def to_sass(options = nil)
|
|
72
|
+
Sass::Script::String.new("color-stop(#{color.to_sass rescue nil}, #{stop.to_sass rescue nil})")
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
module Gradient
|
|
77
|
+
|
|
78
|
+
def self.included(base)
|
|
79
|
+
base.extend ClassMethods
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
module ClassMethods
|
|
83
|
+
def standardized_prefix(prefix)
|
|
84
|
+
class_eval %Q{
|
|
85
|
+
def to_#{prefix}(options = self.options)
|
|
86
|
+
Sass::Script::String.new("-#{prefix}-\#{to_s_prefixed(options)}")
|
|
87
|
+
end
|
|
88
|
+
}
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def inspect
|
|
93
|
+
to_s
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def supports?(aspect)
|
|
97
|
+
GRADIENT_ASPECTS.include?(aspect)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def has_aspect?
|
|
101
|
+
true
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def is_position(pos)
|
|
105
|
+
pos.value =~ Compass::Core::SassExtensions::Functions::Constants::POSITIONS
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def angle?(value)
|
|
109
|
+
value.is_a?(Sass::Script::Number) &&
|
|
110
|
+
value.numerator_units.size == 1 &&
|
|
111
|
+
value.numerator_units.first == "deg" &&
|
|
112
|
+
value.denominator_units.empty?
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
class RadialGradient < Sass::Script::Literal
|
|
118
|
+
include Gradient
|
|
119
|
+
|
|
120
|
+
attr_accessor :position, :shape_and_size, :color_stops
|
|
121
|
+
|
|
122
|
+
def children
|
|
123
|
+
[color_stops, position, shape_and_size].compact
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def initialize(position, shape_and_size, color_stops)
|
|
127
|
+
unless color_stops.value.size >= 2
|
|
128
|
+
raise Sass::SyntaxError, "At least two color stops are required for a radial-gradient"
|
|
129
|
+
end
|
|
130
|
+
if angle?(position)
|
|
131
|
+
raise Sass::SyntaxError, "CSS no longer allows angles in radial-gradients."
|
|
132
|
+
end
|
|
133
|
+
self.position = position
|
|
134
|
+
self.shape_and_size = shape_and_size
|
|
135
|
+
self.color_stops = color_stops
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def to_s(options = self.options)
|
|
139
|
+
s = "radial-gradient("
|
|
140
|
+
s << position.to_s(options) << ", " if position
|
|
141
|
+
s << shape_and_size.to_s(options) << ", " if shape_and_size
|
|
142
|
+
s << color_stops.to_s(options)
|
|
143
|
+
s << ")"
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def to_s_prefixed(options = self.options)
|
|
147
|
+
to_s(options)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
standardized_prefix :webkit
|
|
151
|
+
standardized_prefix :moz
|
|
152
|
+
standardized_prefix :o
|
|
153
|
+
|
|
154
|
+
def to_svg(options = self.options)
|
|
155
|
+
# XXX Add shape support if possible
|
|
156
|
+
radial_svg_gradient(color_stops, position || _center_position)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def to_css2(options = self.options)
|
|
160
|
+
Sass::Script::String.new("")
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
class LinearGradient < Sass::Script::Literal
|
|
165
|
+
include Gradient
|
|
166
|
+
|
|
167
|
+
attr_accessor :color_stops, :position_or_angle, :legacy
|
|
168
|
+
|
|
169
|
+
def children
|
|
170
|
+
[color_stops, position_or_angle].compact
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def initialize(position_or_angle, color_stops, legacy=false)
|
|
174
|
+
unless color_stops.value.size >= 2
|
|
175
|
+
raise Sass::SyntaxError, "At least two color stops are required for a linear-gradient"
|
|
176
|
+
end
|
|
177
|
+
self.position_or_angle = position_or_angle
|
|
178
|
+
self.color_stops = color_stops
|
|
179
|
+
self.legacy = legacy
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def to_s_prefixed(options = self.options)
|
|
183
|
+
s = "linear-gradient("
|
|
184
|
+
if legacy
|
|
185
|
+
s << position_or_angle.to_s(options) << ", " if position_or_angle
|
|
186
|
+
else
|
|
187
|
+
s << convert_to_or_from_legacy(position_or_angle, options) << ", " if position_or_angle
|
|
188
|
+
end
|
|
189
|
+
s << color_stops.to_s(options)
|
|
190
|
+
s << ")"
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def convert_to_or_from_legacy(position_or_angle, options = self.options)
|
|
194
|
+
input = if position_or_angle.is_a?(Sass::Script::Number)
|
|
195
|
+
position_or_angle
|
|
196
|
+
else
|
|
197
|
+
opts(Sass::Script::List.new(position_or_angle.to_s.split(' ').map {|s| Sass::Script::String.new(s) }, :space))
|
|
198
|
+
end
|
|
199
|
+
return convert_angle_from_offical(input).to_s(options)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def to_s(options = self.options)
|
|
203
|
+
s = 'linear-gradient('
|
|
204
|
+
if legacy
|
|
205
|
+
s << convert_to_or_from_legacy(position_or_angle, options) << ", " if position_or_angle
|
|
206
|
+
else
|
|
207
|
+
s << position_or_angle.to_s(options) << ", " if position_or_angle
|
|
208
|
+
end
|
|
209
|
+
s << color_stops.to_s(options)
|
|
210
|
+
s << ")"
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
standardized_prefix :webkit
|
|
214
|
+
standardized_prefix :moz
|
|
215
|
+
standardized_prefix :o
|
|
216
|
+
|
|
217
|
+
def supports?(aspect)
|
|
218
|
+
# I don't know how to support degree-based gradients in old webkit gradients (owg) or svg so we just disable them.
|
|
219
|
+
if %w(owg svg).include?(aspect) && position_or_angle.is_a?(Sass::Script::Number) && position_or_angle.numerator_units.include?("deg")
|
|
220
|
+
false
|
|
221
|
+
else
|
|
222
|
+
super
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def to_svg(options = self.options)
|
|
227
|
+
linear_svg_gradient(color_stops, position_or_angle || Sass::Script::String.new("top"))
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def to_css2(options = self.options)
|
|
231
|
+
Sass::Script::String.new("")
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
module Functions
|
|
236
|
+
|
|
237
|
+
def convert_angle_from_offical(deg)
|
|
238
|
+
if deg.is_a?(Sass::Script::Number)
|
|
239
|
+
return Sass::Script::Number.new((deg.value.to_f - 450).abs % 360, ['deg'])
|
|
240
|
+
else
|
|
241
|
+
args = deg.value
|
|
242
|
+
direction = []
|
|
243
|
+
if args[0] == Sass::Script::String.new('to')
|
|
244
|
+
if args.size < 2
|
|
245
|
+
direction = args
|
|
246
|
+
else
|
|
247
|
+
direction << opposite_position(args[1])
|
|
248
|
+
end
|
|
249
|
+
else
|
|
250
|
+
direction << Sass::Script::String.new('to')
|
|
251
|
+
args.each do |pos|
|
|
252
|
+
direction << opposite_position(pos)
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
return Sass::Script::String.new(direction.join(' '))
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# given a position list, return a corresponding position in percents
|
|
260
|
+
# otherwise, returns the original argument
|
|
261
|
+
def grad_point(position)
|
|
262
|
+
original_value = position
|
|
263
|
+
position = unless position.is_a?(Sass::Script::List)
|
|
264
|
+
opts(Sass::Script::List.new([position], :space))
|
|
265
|
+
else
|
|
266
|
+
opts(Sass::Script::List.new(position.value.dup, position.separator))
|
|
267
|
+
end
|
|
268
|
+
# Handle unknown arguments by passing them along untouched.
|
|
269
|
+
unless position.value.all?{|p| is_position(p) }
|
|
270
|
+
return original_value
|
|
271
|
+
end
|
|
272
|
+
if (position.value.first.value =~ /top|bottom/) or (position.value.last.value =~ /left|right/)
|
|
273
|
+
# browsers are pretty forgiving of reversed positions so we are too.
|
|
274
|
+
position = Sass::Script::List.new(position.value.reverse, position.separator)
|
|
275
|
+
end
|
|
276
|
+
if position.value.size == 1
|
|
277
|
+
if position.value.first.value =~ /top|bottom/
|
|
278
|
+
position = Sass::Script::List.new(
|
|
279
|
+
[Sass::Script::String.new("center"), position.value.first], position.separator)
|
|
280
|
+
elsif position.value.first.value =~ /left|right/
|
|
281
|
+
position = Sass::Script::List.new(
|
|
282
|
+
[position.value.first, Sass::Script::String.new("center")], position.separator)
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
position = Sass::Script::List.new(position.value.map do |p|
|
|
286
|
+
case p.value
|
|
287
|
+
when /top|left/
|
|
288
|
+
Sass::Script::Number.new(0, ["%"])
|
|
289
|
+
when /bottom|right/
|
|
290
|
+
Sass::Script::Number.new(100, ["%"])
|
|
291
|
+
when /center/
|
|
292
|
+
Sass::Script::Number.new(50, ["%"])
|
|
293
|
+
else
|
|
294
|
+
p
|
|
295
|
+
end
|
|
296
|
+
end, position.separator)
|
|
297
|
+
position
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def color_stops(*args)
|
|
301
|
+
opts(Sass::Script::List.new(args.map do |arg|
|
|
302
|
+
if ColorStop === arg
|
|
303
|
+
arg
|
|
304
|
+
elsif Sass::Script::Color === arg
|
|
305
|
+
ColorStop.new(arg)
|
|
306
|
+
elsif Sass::Script::List === arg
|
|
307
|
+
ColorStop.new(*arg.value)
|
|
308
|
+
elsif Sass::Script::String === arg && arg.value == "transparent"
|
|
309
|
+
ColorStop.new(arg)
|
|
310
|
+
elsif Sass::Script::String === arg && arg.value == "currentColor"
|
|
311
|
+
ColorStop.new(arg)
|
|
312
|
+
else
|
|
313
|
+
raise Sass::SyntaxError, "Not a valid color stop: #{arg.class.name}: #{arg}"
|
|
314
|
+
end
|
|
315
|
+
end, :comma))
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
def radial_gradient(position_or_angle, shape_and_size, *color_stops)
|
|
319
|
+
# Have to deal with variable length/meaning arguments.
|
|
320
|
+
if color_stop?(shape_and_size)
|
|
321
|
+
color_stops.unshift(shape_and_size)
|
|
322
|
+
shape_and_size = nil
|
|
323
|
+
elsif list_of_color_stops?(shape_and_size)
|
|
324
|
+
# Support legacy use of the color-stops() function
|
|
325
|
+
color_stops = shape_and_size.value + color_stops
|
|
326
|
+
shape_and_size = nil
|
|
327
|
+
end
|
|
328
|
+
shape_and_size = nil if shape_and_size && !shape_and_size.to_bool # nil out explictly passed falses
|
|
329
|
+
# ditto for position_or_angle
|
|
330
|
+
if color_stop?(position_or_angle)
|
|
331
|
+
color_stops.unshift(position_or_angle)
|
|
332
|
+
position_or_angle = nil
|
|
333
|
+
elsif list_of_color_stops?(position_or_angle)
|
|
334
|
+
color_stops = position_or_angle.value + color_stops
|
|
335
|
+
position_or_angle = nil
|
|
336
|
+
end
|
|
337
|
+
position_or_angle = nil if position_or_angle && !position_or_angle.to_bool
|
|
338
|
+
|
|
339
|
+
# Support legacy use of the color-stops() function
|
|
340
|
+
if color_stops.size == 1 && list_of_color_stops?(color_stops.first)
|
|
341
|
+
color_stops = color_stops.first.value
|
|
342
|
+
end
|
|
343
|
+
RadialGradient.new(position_or_angle, shape_and_size, send(:color_stops, *color_stops))
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
def _build_linear_gradient(position_or_angle, *color_stops)
|
|
347
|
+
if color_stop?(position_or_angle)
|
|
348
|
+
color_stops.unshift(position_or_angle)
|
|
349
|
+
position_or_angle = nil
|
|
350
|
+
elsif list_of_color_stops?(position_or_angle)
|
|
351
|
+
color_stops = position_or_angle.value + color_stops
|
|
352
|
+
position_or_angle = nil
|
|
353
|
+
end
|
|
354
|
+
position_or_angle = nil if position_or_angle && !position_or_angle.to_bool
|
|
355
|
+
|
|
356
|
+
# Support legacy use of the color-stops() function
|
|
357
|
+
if color_stops.size == 1 && (stops = list_of_color_stops?(color_stops.first))
|
|
358
|
+
color_stops = stops
|
|
359
|
+
end
|
|
360
|
+
return [position_or_angle, color_stops]
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
def _linear_gradient(position_or_angle, *color_stops)
|
|
364
|
+
position_or_angle, color_stops = _build_linear_gradient(position_or_angle, *color_stops)
|
|
365
|
+
LinearGradient.new(position_or_angle, send(:color_stops, *color_stops))
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
def _linear_gradient_legacy(position_or_angle, *color_stops)
|
|
369
|
+
position_or_angle, color_stops = _build_linear_gradient(position_or_angle, *color_stops)
|
|
370
|
+
LinearGradient.new(position_or_angle, send(:color_stops, *color_stops), true)
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
# returns color-stop() calls for use in webkit.
|
|
374
|
+
def grad_color_stops(color_list)
|
|
375
|
+
stops = color_stops_in_percentages(color_list).map do |stop, color|
|
|
376
|
+
"color-stop(#{stop.inspect}, #{ColorStop.color_to_s(color)})"
|
|
377
|
+
end
|
|
378
|
+
Sass::Script::String.new(stops.join(", "))
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
def color_stops_in_percentages(color_list)
|
|
382
|
+
assert_type color_list, :List
|
|
383
|
+
color_list = normalize_stops(color_list)
|
|
384
|
+
max = color_list.value.last.stop
|
|
385
|
+
last_value = nil
|
|
386
|
+
color_stops = color_list.value.map do |pos|
|
|
387
|
+
# have to convert absolute units to percentages for use in color stop functions.
|
|
388
|
+
stop = pos.stop
|
|
389
|
+
stop = stop.div(max).times(Sass::Script::Number.new(100,["%"])) if stop.numerator_units == max.numerator_units && max.numerator_units != ["%"]
|
|
390
|
+
# Make sure the color stops are specified in the right order.
|
|
391
|
+
if last_value && stop.numerator_units == last_value.numerator_units && stop.denominator_units == last_value.denominator_units && (stop.value * 1000).round < (last_value.value * 1000).round
|
|
392
|
+
raise Sass::SyntaxError.new("Color stops must be specified in increasing order. #{stop.value} came after #{last_value.value}.")
|
|
393
|
+
end
|
|
394
|
+
last_value = stop
|
|
395
|
+
[stop, pos.color]
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
# only used for webkit
|
|
400
|
+
def linear_end_position(position_or_angle, color_list)
|
|
401
|
+
start_point = grad_point(position_or_angle || Sass::Script::String.new("top"))
|
|
402
|
+
end_point = grad_point(opposite_position(position_or_angle || Sass::Script::String.new("top")))
|
|
403
|
+
end_target = color_list.value.last.stop
|
|
404
|
+
|
|
405
|
+
if color_list.value.last.stop && color_list.value.last.stop.numerator_units == ["px"]
|
|
406
|
+
new_end = color_list.value.last.stop.value
|
|
407
|
+
if start_point.value.first == end_point.value.first && start_point.value.last.value == 0
|
|
408
|
+
# this means top-to-bottom
|
|
409
|
+
end_point.value[1] = Sass::Script::Number.new(end_target.value)
|
|
410
|
+
elsif start_point.value.last == end_point.value.last && start_point.value.first.value == 0
|
|
411
|
+
# this implies left-to-right
|
|
412
|
+
end_point.value[0] = Sass::Script::Number.new(end_target.value)
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
end_point
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
# returns the end position of the gradient from the color stop
|
|
419
|
+
def grad_end_position(color_list, radial = Sass::Script::Bool.new(false))
|
|
420
|
+
assert_type color_list, :List
|
|
421
|
+
default = Sass::Script::Number.new(100)
|
|
422
|
+
grad_position(color_list, Sass::Script::Number.new(color_list.value.size), default, radial)
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
def grad_position(color_list, index, default, radial = Sass::Script::Bool.new(false))
|
|
426
|
+
assert_type color_list, :List
|
|
427
|
+
stop = color_list.value[index.value - 1].stop
|
|
428
|
+
if stop && radial.to_bool
|
|
429
|
+
orig_stop = stop
|
|
430
|
+
if stop.unitless?
|
|
431
|
+
if stop.value <= 1
|
|
432
|
+
# A unitless number is assumed to be a percentage when it's between 0 and 1
|
|
433
|
+
stop = stop.times(Sass::Script::Number.new(100, ["%"]))
|
|
434
|
+
else
|
|
435
|
+
# Otherwise, a unitless number is assumed to be in pixels
|
|
436
|
+
stop = stop.times(Sass::Script::Number.new(1, ["px"]))
|
|
437
|
+
end
|
|
438
|
+
end
|
|
439
|
+
if stop.numerator_units == ["%"] && color_list.value.last.stop && color_list.value.last.stop.numerator_units == ["px"]
|
|
440
|
+
stop = stop.times(color_list.value.last.stop).div(Sass::Script::Number.new(100, ["%"]))
|
|
441
|
+
end
|
|
442
|
+
Compass::Logger.new.record(:warning, "Webkit only supports pixels for the start and end stops for radial gradients. Got: #{orig_stop}") if stop.numerator_units != ["px"]
|
|
443
|
+
stop.div(Sass::Script::Number.new(1, stop.numerator_units, stop.denominator_units))
|
|
444
|
+
elsif stop
|
|
445
|
+
stop
|
|
446
|
+
else
|
|
447
|
+
default
|
|
448
|
+
end
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
def linear_svg_gradient(color_stops, start)
|
|
452
|
+
x1, y1 = *grad_point(start).value
|
|
453
|
+
x2, y2 = *grad_point(opposite_position(start)).value
|
|
454
|
+
stops = color_stops_in_percentages(color_stops)
|
|
455
|
+
|
|
456
|
+
svg = linear_svg(stops, x1, y1, x2, y2)
|
|
457
|
+
inline_image_string(svg.gsub(/\s+/, ' '), 'image/svg+xml')
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
def radial_svg_gradient(color_stops, center)
|
|
461
|
+
cx, cy = *grad_point(center).value
|
|
462
|
+
r = grad_end_position(color_stops, Sass::Script::Bool.new(true))
|
|
463
|
+
stops = color_stops_in_percentages(color_stops)
|
|
464
|
+
|
|
465
|
+
svg = radial_svg(stops, cx, cy, r)
|
|
466
|
+
inline_image_string(svg.gsub(/\s+/, ' '), 'image/svg+xml')
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
private
|
|
470
|
+
|
|
471
|
+
def color_stop?(arg)
|
|
472
|
+
arg.is_a?(ColorStop) ||
|
|
473
|
+
(arg.is_a?(Sass::Script::List) && ColorStop.new(*arg.value)) ||
|
|
474
|
+
ColorStop.new(arg)
|
|
475
|
+
rescue
|
|
476
|
+
nil
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
def normalize_stops(color_list)
|
|
480
|
+
positions = color_list.value.map{|obj| obj.dup}
|
|
481
|
+
# fill in the start and end positions, if unspecified
|
|
482
|
+
positions.first.stop = Sass::Script::Number.new(0) unless positions.first.stop
|
|
483
|
+
positions.last.stop = Sass::Script::Number.new(100, ["%"]) unless positions.last.stop
|
|
484
|
+
# fill in empty values
|
|
485
|
+
for i in 0...positions.size
|
|
486
|
+
if positions[i].stop.nil?
|
|
487
|
+
num = 2.0
|
|
488
|
+
for j in (i+1)...positions.size
|
|
489
|
+
if positions[j].stop
|
|
490
|
+
positions[i].stop = positions[i-1].stop.plus((positions[j].stop.minus(positions[i-1].stop)).div(Sass::Script::Number.new(num)))
|
|
491
|
+
break
|
|
492
|
+
else
|
|
493
|
+
num += 1
|
|
494
|
+
end
|
|
495
|
+
end
|
|
496
|
+
end
|
|
497
|
+
end
|
|
498
|
+
# normalize unitless numbers
|
|
499
|
+
positions.each do |pos|
|
|
500
|
+
if pos.stop.unitless? && pos.stop.value <= 1
|
|
501
|
+
pos.stop = pos.stop.times(Sass::Script::Number.new(100, ["%"]))
|
|
502
|
+
elsif pos.stop.unitless?
|
|
503
|
+
pos.stop = pos.stop.times(Sass::Script::Number.new(1, ["px"]))
|
|
504
|
+
end
|
|
505
|
+
end
|
|
506
|
+
if (positions.last.stop.eq(Sass::Script::Number.new(0, ["px"])).to_bool ||
|
|
507
|
+
positions.last.stop.eq(Sass::Script::Number.new(0, ["%"])).to_bool)
|
|
508
|
+
raise Sass::SyntaxError.new("Color stops must be specified in increasing order")
|
|
509
|
+
end
|
|
510
|
+
if defined?(Sass::Script::List)
|
|
511
|
+
opts(Sass::Script::List.new(positions, color_list.separator))
|
|
512
|
+
else
|
|
513
|
+
color_list.class.new(*positions)
|
|
514
|
+
end
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
def parse_color_stop(arg)
|
|
518
|
+
return ColorStop.new(arg) if arg.is_a?(Sass::Script::Color)
|
|
519
|
+
return nil unless arg.is_a?(Sass::Script::String)
|
|
520
|
+
color = stop = nil
|
|
521
|
+
expr = Sass::Script::Parser.parse(arg.value, 0, 0)
|
|
522
|
+
case expr
|
|
523
|
+
when Sass::Script::Color
|
|
524
|
+
color = expr
|
|
525
|
+
when Sass::Script::Funcall
|
|
526
|
+
color = expr
|
|
527
|
+
when Sass::Script::Operation
|
|
528
|
+
unless [:concat, :space].include?(expr.instance_variable_get("@operator"))
|
|
529
|
+
# This should never happen.
|
|
530
|
+
raise Sass::SyntaxError, "Couldn't parse a color stop from: #{arg.value}"
|
|
531
|
+
end
|
|
532
|
+
color = expr.instance_variable_get("@operand1")
|
|
533
|
+
stop = expr.instance_variable_get("@operand2")
|
|
534
|
+
else
|
|
535
|
+
raise Sass::SyntaxError, "Couldn't parse a color stop from: #{arg.value}"
|
|
536
|
+
end
|
|
537
|
+
ColorStop.new(color, stop)
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
def list_of_color_stops?(arg)
|
|
541
|
+
if arg.respond_to?(:value)
|
|
542
|
+
arg.value.is_a?(Array) && arg.value.all?{|a| color_stop?(a)} ? arg.value : nil
|
|
543
|
+
elsif arg.is_a?(Array)
|
|
544
|
+
arg.all?{|a| color_stop?(a)} ? arg : nil
|
|
545
|
+
end
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
def linear_svg(color_stops, x1, y1, x2, y2)
|
|
549
|
+
transform = ''
|
|
550
|
+
if angle?(position_or_angle)
|
|
551
|
+
transform = %Q{ gradientTransform = "rotate(#{position_or_angle.value})"}
|
|
552
|
+
end
|
|
553
|
+
gradient = %Q{<linearGradient id="grad" gradientUnits="userSpaceOnUse" x1="#{x1}" y1="#{y1}" x2="#{x2}" y2="#{y2}"#{transform}>#{color_stops_svg(color_stops)}</linearGradient>}
|
|
554
|
+
svg(gradient)
|
|
555
|
+
end
|
|
556
|
+
|
|
557
|
+
def radial_svg(color_stops, cx, cy, r)
|
|
558
|
+
gradient = %Q{<radialGradient id="grad" gradientUnits="userSpaceOnUse" cx="#{cx}" cy="#{cy}" r="#{r}">#{color_stops_svg(color_stops)}</radialGradient>}
|
|
559
|
+
svg(gradient)
|
|
560
|
+
end
|
|
561
|
+
|
|
562
|
+
# color_stops = array of: [stop, color]
|
|
563
|
+
def color_stops_svg(color_stops)
|
|
564
|
+
color_stops.each.map{ |stop, color|
|
|
565
|
+
s = %{<stop offset="#{stop.to_s}"}
|
|
566
|
+
s << %{ stop-color="#{ColorStop.color_to_svg_s(color)}"}
|
|
567
|
+
alpha = ColorStop.color_to_svg_alpha(color)
|
|
568
|
+
s << %{ stop-opacity="#{alpha}"} if alpha != 1
|
|
569
|
+
s << "/>"
|
|
570
|
+
}.join
|
|
571
|
+
end
|
|
572
|
+
|
|
573
|
+
def svg(gradient)
|
|
574
|
+
svg = <<-EOS
|
|
575
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
576
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"><defs>#{gradient}</defs><rect x="0" y="0" width="100%" height="100%" fill="url(#grad)" /></svg>
|
|
577
|
+
EOS
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
def _center_position
|
|
581
|
+
opts(Sass::Script::List.new([
|
|
582
|
+
Sass::Script::String.new("center"),
|
|
583
|
+
Sass::Script::String.new("center")
|
|
584
|
+
],:space))
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
def opts(v)
|
|
588
|
+
v.options = options
|
|
589
|
+
v
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
module Assertions
|
|
595
|
+
def assert_type(value, type, name = nil)
|
|
596
|
+
return if value.is_a?(Sass::Script.const_get(type))
|
|
597
|
+
err = "#{value.inspect} is not a #{type.to_s.downcase}"
|
|
598
|
+
err = "$#{name}: " + err if name
|
|
599
|
+
raise ArgumentError.new(err)
|
|
600
|
+
end
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
class LinearGradient < Sass::Script::Literal
|
|
604
|
+
include Assertions
|
|
605
|
+
include Functions
|
|
606
|
+
include Compass::Core::SassExtensions::Functions::Constants
|
|
607
|
+
include Compass::Core::SassExtensions::Functions::InlineImage
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
class RadialGradient < Sass::Script::Literal
|
|
611
|
+
include Assertions
|
|
612
|
+
include Functions
|
|
613
|
+
include Compass::Core::SassExtensions::Functions::Constants
|
|
614
|
+
include Compass::Core::SassExtensions::Functions::InlineImage
|
|
615
|
+
end
|
|
616
|
+
end
|