compass-core-sass37 1.1.0
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/browser_support.rb +64 -0
- data/lib/compass/configuration/adapters.rb +109 -0
- data/lib/compass/configuration/data.rb +199 -0
- data/lib/compass/configuration/defaults.rb +207 -0
- data/lib/compass/configuration/inheritance.rb +307 -0
- data/lib/compass/configuration/paths.rb +19 -0
- data/lib/compass/configuration/watch.rb +38 -0
- data/lib/compass/configuration.rb +175 -0
- data/lib/compass/core/caniuse.rb +314 -0
- data/lib/compass/core/generated_version.rb +6 -0
- data/lib/compass/core/sass_extensions/functions/colors.rb +67 -0
- data/lib/compass/core/sass_extensions/functions/configuration.rb +173 -0
- data/lib/compass/core/sass_extensions/functions/constants.rb +56 -0
- data/lib/compass/core/sass_extensions/functions/cross_browser_support.rb +270 -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 +72 -0
- data/lib/compass/core/sass_extensions/functions/files.rb +33 -0
- data/lib/compass/core/sass_extensions/functions/font_files.rb +65 -0
- data/lib/compass/core/sass_extensions/functions/gradient_support.rb +859 -0
- data/lib/compass/core/sass_extensions/functions/image_size.rb +117 -0
- data/lib/compass/core/sass_extensions/functions/inline_image.rb +63 -0
- data/lib/compass/core/sass_extensions/functions/lists.rb +102 -0
- data/lib/compass/core/sass_extensions/functions/math.rb +105 -0
- data/lib/compass/core/sass_extensions/functions/selectors.rb +79 -0
- data/lib/compass/core/sass_extensions/functions/urls.rb +315 -0
- data/lib/compass/core/sass_extensions/functions.rb +41 -0
- data/lib/compass/core/sass_extensions/monkey_patches/browser_support.rb +119 -0
- data/lib/compass/core/sass_extensions/monkey_patches/traversal.rb +23 -0
- data/lib/compass/core/sass_extensions/monkey_patches.rb +3 -0
- data/lib/compass/core/sass_extensions.rb +10 -0
- data/lib/compass/core/version.rb +13 -0
- data/lib/compass/core.rb +78 -0
- data/lib/compass/error.rb +5 -0
- data/lib/compass/frameworks.rb +181 -0
- data/lib/compass/util.rb +19 -0
- data/lib/compass-core.rb +1 -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 +447 -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 +21 -0
- data/stylesheets/compass/css3/_box.scss +85 -0
- data/stylesheets/compass/css3/_columns.scss +212 -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 +152 -0
- data/stylesheets/compass/css3/_inline-block.scss +31 -0
- data/stylesheets/compass/css3/_opacity.scss +27 -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 +190 -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 +183 -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 +74 -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 +20 -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 +257 -0
@@ -0,0 +1,175 @@
|
|
1
|
+
module Compass
|
2
|
+
module Configuration
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def attributes_for_directory(dir_name, http_dir_name = dir_name)
|
6
|
+
[
|
7
|
+
"#{dir_name}_dir",
|
8
|
+
"#{dir_name}_path",
|
9
|
+
("http_#{http_dir_name}_dir" if http_dir_name),
|
10
|
+
("http_#{http_dir_name}_path" if http_dir_name)
|
11
|
+
].compact.map{|a| a.to_sym}
|
12
|
+
end
|
13
|
+
|
14
|
+
# Registers a new configuration property.
|
15
|
+
# Extensions can use this to add new configuration options to compass.
|
16
|
+
#
|
17
|
+
# @param [Symbol] name The name of the property.
|
18
|
+
# @param [String] comment A comment for the property.
|
19
|
+
# @param [Proc] default A method to calculate the default value for the property.
|
20
|
+
# The proc is executed in the context of the project's configuration data.
|
21
|
+
def add_configuration_property(name, comment = nil, &default)
|
22
|
+
ATTRIBUTES << name
|
23
|
+
if comment.is_a?(String)
|
24
|
+
unless comment[0..0] == "#"
|
25
|
+
comment = "# #{comment}"
|
26
|
+
end
|
27
|
+
unless comment[-1..-1] == "\n"
|
28
|
+
comment = comment + "\n"
|
29
|
+
end
|
30
|
+
Data.class_eval <<-COMMENT
|
31
|
+
def comment_for_#{name}
|
32
|
+
#{comment.inspect}
|
33
|
+
end
|
34
|
+
COMMENT
|
35
|
+
end
|
36
|
+
Data.send(:define_method, :"default_#{name}", &default) if default
|
37
|
+
Data.inherited_accessor(name)
|
38
|
+
if name.to_s =~ /dir|path/
|
39
|
+
Data.strip_trailing_separator(name)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# For testing purposes
|
44
|
+
def remove_configuration_property(name)
|
45
|
+
ATTRIBUTES.delete(name)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
ATTRIBUTES = [
|
51
|
+
# What kind of project?
|
52
|
+
:project_type,
|
53
|
+
# Where is the project?
|
54
|
+
:project_path,
|
55
|
+
:http_path,
|
56
|
+
# Where are the various bits of the project
|
57
|
+
attributes_for_directory(:css, :stylesheets),
|
58
|
+
attributes_for_directory(:sass, nil),
|
59
|
+
attributes_for_directory(:images),
|
60
|
+
attributes_for_directory(:generated_images),
|
61
|
+
attributes_for_directory(:javascripts),
|
62
|
+
attributes_for_directory(:fonts),
|
63
|
+
attributes_for_directory(:extensions, nil),
|
64
|
+
# Compilation options
|
65
|
+
:output_style,
|
66
|
+
:sourcemap,
|
67
|
+
:environment,
|
68
|
+
:relative_assets,
|
69
|
+
:sass_options,
|
70
|
+
attributes_for_directory(:cache, nil),
|
71
|
+
:cache,
|
72
|
+
# Helper configuration
|
73
|
+
:asset_host,
|
74
|
+
:asset_cache_buster,
|
75
|
+
:line_comments,
|
76
|
+
:color_output,
|
77
|
+
:preferred_syntax,
|
78
|
+
:disable_warnings,
|
79
|
+
:sprite_engine,
|
80
|
+
:chunky_png_options
|
81
|
+
].flatten
|
82
|
+
|
83
|
+
ARRAY_ATTRIBUTES = [
|
84
|
+
:additional_import_paths,
|
85
|
+
:sprite_load_path,
|
86
|
+
:required_libraries,
|
87
|
+
:loaded_frameworks,
|
88
|
+
:framework_path
|
89
|
+
]
|
90
|
+
|
91
|
+
ARRAY_ATTRIBUTE_OPTIONS = {
|
92
|
+
:sprite_load_path => { :clobbers => true }
|
93
|
+
}
|
94
|
+
|
95
|
+
RUNTIME_READONLY_ATTRIBUTES = [
|
96
|
+
:cache,
|
97
|
+
attributes_for_directory(:cache, nil),
|
98
|
+
:chunky_png_options,
|
99
|
+
:color_output,
|
100
|
+
attributes_for_directory(:css, :stylesheets),
|
101
|
+
:environment,
|
102
|
+
attributes_for_directory(:extensions, nil),
|
103
|
+
:framework_path,
|
104
|
+
attributes_for_directory(:javascripts),
|
105
|
+
:line_comments,
|
106
|
+
:loaded_frameworks,
|
107
|
+
:output_style,
|
108
|
+
:preferred_syntax,
|
109
|
+
:project_path,
|
110
|
+
:project_type,
|
111
|
+
:required_libraries,
|
112
|
+
attributes_for_directory(:sass, nil),
|
113
|
+
:sass_options,
|
114
|
+
:sourcemap,
|
115
|
+
:sprite_engine,
|
116
|
+
].flatten
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
class << self
|
121
|
+
# The Compass configuration singleton.
|
122
|
+
def configuration
|
123
|
+
@configuration ||= default_configuration
|
124
|
+
if block_given?
|
125
|
+
yield @configuration
|
126
|
+
end
|
127
|
+
@configuration
|
128
|
+
end
|
129
|
+
|
130
|
+
def default_configuration
|
131
|
+
Compass::Configuration::Data.new('defaults').extend(Compass::Configuration::Defaults)
|
132
|
+
end
|
133
|
+
|
134
|
+
def add_configuration(data, filename = nil)
|
135
|
+
return if data.nil?
|
136
|
+
|
137
|
+
|
138
|
+
unless data.is_a?(Compass::Configuration::Data)
|
139
|
+
# XXX HAX Need to properly factor this apart from the main compass project
|
140
|
+
if respond_to?(:configuration_for)
|
141
|
+
data = configuration_for(data, filename)
|
142
|
+
else
|
143
|
+
raise ArgumentError, "Invalid argument: #{data.inspect}"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
data.inherit_from!(configuration) if configuration
|
148
|
+
data.on_top!
|
149
|
+
@configuration = data
|
150
|
+
end
|
151
|
+
|
152
|
+
def reset_configuration!
|
153
|
+
@configuration = nil
|
154
|
+
end
|
155
|
+
|
156
|
+
# Returns a full path to the relative path to the project directory
|
157
|
+
def projectize(path, project_path = nil)
|
158
|
+
project_path ||= configuration.project_path
|
159
|
+
File.join(project_path, *path.split('/'))
|
160
|
+
end
|
161
|
+
|
162
|
+
def deprojectize(path, project_path = nil)
|
163
|
+
project_path ||= configuration.project_path
|
164
|
+
if path[0..(project_path.size - 1)] == project_path
|
165
|
+
path[(project_path.size + 1)..-1]
|
166
|
+
else
|
167
|
+
path
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
%w(defaults inheritance paths data watch adapters).each do |lib|
|
174
|
+
require "compass/configuration/#{lib}"
|
175
|
+
end
|
@@ -0,0 +1,314 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
require 'singleton'
|
3
|
+
class Compass::Core::CanIUse
|
4
|
+
include Singleton
|
5
|
+
|
6
|
+
DATA_FILE_NAME = File.join(Compass::Core.base_directory, "data", "caniuse.json")
|
7
|
+
DATA_FEATURE_FILES = Dir.glob(File.join(Compass::Core.base_directory, "data", "caniuse_extras", "**", "*.json"))
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@data = MultiJson.load(File.read(DATA_FILE_NAME))
|
11
|
+
# support ad-hoc features
|
12
|
+
DATA_FEATURE_FILES.each do |feature_file|
|
13
|
+
feature_name = File.basename(feature_file, ".json")
|
14
|
+
# if the feature doesn't exist in the master `caniuse.json`
|
15
|
+
if @data["data"][feature_name].nil?
|
16
|
+
@data["data"][feature_name] = MultiJson.load(File.read(feature_file))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# The browser names from caniuse are ugly.
|
22
|
+
PUBLIC_BROWSER_NAMES = Hash.new {|h, k| k}
|
23
|
+
PUBLIC_BROWSER_NAMES.update(
|
24
|
+
"and_chr" => "android-chrome",
|
25
|
+
"and_ff" => "android-firefox",
|
26
|
+
"android" => "android",
|
27
|
+
"bb" => "blackberry",
|
28
|
+
"chrome" => "chrome",
|
29
|
+
"firefox" => "firefox",
|
30
|
+
"ie" => "ie",
|
31
|
+
"ie_mob" => "ie-mobile",
|
32
|
+
"ios_saf" => "ios-safari",
|
33
|
+
"op_mini" => "opera-mini",
|
34
|
+
"op_mob" => "opera-mobile",
|
35
|
+
"opera" => "opera",
|
36
|
+
"safari" => "safari"
|
37
|
+
)
|
38
|
+
CAN_I_USE_NAMES = Hash.new {|h, k| k}
|
39
|
+
CAN_I_USE_NAMES.update(PUBLIC_BROWSER_NAMES.invert)
|
40
|
+
|
41
|
+
# Returns all the known browsers according to caniuse
|
42
|
+
def browsers
|
43
|
+
@browsers ||= @data["agents"].keys.map{|b| PUBLIC_BROWSER_NAMES[b] }.sort
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the prefix corresponding to a particular browser
|
47
|
+
def prefix(browser, version = nil)
|
48
|
+
version = caniuse_version(browser, version)
|
49
|
+
assert_valid_browser browser
|
50
|
+
assert_valid_version browser, version if version
|
51
|
+
data = browser_data(browser)
|
52
|
+
p = if data["prefix_exceptions"] && data["prefix_exceptions"][version]
|
53
|
+
data["prefix_exceptions"][version]
|
54
|
+
else
|
55
|
+
data["prefix"]
|
56
|
+
end
|
57
|
+
"-#{p}"
|
58
|
+
end
|
59
|
+
|
60
|
+
# returns all possible prefixes a browser might use.
|
61
|
+
def all_prefixes(browser)
|
62
|
+
assert_valid_browser browser
|
63
|
+
data = browser_data(browser)
|
64
|
+
prefixes = ["-#{data["prefix"]}"]
|
65
|
+
if data["prefix_exceptions"]
|
66
|
+
prefixes += data["prefix_exceptions"].values.uniq.map{|p| "-#{p}"}
|
67
|
+
end
|
68
|
+
prefixes
|
69
|
+
end
|
70
|
+
|
71
|
+
# returns the prefixes needed by the list of browsers given
|
72
|
+
def prefixes(browsers = browsers())
|
73
|
+
result = browsers.map{|b| all_prefixes(b) }
|
74
|
+
result.flatten!
|
75
|
+
result.uniq!
|
76
|
+
result.sort!
|
77
|
+
result
|
78
|
+
end
|
79
|
+
|
80
|
+
def browser_ranges(capability, prefix = nil, include_unprefixed_versions = true)
|
81
|
+
assert_valid_capability capability
|
82
|
+
browsers = prefix.nil? ? browsers() : browsers_with_prefix(prefix)
|
83
|
+
browsers.inject({}) do |m, browser|
|
84
|
+
browser_versions = versions(browser)
|
85
|
+
min_version = find_first_prefixed_version(browser, browser_versions, capability, prefix)
|
86
|
+
if min_version
|
87
|
+
max_version = if include_unprefixed_versions
|
88
|
+
browser_versions.last
|
89
|
+
else
|
90
|
+
find_first_prefixed_version(browser, browser_versions.reverse, capability, prefix)
|
91
|
+
end
|
92
|
+
m.update(browser => [min_version, max_version])
|
93
|
+
end
|
94
|
+
m
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def find_first_prefixed_version(browser, versions, capability, prefix)
|
99
|
+
versions.find do |version|
|
100
|
+
support = browser_support(browser, version, capability)
|
101
|
+
if prefix.nil?
|
102
|
+
support !~ /\b(n|p)\b/ && support !~ /\bx\b/
|
103
|
+
else
|
104
|
+
actual_prefix = prefix(browser, version)
|
105
|
+
support !~ /\b(n|p)\b/ && support =~ /\bx\b/ && prefix == actual_prefix
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# @overload omitted_usage(browser, min_supported_version)
|
111
|
+
# How many users would be omitted if support for the given browser starts
|
112
|
+
# with the given version.
|
113
|
+
#
|
114
|
+
# @overload omitted_usage(browser, min_unsupported_version, max_unsupported_version)
|
115
|
+
# How many users would be omitted if the browsers with version
|
116
|
+
def omitted_usage(browser, min_version, max_version = nil)
|
117
|
+
versions = versions(browser)
|
118
|
+
min_version = caniuse_version(browser, min_version)
|
119
|
+
max_version = caniuse_version(browser, max_version)
|
120
|
+
if max_version.nil?
|
121
|
+
assert_valid_version browser, min_version
|
122
|
+
else
|
123
|
+
assert_valid_version browser, min_version, max_version
|
124
|
+
end
|
125
|
+
usage = 0
|
126
|
+
in_range = max_version.nil?
|
127
|
+
versions.each do |version|
|
128
|
+
break if max_version.nil? && version == min_version
|
129
|
+
in_range = true if (!max_version.nil? && version == min_version)
|
130
|
+
usage += usage(browser, version) if in_range
|
131
|
+
break if !max_version.nil? && version == max_version
|
132
|
+
end
|
133
|
+
return usage
|
134
|
+
end
|
135
|
+
|
136
|
+
# returns the list of browsers that use the given prefix
|
137
|
+
def browsers_with_prefix(prefix)
|
138
|
+
assert_valid_prefix prefix
|
139
|
+
prefix = "-" + prefix unless prefix.start_with?("-")
|
140
|
+
browsers.select {|b| all_prefixes(b).include?(prefix) }
|
141
|
+
end
|
142
|
+
|
143
|
+
SPEC_VERSION_MATCHERS = Hash.new do |h, k|
|
144
|
+
h[k] = /##{k}\b/
|
145
|
+
end
|
146
|
+
|
147
|
+
CAPABILITY_MATCHERS = {
|
148
|
+
:full_support => lambda {|support, capability| !support ^ (capability =~ /\by\b/) },
|
149
|
+
:partial_support => lambda {|support, capability| !support ^ (capability =~ /\ba\b/) },
|
150
|
+
:prefixed => lambda {|support, capability| !support ^ (capability =~ /\bx\b/) },
|
151
|
+
:spec_versions => lambda {|versions, capability| versions.any? {|v| capability =~ SPEC_VERSION_MATCHERS[v] } }
|
152
|
+
}
|
153
|
+
|
154
|
+
# Return whether the capability matcher the options specified.
|
155
|
+
# For each capability option in the options the capability will need to match it.
|
156
|
+
def capability_matches(support, capability_options_list)
|
157
|
+
capability_options_list.any? do |capability_options|
|
158
|
+
capability_options.all? {|c, v| CAPABILITY_MATCHERS[c].call(v, support)}
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# returns the percentage of users (0-100) that would be affected if the prefix
|
163
|
+
# was not used with the given capability.
|
164
|
+
def prefixed_usage(prefix, capability, capability_options_list)
|
165
|
+
assert_valid_prefix prefix
|
166
|
+
assert_valid_capability capability
|
167
|
+
usage = 0
|
168
|
+
browsers_with_prefix(prefix).each do |browser|
|
169
|
+
versions(browser).each do |version|
|
170
|
+
next unless prefix == prefix(browser, version)
|
171
|
+
support = browser_support(browser, version, capability)
|
172
|
+
if capability_matches(support, capability_options_list) and support =~ /\bx\b/
|
173
|
+
usage += usage(browser, version)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
usage
|
178
|
+
end
|
179
|
+
|
180
|
+
def next_version(browser, version)
|
181
|
+
version = caniuse_version(browser, version)
|
182
|
+
versions = versions(browser)
|
183
|
+
index = versions.index(version)
|
184
|
+
index < versions.length - 1 ? versions[index + 1] : nil
|
185
|
+
end
|
186
|
+
|
187
|
+
def previous_version(browser, version)
|
188
|
+
version = caniuse_version(browser, version)
|
189
|
+
versions = versions(browser)
|
190
|
+
index = versions.index(version)
|
191
|
+
index > 0 ? versions[index - 1] : nil
|
192
|
+
end
|
193
|
+
|
194
|
+
# Returns whether the given minimum version of a browser
|
195
|
+
# requires the use of a prefix for the stated capability.
|
196
|
+
def requires_prefix(browser, min_version, capability, capability_options_list)
|
197
|
+
min_version = caniuse_version(browser, min_version)
|
198
|
+
assert_valid_browser browser
|
199
|
+
assert_valid_capability capability
|
200
|
+
found_version = false
|
201
|
+
versions(browser).each do |version|
|
202
|
+
found_version ||= version == min_version
|
203
|
+
next unless found_version
|
204
|
+
support = browser_support(browser, version, capability)
|
205
|
+
if capability_matches(support, capability_options_list) and support =~ /\bx\b/
|
206
|
+
return prefix(browser, version)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
raise ArgumentError, "#{min_version} is not a version for #{browser}" unless found_version
|
210
|
+
nil
|
211
|
+
end
|
212
|
+
|
213
|
+
# These are versions that users might reasonably type
|
214
|
+
# mapped to the caniuse version.
|
215
|
+
ALTERNATE_VERSIONS = {
|
216
|
+
"android" => {
|
217
|
+
"4.2" => "4.2-4.3",
|
218
|
+
"4.3" => "4.2-4.3"
|
219
|
+
},
|
220
|
+
"opera" => {
|
221
|
+
"9.5" => "9.5-9.6",
|
222
|
+
"9.6" => "9.5-9.6",
|
223
|
+
"10.0" => "10.0-10.1",
|
224
|
+
"10.1" => "10.0-10.1",
|
225
|
+
},
|
226
|
+
"opera-mobile" => {
|
227
|
+
"14" => "0"
|
228
|
+
}
|
229
|
+
}
|
230
|
+
|
231
|
+
# Returns the versions of a browser. If the min_usage parameter is provided,
|
232
|
+
# only those versions having met the threshold of user percentage.
|
233
|
+
#
|
234
|
+
# @param min_usage a decimal number betwee 0 and 100
|
235
|
+
def versions(browser, min_usage = 0)
|
236
|
+
assert_valid_browser browser
|
237
|
+
versions = browser_data(browser)["versions"].compact
|
238
|
+
return versions if min_usage == 0
|
239
|
+
versions.select {|v| browser_data(browser)["usage_global"][v] > min_usage }
|
240
|
+
end
|
241
|
+
|
242
|
+
# The list of capabilities tracked by caniuse.
|
243
|
+
def capabilities
|
244
|
+
@capabilities ||= @data["data"].keys.select do |cap|
|
245
|
+
cats = @data["data"][cap]["categories"]
|
246
|
+
cats.any?{|cat| cat =~ /CSS/ }
|
247
|
+
end.sort
|
248
|
+
end
|
249
|
+
|
250
|
+
# the usage % for a given browser version.
|
251
|
+
def usage(browser, version)
|
252
|
+
browser_data(browser)["usage_global"][version]
|
253
|
+
end
|
254
|
+
|
255
|
+
# returns a valid version given the version provided by the user
|
256
|
+
# This is used to maintain API compatibility when caniuse removes
|
257
|
+
# a version from their data (which seems to be replaced with a semantic equivalent).
|
258
|
+
def caniuse_version(browser, version)
|
259
|
+
return unless version
|
260
|
+
ALTERNATE_VERSIONS[browser] && ALTERNATE_VERSIONS[browser][version] || version
|
261
|
+
end
|
262
|
+
|
263
|
+
def inspect
|
264
|
+
"#{self.class.name}(#{browsers.join(", ")})"
|
265
|
+
end
|
266
|
+
|
267
|
+
# the browser data assocated with a given capability
|
268
|
+
def capability_data(capability)
|
269
|
+
@data["data"][capability]
|
270
|
+
end
|
271
|
+
|
272
|
+
def browser_support(browser, version, capability)
|
273
|
+
version = caniuse_version(browser, version)
|
274
|
+
capability_data(capability)["stats"][CAN_I_USE_NAMES[browser]][version]
|
275
|
+
end
|
276
|
+
|
277
|
+
# the metadata assocated with a given browser
|
278
|
+
def browser_data(browser)
|
279
|
+
@data["agents"][CAN_I_USE_NAMES[browser]]
|
280
|
+
end
|
281
|
+
|
282
|
+
# efficiently checks if a prefix is valid
|
283
|
+
def assert_valid_prefix(prefix)
|
284
|
+
@known_prefixes ||= Set.new(prefixes(browsers))
|
285
|
+
unless @known_prefixes.include?(prefix)
|
286
|
+
raise ArgumentError, "#{prefix} is not known browser prefix."
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
# efficiently checks if a browser is valid
|
291
|
+
def assert_valid_browser(browser)
|
292
|
+
@known_browsers ||= Set.new(browsers)
|
293
|
+
unless @known_browsers.include?(browser)
|
294
|
+
raise ArgumentError, "#{browser} is not known browser."
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
# efficiently checks if a capability is valid
|
299
|
+
def assert_valid_capability(capability)
|
300
|
+
@known_capabilities ||= Set.new(capabilities)
|
301
|
+
unless @known_capabilities.include?(capability)
|
302
|
+
raise ArgumentError, "#{capability} is not known browser capability."
|
303
|
+
end
|
304
|
+
nil
|
305
|
+
end
|
306
|
+
|
307
|
+
def assert_valid_version(browser, *versions)
|
308
|
+
versions.each do |v|
|
309
|
+
unless versions(browser).include?(v)
|
310
|
+
raise ArgumentError, "#{v} is not known version for #{browser}."
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Compass::Core::SassExtensions::Functions::Colors
|
2
|
+
|
3
|
+
# a genericized version of lighten/darken so that negative values can be used.
|
4
|
+
def adjust_lightness(color, amount)
|
5
|
+
assert_type color, :Color
|
6
|
+
assert_type amount, :Number
|
7
|
+
color.with(:lightness => Sass::Util.restrict(color.lightness + amount.value, 0..100))
|
8
|
+
end
|
9
|
+
|
10
|
+
# Scales a color's lightness by some percentage.
|
11
|
+
# If the amount is negative, the color is scaled darker, if positive, it is scaled lighter.
|
12
|
+
# This will never return a pure light or dark color unless the amount is 100%.
|
13
|
+
def scale_lightness(color, amount)
|
14
|
+
assert_type color, :Color
|
15
|
+
assert_type amount, :Number
|
16
|
+
color.with(:lightness => scale_color_value(color.lightness, amount.value))
|
17
|
+
end
|
18
|
+
|
19
|
+
# a genericized version of saturation/desaturate so that negative values can be used.
|
20
|
+
def adjust_saturation(color, amount)
|
21
|
+
assert_type color, :Color
|
22
|
+
assert_type amount, :Number
|
23
|
+
color.with(:saturation => Sass::Util.restrict(color.saturation + amount.value, 0..100))
|
24
|
+
end
|
25
|
+
|
26
|
+
# Scales a color's saturation by some percentage.
|
27
|
+
# If the amount is negative, the color is desaturated, if positive, it is saturated.
|
28
|
+
# This will never return a pure saturated or desaturated color unless the amount is 100%.
|
29
|
+
def scale_saturation(color, amount)
|
30
|
+
assert_type color, :Color
|
31
|
+
assert_type amount, :Number
|
32
|
+
color.with(:saturation => scale_color_value(color.saturation, amount.value))
|
33
|
+
end
|
34
|
+
|
35
|
+
def shade(color, percentage)
|
36
|
+
assert_type color, :Color
|
37
|
+
assert_type percentage, :Number
|
38
|
+
black = rgb_color(0, 0, 0)
|
39
|
+
mix(black, color, percentage)
|
40
|
+
end
|
41
|
+
|
42
|
+
def tint(color, percentage)
|
43
|
+
assert_type color, :Color
|
44
|
+
assert_type percentage, :Number
|
45
|
+
white = rgb_color(255, 255, 255)
|
46
|
+
mix(white, color, percentage)
|
47
|
+
end
|
48
|
+
|
49
|
+
# returns an IE hex string for a color with an alpha channel
|
50
|
+
# suitable for passing to IE filters.
|
51
|
+
def ie_hex_str(color)
|
52
|
+
assert_type color, :Color
|
53
|
+
alpha = (color.alpha * 255).round
|
54
|
+
alphastr = alpha.to_s(16).rjust(2, '0')
|
55
|
+
identifier("##{alphastr}#{color.send(:hex_str)[1..-1]}".upcase)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
def scale_color_value(value, amount)
|
60
|
+
if amount > 0
|
61
|
+
value += (100 - value) * (amount / 100.0)
|
62
|
+
elsif amount < 0
|
63
|
+
value += value * amount / 100.0
|
64
|
+
end
|
65
|
+
value
|
66
|
+
end
|
67
|
+
end
|