rxhp 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,9 +2,6 @@ require 'rxhp/error'
2
2
 
3
3
  module Rxhp
4
4
  module AttributeValidator
5
- class ValidationError < Rxhp::ScriptError
6
- end
7
-
8
5
  class UnacceptableAttributeError < ValidationError
9
6
  attr_reader :element, :attribute, :value
10
7
  def initialize element, attribute, value
@@ -63,17 +60,41 @@ module Rxhp
63
60
  matcher.any? { |x| match? x, name, value }
64
61
  when Hash
65
62
  matcher.any? do |name_matcher, value_matcher|
66
- name_match = match?(name_matcher, name, nil)
67
- value_match = match?(value_matcher, value, nil)
68
- name_match && value_match
63
+ name_match = match_value?(name_matcher, name_from_symbol(name))
64
+ if name_match
65
+ match_value?(value_matcher, value)
66
+ else
67
+ false
68
+ end
69
69
  end
70
+ else
71
+ match_value? matcher, name
72
+ end
73
+ end
74
+
75
+ def self.match_value? matcher, value
76
+ if matcher == String
77
+ return (value.is_a? String) || (value.is_a? Symbol)
78
+ end
79
+
80
+ case matcher
81
+ when Array
82
+ matcher.any? {|x| match_value?(x, value) }
70
83
  when Symbol
71
- matcher.to_s.gsub('_', '-') == name
84
+ name_from_symbol(matcher) == value
72
85
  else
73
- matcher === name
86
+ if value.is_a? Symbol
87
+ (matcher === value.to_s) || (matcher === name_from_symbol(value))
88
+ else
89
+ matcher === value
90
+ end
74
91
  end
75
92
  end
76
93
 
94
+ def self.name_from_symbol symbol
95
+ symbol.to_s.gsub('_', '-')
96
+ end
97
+
77
98
  def self.included(klass)
78
99
  klass.extend(ClassMethods)
79
100
  class << klass
@@ -90,7 +111,7 @@ module Rxhp
90
111
  alias :require_attribute :require_attributes
91
112
 
92
113
  def accept_all_attributes
93
- attribute_matches.push Object
114
+ accept_attributes Object
94
115
  end
95
116
  end
96
117
 
@@ -12,8 +12,8 @@ module Rxhp
12
12
  class ComposableElement < Rxhp::Element
13
13
  include Rxhp::AttributeValidator
14
14
 
15
- def initialize *args
16
- super *args
15
+ def validate!
16
+ super
17
17
  validate_attributes!
18
18
  end
19
19
 
@@ -23,7 +23,7 @@ module Rxhp
23
23
  # This calls compose, provides the 'yield' magic, and callls render on
24
24
  # the output.
25
25
  def render options = {}
26
- validate_attributes!
26
+ validate!
27
27
  self.compose do
28
28
  # Allow 'yield' to embed all children
29
29
  self.children.each do |child|
data/lib/rxhp/element.rb CHANGED
@@ -14,12 +14,26 @@ module Rxhp
14
14
  def initialize attributes = {}
15
15
  @attributes = attributes
16
16
  @children = Array.new
17
+ validate!
17
18
  end
18
19
 
19
20
  def children?
20
21
  !children.empty?
21
22
  end
22
23
 
24
+ def valid?
25
+ begin
26
+ validate!
27
+ true
28
+ rescue Rxhp::ValidationError
29
+ false
30
+ end
31
+ end
32
+
33
+ def validate!
34
+ # no-op
35
+ end
36
+
23
37
  # Return a flat HTML string for this element and all its' decendants.
24
38
  #
25
39
  # You probably don't want to implement this yourself - interesting
@@ -41,18 +55,7 @@ module Rxhp
41
55
  def render_children options = {}
42
56
  return if children.empty?
43
57
 
