css_compare 0.1.3 → 0.2.0

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