csspool 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.DS_Store +0 -0
  2. data/CHANGELOG.txt +10 -0
  3. data/Manifest.txt +36 -2
  4. data/README.txt +4 -4
  5. data/Rakefile +1 -1
  6. data/lib/css/sac/conditions/attribute_condition.rb +52 -0
  7. data/lib/css/sac/conditions/begin_hyphen_condition.rb +22 -0
  8. data/lib/css/sac/conditions/class_condition.rb +22 -0
  9. data/lib/css/sac/conditions/combinator_condition.rb +36 -0
  10. data/lib/css/sac/conditions/condition.rb +27 -0
  11. data/lib/css/sac/conditions/id_condition.rb +27 -0
  12. data/lib/css/sac/conditions/one_of_condition.rb +22 -0
  13. data/lib/css/sac/conditions/pseudo_class_condition.rb +24 -0
  14. data/lib/css/sac/conditions.rb +5 -0
  15. data/lib/css/sac/document_handler.rb +1 -1
  16. data/lib/css/sac/parser.rb +5 -3
  17. data/lib/css/sac/selectors/child_selector.rb +36 -0
  18. data/lib/css/sac/selectors/conditional_selector.rb +43 -0
  19. data/lib/css/sac/selectors/descendant_selector.rb +36 -0
  20. data/lib/css/sac/selectors/element_selector.rb +35 -0
  21. data/lib/css/sac/selectors/selector.rb +23 -0
  22. data/lib/css/sac/selectors/sibling_selector.rb +35 -0
  23. data/lib/css/sac/selectors/simple_selector.rb +25 -0
  24. data/lib/css/sac/selectors.rb +3 -85
  25. data/lib/css/sac/visitable.rb +104 -0
  26. data/lib/parser.y +24 -15
  27. data/test/condition_test_case.rb +6 -0
  28. data/test/helper.rb +2 -0
  29. data/test/selector_test_case.rb +20 -0
  30. data/test/test_attribute_condition.rb +30 -0
  31. data/test/test_begin_hyphen_condition.rb +15 -0
  32. data/test/test_child_selector.rb +48 -0
  33. data/test/test_class_condition.rb +15 -0
  34. data/test/test_combinator_condition.rb +29 -0
  35. data/test/test_condition.rb +13 -0
  36. data/test/test_conditional_selector.rb +29 -0
  37. data/test/test_descendant_selector.rb +52 -0
  38. data/test/test_element_selector.rb +22 -0
  39. data/test/test_id_condition.rb +16 -0
  40. data/test/test_one_of_condition.rb +15 -0
  41. data/test/test_parser.rb +58 -0
  42. data/test/test_selector.rb +19 -0
  43. data/test/test_selector_as_string.rb +11 -0
  44. data/test/test_selector_parser.rb +2 -2
  45. data/test/test_sibling_selector.rb +33 -0
  46. data/test/test_simple_selector.rb +9 -0
  47. data/test/test_specificity.rb +76 -0
  48. data/test/test_xpath.rb +105 -0
  49. metadata +38 -4
  50. data/lib/css/sac/attribute_condition.rb +0 -78
  51. data/lib/css/sac/condition.rb +0 -21
@@ -0,0 +1,19 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class SelectorTest < SelectorTestCase
4
+ class MySelector < Selector; end
5
+
6
+ def test_equals2
7
+ first = Selector.new(1)
8
+ second = Selector.new(1)
9
+ assert_equal first, second
10
+
11
+
12
+ third = Selector.new(2)
13
+ assert_not_equal first, third
14
+
15
+ fourth = MySelector.new(1)
16
+ assert_equal first, fourth
17
+ assert_not_equal first, 1
18
+ end
19
+ end
@@ -11,6 +11,17 @@ class SelectorAsStringTest < Test::Unit::TestCase
11
11
  end
12
12
  end
13
13
 
