class Compass::Core::CanIUse

Constants

ALTERNATE_VERSIONS

These are versions that users might reasonably type mapped to the caniuse version.

CAN_I_USE_NAMES
CAPABILITY_MATCHERS
DATA_FEATURE_FILES
DATA_FILE_NAME
PUBLIC_BROWSER_NAMES

The browser names from caniuse are ugly.

SPEC_VERSION_MATCHERS

Public Class Methods

new() click to toggle source
# 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

Public Instance Methods

all_prefixes(browser) click to toggle source

returns all possible prefixes a browser might use.

# 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) click to toggle source

efficiently checks if a browser is valid

# 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) click to toggle source

efficiently checks if a capability is valid

# 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) click to toggle source

efficiently checks if a prefix is valid

# 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) click to toggle source
# 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) click to toggle source

the metadata assocated with a given browser

# 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) click to toggle source
# 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) click to toggle source
# 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() click to toggle source

Returns all the known browsers according to caniuse

# 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) click to toggle source

returns the list of browsers that use the given prefix

# 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) click to toggle source

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).

# 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() click to toggle source

The list of capabilities tracked by caniuse.

# 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) click to toggle source

the browser data assocated with a given capability

# File lib/compass/core/caniuse.rb, line 268
def capability_data(capability)
  @data["data"][capability]
end
capability_matches(support, capability_options_list) click to toggle source

Return whether the capability matcher the options specified. For each capability option in the options the capability will need to match it.

# File lib/compass/core/caniuse.rb, line 156
def capability_matches(support, capability_options_list)
  capability_options_list.any? do |capability_options|
    capability_options.all? {|c, v| CAPABILITY_MATCHERS[c].call(v, support)}
  end
end
find_first_prefixed_version(browser, versions, capability, prefix) click to toggle source
# 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() click to toggle source
# File lib/compass/core/caniuse.rb, line 263
def inspect
  "#{self.class.name}(#{browsers.join(", ")})"
end
next_version(browser, version) click to toggle source
# 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_version, max_version = nil) click to toggle source

@overload #omitted_usage(browser, min_supported_version)

How many users would be omitted if support for the given browser starts
with the given version.

@overload #omitted_usage(browser, min_unsupported_version, max_unsupported_version)

How many users would be omitted if the browsers with version
# 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) click to toggle source

Returns the prefix corresponding to a particular browser

# 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) click to toggle source

returns the percentage of users (0-100) that would be affected if the prefix was not used with the given capability.

# File lib/compass/core/caniuse.rb, line 164
def prefixed_usage(prefix, capability, capability_options_list)
  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, capability_options_list) and support =~ /\bx\b/
        usage += usage(browser, version)
      end
    end
  end
  usage
end
prefixes(browsers = browsers) click to toggle source

returns the prefixes needed by the list of browsers given

# 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) click to toggle source
# 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) click to toggle source

Returns whether the given minimum version of a browser requires the use of a prefix for the stated capability.

# File lib/compass/core/caniuse.rb, line 196
def requires_prefix(browser, min_version, capability, capability_options_list)
  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, capability_options_list) 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) click to toggle source

the usage % for a given browser version.

# File lib/compass/core/caniuse.rb, line 251
def usage(browser, version)
  browser_data(browser)["usage_global"][version]
end
versions(browser, min_usage = 0) click to toggle source

Returns the versions of a browser. If the min_usage parameter is provided, only those versions having met the threshold of user percentage.

@param min_usage a decimal number betwee 0 and 100

# 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