brauser 3.3.2 → 4.0.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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -0
  3. data/.travis-gemfile +4 -5
  4. data/.travis.yml +2 -2
  5. data/CHANGELOG.md +4 -0
  6. data/Gemfile +7 -8
  7. data/README.md +31 -95
  8. data/Rakefile +0 -1
  9. data/brauser.gemspec +4 -4
  10. data/default_definitions/browsers.rb +50 -0
  11. data/default_definitions/languages.rb +118 -0
  12. data/default_definitions/platforms.rb +24 -0
  13. data/doc/Brauser.html +6 -6
  14. data/doc/Brauser/Browser.html +3867 -580
  15. data/doc/Brauser/Definitions.html +537 -0
  16. data/doc/Brauser/Definitions/Base.html +342 -0
  17. data/doc/Brauser/Definitions/Browser.html +1047 -0
  18. data/doc/Brauser/Definitions/Language.html +496 -0
  19. data/doc/Brauser/Definitions/Platform.html +686 -0
  20. data/doc/Brauser/Hooks.html +2 -2
  21. data/doc/Brauser/Hooks/RubyOnRails.html +9 -9
  22. data/doc/Brauser/Parser.html +513 -0
  23. data/doc/Brauser/Value.html +601 -0
  24. data/doc/Brauser/Version.html +5 -5
  25. data/doc/_index.html +25 -108
  26. data/doc/class_list.html +1 -1
  27. data/doc/file.README.html +33 -97
  28. data/doc/index.html +33 -97
  29. data/doc/method_list.html +72 -120
  30. data/doc/top-level-namespace.html +2 -2
  31. data/lib/brauser.rb +13 -15
  32. data/lib/brauser/browser.rb +195 -66
  33. data/lib/brauser/definitions/base.rb +71 -0
  34. data/lib/brauser/definitions/browser.rb +80 -0
  35. data/lib/brauser/definitions/language.rb +29 -0
  36. data/lib/brauser/definitions/platform.rb +42 -0
  37. data/lib/brauser/hooks.rb +1 -2
  38. data/lib/brauser/parser.rb +47 -0
  39. data/lib/brauser/value.rb +39 -0
  40. data/lib/brauser/version.rb +3 -4
  41. data/spec/brauser/browser_spec.rb +73 -564
  42. data/spec/brauser/default_definitions_spec.rb +129 -0
  43. data/spec/brauser/definitions/base_spec.rb +48 -0
  44. data/spec/brauser/definitions/browser_spec.rb +47 -0
  45. data/spec/brauser/definitions/language_spec.rb +18 -0
  46. data/spec/brauser/definitions/platform_spec.rb +36 -0
  47. data/spec/brauser/hooks_spec.rb +5 -6
  48. data/spec/brauser/parser_spec.rb +31 -0
  49. data/spec/brauser/value_spec.rb +34 -0
  50. data/spec/coverage_helper.rb +0 -1
  51. data/spec/spec_helper.rb +0 -1
  52. metadata +50 -23
  53. data/lib/brauser/browseable/attributes.rb +0 -95
  54. data/lib/brauser/browseable/general.rb +0 -104
  55. data/lib/brauser/browseable/parsing.rb +0 -127
  56. data/lib/brauser/browseable/partial_querying.rb +0 -116
  57. data/lib/brauser/browseable/querying.rb +0 -63
  58. data/lib/brauser/browseable/register.rb +0 -73
  59. data/lib/brauser/definition.rb +0 -80
  60. data/lib/brauser/definitions/browsers.rb +0 -68
  61. data/lib/brauser/definitions/languages.rb +0 -130
  62. data/lib/brauser/definitions/platforms.rb +0 -30
  63. data/lib/brauser/query.rb +0 -36
  64. data/lib/brauser/queryable/chainers.rb +0 -56
  65. data/lib/brauser/queryable/queries.rb +0 -60
  66. data/spec/brauser/definition_spec.rb +0 -39
  67. data/spec/brauser/query_spec.rb +0 -111
