hobo 1.0.3 → 1.1.0.pre0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/CHANGES.txt +0 -66
  2. data/README +3 -0
  3. data/Rakefile +7 -7
  4. data/doctest/model.rdoctest +0 -2
  5. data/doctest/multi_model_forms.rdoctest +0 -2
  6. data/doctest/scopes.rdoctest +13 -21
  7. data/lib/active_record/association_collection.rb +7 -16
  8. data/lib/hobo.rb +10 -65
  9. data/lib/hobo/accessible_associations.rb +1 -5
  10. data/lib/hobo/authentication_support.rb +1 -1
  11. data/lib/hobo/controller.rb +5 -5
  12. data/lib/hobo/hobo_helper.rb +0 -84
  13. data/lib/hobo/lifecycles/lifecycle.rb +37 -31
  14. data/lib/hobo/lifecycles/transition.rb +1 -2
  15. data/lib/hobo/model.rb +13 -21
  16. data/lib/hobo/model_controller.rb +8 -8
  17. data/lib/hobo/rapid_helper.rb +12 -1
  18. data/lib/hobo/scopes/automatic_scopes.rb +26 -13
  19. data/lib/hobo/scopes/named_scope_extensions.rb +16 -28
  20. data/lib/hobo/user_controller.rb +1 -0
  21. data/lib/hobo/view_hints.rb +1 -5
  22. data/rails_generators/hobo/templates/initializer.rb +1 -1
  23. data/rails_generators/hobo_front_controller/templates/summary.dryml +4 -2
  24. data/rails_generators/hobo_model/hobo_model_generator.rb +12 -0
  25. data/rails_generators/hobo_model/templates/model.rb +9 -2
  26. data/rails_generators/hobo_rapid/templates/hobo-rapid.js +98 -23
  27. data/rails_generators/hobo_rapid/templates/themes/clean/public/stylesheets/clean.css +1 -1
  28. data/rails_generators/hobo_rapid/templates/themes/clean/public/stylesheets/rapid-ui.css +3 -1
  29. data/{dryml_generators → rapid_generators}/rapid/cards.dryml.erb +0 -0
  30. data/{dryml_generators → rapid_generators}/rapid/forms.dryml.erb +0 -0
  31. data/{dryml_generators → rapid_generators}/rapid/pages.dryml.erb +1 -1
  32. data/taglibs/rapid.dryml +2 -0
  33. data/taglibs/rapid_core.dryml +10 -9
  34. data/taglibs/rapid_forms.dryml +70 -35
  35. data/taglibs/rapid_lifecycles.dryml +17 -4
  36. data/taglibs/rapid_plus.dryml +3 -3
  37. data/taglibs/rapid_summary.dryml +11 -0
  38. data/taglibs/rapid_user_pages.dryml +39 -28
  39. data/tasks/hobo_tasks.rake +1 -1
  40. metadata +45 -61
  41. data/hobo.gemspec +0 -226
  42. data/lib/hobo/dryml.rb +0 -188
  43. data/lib/hobo/dryml/dryml_builder.rb +0 -140
  44. data/lib/hobo/dryml/dryml_doc.rb +0 -159
  45. data/lib/hobo/dryml/dryml_generator.rb +0 -263
  46. data/lib/hobo/dryml/dryml_support_controller.rb +0 -13
  47. data/lib/hobo/dryml/parser.rb +0 -3
  48. data/lib/hobo/dryml/parser/attribute.rb +0 -41
  49. data/lib/hobo/dryml/parser/base_parser.rb +0 -254
  50. data/lib/hobo/dryml/parser/document.rb +0 -57
  51. data/lib/hobo/dryml/parser/element.rb +0 -27
  52. data/lib/hobo/dryml/parser/elements.rb +0 -45
  53. data/lib/hobo/dryml/parser/source.rb +0 -58
  54. data/lib/hobo/dryml/parser/text.rb +0 -13
  55. data/lib/hobo/dryml/parser/tree_parser.rb +0 -67
  56. data/lib/hobo/dryml/part_context.rb +0 -137
  57. data/lib/hobo/dryml/scoped_variables.rb +0 -42
  58. data/lib/hobo/dryml/tag_parameters.rb +0 -36
  59. data/lib/hobo/dryml/taglib.rb +0 -123
  60. data/lib/hobo/dryml/template.rb +0 -1019
  61. data/lib/hobo/dryml/template_environment.rb +0 -613
  62. data/lib/hobo/dryml/template_handler.rb +0 -187
  63. data/lib/hobo/static_tags +0 -98
  64. data/taglibs/core.dryml +0 -104
