css_compare 0.1.3 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7870883a1448bb39dcff1dcbb3eb4c6736999d07
4
- data.tar.gz: 1adfcdbfbf8ff6c45d5e6e682502f1b5377b06d2
3
+ metadata.gz: fca000673eaa0c61fd27e1183311064be28dedc7
4
+ data.tar.gz: 78a349c577139e8e94f866f46bb2f5bcbacde6d8
5
5
  SHA512:
6
- metadata.gz: 4ec908933d4cbc9fa6c51627cf940c7c15824f8768030b70c3580e4afae3b888c1e10c9a8466c9a87821dd3ad566fe7866f4973d045276dc43b56881d567fbb3
7
- data.tar.gz: be25bdc14bce1a42302c2b440422713727a84a036162133f22f81a50df0db44202ffe3993092fcc1d9cce2e968f39cda829bccde4dba26af92657ace679583e4
6
+ metadata.gz: 8943b8ac544e8e76b302f9c3cd03671d02f74676ae6fca0886d86c7772d9f3ef64695f2641d5f7e0de0ee8796c7725c8174ba714497794d13a320ae151de722d
7
+ data.tar.gz: 3b451d7188514141afd63dc1fedc135bf306a94c47cbfba45efb96eedc4d39627cb199eeb77cda4403712e10f0dd4dc69176923979ca972073a00d50f23c8b79
@@ -1,5 +1,5 @@
1
1
  module CssCompare
2
2
  # The root directory of the Less2Sass source tree.
3
3
  ROOT_DIR = File.expand_path(File.join(__FILE__, '../../..'))
4
- VERSION = '0.1.3'.freeze
4
+ VERSION = '0.2.0'.freeze
5
5
  end
@@ -1,3 +1,4 @@
1
+ require 'css_compare/css/value_factory'
1
2
  require 'css_compare/css/component'
2
3
  require 'css_compare/css/parser'
3
4
  require 'css_compare/css/engine'
@@ -11,10 +11,21 @@ module CssCompare
11
11
  # @param [Hash] that second hash to compare
12
12
  # @return [Boolean]
13
13
  def ==(this, that)
14
- keys = this.keys + that.keys
15
- keys.uniq!
14
+ keys = merge_keys(this, that)
16
15
  keys.all? { |key| this[key] && that[key] && this[key] == that[key] }
17
16
  end
17
+
18
+ def equals?(this, that)
19
+ keys = merge_keys(this, that)
20
+ keys.all? { |key| this[key] && that[key] && this[key].equals?(that[key]) }
21
+ end
22
+
23
+ private
24
+
25
+ def merge_keys(this, that)
26
+ keys = this.keys + that.keys
27
+ keys.uniq
28
+ end
18
29
  end
19
30
  end
20
31
  end
@@ -28,7 +28,7 @@ module CssCompare
28
28
  def initialize(node, conditions)
29
29
  @name = node.resolved_name
30
30
  @values = {}
31
- value = Value.new(node.resolved_value)
31
+ value = Value.new(node)
32
32
  conditions.each { |c| set_value(value.clone, c) }
33
33
  end
34
34
 
@@ -42,7 +42,8 @@ module CssCompare
42
42
  # with.
43
43
  # @return [Boolean]
44
44
  def ==(other)
45
- super(@values, other.values)
45
+ return super(@values, other.values) unless font?
46
+ equals?(@values, other.values)
46
47
  end
47
48
 
48
49
  # Merges the property with another one.
@@ -141,6 +142,10 @@ module CssCompare
141
142
  val.to_s.include?('!important')
142
143
  end
143
144
 
145
+ def font?
146
+ @name['font']
147
+ end
148
+
144
149
  # Breaks down complex properties like `border` into
145
150
  # smaller chunks (`border-width`, `border-style`, `border-color`)
146
151
  #
@@ -4,10 +4,10 @@ module CssCompare
4
4
  # Represents the value of a CSS property under
5
5
  # certain conditions declared by @media queries.
6
6
  class Value < Base
7
- # @return [#to_s]
7
+ # @return [CssCompare::CSS::Value::Base]
8
8
  attr_accessor :value
9
9
 
10
- # @param [#to_s] val the value of the property
10
+ # @param [Sass::Tree::PropNode] val the value of the property
11
11
  def initialize(val)
12
12
  self.value = val
13
13
  end
@@ -16,23 +16,25 @@ module CssCompare
16
16
  # Equal values mean, that the actual value and
