brauser 3.3.2 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
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