14
+ def test_equal2
15
+ @sac.parse('h1 > h2 { }')
16
+ selectors = @sac.document_handler.selectors
17
+ @sac.document_handler.selectors = []
18
+
19
+ @sac.parse('h1 > h2 { }')
20
+ selectors2 = @sac.document_handler.selectors
21
+
22
+ assert_equal selectors, selectors2
23
+ end
24
+
14
25
  def test_any_node_selector
15
26
  @sac.parse('* { }')
16
27
  selectors = @sac.document_handler.selectors
@@ -71,7 +71,7 @@ class SelectorParserTest < Test::Unit::TestCase
71
71
  @@single_selector_tests = {
72
72
  :id => {
73
73
  :css => '#foo { }',
74
- :value => '#foo',
74
+ :value => 'foo',
75
75
  :type => :SAC_ID_CONDITION,
76
76
  },
77
77
  :class => {
@@ -94,7 +94,7 @@ class SelectorParserTest < Test::Unit::TestCase
94
94
  @@multiple_selector_tests = {
95
95
  :ids => {
96
96
  :css => '#foo#bar#baz { }',
97
- :values => %w{ #foo #bar #baz },
97
+ :values => %w{ foo bar baz },
98
98
  :types => [:SAC_ID_CONDITION] * 3,
99
99
  },
100
100
  :classes => {
@@ -0,0 +1,33 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class SiblingSelectorTest < SelectorTestCase
4
+ def test_equals2
5
+ first = SiblingSelector.new(1,1)
6
+ second = SiblingSelector.new(1,1)
7
+ assert_equal first, second
8
+
9
+ third = SiblingSelector.new(1,2)
10
+ assert_not_equal first, third
11
+
12
+ fourth = SiblingSelector.new(2,1)
13
+ assert_not_equal first, fourth
14
+ end
15
+
16
+ def test_equals_tilde
17
+ selector = ElementSelector.new('div')
18
+ sibling = ElementSelector.new('p')
19
+ sel = SiblingSelector.new(selector, sibling)
20
+
21
+ sibling = Node.new('p', nil, nil, nil)
22
+ node = Node.new('div', nil, nil, sibling)
23
+ assert sel =~ node
24
+
25
+ sibling1 = Node.new('div', nil, nil, nil)
26
+ node1 = Node.new('p', nil, nil, sibling)
27
+ assert(! (sel =~ node1))
28
+
29
+ assert(! (sel =~ NoParentNode.new('div')))
30
+ assert(! (sel =~ Node.new('div', nil, nil)))
31
+ end
32
+ end
33
+
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class SimpleSelectorTest < SelectorTestCase
4
+ def test_equals_tilde
5
+ sel = SimpleSelector.new
6
+ assert(! (sel =~ nil))
7
+ assert(sel =~ Node.new)
8
+ end
9
+ end
@@ -0,0 +1,76 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ # http://www.w3.org/TR/REC-CSS2/cascade.html#specificity
4
+ # * {} /* a=0 b=0 c=0 -> specificity = 0 */
5
+ # LI {} /* a=0 b=0 c=1 -> specificity = 1 */
6
+ # UL LI {} /* a=0 b=0 c=2 -> specificity = 2 */
7
+ # UL OL+LI {} /* a=0 b=0 c=3 -> specificity = 3 */
8
+ # H1 + *[REL=up]{} /* a=0 b=1 c=1 -> specificity = 11 */
9
+ # UL OL LI.red {} /* a=0 b=1 c=3 -> specificity = 13 */
10
+ # LI.red.level {} /* a=0 b=2 c=1 -> specificity = 21 */
11
+ # #x34y {} /* a=1 b=0 c=0 -> specificity = 100 */
12
+ class SpecificityTest < Test::Unit::TestCase
13
+ def setup
14
+ @sac = CSS::SAC::Parser.new()
15
+ class << @sac.document_handler
16
+ attr_accessor :selectors
17
+ alias :start_selector :selectors=
18
+ end
19
+ end
20
+
21
+ def test_star
22
+ @sac.parse('* {}')
23
+ selector = @sac.document_handler.selectors.first
24
+ assert_not_nil selector
25
+ assert_equal 0, selector.specificity
26
+ end
27
+
28
+ def test_li
29
+ @sac.parse('li {}')
30
+ selector = @sac.document_handler.selectors.first
31
+ assert_not_nil selector
32
+ assert_equal 1, selector.specificity
33
+ end
34
+
35
+ def test_ul_li
36
+ @sac.parse('ul li {}')
37
+ selector = @sac.document_handler.selectors.first
38
+ assert_not_nil selector
39
+ assert_equal 2, selector.specificity
40
+ end
41
+
42
+ def test_ul_ol_plus_li
43
+ @sac.parse('ul ol+li {}')
44
+ selector = @sac.document_handler.selectors.first
45
+ assert_not_nil selector
46
+ assert_equal 3, selector.specificity
47
+ end
48
+
49
+ def test_h1_attributes
50
+ @sac.parse('h1 + *[REL=up] {}')
51
+ selector = @sac.document_handler.selectors.first
52
+ assert_not_nil selector
53
+ assert_equal 11, selector.specificity
54
+ end
55
+
56
+ def test_one_class_selector
57
+ @sac.parse('ul ol li.red {}')
58
+ selector = @sac.document_handler.selectors.first
59
+ assert_not_nil selector
60
+ assert_equal 13, selector.specificity
61
+ end
62
+
63
+ def test_two_class_selectors
64
+ @sac.parse('li.red.level {}')
65
+ selector = @sac.document_handler.selectors.first
66
+ assert_not_nil selector
67
+ assert_equal 21, selector.specificity
68
+ end
69
+
70
+ def test_id_selector
71
+ @sac.parse('#x34y {}')
72
+ selector = @sac.document_handler.selectors.first
73
+ assert_not_nil selector
74
+ assert_equal 100, selector.specificity
75
+ end
76
+ end
@@ -0,0 +1,105 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ # Thanks, Joe!
4
+ # http://www.joehewitt.com/blog/files/getElementsBySelector.js
5
+
6
+ class XPathTest < Test::Unit::TestCase
7
+ def setup
8
+ @parser = CSS::SAC::Parser.new()
9
+ class << @parser.document_handler
10
+ attr_accessor :selectors
11
+ def start_selector(selectors)
12
+ @selectors = selectors
13
+ end
14
+ end
15
+ end
16
+
17
+ # TODO: looks like attribute value quoting
18
+ # might be broken on the css side?
19
+ # this: input[type="text"] should be valid CSS
20
+ # and probably not return the quotes in the node
21
+
22
+ def test_any
23
+ assert_xpath("//*", "*")
24
+ end
25
+
26
+ def test_element
27
+ assert_xpath("//h1", "h1")
28
+ end
29
+
30
+ def test_id
31
+ assert_xpath("//*[@id='foo']", "#foo")
32
+ end
33
+
34
+ def test_class
35
+ assert_xpath("//*[contains(@class, 'foo')]", ".foo")
36
+ end
37
+
38
+ def test_attribute_with_no_value
39
+ assert_xpath("//*[@checked]", "[checked]")
40
+ end
41
+
42
+ def test_attribute_with_value
43
+ assert_xpath("//*[@type='text']", "[type=text]")
44
+ end
45
+
46
+ def test_hyphen_separated_attribute
47
+ # the contains behavior is probably fine here
48
+ assert_xpath("//*[contains(@type, 'text')]", "[type~=text]")
49
+ end
50
+
51
+ def test_space_separated_attribute
52
+ # the contains behavior is probably fine here
53
+ assert_xpath("//*[contains(@type, 'text')]", "[type|=text]")
54
+ end
55
+
56
+ def test_element_with_id
57
+ assert_xpath("//h1[@id='monkey']", "h1#monkey")
58
+ end
59
+
60
+ def test_element_with_class
61
+ assert_xpath("//h1[contains(@class, 'foo')]", "h1.foo")
62
+ end
63
+
64
+ def test_element_with_id_and_class
65
+ assert_xpath("//h1[@id='monkey'][contains(@class, 'foo')]", "h1#monkey.foo")
66
+ end
67
+
68
+ def test_element_with_multiple_classes
69
+ assert_xpath("//h1[contains(@class, 'foo')][contains(@class, 'bar')]", "h1.foo.bar")
70
+ end
71
+
72
+ def test_descendant
73
+ assert_xpath("//div//p", "div p")
74
+ assert_xpath("//div//*[contains(@class, 'angry')]", "div .angry")
75
+ end
76
+
77
+ def test_direct_descendant
78
+ assert_xpath("//div/p", "div > p")
79
+ end
80
+
81
+ def test_sibling
82
+ assert_xpath("//div/following-sibling::p", "div + p")
83
+ end
84
+
85
+ def test_safely_ignores_pseudoclasses
86
+ assert_xpath("//a", "a:hover")
87
+ end
88
+
89
+ private
90
+
91
+ def assert_xpath(xpath, css)
92
+ assert_equal(xpath, selector_for(css).to_xpath)
93
+ end
94
+
95
+ def selector_for(string)
96
+ selectors = selectors_for(string)
97
+ assert_equal(1, selectors.length)
98
+ selectors.first
99
+ end
100
+
101
+ def selectors_for(string)
102
+ @parser.parse("#{string} {}")
103
+ @parser.document_handler.selectors
104
+ end
105
+ end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: csspool
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.0
7
- date: 2007-11-02 00:00:00 -07:00
6
+ version: 0.1.1
7
+ date: 2007-11-17 00:00:00 -08:00
8
8
  summary: Parses CSS
9
9
  require_paths:
10
10
  - lib
@@ -29,13 +29,21 @@ post_install_message:
29
29
  authors:
30
30
  - Aaron Patterson
31
31
  files:
32
+ - .DS_Store
32
33
  - CHANGELOG.txt
33
34
  - Manifest.txt
34
35
  - README.txt
35
36
  - Rakefile
36
37
  - lib/css/sac.rb
37
- - lib/css/sac/attribute_condition.rb
38
- - lib/css/sac/condition.rb
38
+ - lib/css/sac/conditions.rb
39
+ - lib/css/sac/conditions/attribute_condition.rb
40
+ - lib/css/sac/conditions/begin_hyphen_condition.rb
41
+ - lib/css/sac/conditions/class_condition.rb
42
+ - lib/css/sac/conditions/combinator_condition.rb
43
+ - lib/css/sac/conditions/condition.rb
44
+ - lib/css/sac/conditions/id_condition.rb
45
+ - lib/css/sac/conditions/one_of_condition.rb
46
+ - lib/css/sac/conditions/pseudo_class_condition.rb
39
47
  - lib/css/sac/document_handler.rb
40
48
  - lib/css/sac/error_handler.rb
41
49
  - lib/css/sac/generated_property_parser.rb
@@ -45,22 +53,48 @@ files:
45
53
  - lib/css/sac/parser.rb
46
54
  - lib/css/sac/property_parser.rb
47
55
  - lib/css/sac/selectors.rb
56
+ - lib/css/sac/selectors/child_selector.rb
57
+ - lib/css/sac/selectors/conditional_selector.rb
58
+ - lib/css/sac/selectors/descendant_selector.rb
59
+ - lib/css/sac/selectors/element_selector.rb
60
+ - lib/css/sac/selectors/selector.rb
61
+ - lib/css/sac/selectors/sibling_selector.rb
62
+ - lib/css/sac/selectors/simple_selector.rb
48
63
  - lib/css/sac/token.rb
49
64
  - lib/css/sac/tokenizer.rb
65
+ - lib/css/sac/visitable.rb
50
66
  - lib/parser.y
51
67
  - lib/property_parser.y
52
68
  - lib/property_parser.y.erb
69
+ - test/condition_test_case.rb
53
70
  - test/helper.rb
71
+ - test/selector_test_case.rb
54
72
  - test/test_all.rb
73
+ - test/test_attribute_condition.rb
74
+ - test/test_begin_hyphen_condition.rb
75
+ - test/test_child_selector.rb
76
+ - test/test_class_condition.rb
77
+ - test/test_combinator_condition.rb
78
+ - test/test_condition.rb
79
+ - test/test_conditional_selector.rb
80
+ - test/test_descendant_selector.rb
81
+ - test/test_element_selector.rb
82
+ - test/test_id_condition.rb
55
83
  - test/test_lexeme.rb
56
84
  - test/test_lexical_unit.rb
85
+ - test/test_one_of_condition.rb
57
86
  - test/test_parse_error.rb
58
87
  - test/test_parser.rb
59
88
  - test/test_property_parser.rb
89
+ - test/test_selector.rb
60
90
  - test/test_selector_as_string.rb
61
91
  - test/test_selector_parser.rb
92
+ - test/test_sibling_selector.rb
93
+ - test/test_simple_selector.rb
94
+ - test/test_specificity.rb
62
95
  - test/test_token.rb
63
96
  - test/test_tokenizer.rb
97
+ - test/test_xpath.rb
64
98
  test_files:
65
99
  - test/test_all.rb
66
100
  rdoc_options:
@@ -1,78 +0,0 @@
1
- module CSS
2
- module SAC
3
- class AttributeCondition < Condition
4
- attr_accessor :local_name, :value, :specified
5
- alias :specified? :specified
6
-
7
- class << self
8
- def pseudo_class_condition(pseudo_class)
9
- self.new do |condition|
10
- condition.condition_type = :SAC_PSEUDO_CLASS_CONDITION
11
- condition.value = pseudo_class
12
- end
13
- end
14
-
15
- def attribute_id(id_value)
16
- self.new do |condition|
17
- condition.condition_type = :SAC_ID_CONDITION
18
- condition.specified = true
19
- condition.value = id_value
20
- end
21
- end
22
-
23
- def class_condition(class_name)
24
- self.new do |condition|
25
- condition.condition_type = :SAC_CLASS_CONDITION
26
- condition.specified = true
27
- condition.value = class_name
28
- end
29
- end
30
-
31
- def attribute_condition(attribute, conditions)
32
- self.new do |condition|
33
- if attribute
34
- condition.condition_type = :SAC_ATTRIBUTE_CONDITION
35
- condition.local_name = attribute
36
- end
37
-
38
- if conditions
39
- condition.condition_type =
40
- case conditions.first
41
- when '~='
42
- :SAC_ONE_OF_ATTRIBUTE_CONDITION
43
- when '|='
44
- :SAC_BEGIN_HYPHEN_ATTRIBUTE_CONDITION
45
- when '='
46
- :SAC_ATTRIBUTE_CONDITION
47
- end
48
- condition.value = conditions.last
49
- condition.specified = true
50
- end
51
- end
52
- end
53
- end
54
-
55
- def initialize(attribute = nil, conditions = nil)
56
- @specified = false
57
- @local_name = nil
58
- @value = nil
59
- yield self if block_given?
60
- end
61
-
62
- def to_css
63
- case condition_type
64
- when :SAC_ONE_OF_ATTRIBUTE_CONDITION
65
- "[#{local_name}~=#{value}]"
66
- when :SAC_BEGIN_HYPHEN_ATTRIBUTE_CONDITION
67
- "[#{local_name}|=#{value}]"
68
- when :SAC_ATTRIBUTE_CONDITION
69
- "[#{local_name}=#{value}]"
70
- when :SAC_CLASS_CONDITION
71
- ".#{value}"
72
- when :SAC_ID_CONDITION
73
- "#{value}"
74
- end
75
- end
76
- end
77
- end
78
- end
@@ -1,21 +0,0 @@
1
- module CSS
2
- module SAC
3
- class Condition
4
- attr_accessor :condition_type
5
- end
6
-
7
- class CombinatorCondition < Condition
8
- attr_accessor :first_condition, :second_condition
9
-
10
- def initialize(first, second, type = :SAC_AND_CONDITION)
11
- @first_condition = first
12
- @second_condition = second
13
- @condition_type = type
14
- end
15
-
16
- def to_css
17
- "#{first_condition.to_css}#{second_condition.to_css}"
18
- end
19
- end
20
- end
21
- end