44
- out = String.new
45
- children.each do |child|
46
- case child
47
- when Element
48
- out += child.render(options)
49
- when String
50
- out += self.render_string(child, options)
51
- else
52
- out += self.render_string(child.to_s, options)
53
- end
54
- end
55
- out
58
+ flattened_children.map{ |child| render_child(child, options) }.join
56
59
  end
57
60
 
58
61
  # Fill default options
@@ -66,5 +69,44 @@ module Rxhp
66
69
  :indent => 2,
67
70
  }.merge(options)
68
71
  end
72
+
73
+ private
74
+
75
+ def render_child child, options
76
+ case child
77
+ when Element
78
+ child.render(options)
79
+ when String
80
+ self.render_string(child, options)
81
+ when Enumerable
82
+ child.map{ |grandchild| render_child(grandchild, options) }.join
83
+ else
84
+ self.render_string(child.to_s, options)
85
+ end
86
+ end
87
+
88
+ def flattened_children
89
+ no_frags = []
90
+ children.each do |node|
91
+ if node.is_a? Rxhp::Fragment
92
+ no_frags += node.children
93
+ else
94
+ no_frags.push node
95
+ end
96
+ end
97
+
98
+ previous = nil
99
+ no_consecutive_strings = []
100
+ no_frags.each do |node|
101
+ if node.is_a?(String) && previous.is_a?(String)
102
+ previous << node
103
+ else
104
+ no_consecutive_strings.push node
105
+ previous = node
106
+ end
107
+ end
108
+
109
+ no_consecutive_strings
110
+ end
69
111
  end
70
112
  end
data/lib/rxhp/error.rb CHANGED
@@ -4,4 +4,7 @@ module Rxhp
4
4
 
5
5
  class ScriptError < ::ScriptError
6
6
  end
7
+
8
+ class ValidationError < Rxhp::ScriptError
9
+ end
7
10
  end
data/lib/rxhp/html.rb CHANGED
@@ -11,7 +11,9 @@ module Rxhp
11
11
 
12
12
  class <<self
13
13
  def fragment x
14
- Rxhp::Scope.current.children.push x
14
+ scope = Rxhp::Scope.current
15
+ scope.children.push x
16
+ scope
15
17
  end
16
18
  alias :frag :fragment
17
19
  alias :text :fragment
@@ -30,21 +30,21 @@ module Rxhp
30
30
  accept_attributes Rxhp::Html::GLOBAL_ATTRIBUTES
31
31
  accept_attributes Rxhp::Html::GLOBAL_EVENT_HANDLERS
32
32
 
33
- def initialize *args
34
- super *args
35
- validate_attributes!
36
- end
37
-
38
33
  def tag_name
39
34
  raise NotImplementedError.new
40
35
  end
41
36
 
37
+ def validate!
38
+ super
39
+ validate_attributes!
40
+ end
41
+
42
42
  # Render the element.
43
43
  #
44
44
  # Pays attention to the formatter type, doctype, pretty print options,
45
45
  # etc.
46
46
  def render options = {}
47
- validate_attributes!
47
+ validate!
48
48
  options = fill_options(options)
49
49
 
50
50
  open = render_open_tag(options)
@@ -53,14 +53,15 @@ module Rxhp
53
53
 
54
54
  if options[:pretty]
55
55
  indent = ' ' * (options[:indent] * options[:depth])
56
- out = "%s%s\n" % [indent, open]
57
- out += inner if inner
58
- out += "%s%s\n" % [indent, close] if close && !close.empty?
56
+ out = indent.dup
57
+ out << open << "\n"
58
+ out << inner if inner
59
+ out << indent << close << "\n" if close && !close.empty?
59
60
  out
60
61
  else
61
62
  out = open
62
- out += inner if inner
63
- out += close if close
63
+ out << inner if inner
64
+ out << close if close
64
65
  out
65
66
  end
66
67
  end
@@ -98,17 +99,20 @@ module Rxhp
98
99
  out = '<' + tag_name
99
100
  unless attributes.empty?
100
101
  attributes.each do |name,value|
