flex_scaffold 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.
Files changed (48) hide show
  1. data/CHANGELOG +4 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README +169 -0
  4. data/Rakefile +116 -0
  5. data/TODO +23 -0
  6. data/generators/flex_scaffold/USAGE +16 -0
  7. data/generators/flex_scaffold/flex_scaffold_generator.rb +434 -0
  8. data/generators/flex_scaffold/templates/_form.rhtml +1 -0
  9. data/generators/flex_scaffold/templates/_index.rmxml +210 -0
  10. data/generators/flex_scaffold/templates/_list.rhtml +0 -0
  11. data/generators/flex_scaffold/templates/_list.rmxml +17 -0
  12. data/generators/flex_scaffold_resource/USAGE +36 -0
  13. data/generators/flex_scaffold_resource/flex_scaffold_resource_generator.rb +81 -0
  14. data/generators/flex_scaffold_resource/templates/controller.rb +101 -0
  15. data/generators/flex_scaffold_resource/templates/index.rhtml +3 -0
  16. data/generators/flex_scaffold_resource/templates/layout.rhtml +19 -0
  17. data/init.rb +29 -0
  18. data/install.rb +1 -0
  19. data/lib/action_view_helper.rb +49 -0
  20. data/lib/actionscript_helper.rb +81 -0
  21. data/lib/config.rb +49 -0
  22. data/lib/flex_scaffold_plugin.rb +25 -0
  23. data/lib/flexobject_view_helper.rb +132 -0
  24. data/lib/mtag_helper.rb +98 -0
  25. data/lib/mxml_helper.rb +107 -0
  26. data/lib/rest_scaffolding.rb +137 -0
  27. data/lib/validations.rb +180 -0
  28. data/public/crossdomain.xml +6 -0
  29. data/public/history.htm +21 -0
  30. data/public/history.swf +0 -0
  31. data/public/images/add.gif +0 -0
  32. data/public/images/arrow_down.gif +0 -0
  33. data/public/images/arrow_up.gif +0 -0
  34. data/public/images/create.gif +0 -0
  35. data/public/images/delete.gif +0 -0
  36. data/public/images/indicator-small.gif +0 -0
  37. data/public/images/indicator.gif +0 -0
  38. data/public/images/read.gif +0 -0
  39. data/public/images/search.gif +0 -0
  40. data/public/images/update.gif +0 -0
  41. data/public/javascripts/flashobject.js +168 -0
  42. data/public/javascripts/history.js +48 -0
  43. data/public/playerProductInstall.swf +0 -0
  44. data/public/stylesheets/default.css +28 -0
  45. data/tasks/compile_swf.rake +100 -0
  46. data/tasks/flex_scaffold.rake +38 -0
  47. data/uninstall.rb +1 -0
  48. metadata +125 -0