@@ -1,57 +0,0 @@
1
- module Hobo::Dryml
2
-
3
- module Parser
4
-
5
- class Document < REXML::Document
6
-
7
- def initialize(source, path)
8
- super(nil)
9
-
10
- # Replace <%...%> scriptlets with xml-safe references into a hash of scriptlets
11
- @scriptlets = {}
12
- source = source.gsub(/<%(.*?)%>/m) do
13
- _, scriptlet = *Regexp.last_match
14
- id = @scriptlets.size + 1
15
- @scriptlets[id] = scriptlet
16
- newlines = "\n" * scriptlet.count("\n")
17
- "[![DRYML-ERB#{id}#{newlines}]!]"
18
- end
19
-
20
-
21
- @reference_src = "<dryml_page>" + source + "</dryml_page>"
22
- rex_src = Hobo::Dryml::Parser::Source.new(@reference_src)
23
-
24
- @elements = Hobo::Dryml::Parser::Elements.new(self)
25
- build(rex_src)
26
-
27
- rescue REXML::ParseException => e
28
- raise Hobo::Dryml::DrymlSyntaxError, "File: #{path}\n#{e}"
29
- end
30
-
31
-
32
- def element_line_num(el)
33
- offset = el.source_offset
34
- @reference_src[0..offset].count("\n") + 1
35
- end
36
-
37
-
38
- def default_attribute_value
39
- "&true"
40
- end
41
-
42
-
43
- def restore_erb_scriptlets(src)
44
- src.gsub(/\[!\[DRYML-ERB(\d+)\s*\]!\]/m) {|s| "<%#{@scriptlets[$1.to_i]}%>" }
45
- end
46
-
47
-
48
- private
49
- def build( source )
50
- Hobo::Dryml::Parser::TreeParser.new( source, self ).parse
51
- end
52
-
53
- end
54
-
55
- end
56
-
57
- end
@@ -1,27 +0,0 @@
1
- module Hobo::Dryml::Parser
2
-
3
- class Element < REXML::Element
4
-
5
- def initialize(*args)
6
- super
7
- @elements = Hobo::Dryml::Parser::Elements.new(self)
8
- end
9
-
10
- def dryml_name
11
- expanded_name.sub(/:.*/, "")
12
- end
13
-
14
- attr_accessor :start_tag_source, :source_offset
15
-
16
- attr_writer :has_end_tag
17
- def has_end_tag?
18
- @has_end_tag
19
- end
20
-
21
- def parameter_tag?
22
- expanded_name =~ /:$/
23
- end
24
-
25
- end
26
-
27
- end
@@ -1,45 +0,0 @@
1
- module Hobo::Dryml::Parser
2
-
3
- class Element < REXML::Element
4
-
5
- def initialize(*args)
6
- super
7
- @elements = Hobo::Dryml::Parser::Elements.new(self)
8
- end
9
-
10
- def dryml_name
11
- expanded_name.sub(/:.*/, "")
12
- end
13
-
14
- attr_accessor :start_tag_source, :source_offset
15
-
16
- attr_writer :has_end_tag
17
- def has_end_tag?
18
- @has_end_tag
19
- end
20
-
21
- def parameter_tag?
22
- expanded_name =~ /:$/
23
- end
24
-
25
- end
26
-
27
- class Elements < REXML::Elements
28
-
29
- # Override to ensure DRYML elements are created
30
- def add(element=nil)
31
- rv = nil
32
- if element.nil?
33
- Hobo::Dryml::Parser::Element.new("", self, @element.context)
34
- elsif not element.kind_of?(Element)
35
- Hobo::Dryml::Parser::Element.new(element, self, @element.context)
36
- else
37
- @element << element
38
- element.context = @element.context
39
- element
40
- end
41
- end
42
-
43
- end
44
-
45
- end
@@ -1,58 +0,0 @@
1
- module Hobo::Dryml::Parser
2
-
3
- # A REXML source that keeps track of where in the buffer it is
4
- class Source < REXML::Source
5
-
6
- def initialize(src)
7
- super(src)
8
- @buffer_offset = 0
9
- end
10
-
11
- attr_reader :last_match_offset
12
-
13
- def remember_match(m)
14
- if m
15
- @last_match = m
16
- @last_match_offset = @buffer_offset + m.begin(0)
17
- @orig[@last_match_offset..@last_match_offset+m[0].length] == @buffer[m.begin(0)..m.end(0)]
18
- end
19
- m
20
- end
21
-
22
- def advance_buffer(md)
23
- @buffer = md.post_match
24
- @buffer_offset += md.end(0)
25
- end
26
-
27
- def scan(pattern, cons=false)
28
- raise '!'
29
- return nil if @buffer.nil?
30
- rv = @buffer.scan(pattern)
31
- if cons and rv.size > 0
32
- advance_buffer(Regexp.last_match)
33
- end
34
- rv
35
- end
36
-
37
- def consume(pattern)
38
- md = remember_match(pattern.match(@buffer))
39
- if md
40
- advance_buffer(md)
41
- @buffer
42
- end
43
- end
44
-
45
- def match(pattern, cons=false)
46
- md = remember_match(pattern.match(@buffer))
47
- advance_buffer(md) if cons and md
48
- return md
49
- end
50
-
51
- def current_line
52
- pos = last_match_offset || 0
53
- [0, 0, @orig[0..pos].count("\n") + 1]
54
- end
55
-
56
- end
57
-
58
- end
@@ -1,13 +0,0 @@
1
- module Hobo::Dryml::Parser
2
-
3
- class Text < REXML::Text
4
-
5
- def parent=(parent)
6
- # Bypass immediate super
7
- REXML::Child.instance_method(:parent=).bind(self).call(parent)
8
- Text.check(@string, /</, nil) if @raw and @parent && Text.respond_to?(:check)
9
- end
10
-
11
- end
12
-
13
- end
@@ -1,67 +0,0 @@
1
- module Hobo::Dryml::Parser
2
-
3
- class TreeParser < REXML::Parsers::TreeParser
4
- def initialize( source, build_context = Document.new )
5
- @build_context = build_context
6
- @parser = Hobo::Dryml::Parser::BaseParser.new(source)
7
- end
8
-
9
-
10
- def parse
11
- tag_stack = []
12
- in_doctype = false
13
- entities = nil
14
- begin
15
- while true
16
- event = @parser.pull
17
- #STDERR.puts "TREEPARSER GOT #{event.inspect}"
18
- case event[0]
19
- when :end_document
20
- unless tag_stack.empty?
21
- #raise ParseException.new("No close tag for #{tag_stack.inspect}")
22
- raise ParseException.new("No close tag for #{@build_context.xpath}")
23
- end
24
- return
25
- when :start_element
26
- tag_stack.push(event[1])
27
- el = @build_context = @build_context.add_element( event[1] )
28
- event[2].each do |key, value|
29
- el.attributes[key]=Hobo::Dryml::Parser::Attribute.new(key,value,self)
30
- end
31
- @build_context.start_tag_source = event[3]
32
- @build_context.source_offset = event[4]
33
- when :end_element
34
- tag_stack.pop
35
- @build_context.has_end_tag = event[2]
36
- @build_context = @build_context.parent
37
- when :text
38
- if not in_doctype
39
- if @build_context[-1].instance_of? Text
40
- @build_context[-1] << event[1]
41
- else
42
- @build_context.add(
43
- Hobo::Dryml::Parser::Text.new(event[1], @build_context.whitespace, nil, true)
44
- ) unless (
45
- @build_context.ignore_whitespace_nodes and
46
- event[1].strip.size==0
47
- )
48
- end
49
- end
50
- when :comment
51
- c = REXML::Comment.new( event[1] )
52
- @build_context.add( c )
53
- when :cdata
54
- c = REXML::CData.new( event[1] )
55
- @build_context.add( c )
56
- when :processing_instruction
57
- @build_context.add( Instruction.new( event[1], event[2] ) )
58
- end
59
- end
60
- rescue REXML::Validation::ValidationException
61
- raise
62
- rescue
63
- raise REXML::ParseException.new( $!.message, @parser.source, @parser, $! )
64
- end
65
- end
66
- end
67
- end
@@ -1,137 +0,0 @@
1
- module Hobo
2
-
3
- module Dryml
4
-
5
- # Raised when the part context fails its integrity check.
6
- class PartContext
7
-
8
- class TamperedWithPartContext < StandardError; end
9
-
10
- class TypedId < String; end
11
-
12
- class << self
13
- attr_accessor :secret, :digest
14
- end
15
- self.digest = 'SHA1'
16
-
17
-
18
- def self.client_side_storage(contexts, session)
19
- return "" if contexts.empty?
20
-
21
- contexts.map do |dom_id, context|
22
- code = context.marshal(session).split("\n").map{|line| "'#{line}\\n'"}.join(" +\n ")
23
- "hoboParts['#{dom_id}'] = (#{code});\n"
24
- end.join
25
- end
26
-
27
-
28
- def self.pre_marshal(x)
29
- if x.is_a?(ActiveRecord::Base) && x.respond_to?(:typed_id)
30
- TypedId.new(x.typed_id)
31
- else
32
- x
33
- end
34
- end
35
-
36
-
37
- def self.for_call(part_name, environment, locals)
38
- new do |c|
39
- c.part_name = part_name
40
- c.locals = locals.map { |l| pre_marshal(l) }
41
- c.this_id = environment.typed_id
42
- c.form_field_path = environment.form_field_path
43
- end
44
- end
45
-
46
-
47
- def self.for_refresh(encoded_context, page_this, session)
48
- new do |c|
49
- c.unmarshal(encoded_context, page_this, session)
50
- end
51
- end
52
-
53
-
54
- def initialize
55
- yield self
56
- end
57
-
58
- attr_accessor :part_name, :locals, :this, :this_field, :this_id, :form_field_path
59
-
60
-
61
- def marshal(session)
62
- context = [@part_name, @this_id, @locals]
63
- context << form_field_path if form_field_path
64
- data = Base64.encode64(Marshal.dump(context)).strip
65
- digest = generate_digest(data, session)
66
- "#{data}--#{digest}"
67
- end
68
-
69
-
70
- # Unmarshal part context to a hash and verify its integrity.
71
- def unmarshal(client_store, page_this, session)
72
- data, digest = CGI.unescape(client_store).strip.split('--')
73
-
74
- raise TamperedWithPartContext unless digest == generate_digest(data, session)
75
-
76
- context = Marshal.load(Base64.decode64(data))
77
-
78
- part_name, this_id, locals, form_field_path = context
79
-
80
- if RAILS_DEFAULT_LOGGER
81
- RAILS_DEFAULT_LOGGER.info "Call part: #{part_name}. this-id = #{this_id}, locals = #{locals.inspect}"
82
- RAILS_DEFAULT_LOGGER.info " : form_field_path = #{form_field_path.inspect}" if form_field_path
83
- end
84
-
85
- self.part_name = part_name
86
- self.this_id = this_id
87
- self.locals = restore_locals(locals)
88
- self.form_field_path = form_field_path
89
-
90
- parse_this_id(page_this)
91
- end
92
-
93
-
94
- # Generate the HMAC keyed message digest. Uses SHA1 by default.
95
- def generate_digest(data, session)
96
- secret = self.class.secret || ActionController::Base.session_options[:secret] || ActionController::Base.cached_session_options.first[:secret]
97
- key = secret.respond_to?(:call) ? secret.call(session) : secret
98
- OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new(self.class.digest), key, data)
99
- end
100
-
101
-
102
-
103
- def parse_this_id(page_this)
104
- if this_id == "this"
105
- self.this = page_this
106
- elsif this_id =~ /^this:(.*)/
107
- self.this = page_this
108
- self.this_field = $1
109
- elsif this_id == "nil"
110
- nil
111
- else
112
- parts = this_id.split(':')
113
- if parts.length == 3
114
- self.this = Hobo::Model.find_by_typed_id("#{parts[0]}:#{parts[1]}")
115
- self.this_field = parts[2]
116
- else
117
- self.this = Hobo::Model.find_by_typed_id(this_id)
118
- end
119
- end
120
- end
121
-
122
-
123
- def restore_locals(locals)
124
- locals.map do |l|
125
- if l.is_a?(TypedId)
126
- Hobo::Model.find_by_typed_id(l)
127
- else
128
- l
129
- end
130
- end
131
- end
132
-
133
- end
134
-
135
- end
136
-
137
- end
@@ -1,42 +0,0 @@
1
- module Hobo::Dryml
2
-
3
- class ScopedVariables
4
-
5
- def initialize(variables=nil)
6
- @scopes = variables ? [variables] : []
7
- end
8
-
9
- def [](key)
10
- s = scope_with_key(key) and s[key]
11
- end
12
-
13
- def []=(key, val)
14
- s = scope_with_key(key) or raise ArgumentError, "no such scoped variable: #{key}"
15
- s[key] = val
16
- end
17
-
18
- def new_scope(variables)
19
- @scopes << variables.dup
20
- res = yield
21
- @scopes.pop
22
- res
23
- end
24
-
25
- def scope_with_key(key)
26
- @scopes.reverse_each do |s|
27
- return s if s.has_key?(key)
28
- end
29
- nil
30
- end
31
-
32
- def method_missing(name, *args)
33
- if name.to_s =~ /=$/
34
- self[name.to_s[0..-2].to_sym] = args.first
35
- else
36
- self[name]
37
- end
38
- end
39
-
40
- end
41
-
42
- end