raw 0.49.0

Sign up to get free protection for your applications and to get access to all the features.
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