@@ -1,95 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- # This file is part of the brauser gem. Copyright (C) 2013 and above Shogun <shogun@cowtech.it>.
4
- # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
- #
6
-
7
- module Brauser
8
- # The interface of brauser browsers.
9
- module Browseable
10
- # Methods to handle attributes.
11
- module Attributes
12
- # Gets a human-readable browser name.
13
- #
14
- # @return [String] A human-readable browser name.
15
- def readable_name
16
- parse_agent(@agent) unless @name
17
- ::Brauser::Browser.browsers.fetch(@name).label
18
- rescue KeyError
19
- "Unknown Browser"
20
- end
21
-
22
- # Gets a human-readable platform name.
23
- #
24
- # @return [String] A readable platform name.
25
- def platform_name
26
- parse_agent(@agent) unless @platform
27
- ::Brauser::Browser.platforms[@platform].try(:label) || "Unknown Platform"
28
- end
29
-
30
- # Returns an array of information about the browser. Information are strings which are suitable to use as CSS classes.
31
- #
32
- # For version, it will be included a class for every token of the version. For example, version `7.0.1.2` will return this:
33
- #
34
- # ```ruby
35
- # ["version-7", "version-7_0", "version-7_0_1", "version-7_0_1_2"]
36
- # ```
37
- #
38
- # If you provide a block (with accepts name, version and platform as arguments), it will be used for translating the name.
39
- #
40
- # @param join [String|NilClass] If non falsy, the separator to use to join information. If falsy, informations will be returned as array.
41
- # @param name [Boolean] If non falsy, the string to prepend to the name. If falsy, the name information will not be included.
42
- # @param version [String|NilClass] If non falsy, the string to prepend to the version. If falsy, the version information will not be included.
43
- # @param platform [String|NilClass] If non falsy, the string to prepend to the platform. If falsy, the platform information will not be included.
44
- # @param block [Proc] A block to translate browser name.
45
- # @return [String|Array] CSS ready information of the current browser.
46
- def classes(join = " ", name = "", version = "version-", platform = "platform-", &block)
47
- platform = "platform-" if platform.is_a?(TrueClass)
48
- rv = [stringify_name(name, &block), stringify_version(version), !platform ? nil : (platform + @platform.to_s)].compact.flatten
49
- join ? rv.join(join) : rv
50
- end
51
- alias_method :meta, :classes
52
- alias_method :to_s, :classes
53
-
54
- private
55
-
56
- # Stringifies a browser name(s).
57
- #
58
- # @param name [Boolean] If non falsy, the string to prepend to the name. If falsy, the name information will not be included.
59
- # @param block [Proc] A block to translate browser name.
60
- # @return [String|Array|nil] The browser name(s) or `nil`, if it was set to be skipped.
61
- def stringify_name(name, &block)
62
- if name
63
- name, block = prepare_name_stringification(name, block)
64
- names = block.call(@name, @version, @platform).ensure_array { |n| "#{name}#{n}" }
65
- names.length > 1 ? names : names.first
66
- else
67
- nil
68
- end
69
- end
70
-
71
- # Prepare a name stringification
72
- #
73
- # @param name [Boolean] If non falsy, the string to prepend to the name. If falsy, the name information will not be included.
74
- # @param block [Proc] A block to translate browser name.
75
- # @return [Array] A name and a translator ready to use.
76
- def prepare_name_stringification(name, block)
77
- parse_agent(@agent) unless @name
78
- [(name.is_a?(TrueClass) ? "" : name), block || proc { |n, *| n == :msie_compatibility ? [:msie_compatibility, :msie] : n }]
79
- end
80
-
81
- # Stringifies a browser version.
82
- #
83
- # @param version [String|NilClass] If non falsy, the string to prepend to the version. If falsy, the version information will not be included.
84
- # @return [Array] The version strings or `nil`, if it was set to be skipped.
85
- def stringify_version(version)
86
- version = "version-" if version.is_a?(TrueClass)
87
- tokens = @version.split(".")
88
-
89
- !version ? nil : tokens.reduce([version + tokens.shift]) {|prev, current|
90
- prev + [prev.last + "_" + current]
91
- }.flatten
92
- end
93
- end
94
- end
95
- end
@@ -1,104 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- # This file is part of the brauser gem. Copyright (C) 2013 and above Shogun <shogun@cowtech.it>.
4
- # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
- #
6
-
7
- module Brauser
8
- # The interface of brauser browsers.
9
- module Browseable
10
- # General methods.
11
- module General
12
- extend ActiveSupport::Concern
13
-
14
- # Class methods.
15
- module ClassMethods
16
- # Returns the list of browser that can be recognized.
17
- #
18
- # The keys are the browser name, the values are arrays of the name matcher, the version match and the label.
19
- #
20
- # @return [Hash] The list of browser that can be recognized.
21
- def browsers
22
- @definitions[:browsers]
23
- end
24
-
25
- # Returns the list of platforms that can be recognized.
26
- #
27
- # The keys are the platform name, values are arrays of the matcher and the label.
28
- #
29
- # @return [Hash] The list of platform that can be recognized.
30
- def platforms
31
- @definitions[:platforms]
32
- end
33
-
34
- # Returns the list of languages that can be recognized.
35
- #
36
- # The keys are the languages code, the values the labels.
37
- #
38
- # @return [Hash] The list of languages that can be recognized.
39
- def languages
40
- @definitions[:languages]
41
- end
42
-
43
- # Compares two versions.
44
- #
45
- # @param v1 [String] The first versions to compare.
46
- # @param operator [Symbol] The operator to use for comparison, can be one of `[:lt, :lte, :eq, :gte, :gt]`.
47
- # @param v2 [Symbol] The second version to compare.
48
- # @return [Boolean] true if comparison is valid, `false` otherwise.
49
- def compare_versions(v1 = "", operator = :eq, v2 = "")
50
- valid_results = {lt: [-1], lte: [-1, 0], eq: [0], gte: [0, 1], gt: [1]}.fetch(operator, [])
51
-
52
- if valid_results.present? && v1.ensure_string.present?
53
- p1, p2 = find_relevant_tokens(v1, v2)
54
- p1, p2 = normalize_tokens(p1, p2)
55
- valid_results.include?(p1 <=> p2)
56
- else
57
- false
58
- end
59
- end
60
-
61
- private
62
-
63
- # Find relevant tokens (that is, the first two which are not equals) in a string for comparison.
64
- #
65
- # @param v1 [String] The first versions to compare.
66
- # @param v2 [String] The second version to compare.
67
- # @return [Array] The tokens to compare.
68
- def find_relevant_tokens(v1, v2)
69
- v1 = v1.ensure_string.strip.split(".")
70
- v2 = v2.ensure_string.strip.split(".")
71
-
72
- p1 = nil
73
- p2 = nil
74
- [v1.length, v2.length].max.times do |i|
75
- p1 = v1[i]
76
- p2 = v2[i]
77
- break if !p1 && !p2 || p1 != p2
78
- end
79
-
80
- [p1 || "0", p2 || "0"]
81
- end
82
-
83
- # Normalizes token for comparison.
84
- #
85
- # @param p1 [String] The first token to normalize.
86
- # @param p2 [String] The second token to normalize.
87
- # @return [Array] The tokens to compare.
88
- def normalize_tokens(p1, p2)
89
- if !p1.is_integer?
90
- ll = p1.length
91
- p1 = p2 + p1
92
- p2 += ("z" * ll)
93
- else
94
- ll = [p1.length, p2.length].max
95
- p1 = p1.rjust(ll, "0")
96
- p2 = p2.rjust(ll, "0")
97
- end
98
-
99
- [p1, p2]
100
- end
101
- end
102
- end
103
- end
104
- end
@@ -1,127 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- # This file is part of the brauser gem. Copyright (C) 2013 and above Shogun <shogun@cowtech.it>.
4
- # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
- #
6
-
7
- module Brauser
8
- # The interface of brauser browsers.
9
- module Browseable
10
- # Methods to parse the user agent.
11
- module Parsing
12
- # Parses the User-Agent header.
13
- # @param agent [String] The User-Agent header.
14
- # @return [Boolean] `true` if the browser was detected, `false` otherwise.
15
- def parse_agent(agent = nil)
16
- agent = agent.ensure_string
17
-
18
- @name, _ = match_name_and_version(agent)
19
- @version = adjust_version(@version)
20
- @platform = match_platform(agent)
21
-
22
- (@name != :unknown) ? true : false
23
- end
24
-
25
- # Parses the Accept-Language header.
26
- #
27
- # @param accept_language [String] The Accept-Language header.
28
- # @return [Array] The list of accepted languages.
29
- def parse_accept_language(accept_language = nil)
30
- accept_language.ensure_string.gsub(/;q=[\d.]+/, "").split(",").map { |l| l.downcase.strip }.select { |l| l.present? }
31
- end
32
-
33
- private
34
-
35
- # Matches a browser name and version.
36
- #
37
- # @param agent [String] The User-Agent header.
38
- # @return [String|Symbol] The browser name or `:unknown`, if no match was found.
39
- def match_name_and_version(agent)
40
- catch(:name) do
41
- ::Brauser::Browser.browsers.each do |tag, definition|
42
- matched = definition.match(:primary, definition, agent)
43
-
44
- if matched
45
- @version = definition.match(:secondary, definition, agent)
46
- throw(:name, tag)
47
- end
48
- end
49
-
50
- :unknown
51
- end
52
- end
53
-
54
- # Adjusts a browser version.
55
- #
56
- # @param version [String] The version to adjust.
57
- # @return [String] The adjusted version.
58
- def adjust_version(version)
59
- # Adjust version
60
- if version.blank?
61
- "0.0"
62
- elsif version.is_a?(::MatchData)
63
- version.to_a.last
64
- else
65
- version
66
- end
67
- end
68
-
69
- # Matches a browser platform.
70
- #
71
- # @param agent [String] The User-Agent header.
72
- # @return [String|Symbol] The browser platform or `:unknown`, if no match was found.
73
- def match_platform(agent)
74
- catch(:platform) do
75
- ::Brauser::Browser.platforms.each do |tag, definition|
76
- throw(:platform, tag) if definition.match(:primary, definition, agent)
77
- end
78
-
79
- :unknown
80
- end
81
- end
82
-
83
- # Parse query, getting all arguments.
84
- #
85
- # @param query [String] The query to issue. Use `__` to separate query and `_` in place of `.` in the version.
86
- # @return [Array] And array of `[method, arguments]` entries.
87
- def parse_query(query)
88
- query.gsub(/\?$/, "").gsub(/(_(v|on|is))/, " \\2").split(" ").map do |part|
89
- parse_query_part(part)
90
- end
91
- end
92
-
93
- # Handles a part of a query.
94
- #
95
- # @param part [String] A part of a query.
96
- # @return [Boolean|Query|nil] A query or a boolean value (if `method` ends with `?`). If the query is not valid, `NoMethodError` will be raised.
97
- def parse_query_part(part)
98
- method, arguments = part.split("_", 2)
99
-
100
- if method == "v" || method == "version"
101
- arguments = parse_query_version(arguments)
102
- elsif !%w(is on).include?(method)
103
- raise NoMethodError
104
- end
105
-
106
- [method, arguments]
107
- end
108
-
109
- # Parses the version for a query.
110
- #
111
- # @param version [String] The version to parse.
112
- # @return [String] The parsed version.
113
- def parse_query_version(version)
114
- [
115
- [/_?eq_?/, " == "], # Parse ==
116
- [/_?lte_?/, " <= "], # Parse <=
117
- [/_?gte_?/, " >= "], # Parse >=
118
- [/_?lt_?/, " < "], # Parse <
119
- [/_?gt_?/, " > "], # Parse >
120
- [/_?and_?/, " && "], # Parse &&
121
- ["_", "."], # Dot notation
122
- [/\s+/, " "]
123
- ].reduce(version) { |a, e| a.gsub(e[0], e[1]) }.strip
124
- end
125
- end
126
- end
127
- end
@@ -1,116 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- # This file is part of the brauser gem. Copyright (C) 2013 and above Shogun <shogun@cowtech.it>.
4
- # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
- #
6
-
7
- module Brauser
8
- # The interface of brauser browsers.
9
- module Browseable
10
- # Methods to query with chaining.
11
- module PartialQuerying
12
- # Checks if the browser is a specific name and optionally of a specific version and platform.
13
- #
14
- # @see #version?
15
- # @see #on?
16
- #
17
- # @param names [Symbol|Array] A list of specific names to match. Also, this meta-names are supported: `:capable` and `:tablet`.
18
- # @param versions [String|Hash] A string in the form `operator version && ...` (example: `>= 7 && < 4`) or an hash with specific version to match against,
19
- # in form `{:operator => version}`, where operator is one of `:lt, :lte, :eq, :gt, :gte`.
20
- # @param platforms [Symbol|Array] A list of specific platform to match. Valid values are all those possible for the platform attribute.
21
- # @return [Query] A query which can evaluated for concatenation or result.
22
- def is(names = [], versions = {}, platforms = [])
23
- parse_agent(@agent) unless @name
24
-
25
- names = adjust_names(names)
26
- versions = parse_versions_query(versions)
27
- platforms = platforms.ensure_array
28
-
29
- ::Brauser::Query.new(self,
30
- (names.blank? || (names.include?(@name) && check_capable(names))) &&
31
- (versions.blank? || version?(versions)) &&
32
- (platforms.blank? || on?(platforms))
33
- )
34
- end
35
-
36
- # Checks if the browser is a specific version.
37
- #
38
- # @param versions [String|Hash] A string in the form `operator version && ...` (example: `>= 7 && < 4`) or an hash with specific version to match against,
39
- # in form `{:operator => version}`, where operator is one of `:lt, :lte, :eq, :gt, :gte`.
40
- # @return [Query] A query which can evaluated for concatenation or result.
41
- def version_equals_to(versions = {})
42
- parse_agent(@agent) unless @version
43
- versions = versions.is_a?(String) ? parse_versions_query(versions) : versions.ensure_hash
44
-
45
- ::Brauser::Query.new(self, versions.all? { |operator, value| Brauser::Browser.compare_versions(@version, operator, value) })
46
- end
47
- alias_method :v, :version_equals_to
48
-
49
- # Check if the browser is on a specific platform.
50
- #
51
- # @param platforms [Symbol|Array] A list of specific platform to match.
52
- # @return [Query] A query which can evaluated for concatenation or result.
53
- def on(platforms = [])
54
- parse_agent(@agent) unless @platform
55
-
56
- ::Brauser::Query.new(self, platforms.blank? || platforms.ensure_array(nil, true, true, true, :to_sym).include?(@platform))
57
- end
58
-
59
- # Check if the browser accepts the specified languages.
60
- #
61
- # @param langs [String|Array] A list of languages to match against.
62
- # @return [Query] A query which can evaluated for concatenation or result.
63
- def accepts(langs = [])
64
- parse_accept_language(@accept_language) unless @languages
65
-
66
- ::Brauser::Query.new(self, (@languages & langs.ensure_array(nil, true, true, true, :to_s)).present?)
67
- end
68
-
69
- private
70
-
71
- # Adjusts names for correct matching.
72
- #
73
- # @param names [Array] A list of names.
74
- # @return [Array] The adjusted list of names.
75
- def adjust_names(names)
76
- # Adjust names
77
- names = names.ensure_array(nil, true, true, true, :to_sym)
78
- names << [:msie, :msie_compatibility] if names.include?(:ie) || names.include?(:msie)
79
- names << [:chromium] if names.include?(:chrome)
80
- names << [:chrome, :firefox, :safari, :opera, :msie] if names.include?(:capable)
81
- names << [:ipad, :android, :kindle] if names.include?(:tablet)
82
- names.flatten.compact.uniq
83
- end
84
-
85
- # Checks if the browser is capable.
86
- #
87
- # @param names [Array] A list of names.
88
- # @return [Boolean] `true` if the browser is capable, `false` otherwise.
89
- def check_capable(names)
90
- !names.include?(:capable) || @name != :msie || Brauser::Browser.compare_versions(@version, :gte, 9)
91
- end
92
-
93
- # Parses a version query.
94
- #
95
- # @param versions [String|Hash] A string in the form `operator version && ...` (example: `>= 7 && < 4`) or an hash with specific version to match
96
- # against, in form `{:operator => version}`, where operator is one of `:lt, :lte, :eq, :gt, :gte`.
97
- # @return [Hash] The hash representation of the query.
98
- def parse_versions_query(versions)
99
- versions.is_a?(::Hash) ? versions : versions.ensure_string.split(/\s*&&\s*/).reduce({}) do |prev, token|
100
- operator, version = parse_versions_query_component(token)
101
- prev[operator] = version if operator.present? && version.present?
102
- prev
103
- end
104
- end
105
-
106
- # Parses a token of a version query.
107
- #
108
- # @param token [String] The token to parse.
109
- # @return [Array] An operator and an argument.
110
- def parse_versions_query_component(token)
111
- operator, version = token.strip.split(/\s+/, 2).map(&:strip)
112
- [{"<" => :lt, "<=" => :lte, "=" => :eq, "==" => :eq, ">" => :gt, ">=" => :gte}.fetch(operator, nil), version]
113
- end
114
- end
115
- end
116
- end
@@ -1,63 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- # This file is part of the brauser gem. Copyright (C) 2013 and above Shogun <shogun@cowtech.it>.
4
- # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
- #
6
-
7
- module Brauser
8
- # The interface of brauser browsers.
9
- module Browseable
10
- # Methods to end querying.
11
- module Querying
12
- # Checks if the browser is a specific name and optionally of a specific version and platform.
13
- #
14
- # @see #v?
15
- # @see #on?
16
- #
17
- # @param names [Symbol|Array] A list of specific names to match. Also, this meta-names are supported: `:capable` and `:tablet`.
18
- # @param versions [Hash] An hash with specific version to match against. Need to be in form `{:operator => version}`, where operator
19
- # is one of `:lt, :lte, :eq, :gt, :gte`.
20
- # @param platforms [Symbol|Array] A list of specific platform to match. Valid values are all those possible for the platform attribute.
21
- # @return [Boolean] `true` if current browser matches, `false` otherwise.
22
- def is?(names = [], versions = {}, platforms = [])
23
- is(names, versions, platforms).result
24
- end
25
-
26
- # Checks if the browser is a specific version.
27
- #
28
- # @param versions [String|Hash] A string in the form `operator version && ...` (example: `>= 7 && < 4`) or an hash with specific version to match against,
29
- # in form `{:operator => version}`, where operator is one of `:lt, :lte, :eq, :gt, :gte`.
30
- # @return [Boolean] `true` if current browser matches, `false` otherwise.
31
- def version?(versions = {})
32
- version(versions).result
33
- end
34
- alias_method :v?, :version?
35
-
36
- # Check if the browser is on a specific platform.
37
- #
38
- # @param platforms [Symbol|Array] A list of specific platform to match.
39
- # @return [Boolean] `true` if current browser matches, `false` otherwise.
40
- def on?(platforms = [])
41
- on(platforms).result
42
- end
43
-
44
- # Check if the browser accepts the specified languages.
45
- #
46
- # @param langs [String|Array] A list of languages to match against.
47
- # @return [Boolean] `true` if current browser matches, `false` otherwise.
48
- def accepts?(langs = [])
49
- accepts(langs).result
50
- end
51
-
52
- # Check if the browser is supported.
53
- #
54
- # @param supported [Hash|String] A map of engines and minimum supported major version, or a path to YAML file containing the map.
55
- # @return [Boolean] `true` if current browser is supported, `false` otherwise.
56
- def supported?(supported)
57
- supported = YAML.load_file(supported).symbolize_keys if supported.is_a?(String)
58
- minimum = supported[name]
59
- (minimum && v?(gte: minimum)).to_boolean
60
- end
61
- end
62
- end
63
- end