raw 0.49.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 (148) hide show
  1. data/doc/CONTRIBUTORS +106 -0
  2. data/doc/LICENSE +32 -0
  3. data/doc/coding_conventions.txt +11 -0
  4. data/lib/raw.rb +42 -0
  5. data/lib/raw/adapter.rb +113 -0
  6. data/lib/raw/adapter/cgi.rb +41 -0
  7. data/lib/raw/adapter/fastcgi.rb +48 -0
  8. data/lib/raw/adapter/mongrel.rb +146 -0
  9. data/lib/raw/adapter/script.rb +94 -0
  10. data/lib/raw/adapter/webrick.rb +144 -0
  11. data/lib/raw/adapter/webrick/vcr.rb +91 -0
  12. data/lib/raw/cgi.rb +323 -0
  13. data/lib/raw/cgi/cookie.rb +47 -0
  14. data/lib/raw/cgi/http.rb +62 -0
  15. data/lib/raw/compiler.rb +138 -0
  16. data/lib/raw/compiler/filter/cleanup.rb +21 -0
  17. data/lib/raw/compiler/filter/elements.rb +166 -0
  18. data/lib/raw/compiler/filter/elements/element.rb +210 -0
  19. data/lib/raw/compiler/filter/localization.rb +23 -0
  20. data/lib/raw/compiler/filter/markup.rb +32 -0
  21. data/lib/raw/compiler/filter/morph.rb +123 -0
  22. data/lib/raw/compiler/filter/morph/each.rb +34 -0
  23. data/lib/raw/compiler/filter/morph/for.rb +11 -0
  24. data/lib/raw/compiler/filter/morph/if.rb +26 -0
  25. data/lib/raw/compiler/filter/morph/selected_if.rb +43 -0
  26. data/lib/raw/compiler/filter/morph/standard.rb +55 -0
  27. data/lib/raw/compiler/filter/morph/times.rb +27 -0
  28. data/lib/raw/compiler/filter/script.rb +116 -0
  29. data/lib/raw/compiler/filter/squeeze.rb +16 -0
  30. data/lib/raw/compiler/filter/static_include.rb +74 -0
  31. data/lib/raw/compiler/filter/template.rb +121 -0
  32. data/lib/raw/compiler/reloader.rb +96 -0
  33. data/lib/raw/context.rb +154 -0
  34. data/lib/raw/context/flash.rb +157 -0
  35. data/lib/raw/context/global.rb +88 -0
  36. data/lib/raw/context/request.rb +338 -0
  37. data/lib/raw/context/response.rb +57 -0
  38. data/lib/raw/context/session.rb +198 -0
  39. data/lib/raw/context/session/drb.rb +11 -0
  40. data/lib/raw/context/session/file.rb +15 -0
  41. data/lib/raw/context/session/memcached.rb +13 -0
  42. data/lib/raw/context/session/memory.rb +12 -0
  43. data/lib/raw/context/session/og.rb +15 -0
  44. data/lib/raw/context/session/pstore.rb +13 -0
  45. data/lib/raw/control.rb +18 -0
  46. data/lib/raw/control/attribute.rb +91 -0
  47. data/lib/raw/control/attribute/checkbox.rb +25 -0
  48. data/lib/raw/control/attribute/datetime.rb +21 -0
  49. data/lib/raw/control/attribute/file.rb +20 -0
  50. data/lib/raw/control/attribute/fixnum.rb +26 -0
  51. data/lib/raw/control/attribute/float.rb +26 -0
  52. data/lib/raw/control/attribute/options.rb +38 -0
  53. data/lib/raw/control/attribute/password.rb +16 -0
  54. data/lib/raw/control/attribute/text.rb +16 -0
  55. data/lib/raw/control/attribute/textarea.rb +16 -0
  56. data/lib/raw/control/none.rb +16 -0
  57. data/lib/raw/control/relation.rb +59 -0
  58. data/lib/raw/control/relation/belongs_to.rb +0 -0
  59. data/lib/raw/control/relation/has_many.rb +97 -0
  60. data/lib/raw/control/relation/joins_many.rb +0 -0
  61. data/lib/raw/control/relation/many_to_many.rb +0 -0
  62. data/lib/raw/control/relation/refers_to.rb +29 -0
  63. data/lib/raw/controller.rb +37 -0
  64. data/lib/raw/controller/publishable.rb +160 -0
  65. data/lib/raw/dispatcher.rb +209 -0
  66. data/lib/raw/dispatcher/format.rb +108 -0
  67. data/lib/raw/dispatcher/format/atom.rb +31 -0
  68. data/lib/raw/dispatcher/format/css.rb +0 -0
  69. data/lib/raw/dispatcher/format/html.rb +42 -0
  70. data/lib/raw/dispatcher/format/json.rb +31 -0
  71. data/lib/raw/dispatcher/format/rss.rb +33 -0
  72. data/lib/raw/dispatcher/format/xoxo.rb +31 -0
  73. data/lib/raw/dispatcher/mounter.rb +60 -0
  74. data/lib/raw/dispatcher/router.rb +111 -0
  75. data/lib/raw/errors.rb +19 -0
  76. data/lib/raw/helper.rb +86 -0
  77. data/lib/raw/helper/benchmark.rb +23 -0
  78. data/lib/raw/helper/buffer.rb +60 -0
  79. data/lib/raw/helper/cookie.rb +32 -0
  80. data/lib/raw/helper/debug.rb +28 -0
  81. data/lib/raw/helper/default.rb +16 -0
  82. data/lib/raw/helper/feed.rb +451 -0
  83. data/lib/raw/helper/form.rb +284 -0
  84. data/lib/raw/helper/javascript.rb +59 -0
  85. data/lib/raw/helper/layout.rb +40 -0
  86. data/lib/raw/helper/navigation.rb +87 -0
  87. data/lib/raw/helper/pager.rb +305 -0
  88. data/lib/raw/helper/table.rb +247 -0
  89. data/lib/raw/helper/xhtml.rb +218 -0
  90. data/lib/raw/helper/xml.rb +125 -0
  91. data/lib/raw/mixin/magick.rb +35 -0
  92. data/lib/raw/mixin/sweeper.rb +71 -0
  93. data/lib/raw/mixin/thumbnails.rb +1 -0
  94. data/lib/raw/mixin/webfile.rb +165 -0
  95. data/lib/raw/render.rb +271 -0
  96. data/lib/raw/render/builder.rb +26 -0
  97. data/lib/raw/render/caching.rb +81 -0
  98. data/lib/raw/render/call.rb +43 -0
  99. data/lib/raw/render/send_file.rb +46 -0
  100. data/lib/raw/render/stream.rb +39 -0
  101. data/lib/raw/scaffold.rb +13 -0
  102. data/lib/raw/scaffold/controller.rb +25 -0
  103. data/lib/raw/scaffold/model.rb +157 -0
  104. data/lib/raw/test.rb +5 -0
  105. data/lib/raw/test/assertions.rb +169 -0
  106. data/lib/raw/test/context.rb +55 -0
  107. data/lib/raw/test/testcase.rb +79 -0
  108. data/lib/raw/util/attr.rb +128 -0
  109. data/lib/raw/util/encode_uri.rb +149 -0
  110. data/lib/raw/util/html_filter.rb +538 -0
  111. data/lib/raw/util/markup.rb +130 -0
  112. data/test/glue/tc_webfile.rb +1 -0
  113. data/test/nitro/CONFIG.rb +3 -0
  114. data/test/nitro/adapter/raw_post1.bin +9 -0
  115. data/test/nitro/adapter/tc_webrick.rb +16 -0
  116. data/test/nitro/cgi/tc_cookie.rb +14 -0
  117. data/test/nitro/cgi/tc_request.rb +61 -0
  118. data/test/nitro/compiler/tc_client_morpher.rb +47 -0
  119. data/test/nitro/compiler/tc_compiler.rb +25 -0
  120. data/test/nitro/dispatcher/tc_mounter.rb +47 -0
  121. data/test/nitro/helper/tc_feed.rb +135 -0
  122. data/test/nitro/helper/tc_navbar.rb +74 -0
  123. data/test/nitro/helper/tc_pager.rb +35 -0
  124. data/test/nitro/helper/tc_table.rb +68 -0
  125. data/test/nitro/helper/tc_xhtml.rb +19 -0
  126. data/test/nitro/tc_caching.rb +19 -0
  127. data/test/nitro/tc_cgi.rb +222 -0
  128. data/test/nitro/tc_context.rb +17 -0
  129. data/test/nitro/tc_controller.rb +103 -0
  130. data/test/nitro/tc_controller_aspect.rb +32 -0
  131. data/test/nitro/tc_controller_params.rb +885 -0
  132. data/test/nitro/tc_dispatcher.rb +109 -0
  133. data/test/nitro/tc_element.rb +85 -0
  134. data/test/nitro/tc_flash.rb +59 -0
  135. data/test/nitro/tc_helper.rb +47 -0
  136. data/test/nitro/tc_render.rb +119 -0
  137. data/test/nitro/tc_router.rb +61 -0
  138. data/test/nitro/tc_server.rb +35 -0
  139. data/test/nitro/tc_session.rb +66 -0
  140. data/test/nitro/tc_template.rb +71 -0
  141. data/test/nitro/util/tc_encode_url.rb +87 -0
  142. data/test/nitro/util/tc_markup.rb +31 -0
  143. data/test/public/blog/another/very_litle/index.xhtml +1 -0
  144. data/test/public/blog/inc1.xhtml +2 -0
  145. data/test/public/blog/inc2.xhtml +1 -0
  146. data/test/public/blog/list.xhtml +9 -0
  147. data/test/public/dummy_mailer/registration.xhtml +5 -0
  148. metadata +244 -0