102
+ name = name.to_s.gsub('_', '-') if name.is_a? Symbol
103
+ value = value.to_s.gsub('_', '-') if value.is_a? Symbol
104
+
101
105
  case value
102
106
  when false
103
107
  next
104
108
  when true
105
109
  if options[:format] == Rxhp::XHTML_FORMAT
106
- out += ' ' + name.to_s + '="' + name.to_s + '"'
110
+ out += ' ' + name + '="' + name + '"'
107
111
  else
108
112
  out += ' ' + name
109
113
  end
110
114
  else
111
- out += ' ' + name.to_s + '="' + html_escape(value.to_s) + '"'
115
+ out += ' ' + name.to_s + '="' + html_escape(value) + '"'
112
116
  end
113
117
  end
114
118
  end
@@ -11,11 +11,12 @@ module Rxhp
11
11
  # - people don't expect to see them
12
12
  # - in XHTML, the opening tag will have been self closing.
13
13
  class HtmlSingletonElement < HtmlElement
14
- def render *args
15
- unless children.empty?
16
- raise Rxhp::ScriptError.new('Singleton element has children')
17
- end
18
- super *args
14
+ class HasChildrenError < Rxhp::ValidationError
15
+ end
16
+
17
+ def validate!
18
+ super
19
+ raise HasChildrenError.new unless children.empty?
19
20
  end
20
21
 
21
22
  protected
data/lib/rxhp/scope.rb CHANGED
@@ -66,12 +66,8 @@ module Rxhp
66
66
 
67
67
  # Append non-block children
68
68
  if children
69
- if children.is_a? Array
70
- children.each do |child|
71
- element.children.push child
72
- end
73
- else
74
- element.children.push children # well, child
69
+ children.each do |child|
70
+ element.children.push child
75
71
  end
76
72
  end
77
73
 
@@ -82,8 +78,9 @@ module Rxhp
82
78
  "In a block, use the 'text' method to include Strings"
83
79
  )
84
80
  end
85
- nil
86
81
  end
82
+ element.validate! if element.respond_to?(:validate!)
83
+ nil
87
84
  end
88
85
  element
89
86
  end
metadata CHANGED
@@ -1,23 +1,33 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rxhp
3
- version: !ruby/object:Gem::Version
4
- version: 0.0.1
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Fred Emmott
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-01-21 00:00:00.000000000Z
17
+
18
+ date: 2012-01-22 00:00:00 Z
13
19
  dependencies: []
20
+
14
21
  description: An object-oriented validating HTML template system
15
- email:
22
+ email:
16
23
  - rxhp-gem@fredemmott.co.uk
17
24
  executables: []
25
+
18
26
  extensions: []
27
+
19
28
  extra_rdoc_files: []
20
- files:
29
+
30
+ files:
21
31
  - lib/rxhp/attribute_validator.rb
22
32
  - lib/rxhp/composable_element.rb
23
33
  - lib/rxhp/constants.rb
@@ -35,26 +45,36 @@ files:
35
45
  - lib/rxhp.rb
36
46
  homepage: https://github.com/fredemmott/rxhp
37
47
  licenses: []
48
+
38
49
  post_install_message:
39
50
  rdoc_options: []
40
- require_paths:
51
+
52
+ require_paths:
41
53
  - lib
42
- required_ruby_version: !ruby/object:Gem::Requirement
54
+ required_ruby_version: !ruby/object:Gem::Requirement
43
55
  none: false
44
- requirements:
45
- - - ! '>='
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
64
  none: false
50
- requirements:
51
- - - ! '>='
52
- - !ruby/object:Gem::Version
53
- version: '0'
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ hash: 3
69
+ segments:
70
+ - 0
71
+ version: "0"
54
72
  requirements: []
73
+
55
74
  rubyforge_project:
56
75
  rubygems_version: 1.8.6
57
76
  signing_key:
58
77
  specification_version: 3
59
78
  summary: An object-oriented validating HTML template system
60
79
  test_files: []
80
+