@@ -0,0 +1,98 @@
1
+ require 'cgi'
2
+ require 'erb'
3
+
4
+ module ActionView
5
+ module Helpers #:nodoc:
6
+ # Use these methods to generate Flex <mx:> tags programmatically when you can't use
7
+ # a Builder. By default, they output XML compliant tags.
8
+ module TagHelper
9
+ include ERB::Util
10
+
11
+ # Returns an empty XML tag of type +name+ which by default is XML
12
+ # compliant. Add attributes by passing an attributes
13
+ # hash to +options+. For attributes with no value like (disabled and
14
+ # readonly), give it a value of true in the +options+ hash. You can use
15
+ # symbols or strings for the attribute names.
16
+ #
17
+ # tag("TextInput")
18
+ # # => <mx:TextInput />
19
+ # tag("TextInput", { :id => 'field_desc', :width => '274', text => '{ image_grid.selectedItem.desc }' })
20
+ # # => <mx:TextInput width="274" text="{ image_grid.selectedItem.desc }" id="field_desc" />
21
+ def mx_tag(name, options = nil, open = false)
22
+ name = name.to_s.camelize
23
+ "<#{tag_ns}#{name}#{tag_options(options) if options} />"
24
+ end
25
+
26
+ # Returns an XML block tag of type +name+ surrounding the +content+. Add
27
+ # attributes by passing an attributes hash to +options+. For attributes
28
+ # with no value, give it a value of true in
29
+ # the +options+ hash. You can use symbols or strings for the attribute names.
30
+ #
31
+ # content_tag('FormItem', content_tag('TextInput'), :id => "image_desc")
32
+ # # => <mx:FormItem id="image_desc">
33
+ # <mx:TextInput />
34
+ # </mx:FormItem>
35
+ #
36
+ # Instead of passing the content as an argument, you can also use a block
37
+ # in which case, you pass your +options+ as the second parameter.
38
+ #
39
+ # <% mx_content_tag 'FormItem', :id => "image_desc" do -%>
40
+ # <mx:TextInput />
41
+ # <% end -%>
42
+ # # => <mx:FormItem id="image_desc"><mx:TextInput /></mx:FormItem>
43
+ #
44
+ # Alternatively to passed in the tag name as a string, you can pass it in as
45
+ # a symbol and it will be CamelCased
46
+ #
47
+ # content_tag(:form_item, content_tag(:text_input), :id => "image_desc")
48
+ # # => <mx:FormItem id="image_desc">
49
+ # <mx:TextInput />
50
+ # </mx:FormItem>
51
+ #
52
+ def mx_content_tag(name, content_or_options_with_block = nil, options = nil, &block)
53
+ name = name.to_s.camelize
54
+ if block_given?
55
+ options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
56
+ content = capture(&block)
57
+ concat(mx_content_tag_string(name, content, options), block.binding)
58
+ else
59
+ content = content_or_options_with_block
60
+ mx_content_tag_string(name, content, options)
61
+ end
62
+ end
63
+
64
+ # Returns a CDATA section with the given +content+. CDATA sections
65
+ # are used to escape blocks of text containing characters which would
66
+ # otherwise be recognized as markup. CDATA sections begin with the string
67
+ # <tt><![CDATA[</tt> and end with (and may not contain) the string <tt>]]></tt>.
68
+ #
69
+ # cdata_section("private function clearForm():void {field_title.text = '';}")
70
+ # # => <![CDATA[
71
+ # private function clearForm():void {
72
+ # field_title.text = '';
73
+ # }
74
+ # ]]>
75
+ def cdata_section(content)
76
+ "<![CDATA[#{content}]]>"
77
+ end
78
+
79
+ # Returns the escaped +xml+ without affecting existing escaped entities.
80
+ #
81
+ # escape_once("1 > 2 &amp; 3")
82
+ # # => "1 &lt; 2 &amp; 3"
83
+ def escape_once(html)
84
+ fix_double_escape(html_escape(html.to_s))
85
+ end
86
+
87
+ private
88
+ def mx_content_tag_string(name, content, options)
89
+ tag_options = options ? tag_options(options) : ""
90
+ "<#{tag_ns}#{name}#{tag_options}>#{content}</#{name}>"
91
+ end
92
+
93
+ def tag_ns
94
+ "mx:"
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,107 @@
1
+ require File.dirname(__FILE__) + '/mtag_helper'
2
+
3
+ module ActionView
4
+ module Helpers
5
+ # Provides functionality for working with MXML in your views.
6
+ #
7
+ # If you wish to use this library and its helpers (ActionView::Helpers::MxmlHelper),
8
+ # you must:
9
+ #
10
+ # * Use <tt>flex_scaffold :model</tt> in your controller.
11
+
12
+ module MxmlHelper
13
+
14
+ # Returns the ActionScript that link to the model to the server as a REST
15
+ # +resource+
16
+ #
17
+ # Example:
18
+ # <mx:Script>
19
+ # <![CDATA[
20
+ #
21
+ # private function clearForm():void {
22
+ # field_name.text = '';
23
+ # field_title.text = '';
24
+ # field_size.text = '';
25
+ # field_uri.text = '';
26
+ # field_desc.text = '';
27
+ # }
28
+ #
29
+ # public function deletegraphics(id:String):void {
30
+ # deletegraphic.url = "/graphics/" + id + ".xml";
31
+ # deletegraphic.send({_method: "DELETE"});
32
+ # }
33
+ #
34
+ # private function sendgraphicUpdate():void {
35
+ #
36
+ # var params:Object = new Object();
37
+ # params['_method'] = "PUT";
38
+ # params['graphic[name]'] = field_name.text;
39
+ # params['graphic[title]'] = field_title.text;
40
+ # params['graphic[size]'] = field_size.text;
41
+ # params['graphic[uri]'] = field_uri.text;
42
+ # params['graphic[desc]'] = field_desc.text;
43
+ #
44
+ # updategraphic.url = "/graphics/" + graphic_grid.selectedItem.id + ".xml";
45
+ # updategraphic.send(params);
46
+ # }
47
+ #
48
+ # ]]>
49
+ # </mx:Script>
50
+ def mx_resource(model, *args)
51
+
52
+ end
53
+
54
+ # Returns the mx HTTPSService defined for a REST service call to rails
55
+ #
56
+ # Example:
57
+ # <mx:HTTPService id="listimage" url="/images.xml" useProxy="false" method="GET"/>
58
+ # <mx:HTTPService id="updateimage" useProxy="false" method="POST" result="listimage.send()"/>
59
+ # <mx:HTTPService id="deleteimage" useProxy="false" method="POST" result="listimage.send()"/>
60
+ # <mx:HTTPService id="createimage" url="/images.xml" useProxy="false" method="POST" result="listimage.send()"
61
+ # contentType="application/xml">
62
+ # <mx:request xmlns="">
63
+ # <image>
64
+ # <title>{field_title.text}</title>
65
+ # <filename>{field_filename.text}</filename>
66
+ # <desc>{field_desc.text}</desc>
67
+ # <size>{field_size.text}</size>
68
+ # </image>
69
+ # </mx:request>
70
+ # </mx:HTTPService>
71
+
72
+ def mx_service
73
+
74
+ end
75
+
76
+ # Returns the application mxml tag
77
+ #
78
+ # Example:
79
+ # <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
80
+ # layout="absolute"
81
+ # width="100%"
82
+ # height="100%"
83
+ # creationComplete="{list<%= singular_name %>.send();}"
84
+ # xmlns:egenial="*"
85
+ # backgroundColor="#808080"
86
+ # backgroundGradientColors="[#808080, #ffffff]">
87
+
88
+ def mx_application(name, *args, &block)
89
+
90
+ end
91
+
92
+ # Returns the validators mxml tag
93
+ #
94
+ # Example:
95
+ # <mx:StringValidator source="{field_create_title}" property="text"
96
+ # tooShortError="This string is shorter than the minimum allowed length of 4."
97
+ # tooLongError="This string is longer than the maximum allowed length of 255."
98
+ # minLength="4" maxLength="255"
99
+ # trigger="{btn_add_create}" triggerEvent="click" />
100
+
101
+ def mx_validators
102
+
103
+ end
104
+
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,137 @@
1
+ require 'action_controller'
2
+
3
+ module ActionController # :nodoc:
4
+ module FlexRestScaffolding # :nodoc:
5
+ def self.append_features(base)
6
+ super
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ # REST Scaffolding provides Flex REST actions for creating, reading,
11
+ # updating, and destroying records.
12
+ #
13
+ # Also returns the schema for the record
14
+ #
15
+ # Example:
16
+ #
17
+ # class ContactsController < ActionController::Base
18
+ # flex_scaffold :contacts
19
+ # end
20
+ module ClassMethods
21
+ # Adds Flex REST actions to the controller. The options
22
+ # are the same as for ActionView::Scaffolding.scaffold, except
23
+ # that the <tt>:suffix</tt> option is not currently supported.
24
+ #
25
+ # These are merely the same as a resource albeit a couple of mods
26
+
27
+ def flex_scaffold(model_id, options = {})
28
+ options.assert_valid_keys(:class_name, :suffix, :size)
29
+
30
+ swf_size = options[:size] || FlexScaffold::Config.default_size
31
+ singular_name = model_id.to_s
32
+ class_name = options[:class_name] || singular_name.camelize
33
+ plural_name = singular_name.pluralize
34
+
35
+ class_eval <<-"end_eval", __FILE__, __LINE__
36
+ # GET /contacts
37
+ # GET /contacts.xml
38
+ def index
39
+ flex_index
40
+ end
41
+
42
+ def flex_index
43
+ @#{singular_name} = #{class_name}.find(:all)
44
+ @swf_name = "_#{plural_name}"
45
+ @page_title = "#{plural_name.camelize}"
46
+ @size = "#{swf_size}"
47
+
48
+ respond_to do |format|
49
+ format.html { render :template => "#{FlexScaffold::Config.plugin_name}/index" } # index.rhtml
50
+ format.xml { render :xml => @#{singular_name}.to_xml }
51
+ end
52
+ end
53
+
54
+ # GET /contacts/1
55
+ # GET /contacts/1.xml
56
+ def show
57
+ @#{singular_name} = #{class_name}.find(params[:id])
58
+
59
+ respond_to do |format|
60
+ format.html # show.rhtml
61
+ format.xml { render :xml => @#{singular_name}.to_xml }
62
+ end
63
+ end
64
+
65
+ # GET /contacts/new
66
+ def new
67
+ @#{singular_name} = #{class_name}.new
68
+ end
69
+
70
+ # GET /contacts/1;edit
71
+ def edit
72
+ @#{singular_name} = #{class_name}.find(params[:id])
73
+ end
74
+
75
+ # POST /contacts
76
+ # POST /contacts.xml
77
+ def create
78
+ @#{singular_name} = #{class_name}.new(params[:#{singular_name}])
79
+
80
+ respond_to do |format|
81
+ if @#{singular_name}.save
82
+ flash[:notice] = '#{class_name} was successfully created.'
83
+ format.html { redirect_to contact_url(@#{singular_name}) }
84
+ format.xml { head :created } # :location => contact_url(@#{singular_name}) # removed from original
85
+ else
86
+ format.html { render :action => "new" }
87
+ format.xml { render :xml => @#{singular_name}.errors.to_xml }
88
+ end
89
+ end
90
+ end
91
+
92
+ # PUT /contacts/1
93
+ # PUT /contacts/1.xml
94
+ def update
95
+ @#{singular_name} = #{class_name}.find(params[:id])
96
+
97
+ respond_to do |format|
98
+ if @#{singular_name}.update_attributes(params[:#{singular_name}])
99
+ flash[:notice] = '#{class_name} was successfully updated.'
100
+ format.html { redirect_to contact_url(@#{singular_name}) }
101
+ format.xml { head :ok }
102
+ else
103
+ format.html { render :action => "edit" }
104
+ format.xml { render :xml => @#{singular_name}.errors.to_xml }
105
+ end
106
+ end
107
+ end
108
+
109
+ # DELETE /contacts/1
110
+ # DELETE /contacts/1.xml
111
+ def destroy
112
+ @#{singular_name} = #{class_name}.find(params[:id])
113
+ @#{singular_name}.destroy
114
+
115
+ respond_to do |format|
116
+ format.html { redirect_to contacts_url }
117
+ format.xml { head :ok }
118
+ end
119
+ end
120
+
121
+ # GET /contacts/schema/1
122
+ # GET /contacts/schema/1.xml
123
+ # TODO: changes routes so that this does not require an ID
124
+ def schema
125
+ response.headers["Content-Type"] = "text/xml"
126
+ render :text => schema_xml(#{class_name})
127
+ end
128
+
129
+ end_eval
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ ActionController::Base.class_eval do
136
+ include ActionController::FlexRestScaffolding
137
+ end
@@ -0,0 +1,180 @@
1
+ module FlexScaffold
2
+
3
+ class Validations
4
+
5
+ VALIDATIONS_INFO = %w( message with on in maximum minimum too_short too_long )
6
+ SCHEMA_INFO = %w( type limit default )
7
+
8
+ def initialize(base={},attrs={}) # :nodoc:
9
+ @record, @attrs, @schema_attrs = base, attrs, {}
10
+ end
11
+
12
+ # Adds a validation of an attribute (+attr_name+) to the record and returns the individual set
13
+ # that was added
14
+ def add(attr_name, type, configuration={})
15
+ attribute = add_type_to_hash(attr_name, type)
16
+ VALIDATIONS_INFO.each do |rule| attribute.update(rule.to_s => configuration[rule.to_sym]) unless configuration[rule.to_sym].nil? end
17
+ @attrs
18
+ end
19
+
20
+ # Adds the schema information into the validation of the attributes. This information includes the
21
+ # +type+, +limit+, and +default+ values.
22
+ def load_schema_info(class_name=@record)
23
+ @attrs.merge(get_schema_info(class_name))
24
+ end
25
+
26
+ # Returns the schema-based validation information of the attributes. This information includes the
27
+ # +type+, +limit+, and +default+ values. It is categorised by the attribute name
28
+ def get_schema_info(class_name=@record)
29
+ klass = Object.const_get(class_name.to_s.camelize) rescue nil
30
+ if klass && klass < ActiveRecord::Base
31
+ klass.columns.each do |col|
32
+ attribute = add_schema_to_hash(col.name)
33
+ SCHEMA_INFO.each do |info| attribute.update(info => eval("col.#{info}.to_s")) end
34
+ end
35
+ end
36
+ @schema_attrs
37
+ end
38
+
39
+ # Removes all the validations that have been added
40
+ def clear
41
+ @attrs = {}
42
+ end
43
+
44
+ # Returns the attribute validations
45
+ def validations
46
+ @attrs
47
+ end
48
+
49
+ # Yields each attribute and associated details per validation added
50
+ def each
51
+ @attrs.each_key { |attr| @attrs[attr].each { |msg| yield attr, msg } }
52
+ end
53
+
54
+ # Returns true if no validations have been added
55
+ def empty?
56
+ @attrs.empty?
57
+ end
58
+
59
+ # Returns the number of attributes with validations
60
+ def size
61
+ @attrs.size
62
+ end
63
+
64
+ # Returns the string of attributes with validations
65
+ def to_s
66
+ @attrs.to_s
67
+ end
68
+
69
+ # Returns an XML representation of the validation object
70
+ def to_xml
71
+ @attrs.to_xml
72
+ end
73
+
74
+ private
75
+
76
+ # TODO: refactor to allow for hierarchical key
77
+ def add_column_to_hash(hash, key)
78
+ hash.update(key.to_s => {}) if hash[key.to_s].nil?
79
+ hash[key.to_s]
80
+ end
81
+
82
+ # "name"=>{"length"=>{"maximum"=>6,
83
+ # "too_long"=>"Your name can't be longer than 6 characters"},
84
+ # "presence"=>{},
85
+ # "inclusion"=>{"in"=>["john", "fred", "tom"]}}
86
+
87
+ def add_type_to_hash(key, type)
88
+ add_column_to_hash(add_column_to_hash(@attrs, key), type)
89
+ end
90
+
91
+ # "name"=>{"schema"=>{"default"=>6,
92
+
93
+ def add_schema_to_hash(key)
94
+ add_column_to_hash(add_column_to_hash(@schema_attrs, key), :schema)
95
+ end
96
+
97
+ end
98
+ end
99
+
100
+ module ActiveRecord #:nodoc:
101
+
102
+ class Base
103
+
104
+ # Returns just the validations set in the model on each attribute
105
+ cattr_accessor :validations
106
+ @@validations = {}
107
+
108
+ class << self
109
+
110
+ # Creates an object and returns all validations without persisting
111
+ def new_validations
112
+ object = new # this triggers the validations so that they are captured
113
+ schema = schema_validations
114
+ object.instance_variable_set(:@validations, schema.merge(validations) )
115
+ unset_aliases
116
+ object
117
+ end
118
+
119
+ # Returns the schema validations defined in the migration
120
+ def schema_validations
121
+ FlexScaffold::Validations.new(name).get_schema_info
122
+ end
123
+
124
+ end
125
+
126
+ end
127
+
128
+ module Validations # :nodoc:
129
+
130
+ def self.included(base) # :nodoc:
131
+ base.extend(ClassMethods)
132
+ end
133
+
134
+ module ClassMethods # :nodoc:
135
+
136
+ VALIDATE_METHODS = %w( presence
137
+ format
138
+ numericality
139
+ exclusion
140
+ inclusion
141
+ uniqueness
142
+ length
143
+ acceptance)
144
+
145
+ VALIDATE_METHODS.each do |method|
146
+
147
+ class_eval <<-"end_eval", __FILE__, __LINE__
148
+ alias_method "base_validates_#{method}_of", "validates_#{method}_of"
149
+ def new_validates_#{method}_of(*attr_names)
150
+ configuration = {}
151
+ configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
152
+ add_validation(:@@validations, attr_names, :#{method}, configuration)
153
+ base_validates_#{method}_of(attr_names, configuration)
154
+ end
155
+ alias_method "validates_#{method}_of", "new_validates_#{method}_of"
156
+
157
+ end_eval
158
+ end
159
+
160
+ protected
161
+
162
+ def unset_aliases # :nodoc:
163
+ sing = class << self; self; end
164
+ VALIDATE_METHODS.each do |method|
165
+ sing.send :alias_method, "validates_#{method}_of", "base_validates_#{method}_of"
166
+ end
167
+ end
168
+
169
+ private
170
+
171
+ # Update the list of validations for the model. This adds new validations
172
+ # to the class <tt>@@validations</tt> variable
173
+ def add_validation(class_var, attr, method, configuration)
174
+ class_variable_set(class_var, FlexScaffold::Validations.new(nil, class_variable_get(class_var)).add(attr, method, configuration))
175
+ end
176
+
177
+ end
178
+ end
179
+ end
180
+
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0"?>
2
+ <cross-domain-policy>
3
+ <allow-access-from domain="*" />
4
+ </cross-domain-policy>
5
+
6
+
@@ -0,0 +1,21 @@
1
+ <html>
2
+ <head>
3
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
4
+ <script type='text/javascript' language='JavaScript1.2' charset='utf-8'>
5
+ var v = new top.Vars(top.getSearch(window));
6
+ var fv = v.toString('$_');
7
+ </script>
8
+ </head>
9
+ <body >
10
+ <script type='text/javascript' language='JavaScript1.2' charset='utf-8'>
11
+ document.writeln('<object id=\"utility\" name=\" \" classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" codebase=\"" + activexDownloadURL + "#version=7,0,14,0\" width=\"100\" height=\"50\">');
12
+ document.writeln('<param name=\"movie\" value=\"history.swf\" />');
13
+ document.writeln('<param name=\"FlashVars\" value=\"'+fv+'&$_lconid='+top.lc_id+'\"/>');
14
+ document.writeln('<param name=\"quality\" value=\"high\" />');
15
+ document.writeln('<param name=\"bgcolor\" value=\"#FFFFFF\" />');
16
+ document.writeln('<param name=\"profile\" value=\"false\" />');
17
+ document.writeln('<embed id=\"utilityEmbed\" name=\"history.swf\" src=\"history.swf\" type=\"application/x-shockwave-flash\" flashvars=\"'+fv+'&$_lconid='+top.lc_id+'\" profile=\"false\" quality=\"high\" bgcolor=\"#FFFFFF\" width=\"100\" height=\"50\" align=\"\" pluginspage=\"" + pluginDownloadURL + "\"></embed>');
18
+ document.writeln('</object>');
19
+ </script>
20
+ </body>
21
+ </html>
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file