@@ -0,0 +1,23 @@
1
+ module Raw
2
+
3
+ # Transform localzation macros.
4
+
5
+ class LocalizationFilter
6
+
7
+ def apply(source)
8
+ source = source.dup
9
+
10
+ # handle symbols.
11
+
12
+ source.gsub!(/\[\[\:(.*?)\]\]/, '#{@lc[\1]}')
13
+
14
+ # handle strings.
15
+
16
+ source.gsub!(/\[\[(.*?)\]\]/, '#{@lc["\1"]}')
17
+
18
+ return text
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,32 @@
1
+ require "raw/util/markup"
2
+
3
+ module Raw
4
+
5
+ class MarkupFilter
6
+
7
+ # Transform the markup macros.
8
+ # Maps #(..) to :sanitize.
9
+ # Maps #|..| to :markup.
10
+ #
11
+ # Additional markup macros:
12
+ #
13
+ # Maps ''..'' to #{...to_link}
14
+ # Maps {{..}} to #{R ..}
15
+ # Maps #<..> to #{R ..}
16
+
17
+ def apply(source)
18
+ source = source.dup
19
+
20
+ source.gsub!(/\#\((.*?)\)/, '#{sanitize(\1)}')
21
+ source.gsub!(/\#\|(.*?)\|/, '#{markup(\1)}')
22
+
23
+ source.gsub!(/\'\'(.*?)\'\'/, '#{\1.to_link}')
24
+ source.gsub!(/\{\{(.*?)\}\}/, '#{R \1}')
25
+ source.gsub!(/\#\<(.*?)\>/, '#{R \1}')
26
+
27
+ return source
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,123 @@
1
+ require "rexml/document"
2
+ require "rexml/streamlistener"
3
+
4
+ require "facets/core/string/blank"
5
+
6
+ module Raw
7
+
8
+ # A Filter that transforms an xml stream. Multiple 'key'
9
+ # attributes are supported per element.
10
+
11
+ class MorphFilter
12
+
13
+ # The default morphers collection.
14
+
15
+ setting :morphers, :default => Dictionary.new, :doc => "The default morphers collection"
16
+
17
+ #--
18
+ # The listener used to parse the xml stream.
19
+ # TODO: add support for morphing comments, text, etc.
20
+ #++
21
+
22
+ class Listener # :nodoc: all
23
+ include REXML::StreamListener
24
+
25
+ attr_accessor :buffer
26
+
27
+ def initialize(filter)
28
+ super()
29
+ @filter = filter
30
+ @buffer = ""
31
+ @stack = []
32
+ end
33
+
34
+ def tag_start(name, attributes)
35
+ morphers = []
36
+
37
+ for morpher_class in @filter.morphers
38
+ if attributes.has_key? morpher_class.key
39
+ morphers << morpher_class.new(name, attributes)
40
+ end
41
+ end
42
+
43
+ morphers.each { |h| h.before_start(@buffer) }
44
+ @buffer << emit_start(name, attributes)
45
+ morphers.each { |h| h.after_start(@buffer) }
46
+
47
+ @stack.push(morphers)
48
+ end
49
+
50
+ def tag_end(name)
51
+ morphers = @stack.pop
52
+ morphers.reverse.each { |h| h.before_end(@buffer) }
53
+ @buffer << emit_end(name)
54
+ morphers.reverse.each { |h| h.after_end(@buffer) }
55
+ end
56
+
57
+ def text(str)
58
+ @buffer << str
59
+ end
60
+
61
+ def instruction(name, attributes)
62
+ @buffer << "<?#{name}#{attributes}?>"
63
+ end
64
+
65
+ def cdata(content)
66
+ @buffer << "<![CDATA[#{content}]]>"
67
+ end
68
+
69
+ def comment(c)
70
+ unless Template.strip_xml_comments
71
+ @buffer << "<!--#{c}-->"
72
+ end
73
+ end
74
+
75
+ def doctype(name, pub_sys, long_name, uri)
76
+ @buffer << "<!DOCTYPE #{name} #{pub_sys} #{long_name} #{uri}>\n"
77
+ end
78
+
79
+ def emit_start(name, attributes)
80
+ attrs = attributes.map{ |k, v| %|#{k}="#{v}"| }.join(' ')
81
+ attrs.blank? ? "<#{name}>" : "<#{name} #{attrs}>"
82
+ end
83
+
84
+ def emit_end(name)
85
+ "</#{name}>"
86
+ end
87
+ end # Listener
88
+
89
+ # A collection of morphers registered with this filter.
90
+
91
+ attr_accessor :morphers
92
+
93
+ # Initialize the filter.
94
+
95
+ def initialize(morphers = nil)
96
+ unless @morphers = morphers
97
+ require "raw/compiler/filter/morph/times"
98
+ require "raw/compiler/filter/morph/each"
99
+ require "raw/compiler/filter/morph/for"
100
+ require "raw/compiler/filter/morph/if"
101
+ require "raw/compiler/filter/morph/selected_if"
102
+
103
+ @morphers = [
104
+ TimesMorpher,
105
+ EachMorpher,
106
+ ForMorpher,
107
+ IfMorpher,
108
+ SelectedIfMorpher
109
+ ]
110
+ end
111
+ end
112
+
113
+ # Apply the filter.
114
+
115
+ def apply(source)
116
+ listen = Listener.new(self)
117
+ REXML::Document.parse_stream(source, listen)
118
+ return listen.buffer
119
+ end
120
+
121
+ end
122
+
123
+ end
@@ -0,0 +1,34 @@
1
+ require "raw/compiler/filter/morph/standard"
2
+
3
+ module Raw
4
+
5
+ # attribute: each, for
6
+ #
7
+ # <li each="item in array">my item is #{item}</li>
8
+ #
9
+ # becomes
10
+ #
11
+ # <?r for item in array ?>
12
+ # <li>my item is #{item}</li>
13
+ # <?r end ?>
14
+
15
+ class EachMorpher < Morpher
16
+ def self.key
17
+ "each"
18
+ end
19
+
20
+ def before_start(buffer)
21
+ if @value =~ / in /
22
+ buffer << "<?r for #@value ?> "
23
+ attributes.delete(@key)
24
+ end
25
+ end
26
+
27
+ def after_end(buffer)
28
+ if @value =~ / in /
29
+ buffer << " <?r end ?>"
30
+ end
31
+ end
32
+ end
33
+
34
+ end
@@ -0,0 +1,11 @@
1
+ require "raw/compiler/filter/morph/each"
2
+
3
+ module Raw
4
+
5
+ class ForMorpher < EachMorpher
6
+ def self.key
7
+ "for"
8
+ end
9
+ end
10
+
11
+ end
@@ -0,0 +1,26 @@
1
+ require "raw/compiler/filter/morph/standard"
2
+
3
+ module Raw
4
+
5
+ # attribute: if, unless
6
+ #
7
+ # <div prop1="one" if="@mycond" prop2="two">@mycond is true</div>
8
+ #
9
+ # becomes
10
+ #
11
+ # <?r if @mycond ?>
12
+ # <div prop1="one" prop2="two">@mycond is true</div>
13
+ # <?r end ?>
14
+
15
+ class IfMorpher < StandardMorpher
16
+ def self.key
17
+ "each"
18
+ end
19
+
20
+ def before_start(buffer)
21
+ buffer << "<?r #@key #@value ?> "
22
+ @attributes.delete(@key)
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,43 @@
1
+ require "raw/compiler/filter/morph/standard"
2
+
3
+ module Raw
4
+
5
+ # attribute: selected_if, checked_if, selected_unless, checked_unless
6
+ #
7
+ # <option value="1" selected_if="@cond">opt1</option>
8
+ #
9
+ # becomes
10
+ #
11
+ # <?r if @cond ?>
12
+ # <option value="1" selected="selected">opt1</option>
13
+ # <?r else ?>
14
+ # <option value="1">opt1</option>
15
+ # <?r end ?>
16
+
17
+ class SelectedIfMorpher < StandardMorpher
18
+ def self.key
19
+ "selected_if"
20
+ end
21
+
22
+ def before_start(buffer)
23
+ @attr, @cond = @key.split("_")
24
+ @attributes.delete(@key)
25
+ @attributes[@attr] = @attr
26
+ buffer << "<?r #@cond #@value ?> "
27
+ end
28
+
29
+ def after_start(buffer)
30
+ @start_index = buffer.length
31
+ end
32
+
33
+ def before_end(buffer)
34
+ @attributes.delete(@attr)
35
+ @end_index = buffer.length
36
+ buffer << Morphing.emit_end(@name)
37
+ buffer << "<?r else ?>"
38
+ buffer << Morphing.emit_start(@name, @attributes)
39
+ buffer << buffer[@start_index...@end_index]
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,55 @@
1
+ module Raw
2
+
3
+ # The base morpher class. Morphers are triggered
4
+ # by a special 'key' attribute in the xml stream and
5
+ # transform the owner element. Typically used along with the
6
+ # MorphFilter.
7
+
8
+ class Morpher
9
+ # The name of the tag.
10
+
11
+ attr_accessor :name
12
+
13
+ # The tag attributes.
14
+
15
+ attr_accessor :attributes
16
+
17
+ # The key
18
+
19
+ attr_accessor :key
20
+
21
+ # The value of the key.
22
+
23
+ attr_accessor :value
24
+
25
+
26
+ def initialize(name, attributes)
27
+ @key = self.class.key
28
+ @name = name
29
+ @attributes = attributes
30
+ @value = @attributes[@key]
31
+ end
32
+
33
+ def before_start(buffer)
34
+ end
35
+
36
+ def after_start(buffer)
37
+ end
38
+
39
+ def before_end(buffer)
40
+ end
41
+
42
+ def after_end(buffer)
43
+ end
44
+ end
45
+
46
+ # A useful super class for Morphers.
47
+
48
+ class StandardMorpher < Morpher
49
+ def after_end(buffer)
50
+ # gmosx: leave the leading space.
51
+ buffer << " <?r end ?>"
52
+ end
53
+ end
54
+
55
+ end
@@ -0,0 +1,27 @@
1
+ require "raw/compiler/filter/morph/standard"
2
+
3
+ module Raw
4
+
5
+ # attribute: times
6
+ #
7
+ # <li times="3">...</li>
8
+ #
9
+ # becomes
10
+ #
11
+ # <?r 3.times do ?>
12
+ # <li>...</li>
13
+ # <?r end ?>
14
+
15
+ class TimesMorpher < StandardMorpher
16
+ def self.key
17
+ "times"
18
+ end
19
+
20
+ def before_start(buffer)
21
+ # gmosx: leave the trailing space.
22
+ buffer << "<?r #@value.times do ?> "
23
+ @attributes.delete(@key)
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,116 @@
1
+ require "facets/core/kernel/constant"
2
+
3
+ require "raw/helper/javascript"
4
+
5
+ module Raw
6
+
7
+ # Generates client-side javascript code.
8
+ # DOES NOT WORK AT THE MOMENT, have to convert this.
9
+
10
+ module ScriptFilter
11
+ extend JavascriptHelper
12
+
13
+ def self.transform(text, compiler)
14
+ begin
15
+ client = constant("#{compiler.controller}::Client")
16
+ rescue NameError => ex
17
+ client = nil
18
+ end
19
+
20
+ if client
21
+ client.send :include, Nitro::ScriptGenerator
22
+ client = client.new
23
+
24
+ functions = {}
25
+ params = {}
26
+
27
+ text.scan(/__nc_(.*)\((.*)\)/) do |match|
28
+ functions[match.first] = true
29
+ params[match.last] = true
30
+ end
31
+
32
+ script = ''
33
+
34
+ for fun in functions.keys
35
+ begin
36
+ client.buffer = ''
37
+ ret = client.send(fun.to_sym)
38
+
39
+ # the function code is accumulated in the client
40
+ # buffer.
41
+
42
+ function_code = client.buffer
43
+
44
+ # if the client action returns a String append it to
45
+ # the function code.
46
+
47
+ function_code << ret if ret.is_a?(String)
48
+
49
+ script << %{
50
+ function __nc_#{fun}(params) {
51
+ #{function_code}
52
+ }
53
+ }
54
+ rescue Object => ex
55
+ Logger.debug ex.inspect if $DBG
56
+ end
57
+ end
58
+
59
+ end
60
+
61
+ # Inject css in the head tag.
62
+
63
+ if css_buffer = compiler.shared[:css_buffer]
64
+ text.sub!(/<\/head>/) do |match|
65
+ %{
66
+ <style>
67
+ #{css_buffer}
68
+ </style>
69
+ </head>
70
+ }
71
+ end
72
+ end
73
+
74
+ # Inject required javascript files in the head tag.
75
+
76
+ required_files = Javascript.required_files
77
+ if crf = compiler.shared[:js_required_files]
78
+ required_files.concat(crf.keys)
79
+ end
80
+
81
+ unless required_files.empty?
82
+ text.sub!(/<\/head>/) do |match|
83
+ %{
84
+ #{include_script *required_files}
85
+ </head>
86
+ }
87
+ end
88
+ end
89
+
90
+ # Inject javascript just before the end of the
91
+ # template.
92
+ #--
93
+ # gmosx: injection happens at the end, so that the DOM
94
+ # tree is created. Dunno if this is valid xhtml though.
95
+ #++
96
+
97
+ js_buffer = compiler.shared[:js_buffer]
98
+
99
+ if script or js_buffer
100
+ text.sub!(/<\/body>/) do |match|
101
+ %{
102
+ <script type="text/javascript">
103
+ #{script}
104
+ #{js_buffer}
105
+ </script>
106
+ </body>
107
+ }
108
+ end
109
+ end
110
+
111
+ return text
112
+ end
113
+
114
+ end
115
+
116
+ end