rxhp 0.0.1 → 0.1.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.
@@ -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
+