glue 0.20.0 → 0.21.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.
Files changed (58) hide show
  1. data/CHANGELOG +161 -110
  2. data/INSTALL +12 -12
  3. data/README +1 -1
  4. data/Rakefile +43 -45
  5. data/doc/AUTHORS +5 -5
  6. data/doc/LICENSE +3 -3
  7. data/doc/RELEASES +32 -24
  8. data/install.rb +7 -17
  9. data/lib/facet/object/alias_class.rb +12 -0
  10. data/lib/glue.rb +35 -35
  11. data/lib/glue/array.rb +46 -46
  12. data/lib/glue/aspects.rb +199 -209
  13. data/lib/glue/attribute.rb +15 -15
  14. data/lib/glue/autoreload.rb +1 -1
  15. data/lib/glue/builder.rb +48 -0
  16. data/lib/glue/builder/xml.rb +114 -0
  17. data/lib/glue/cache.rb +189 -0
  18. data/lib/glue/configuration.rb +108 -90
  19. data/lib/glue/flexob.rb +17 -17
  20. data/lib/glue/hash.rb +71 -71
  21. data/lib/glue/helper.rb +12 -12
  22. data/lib/glue/idgen.rb +9 -0
  23. data/lib/glue/idgen/md5.rb +24 -0
  24. data/lib/glue/idgen/sequential.rb +15 -0
  25. data/lib/glue/literal_method.rb +44 -0
  26. data/lib/glue/localization.rb +130 -0
  27. data/lib/glue/logger.rb +98 -98
  28. data/lib/glue/misc.rb +7 -7
  29. data/lib/glue/mixins.rb +19 -19
  30. data/lib/glue/number.rb +8 -8
  31. data/lib/glue/object.rb +2 -2
  32. data/lib/glue/pool.rb +43 -43
  33. data/lib/glue/property.rb +392 -392
  34. data/lib/glue/sanitize.rb +34 -34
  35. data/lib/glue/settings.rb +1 -1
  36. data/lib/glue/snapshot.rb +104 -0
  37. data/lib/glue/string.rb +129 -129
  38. data/lib/glue/time.rb +53 -53
  39. data/lib/glue/uri.rb +162 -162
  40. data/lib/glue/validation.rb +421 -421
  41. data/lib/vendor/blankslate.rb +53 -0
  42. data/test/glue/builder/tc_xml.rb +56 -0
  43. data/test/glue/tc_aspects.rb +90 -90
  44. data/test/glue/tc_attribute.rb +11 -11
  45. data/test/glue/tc_builder.rb +30 -0
  46. data/test/glue/tc_configuration.rb +97 -97
  47. data/test/glue/tc_flexob.rb +10 -10
  48. data/test/glue/tc_hash.rb +23 -23
  49. data/test/glue/tc_localization.rb +49 -0
  50. data/test/glue/tc_logger.rb +31 -31
  51. data/test/glue/tc_numbers.rb +9 -9
  52. data/test/glue/tc_property.rb +67 -67
  53. data/test/glue/tc_property_mixins.rb +17 -17
  54. data/test/glue/tc_property_type_checking.rb +13 -13
  55. data/test/glue/tc_strings.rb +94 -94
  56. data/test/glue/tc_uri.rb +65 -65
  57. data/test/glue/tc_validation.rb +196 -196
  58. metadata +26 -4
data/lib/glue/sanitize.rb CHANGED
@@ -8,41 +8,41 @@ VERBOTEN_TAGS = %w(form script) unless defined?(VERBOTEN_TAGS)
8
8
  VERBOTEN_ATTRS = /^on/i unless defined?(VERBOTEN_ATTRS)
9
9
 
10
10
  class String
11
- # Sanitizes the given HTML by making form and script tags into regular
12
- # text, and removing all "onxxx" attributes (so that arbitrary Javascript
13
- # cannot be executed). Also removes href attributes that start with
14
- # "javascript:".
15
- #
16
- # Returns the sanitized text.
17
- def self.sanitize(html)
18
- # only do this if absolutely necessary
19
- if html.index("<")
20
- tokenizer = HTML::Tokenizer.new(html)
21
- new_text = ""
11
+ # Sanitizes the given HTML by making form and script tags into regular
12
+ # text, and removing all "onxxx" attributes (so that arbitrary Javascript
13
+ # cannot be executed). Also removes href attributes that start with
14
+ # "javascript:".
15
+ #
16
+ # Returns the sanitized text.
17
+ def self.sanitize(html)
18
+ # only do this if absolutely necessary
19
+ if html.index("<")
20
+ tokenizer = HTML::Tokenizer.new(html)
21
+ new_text = ""
22
22
 
