Class: Compass::Core::CanIUse
- Inherits:
-
Object
- Object
- Compass::Core::CanIUse
- Includes:
- Singleton
- Defined in:
- lib/compass/core/caniuse.rb
Constant Summary collapse
- DATA_FILE_NAME =
File.join(Compass::Core.base_directory, "data", "caniuse.json")
- DATA_FEATURE_FILES =
Dir.glob(File.join(Compass::Core.base_directory, "data", "caniuse_extras", "**", "*.json"))
- PUBLIC_BROWSER_NAMES =
The browser names from caniuse are ugly.
Hash.new {|h, k| k}
- CAN_I_USE_NAMES =
Hash.new {|h, k| k}
- SPEC_VERSION_MATCHERS =
Hash.new do |h, k| h[k] = /##{k}\b/ end
- CAPABILITY_MATCHERS =
{ :full_support => lambda {|support, capability| !support ^ (capability =~ /\by\b/) }, :partial_support => lambda {|support, capability| !support ^ (capability =~ /\ba\b/) }, :prefixed => lambda {|support, capability| !support ^ (capability =~ /\bx\b/) }, :spec_versions => lambda {|versions, capability| versions.any? {|v| capability =~ SPEC_VERSION_MATCHERS[v] } } }
- ALTERNATE_VERSIONS =
These are versions that users might reasonably type mapped to the caniuse version.
{ "android" => { "4.2" => "4.2-4.3", "4.3" => "4.2-4.3" }, "opera" => { "9.5" => "9.5-9.6", "9.6" => "9.5-9.6", "10.0" => "10.0-10.1", "10.1" => "10.0-10.1", }, "opera-mobile" => { "14" => "0" } }
Instance Method Summary collapse
-
#all_prefixes(browser) ⇒ Object
returns all possible prefixes a browser might use.
-
#assert_valid_browser(browser) ⇒ Object
efficiently checks if a browser is valid.
-
#assert_valid_capability(capability) ⇒ Object
efficiently checks if a capability is valid.
-
#assert_valid_prefix(prefix) ⇒ Object
efficiently checks if a prefix is valid.
- #assert_valid_version(browser, *versions) ⇒ Object
-
#browser_data(browser) ⇒ Object
the metadata assocated with a given browser.
- #browser_ranges(capability, prefix = nil, include_unprefixed_versions = true) ⇒ Object
- #browser_support(browser, version, capability) ⇒ Object
-
#browsers ⇒ Object
Returns all the known browsers according to caniuse.
-
#browsers_with_prefix(prefix) ⇒ Object
returns the list of browsers that use the given prefix.
-
#caniuse_version(browser, version) ⇒ Object
returns a valid version given the version provided by the user This is used to maintain API compatibility when caniuse removes a version from their data (which seems to be replaced with a semantic equivalent).
-
#capabilities ⇒ Object
The list of capabilities tracked by caniuse.
-
#capability_data(capability) ⇒ Object
the browser data assocated with a given capability.
-
#capability_matches(support, capability_options_list) ⇒ Object
Return whether the capability matcher the options specified.
- #find_first_prefixed_version(browser, versions, capability, prefix) ⇒ Object
-
#initialize ⇒ CanIUse
constructor
A new instance of CanIUse.
- #inspect ⇒ Object
- #next_version(browser, version) ⇒ Object
- #omitted_usage(browser, min_version, max_version = nil) ⇒ Object
-
#prefix(browser, version = nil) ⇒ Object
Returns the prefix corresponding to a particular browser.
-
#prefixed_usage(prefix, capability, capability_options_list) ⇒ Object
returns the percentage of users (0-100) that would be affected if the prefix was not used with the given capability.
-
#prefixes(browsers = browsers()) ⇒ Object
returns the prefixes needed by the list of browsers given.
- #previous_version(browser, version) ⇒ Object
-
#requires_prefix(browser, min_version, capability, capability_options_list) ⇒ Object
Returns whether the given minimum version of a browser requires the use of a prefix for the stated capability.
-
#usage(browser, version) ⇒ Object
the usage % for a given browser version.
-
#versions(browser, min_usage = 0) ⇒ Object
Returns the versions of a browser.
Constructor Details
#initialize ⇒ CanIUse
Returns a new instance of CanIUse.
9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/compass/core/caniuse.rb', line 9 def initialize @data = MultiJson.load(File.read(DATA_FILE_NAME)) # support ad-hoc features DATA_FEATURE_FILES.each do |feature_file| feature_name = File.basename(feature_file, ".json") # if the feature doesn't exist in the master `caniuse.json` if @data["data"][feature_name].nil? @data["data"][feature_name] = MultiJson.load(File.read(feature_file)) end end end |
Instance Method Details
#all_prefixes(browser) ⇒ Object
returns all possible prefixes a browser might use.
61 62 63 64 65 66 67 68 69 |
# File 'lib/compass/core/caniuse.rb', line 61 def all_prefixes(browser) assert_valid_browser browser data = browser_data(browser) prefixes = ["-#{data["prefix"]}"] if data["prefix_exceptions"] prefixes += data["prefix_exceptions"].values.uniq.map{|p| "-#{p}"} end prefixes end |
#assert_valid_browser(browser) ⇒ Object
efficiently checks if a browser is valid
291 292 293 294 295 296 |
# File 'lib/compass/core/caniuse.rb', line 291 def assert_valid_browser(browser) @known_browsers ||= Set.new(browsers) unless @known_browsers.include?(browser) raise ArgumentError, "#{browser} is not known browser." end end |
#assert_valid_capability(capability) ⇒ Object
efficiently checks if a capability is valid
299 300 301 302 303 304 305 |
# File 'lib/compass/core/caniuse.rb', line 299 def assert_valid_capability(capability) @known_capabilities ||= Set.new(capabilities) unless @known_capabilities.include?(capability) raise ArgumentError, "#{capability} is not known browser capability." end nil end |
#assert_valid_prefix(prefix) ⇒ Object
efficiently checks if a prefix is valid
283 284 285 286 287 288 |
# File 'lib/compass/core/caniuse.rb', line 283 def assert_valid_prefix(prefix) @known_prefixes ||= Set.new(prefixes(browsers)) unless @known_prefixes.include?(prefix) raise ArgumentError, "#{prefix} is not known browser prefix." end end |
#assert_valid_version(browser, *versions) ⇒ Object
307 308 309 310 311 312 313 |
# File 'lib/compass/core/caniuse.rb', line 307 def assert_valid_version(browser, *versions) versions.each do |v| unless versions(browser).include?(v) raise ArgumentError, "#{v} is not known version for #{browser}." end end end |
#browser_data(browser) ⇒ Object
the metadata assocated with a given browser
278 279 280 |
# File 'lib/compass/core/caniuse.rb', line 278 def browser_data(browser) @data["agents"][CAN_I_USE_NAMES[browser]] end |
#browser_ranges(capability, prefix = nil, include_unprefixed_versions = true) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/compass/core/caniuse.rb', line 80 def browser_ranges(capability, prefix = nil, include_unprefixed_versions = true) assert_valid_capability capability browsers = prefix.nil? ? browsers() : browsers_with_prefix(prefix) browsers.inject({}) do |m, browser| browser_versions = versions(browser) min_version = find_first_prefixed_version(browser, browser_versions, capability, prefix) if min_version max_version = if include_unprefixed_versions browser_versions.last else find_first_prefixed_version(browser, browser_versions.reverse, capability, prefix) end m.update(browser => [min_version, max_version]) end m end end |
#browser_support(browser, version, capability) ⇒ Object
272 273 274 275 |
# File 'lib/compass/core/caniuse.rb', line 272 def browser_support(browser, version, capability) version = caniuse_version(browser, version) capability_data(capability)["stats"][CAN_I_USE_NAMES[browser]][version] end |
#browsers ⇒ Object
Returns all the known browsers according to caniuse
42 43 44 |
# File 'lib/compass/core/caniuse.rb', line 42 def browsers @browsers ||= @data["agents"].keys.map{|b| PUBLIC_BROWSER_NAMES[b] }.sort end |
#browsers_with_prefix(prefix) ⇒ Object
returns the list of browsers that use the given prefix
137 138 139 140 141 |
# File 'lib/compass/core/caniuse.rb', line 137 def browsers_with_prefix(prefix) assert_valid_prefix prefix prefix = "-" + prefix unless prefix.start_with?("-") browsers.select {|b| all_prefixes(b).include?(prefix) } end |
#caniuse_version(browser, version) ⇒ Object
returns a valid version given the version provided by the user This is used to maintain API compatibility when caniuse removes a version from their data (which seems to be replaced with a semantic equivalent).
258 259 260 261 |
# File 'lib/compass/core/caniuse.rb', line 258 def caniuse_version(browser, version) return unless version ALTERNATE_VERSIONS[browser] && ALTERNATE_VERSIONS[browser][version] || version end |
#capabilities ⇒ Object
The list of capabilities tracked by caniuse.
243 244 245 246 247 248 |
# File 'lib/compass/core/caniuse.rb', line 243 def capabilities @capabilities ||= @data["data"].keys.select do |cap| cats = @data["data"][cap]["categories"] cats.any?{|cat| cat =~ /CSS/ } end.sort end |
#capability_data(capability) ⇒ Object
the browser data assocated with a given capability
268 269 270 |
# File 'lib/compass/core/caniuse.rb', line 268 def capability_data(capability) @data["data"][capability] end |
#capability_matches(support, capability_options_list) ⇒ Object
Return whether the capability matcher the options specified. For each capability option in the options the capability will need to match it.
156 157 158 159 160 |
# File 'lib/compass/core/caniuse.rb', line 156 def capability_matches(support, ) .any? do || .all? {|c, v| CAPABILITY_MATCHERS[c].call(v, support)} end end |
#find_first_prefixed_version(browser, versions, capability, prefix) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/compass/core/caniuse.rb', line 98 def find_first_prefixed_version(browser, versions, capability, prefix) versions.find do |version| support = browser_support(browser, version, capability) if prefix.nil? support !~ /\b(n|p)\b/ && support !~ /\bx\b/ else actual_prefix = prefix(browser, version) support !~ /\b(n|p)\b/ && support =~ /\bx\b/ && prefix == actual_prefix end end end |
#inspect ⇒ Object
263 264 265 |
# File 'lib/compass/core/caniuse.rb', line 263 def inspect "#{self.class.name}(#{browsers.join(", ")})" end |
#next_version(browser, version) ⇒ Object
180 181 182 183 184 185 |
# File 'lib/compass/core/caniuse.rb', line 180 def next_version(browser, version) version = caniuse_version(browser, version) versions = versions(browser) index = versions.index(version) index < versions.length - 1 ? versions[index + 1] : nil end |
#omitted_usage(browser, min_supported_version) ⇒ Object #omitted_usage(browser, min_unsupported_version, max_unsupported_version) ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/compass/core/caniuse.rb', line 116 def omitted_usage(browser, min_version, max_version = nil) versions = versions(browser) min_version = caniuse_version(browser, min_version) max_version = caniuse_version(browser, max_version) if max_version.nil? assert_valid_version browser, min_version else assert_valid_version browser, min_version, max_version end usage = 0 in_range = max_version.nil? versions.each do |version| break if max_version.nil? && version == min_version in_range = true if (!max_version.nil? && version == min_version) usage += usage(browser, version) if in_range break if !max_version.nil? && version == max_version end return usage end |
#prefix(browser, version = nil) ⇒ Object
Returns the prefix corresponding to a particular browser
47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/compass/core/caniuse.rb', line 47 def prefix(browser, version = nil) version = caniuse_version(browser, version) assert_valid_browser browser assert_valid_version browser, version if version data = browser_data(browser) p = if data["prefix_exceptions"] && data["prefix_exceptions"][version] data["prefix_exceptions"][version] else data["prefix"] end "-#{p}" end |
#prefixed_usage(prefix, capability, capability_options_list) ⇒ Object
returns the percentage of users (0-100) that would be affected if the prefix was not used with the given capability.
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/compass/core/caniuse.rb', line 164 def prefixed_usage(prefix, capability, ) assert_valid_prefix prefix assert_valid_capability capability usage = 0 browsers_with_prefix(prefix).each do |browser| versions(browser).each do |version| next unless prefix == prefix(browser, version) support = browser_support(browser, version, capability) if capability_matches(support, ) and support =~ /\bx\b/ usage += usage(browser, version) end end end usage end |
#prefixes(browsers = browsers()) ⇒ Object
returns the prefixes needed by the list of browsers given
72 73 74 75 76 77 78 |
# File 'lib/compass/core/caniuse.rb', line 72 def prefixes(browsers = browsers()) result = browsers.map{|b| all_prefixes(b) } result.flatten! result.uniq! result.sort! result end |
#previous_version(browser, version) ⇒ Object
187 188 189 190 191 192 |
# File 'lib/compass/core/caniuse.rb', line 187 def previous_version(browser, version) version = caniuse_version(browser, version) versions = versions(browser) index = versions.index(version) index > 0 ? versions[index - 1] : nil end |
#requires_prefix(browser, min_version, capability, capability_options_list) ⇒ Object
Returns whether the given minimum version of a browser requires the use of a prefix for the stated capability.
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/compass/core/caniuse.rb', line 196 def requires_prefix(browser, min_version, capability, ) min_version = caniuse_version(browser, min_version) assert_valid_browser browser assert_valid_capability capability found_version = false versions(browser).each do |version| found_version ||= version == min_version next unless found_version support = browser_support(browser, version, capability) if capability_matches(support, ) and support =~ /\bx\b/ return prefix(browser, version) end end raise ArgumentError, "#{min_version} is not a version for #{browser}" unless found_version nil end |
#usage(browser, version) ⇒ Object
the usage % for a given browser version.
251 252 253 |
# File 'lib/compass/core/caniuse.rb', line 251 def usage(browser, version) browser_data(browser)["usage_global"][version] end |
#versions(browser, min_usage = 0) ⇒ Object
Returns the versions of a browser. If the min_usage parameter is provided, only those versions having met the threshold of user percentage.
235 236 237 238 239 240 |
# File 'lib/compass/core/caniuse.rb', line 235 def versions(browser, min_usage = 0) assert_valid_browser browser versions = browser_data(browser)["versions"].compact return versions if min_usage == 0 versions.select {|v| browser_data(browser)["usage_global"][v] > min_usage } end |