17
17
  # the importance, as well, are set equally.
18
18
  #
19
- # @param [Value] other the value to compare this with
19
+ # @param [CssCompare::CSS::Value::Base] other the value to compare this with
20
20
  # @return [Boolean]
21
21
  def ==(other)
22
- @value.to_s == other.value.to_s
22
+ @value == other.value
23
+ end
24
+
25
+ def equals?(other)
26
+ @value.equals?(other.value)
23
27
  end
24
28
 
25
- # Sets the value and the importance of
26
- # the {Value} node.
27
- #
28
29
  # @private
29
- def value=(value)
30
- original_value = value = value.is_a?(Value) ? value.value : value
31
- # Can't do gsub! because the String gets frozen and can't be further modified by strip
32
- value = value.gsub(/\s*!important\s*/, '')
33
- @is_important = value != original_value
34
- value = sanitize_value(value) if value =~ CONTAIN_STRING
35
- @value = value
30
+ def value=(val)
31
+ if val.is_a?(self.class)
32
+ @is_important = val.important?
33
+ @value = val.value
34
+ else
35
+ @value = ValueFactory.create(val.value)
36
+ @is_important = @value.important?
37
+ end
36
38
  end
37
39
 
38
40
  # Tells, whether or not the value is marked as !important
@@ -44,34 +46,9 @@ module CssCompare
44
46
 
45
47
  # @return [String] the String representation of this node
46
48
  def to_s
