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.
- data/lib/rxhp/attribute_validator.rb +30 -9
- data/lib/rxhp/composable_element.rb +3 -3
- data/lib/rxhp/element.rb +54 -12
- data/lib/rxhp/error.rb +3 -0
- data/lib/rxhp/html.rb +3 -1
- data/lib/rxhp/html_element.rb +17 -13
- data/lib/rxhp/html_singleton_element.rb +6 -5
- data/lib/rxhp/scope.rb +4 -7
- metadata +38 -18
|
@@ -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 =
|
|
67
|
-
|
|
68
|
-
|
|
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
|
|
84
|
+
name_from_symbol(matcher) == value
|
|
72
85
|
else
|
|
73
|
-
|
|
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
|
-
|
|
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
|
|
16
|
-
super
|
|
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
|
-
|
|
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
|
-
|
|
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
data/lib/rxhp/html.rb
CHANGED
data/lib/rxhp/html_element.rb
CHANGED
|
@@ -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
|
-
|
|
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 =
|
|
57
|
-
out
|
|
58
|
-
out
|
|
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
|
|
63
|
-
out
|
|
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
|
|
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
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
super
|
|
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
|
-
|
|
70
|
-
children.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
48
|
-
|
|
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
|
-
|
|
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
|
+
|