23
- while token = tokenizer.next
24
- node = HTML::Node.parse(nil, 0, 0, token, false)
25
- new_text << case node
26
- when HTML::Tag
27
- if VERBOTEN_TAGS.include?(node.name)
28
- node.to_s.gsub(/</, "&lt;")
29
- else
30
- if node.closing != :close
31
- node.attributes.delete_if { |attr,v| attr =~ VERBOTEN_ATTRS }
32
- if node.attributes["href"] =~ /^javascript:/i
33
- node.attributes.delete "href"
34
- end
35
- end
36
- node.to_s
37
- end
38
- else
39
- node.to_s.gsub(/</, "&lt;")
40
- end
41
- end
23
+ while token = tokenizer.next
24
+ node = HTML::Node.parse(nil, 0, 0, token, false)
25
+ new_text << case node
26
+ when HTML::Tag
27
+ if VERBOTEN_TAGS.include?(node.name)
28
+ node.to_s.gsub(/</, "&lt;")
29
+ else
30
+ if node.closing != :close
31
+ node.attributes.delete_if { |attr,v| attr =~ VERBOTEN_ATTRS }
32
+ if node.attributes["href"] =~ /^javascript:/i
33
+ node.attributes.delete "href"
34
+ end
35
+ end
36
+ node.to_s
37
+ end
38
+ else
39
+ node.to_s.gsub(/</, "&lt;")
40
+ end
41
+ end
42
42
 
43
- html = new_text
44
- end
43
+ html = new_text
44
+ end
45
45
 
46
- html
47
- end
46
+ html
47
+ end
48
48
  end
data/lib/glue/settings.rb CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  require 'glue/configuration'
4
4
 
5
- # * George Moschovitis <gm@navel.gr>
5
+ # * George Moschovitis <gm@navel.gr>
@@ -0,0 +1,104 @@
1
+ module Glue
2
+
3
+ # Class Snapshot simply represents a collection of objects from
4
+ # which snapshots were taken via their methods #take_snapshot.
5
+ # It provides methods to add an object to a snapshot
6
+ # (method Glue::Snapshot#add) as well as to restore all objects
7
+ # of the snapshot to their state stored in the snapshot (method
8
+ # Glue::Snapshot#restore).
9
+ #
10
+ # In Wee, this class is used to backtracking the state of
11
+ # components (or decorations/presenters). Components that want
12
+ # an undo-facility to be implemented (triggered for example by
13
+ # a browsers back-button), have to overwrite the
14
+ # Wee::Component#backtrack_state method.
15
+
16
+ class Snapshot
17
+ def initialize
18
+ @objects = Hash.new
19
+ end
20
+
21
+ def add(object)
22
+ oid = object.object_id
23
+ @objects[oid] = [object, object.take_snapshot] unless @objects.include?(oid)
24
+ end
25
+
26
+ def restore
27
+ @objects.each_value { |object, value| object.restore_snapshot(value) }
28
+ end
29
+ end
30
+
31
+ module DupReplaceSnapshotMixin
32
+ def take_snapshot
33
+ dup
34
+ end
35
+
36
+ def restore_snapshot(snap)
37
+ replace(snap)
38
+ end
39
+ end
40
+
41
+ # Implements a value holder. In Wee this is useful for
42
+ # backtracking the reference assigned to an instance variable
43
+ # (not the object itself!). An example where this is used is the
44
+ # <tt>@__decoration</tt> attribute of class Wee::Component.
45
+
46
+ class ValueHolder
47
+ attr_accessor :value
48
+
49
+ def initialize(value=nil)
50
+ @value = value
51
+ end
52
+
53
+ def take_snapshot
54
+ @value
55
+ end
56
+
57
+ def restore_snapshot(value)
58
+ @value = value
59
+ end
60
+ end
61
+
62
+ end
63
+
64
+ #--
65
+ # Extend some base classes of Ruby (Object, Array, String, Hash,
66
+ # Struct) for the two methods #take_snapshot and
67
+ # #restore_snapshot, required by Snapshot.
68
+ #++
69
+
70
+ class Object
71
+ def take_snapshot
72
+ snap = Hash.new
73
+ instance_variables.each do |iv|
74
+ snap[iv] = instance_variable_get(iv)
75
+ end
76
+ snap
77
+ end
78
+
79
+ def restore_snapshot(snap)
80
+ instance_variables.each do |iv|
81
+ instance_variable_set(iv, snap[iv])
82
+ end
83
+ end
84
+ end
85
+
86
+ class Array; include Glue::DupReplaceSnapshotMixin end
87
+
88
+ class String; include Glue::DupReplaceSnapshotMixin end
89
+
90
+ class Hash; include Glue::DupReplaceSnapshotMixin end
91
+
92
+ class Struct
93
+ def take_snapshot
94
+ snap = Hash.new
95
+ each_pair {|k,v| snap[k] = v}
96
+ snap
97
+ end
98
+
99
+ def restore_snapshot(snap)
100
+ snap.each_pair {|k,v| send(k.to_s + "=", v)}
101
+ end
102
+ end
103
+
104
+ # * Michael Neumann <mneumann@ntecs.de>
data/lib/glue/string.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  # * Anastasios Koutoumanos <ak@navel.gr>
3
3
  # * Elias Karakoulakis <ekarak@ktismata.com>