47
- @value.to_s + (@is_important ? ' !important' : '')
48
- end
49
-
50
- private
51
-
52
- CONTAIN_STRING = /['"](.*)['"]/
53
-
54
- # Normalizes string values.
55
- #
56
- # We can assume, that a value describes a path
57
- # if following the removal of leading and trailing
58
- # quotes it begins with a `./`. It can be safely
59
- # removed without affecting the real value of
60
- # the CSS property.
61
- #
62
- # Examples:
63
- # "'path/to/file.css'" #=> "path/to/file.css"
64
- # ""\"path/to/file.css\""" #=> ""path/to/file.css""
65
- # "./path/to/file.css" #=> "path/to/file.css"
66
- #
67
- # @param [String] value the string to sanitize
68
- # @return [String] sanitized string
69
- def sanitize_value(value)
70
- value = value.sub(/\A['"](.*)['"]\Z/, '\1').gsub(/\\"|"|'/, '"') # Solves first two examples
71
- value = value.sub('./', '') if value.start_with?('url(') # Solves third if it's a url value
72
- value
49
+ @value.to_s
73
50
  end
74
51
  end
75
52
  end
76
53
  end
77
- end
54
+ end
@@ -54,6 +54,9 @@ module CssCompare
54
54
  attr_accessor :selectors, :keyframes, :namespaces,
55
55
  :pages, :supports, :charset
56
56
 
57
+ # @note UTF-8 is assumed as default charset
58
+ # @see https://www.w3.org/TR/CSS2/syndata.html#x52
59
+ #
57
60
  # @param [String, Sass::Tree::Node] input the source file of
58
61
  # the CSS project, or its AST
59
62
  def initialize(input)
@@ -76,7 +79,7 @@ module CssCompare
76
79
  @pages = {}
77
80
  @supports = {}
78
81
  @unsupported = []
79
- @charset
82
+ @charset = 'UTF-8'
80
83
  end
81
84
 
82
85
  # Checks, whether two engines are equal.
@@ -278,7 +281,7 @@ module CssCompare
278
281
  # a small change in the the selector's name.
279
282
  #
280
283
  # @param [Sass::Tree:RuleNode] node the Rule node
281
- # @param [Array<String>] parent_query_list processed parent_query_list of the
284
+ # @param [Array<String>] conditions processed parent_query_list of the
282
285
  # parent media node. If the rule is global, it will be assigned
283
286
  # to the media query equal to `@media all {}`.
284
287
  # @return [Void]
@@ -0,0 +1,84 @@
1
+ require 'color'
2
+
3
+ module CssCompare
4
+ module CSS
5
+ module Value
6
+ # The base class for wrapping the CSS property values
7
+ class Base
8
+ # @return [Sass::Script::Tree::Node]
9
+ attr_accessor :value
10
+
11
+ # @param [Sass::Script::Tree::Node] value the SassScript value to be wrapped
12
+ def initialize(value)
13
+ @value = value
14
+ end
15
+
16
+ # Checks, whether the CSS values are equal
17
+ #
18
+ # @return [Boolean]
19
+ def ==(other)
20
+ self.class == other.class
21
+ end
22
+
23
+ def equals?(other)
24
+ self == other
25
+ end
26
+
27
+ # Checks, whether the CSS values are flagged as !important.
28
+ #
29
+ # @return [Boolean]
30
+ def important?
31
+ @value.to_sass.include?('!important')
32
+ end
33
+
34
+ # Checks, whether the CSS value is a color. Subclasses may
35
+ # override this method.
36
+ #
37
+ # @return [Boolean]
38
+ def color?
39
+ false
40
+ end
41
+
42
+ # @return [String]
43
+ def to_s
44
+ @value.to_sass
45
+ end
46
+
47
+ protected
48
+
49
+ # Normalizes the quoted string values.
50
+ #
51
+ # @param [String] value the string to sanitize
52
+ # @return [String] sanitized string
53
+ def sanitize_string(value)
54
+ value.sub(/\A['"](.*)['"]\Z/, '\1').gsub(/\\"|"|'/, '"')
55
+ end
56
+
57
+ def sanitize_font(value)
58
+ value.gsub(/\\"|"|'/, '')
59
+ end
60
+
61
+ # Normalizes the url paths.
62
+ #
63
+ # We can assume, that a value describes a path
64
+ # if following the removal of leading and trailing
65
+ # quotes it begins with a `./`. It can be safely
66
+ # removed without affecting the real value of
67
+ # the CSS property.
68
+ #
69
+ # Examples:
70
+ # "'path/to/file.css'" #=> "path/to/file.css"
71
+ # ""\"path/to/file.css\""" #=> ""path/to/file.css""
72
+ # "./path/to/file.css" #=> "path/to/file.css"
73
+ #
74
+ # @param [String] value the url path to normalize
75
+ # @return [String] the normalized path
76
+ def sanitize_url(value)
77
+ value = sanitize_string(value)
78
+ value = value.sub('./', '') if value.start_with?('./')
79
+ value
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,65 @@
1
+ module CssCompare
2
+ module CSS
3
+ module Value
4
+ # Wraps the SassScript Funcall object
5
+ class Function < Base
6
+
7
+ # Checks, whether two function expressions are equal.
8
+ #
9
+ # @param [Function] other the other function expression
10
+ # @return [Boolean]
11
+ def ==(other)
12
+ if color?
13
+ return false unless other.color?
14
+ ::Color.equivalent?(color, other.color)
15
+ else
16
+ return false unless super
17
+ arg1 = @value.args.length
18
+ arg2 = other.value.args.length
19
+ return false unless arg1 == arg2
20
+ args1 = @value.args.collect { |x| ValueFactory.create(x) }
21
+ args2 = other.value.args.collect { |x| ValueFactory.create(x) }
22
+ args1.each_index { |i| args1[i] == args2[i] }
23
+ end
24
+ end
25
+
26
+ # @see Base#color?
27
+ def color?
28
+ rgb? || hsl?
29
+ end
30
+
31
+ def color
32
+ raise StandardError, 'Function not a color' unless color?
33
+ args = @value.args.collect { |x| x.value.value }
34
+ if rgb?
35
+ ::Color::RGB.new(args[0], args[1], args[2])
36
+ elsif hsl?
37
+ ::Color::HSL.new(args[0], args[1], args[2])
38
+ end
39
+ end
40
+
41
+ def alpha?
42
+ @value.args.length == 4
43
+ end
44
+
45
+ def alpha
46
+ return @value.args[3] if alpha?
47
+ false
48
+ end
49
+
50
+ private
51
+
52
+ RGB_COLOR_FUNCTIONS = %w(rgb rgba)
53
+ HSL_COLOR_FUNCTIONS = %w(hsl hsla)
54
+
55
+ def rgb?
56
+ RGB_COLOR_FUNCTIONS.include?(@value.name)
57
+ end
58
+
59
+ def hsl?
60
+ HSL_COLOR_FUNCTIONS.include?(@value.name)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,26 @@
1
+ module CssCompare
2
+ module CSS
3
+ module Value
4
+ # Wraps the SassScript ListLiteral object.
5
+ class ListLiteral < Base
6
+
7
+ # Checks, whether two list literals are equal.
8
+ #
9
+ # @param [ListLiteral] other the other list literal
10
+ # @return [Boolean]
11
+ def ==(other)
12
+ return false unless super
13
+ elements1 = @value.elements.length
14
+ elements2 = other.value.elements.length
15
+ return false unless elements1 == elements2
16
+ @value.elements.each_index do |i|
17
+ value1 = sanitize_string(@value.elements[i].to_sass)
18
+ value2 = sanitize_string(other.value.elements[i].to_sass)
19
+ return false unless value1 == value2
20
+ end
21
+ true
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,58 @@
1
+ module CssCompare
2
+ module CSS
3
+ module Value
4
+ # Wraps the SassScript Literal object.
5
+ class Literal < Base
6
+
7
+ # Checks, whether two literals are equal.
8
+ #
9
+ # @param [Literal] other the other literal
10
+ # @return [Boolean]
11
+ def ==(other)
12
+ if color?
13
+ return false unless other.color?
14
+ ::Color.equivalent?(color, other.color)
15
+ else
16
+ return false unless super
17
+ value1 = sanitize_string(@value.to_sass)
18
+ value2 = sanitize_string(other.value.to_sass)
19
+ value1 == value2
20
+ end
21
+ end
22
+
23
+ def equals?(other)
24
+ value1 = sanitize_font(@value.to_sass)
25
+ value2 = sanitize_font(other.value.to_sass)
26
+ value1 == value2
27
+ end
28
+
29
+ def color?
30
+ named_color? || hex_color?
31
+ end
32
+
33
+ def color
34
+ return nil unless color?
35
+ hex_color? ? hex_color : named_color
36
+ end
37
+
38
+ private
39
+
40
+ HEX_COLOR_LITERAL = /^#(?:[a-f0-9]{3}){1,2}$/i
41
+
42
+ def named_color?
43
+ ::Color::CSS[@value.to_sass]
44
+ end
45
+
46
+ alias_method :named_color, :named_color?
47
+
48
+ def hex_color?
49
+ @value.to_sass =~ HEX_COLOR_LITERAL
50
+ end
51
+
52
+ def hex_color
53
+ ::Color::RGB.by_hex(@value.to_sass)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,20 @@
1
+ module CssCompare
2
+ module CSS
3
+ module Value
4
+ # Wraps the SassScript `url` Funcall.
5
+ class Url < Base
6
+
7
+ # Checks, whether two url calls are equal.
8
+ #
9
+ # @param [Url] other the other url call
10
+ # @return [Boolean]
11
+ def ==(other)
12
+ return false unless super
13
+ value1 = sanitize_url(@value.args[0].value.value)
14
+ value2 = sanitize_url(other.value.args[0].value.value)
15
+ value1 == value2
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,29 @@
1
+ require 'css_compare/css/value/base'
2
+ require 'css_compare/css/value/literal'
3
+ require 'css_compare/css/value/list_literal'
4
+ require 'css_compare/css/value/function'
5
+ require 'css_compare/css/value/url'
6
+
7
+ module CssCompare
8
+ module CSS
9
+ module ValueFactory
10
+
11
+ # Creates the value object by applying the appropriate wrapper class.
12
+ #
13
+ # @param [Sass::Script::Tree::Node] value the CSS property's value
14
+ # @return [CssCompare::CSS::Value::Base] the wrapped property value
15
+ def self.create(value)
16
+ if value.is_a?(Sass::Script::Tree::Literal)
17
+ Value::Literal.new(value)
18
+ elsif value.is_a?(Sass::Script::Tree::ListLiteral)
19
+ Value::ListLiteral.new(value)
20
+ elsif value.is_a?(Sass::Script::Tree::Funcall)
21
+ return Value::Function.new(value) unless value.name == 'url'
22
+ Value::Url.new(value)
23
+ else
24
+ raise StandardError, 'Unsupported type of CSS value'
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: css_compare
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Attila Večerek
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-21 00:00:00.000000000 Z
11
+ date: 2016-05-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sass
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: color
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.8'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.8'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -82,6 +96,12 @@ files:
82
96
  - lib/css_compare/css/component/value.rb
83
97
  - lib/css_compare/css/engine.rb
84
98
  - lib/css_compare/css/parser.rb
99
+ - lib/css_compare/css/value/base.rb
100
+ - lib/css_compare/css/value/function.rb
101
+ - lib/css_compare/css/value/list_literal.rb
102
+ - lib/css_compare/css/value/literal.rb
103
+ - lib/css_compare/css/value/url.rb
104
+ - lib/css_compare/css/value_factory.rb
85
105
  - lib/css_compare/engine.rb
86
106
  - lib/css_compare/exec.rb
87
107
  - lib/css_compare/util.rb