4
4
  # (c) 2004-2005 Navel, all rights reserved.
5
- # $Id: string.rb 1 2005-04-11 11:04:30Z gmosx $
5
+ # $Id: string.rb 182 2005-07-22 10:07:50Z gmosx $
6
6
 
7
7
  require 'uri'
8
8
 
@@ -25,137 +25,137 @@ module Glue;
25
25
 
26
26
  module StringUtils
27
27
 
28
- # Move this in String class?
29
- #
30
- # Tests a string for a valid value (non nil, not empty)
31
- #
32
- def self.valid?(string)
33
- return (not ((nil == string) or (string.empty?)))
34
- end
35
-
36
- # returns short abstract of long strings (first 'count'
37
- # characters, chopped at the nearest word, appended by '...')
38
- # force_cutoff: break forcibly at 'count' chars. Does not accept
39
- # count < 2.
40
-
41
- def self.head(string, count = 128, force_cutoff = false, ellipsis="...")
42
- return nil unless string
43
- return nil if count < 2
44
-
45
- if string.size > count
46
- cut_at = force_cutoff ? count : (string.index(' ', count-1) || count)
47
- xstring = string.slice(0, cut_at)
48
- return xstring.chomp(" ") + ellipsis
49
- else
50
- return string
51
- end
52
- end
53
-
54
- # Apply a set of rules (regular expression matches) to the
55
- # string
56
- #
57
- # === Requirements:
58
- # - the rules must be applied in order! So we cannot use a
59
- # hash because the ordering is not guaranteed! we use an
60
- # array instead.
61
- #
62
- # === Input:
63
- # the string to rewrite
64
- # the array containing rule-pairs (match, rewrite)
65
- #
66
- # === Output:
67
- # the rewritten string
68
-
69
- MATCH = 0
70
- REWRITE = 1
71
-
72
- def self.rewrite(string, rules)
73
- return nil unless string
74
-
75
- # gmosx: helps to find bugs
76
- raise ArgumentError.new('The rules parameter is nil') unless rules
77
-
78
- rewritten_string = string.dup
79
-
80
- for rule in rules
81
- rewritten_string.gsub!(rule[MATCH], rule[REWRITE])
82
- end
83
-
84
- return (rewritten_string or string)
85
- end
86
-
87
- # Enforces a maximum width of a string inside an
88
- # html container. If the string exceeds this maximum width
89
- # the string gets wraped.
90
- #
91
- # Not really useful, better use the CSS overflow: hidden
92
- # functionality.
93
- #
94
- # === Input:
95
- # the string to be wrapped
96
- # the enforced width
97
- # the separator used for wrapping
98
- #
99
- # === Output:
100
- # the wrapped string
101
- #
102
- # === Example:
103
- # text = "1111111111111111111111111111111111111111111"
104
- # text = wrap(text, 10, " ")
105
- # p text # => "1111111111 1111111111 1111111111"
106
- #
107
- # See the test cases to better understand the behaviour!
108
-
109
- def self.wrap(string, width = 20, separator = " ")
110
- return nil unless string
111
-
112
- re = /([^#{separator}]{1,#{width}})/
113
- wrapped_string = string.scan(re).join(separator)
114
-
115
- return wrapped_string
116
- end
117
-
118
- # Replace dangerours chars in filenames
28
+ # Move this in String class?
29
+ #
30
+ # Tests a string for a valid value (non nil, not empty)
31
+ #
32
+ def self.valid?(string)
33
+ return (not ((nil == string) or (string.empty?)))
34
+ end
35
+
36
+ # returns short abstract of long strings (first 'count'
37
+ # characters, chopped at the nearest word, appended by '...')
38
+ # force_cutoff: break forcibly at 'count' chars. Does not accept
39
+ # count < 2.
40
+
41
+ def self.head(string, count = 128, force_cutoff = false, ellipsis="...")
42
+ return nil unless string
43
+ return nil if count < 2
44
+
45
+ if string.size > count
46
+ cut_at = force_cutoff ? count : (string.index(' ', count-1) || count)
47
+ xstring = string.slice(0, cut_at)
48
+ return xstring.chomp(" ") + ellipsis
49
+ else
50
+ return string
51
+ end
52
+ end
53
+
54
+ # Apply a set of rules (regular expression matches) to the
55
+ # string
56
+ #
57
+ # === Requirements:
58
+ # - the rules must be applied in order! So we cannot use a
59
+ # hash because the ordering is not guaranteed! we use an
60
+ # array instead.
61
+ #
62
+ # === Input:
63
+ # the string to rewrite
64
+ # the array containing rule-pairs (match, rewrite)
65
+ #
66
+ # === Output:
67
+ # the rewritten string
68
+
69
+ MATCH = 0
70
+ REWRITE = 1
71
+
72
+ def self.rewrite(string, rules)
73
+ return nil unless string
74
+
75
+ # gmosx: helps to find bugs
76
+ raise ArgumentError.new('The rules parameter is nil') unless rules
77
+
78
+ rewritten_string = string.dup
79
+
80
+ for rule in rules
81
+ rewritten_string.gsub!(rule[MATCH], rule[REWRITE])
82
+ end
83
+
84
+ return (rewritten_string or string)
85
+ end
86
+
87
+ # Enforces a maximum width of a string inside an
88
+ # html container. If the string exceeds this maximum width
89
+ # the string gets wraped.
90
+ #
91
+ # Not really useful, better use the CSS overflow: hidden
92
+ # functionality.
93
+ #
94
+ # === Input:
95
+ # the string to be wrapped
96
+ # the enforced width
97
+ # the separator used for wrapping
98
+ #
99
+ # === Output:
100
+ # the wrapped string
101
+ #
102
+ # === Example:
103
+ # text = "1111111111111111111111111111111111111111111"
104
+ # text = wrap(text, 10, " ")
105
+ # p text # => "1111111111 1111111111 1111111111"
106
+ #
107
+ # See the test cases to better understand the behaviour!
108
+
109
+ def self.wrap(string, width = 20, separator = " ")
110
+ return nil unless string
111
+
112
+ re = /([^#{separator}]{1,#{width}})/
113
+ wrapped_string = string.scan(re).join(separator)
114
+
115
+ return wrapped_string
116
+ end
117
+
118
+ # Replace dangerours chars in filenames
119
119
  =begin
120
- def self.rationalize_filename(filename)
121
- return nil unless filename
122
- # gmosx: rationalize a copy!!! (add unit test)
123
- xfilename = filename.dup()
124
- # gmosx: replace some dangerous chars!
125
- xfilename.gsub!(/ /, "-")
126
- xfilename.gsub!(/!/, "")
127
- xfilename.gsub!(/'/, "")
128
- xfilename.gsub!(/\(/, "")
129
- xfilename.gsub!(/\)/, "")
130
- # xfilename = self.to_greeklish(xfilename)
131
- return xfilename
132
- end
120
+ def self.rationalize_filename(filename)
121
+ return nil unless filename
122
+ # gmosx: rationalize a copy!!! (add unit test)
123
+ xfilename = filename.dup()
124
+ # gmosx: replace some dangerous chars!
125
+ xfilename.gsub!(/ /, "-")
126
+ xfilename.gsub!(/!/, "")
127
+ xfilename.gsub!(/'/, "")
128
+ xfilename.gsub!(/\(/, "")
129
+ xfilename.gsub!(/\)/, "")
130
+ # xfilename = self.to_greeklish(xfilename)
131
+ return xfilename
132
+ end
133
133
  =end
134
-
135
- # Returns a random string. one possible use is
136
- # password initialization.
137
- #
138
- # === Input:
139
- # the maximum length of the string
140
- #
141
- # === Output:
142
- # the random string
143
-
144
- def self.random(max_length = 8, char_re = /[\w\d]/)
134
+
135
+ # Returns a random string. one possible use is
136
+ # password initialization.
137
+ #
138
+ # === Input:
139
+ # the maximum length of the string
140
+ #
141
+ # === Output:
142
+ # the random string
143
+
144
+ def self.random(max_length = 8, char_re = /[\w\d]/)
145
145
  # gmosx: this is a nice example of input parameter checking.
146
- # this is NOT a real time called method so we can add this
147
- # check. Congrats to the author.
148
- raise ArgumentError.new('char_re must be a regular expression!') unless char_re.is_a?(Regexp)
149
-
150
- string = ""
151
-
152
- while string.length < max_length
153
- ch = rand(255).chr
154
- string << ch if ch =~ char_re
155
- end
156
-
157
- return string
158
- end
146
+ # this is NOT a real time called method so we can add this
147
+ # check. Congrats to the author.
148
+ raise ArgumentError.new('char_re must be a regular expression!') unless char_re.is_a?(Regexp)
149
+
150
+ string = ""
151
+
152
+ while string.length < max_length
153
+ ch = rand(255).chr
154
+ string << ch if ch =~ char_re
155
+ end
156
+
157
+ return string
158
+ end
159
159
 
160
160
  end
161
161