wedge 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/Gemfile +2 -0
  4. data/lib/roda/plugins/wedge.rb +15 -5
  5. data/lib/wedge/component.rb +40 -9
  6. data/lib/wedge/config.rb +2 -0
  7. data/lib/wedge/dom.rb +1 -0
  8. data/lib/wedge/events.rb +1 -1
  9. data/lib/wedge/html.rb +39 -0
  10. data/lib/wedge/middleware.rb +14 -12
  11. data/lib/wedge/plugins/uploader.rb +287 -0
  12. data/lib/wedge/require.rb +23 -35
  13. data/lib/wedge/version.rb +1 -1
  14. data/lib/wedge.rb +29 -18
  15. data/playground/Gruntfile.coffee +99 -0
  16. data/playground/app/app.rb +57 -0
  17. data/playground/app/components/index.rb +12 -0
  18. data/playground/app/components/layout.rb +38 -0
  19. data/playground/app/components/uploader.rb +32 -0
  20. data/playground/app/config/boot.rb +14 -0
  21. data/playground/app/config/variables.rb +16 -0
  22. data/{test/dummy → playground/backup}/components/bar.rb +0 -0
  23. data/{test/dummy → playground/backup}/components/base.rb +0 -0
  24. data/{test/dummy → playground/backup}/components/layout.rb +0 -0
  25. data/playground/backup/components/profile.rb +0 -0
  26. data/{test/dummy → playground/backup}/components/root.rb +12 -4
  27. data/{test/dummy → playground/backup}/forms/bar.rb +0 -0
  28. data/{test/dummy → playground/backup}/forms/foo.rb +0 -0
  29. data/playground/backup/html/layout.html +9 -0
  30. data/playground/bower.json +25 -0
  31. data/playground/config.ru +5 -0
  32. data/playground/package.json +19 -0
  33. data/playground/public/css/styles.css +2649 -0
  34. data/playground/public/css/styles.css.map +7 -0
  35. data/playground/public/includes/_head.html +9 -0
  36. data/playground/public/index.html +18 -0
  37. data/playground/public/uploader.html +33 -0
  38. data/playground/public/vendor/font-awesome/fonts/FontAwesome.otf +0 -0
  39. data/playground/public/vendor/font-awesome/fonts/fontawesome-webfont.eot +0 -0
  40. data/playground/public/vendor/font-awesome/fonts/fontawesome-webfont.svg +565 -0
  41. data/playground/public/vendor/font-awesome/fonts/fontawesome-webfont.ttf +0 -0
  42. data/playground/public/vendor/font-awesome/fonts/fontawesome-webfont.woff +0 -0
  43. data/playground/public/vendor/font-awesome/fonts/fontawesome-webfont.woff2 +0 -0
  44. data/playground/public/vendor/jquery/jquery.js +9210 -0
  45. data/playground/public/vendor/normalize-css/normalize.css +424 -0
  46. data/playground/src/css/_uploader.scss +73 -0
  47. data/playground/src/css/_variables.scss +16 -0
  48. data/playground/src/css/addons/_buttons.scss +12 -0
  49. data/playground/src/css/styles.scss +14 -0
  50. data/playground/src/includes/_head.slim +12 -0
  51. data/playground/src/index.slim +6 -0
  52. data/playground/src/uploader.slim +13 -0
  53. data/wedge.gemspec +1 -1
  54. metadata +46 -23
  55. data/test/dummy/app.rb +0 -46
  56. data/test/dummy/config.ru +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a0bb0fe7c7495477be902553128393527696afe1
4
- data.tar.gz: 11a43824c93d96973043520a5429e73bc89f94df
3
+ metadata.gz: c03ec1090649b719dd845c4167b3c717886cd59a
4
+ data.tar.gz: d8193a5ffec834680dbe884db02416ccc935805b
5
5
  SHA512:
6
- metadata.gz: 394f8a1cef109e32f546ea7d9166a67307f11ed6701739ce4feab23b9e7d6033397e0ef90b0e13b57a5311dd2e996ef6189452110f517c092eab5621924b007b
7
- data.tar.gz: 49b95ed36fe62f5ab1fe7234e4bac2066d6f027c9dbea69082df961f091e2f5c5d50152fa5f5f4e419f4b05106cadf076078331bfa29d8f31d0fbd5ed8813eeb
6
+ metadata.gz: c62a5ab5e18f862c9734e2abb8ccfa3422ac5e6d97942283e01cebd2df94bd4ea2ffbf444b27e1e7844e6797688d217608e0edc35b442cbe3df0f4182bf57a88
7
+ data.tar.gz: 0c3746d9d3074b798bb5dc1836785c2e4b46c8a6bbeffdadeb2ad397b8070dced9bbe358e43cd251582a5e58a96afeb777d9bca59d229d5d8a8c40822d35c928
data/.gitignore CHANGED
@@ -11,4 +11,8 @@
11
11
  *.so
12
12
  *.o
13
13
  *.a
14
+ .env
14
15
  mkmf.log
16
+ bower_components/
17
+ node_modules/
18
+ .sass-cache/
data/Gemfile CHANGED
@@ -7,5 +7,7 @@ gem 'opal', github: 'opal/opal', path: '~/gems/opal'
7
7
  gem 'opal-jquery', github: 'opal/opal-jquery'
8
8
  gem 'binding_of_caller'
9
9
  gem 'better_errors'
10
+ gem 'slim'
11
+ gem 'sass'
10
12
  gem 'thin'
11
13
  gem 'roda-bin'
@@ -33,6 +33,10 @@ class Roda
33
33
  def wedge(name, *args, &block)
34
34
  ::Wedge.scope!(self)[name, *args, &block]
35
35
  end
36
+
37
+ def wedge_plugin(name, *args, &block)
38
+ ::Wedge.scope!(self)["#{name}_plugin", *args, &block]
39
+ end
36
40
  end
37
41
 
38
42
  module RequestClassMethods
@@ -62,17 +66,23 @@ class Roda
62
66
  data = scope.request.params
63
67
 
64
68
  begin
69
+ # try json
65
70
  data.merge!(body ? JSON.parse(body) : {})
66
71
  rescue
67
- # can't be parsed by json
72
+ begin
73
+ # try form data
74
+ data.merge!(body ? Rack::Utils.parse_query(body) : {})
75
+ rescue
76
+ # no data
77
+ end
68
78
  end
69
79
 
70
80
  data = data.indifferent
71
- name = data.delete(:wedge_name)
72
- method_called = data.delete(:wedge_method_called)
73
- method_args = data.delete(:wedge_method_args)
81
+ name = data.delete(:__wedge_name__)
82
+ method_called = data.delete(:__wedge_method__)
83
+ method_args = data.delete(:__wedge_args__)
74
84
 
75
- if method_args == 'wedge_data' && data
85
+ if method_args == '__wedge_data__' && data
76
86
  method_args = [data]
77
87
  res = scope.wedge(name).send(method_called, *method_args) || ''
78
88
  else
@@ -16,7 +16,12 @@ class Wedge
16
16
  end
17
17
  end
18
18
 
19
- if args.any?
19
+ obj.config.before_compile.each do |blk|
20
+ obj.instance_exec &blk
21
+ end
22
+
23
+ if args.length > 0
24
+ obj.config.initialize_args = args
20
25
  obj.send :initialize, *args, &block
21
26
  else
22
27
  obj.send :initialize, &block
@@ -56,12 +61,12 @@ class Wedge
56
61
  end
57
62
  alias_method :name, :wedge_name
58
63
 
59
- def wedge_html(html, &block)
64
+ def wedge_html(html = '', &block)
60
65
  unless RUBY_ENGINE == 'opal'
61
66
  wedge_config.html = begin
62
67
  File.read html
63
68
  rescue
64
- html
69
+ (html.is_a?(HTML::DSL) || html.is_a?(DOM)) ? html.to_html : html
65
70
  end.strip
66
71
 
67
72
  if block_given?
@@ -94,7 +99,6 @@ class Wedge
94
99
  alias_method :tmpl, :wedge_tmpl
95
100
 
96
101
  def wedge_dom &block
97
- @wedge_dom ||= DOM.new wedge_config.html
98
102
 
99
103
  unless RUBY_ENGINE == 'opal'
100
104
  if block_given?
@@ -102,7 +106,7 @@ class Wedge
102
106
  end
103
107
  end
104
108
 
105
- @wedge_dom
109
+ @wedge_dom ||= DOM.new wedge_config.html
106
110
  end
107
111
  alias_method :dom, :wedge_dom
108
112
 
@@ -163,9 +167,9 @@ class Wedge
163
167
  payload = config.client_data.reject do |k, _|
164
168
  %w(html tmpl requires plugins object_events js_loaded).include? k
165
169
  end
166
- payload[:wedge_name] = payload[:name]
167
- payload[:wedge_method_called] = meth
168
- payload[:wedge_method_args] = args
170
+ payload[:__wedge_name__] = payload[:name]
171
+ payload[:__wedge_method__] = meth
172
+ payload[:__wedge_args__] = args
169
173
 
170
174
  # we want to remove the assets key from the call so we don't get
171
175
  # an error if they assets_key has changed and the user hasn't
@@ -197,12 +201,34 @@ class Wedge
197
201
  include m
198
202
  end
199
203
  end
204
+
205
+ def set_dom dom
206
+ @wedge_dom = dom.is_a?(Wedge::DOM) ? dom : Wedge::DOM.new(dom)
207
+ end
208
+
209
+ def html!(&b)
210
+ unless RUBY_ENGINE == 'opal'
211
+ DOM.new HTML::DSL.html(&b).to_html
212
+ end
213
+ end
214
+
215
+ def store
216
+ wedge_config.store
217
+ end
218
+
219
+ def before_compile &block
220
+ wedge_config.before_compile << block unless RUBY_ENGINE == 'opal'
221
+ end
200
222
  end
201
223
 
202
224
  if RUBY_ENGINE == 'opal'
203
225
  def wedge(*args)
204
226
  Wedge[*args]
205
227
  end
228
+
229
+ def wedge_plugin(name, *args, &block)
230
+ wedge("#{name}_plugin", *args, &block)
231
+ end
206
232
  end
207
233
 
208
234
  def wedge_scope
@@ -282,7 +308,7 @@ class Wedge
282
308
  return unless server?
283
309
 
284
310
  client_data = config.client_data.dup
285
- client_data.merge! method_called: method, method_args: args
311
+ client_data.merge! method_called: method, method_args: args, initialize_args: config.initialize_args
286
312
 
287
313
  compiled_opts = Base64.encode64 client_data.to_json
288
314
  javascript = <<-JS
@@ -304,6 +330,11 @@ class Wedge
304
330
  response
305
331
  end
306
332
 
333
+ def wedge_html(&b)
334
+ DOM.new HTML::DSL.html(&b).to_html
335
+ end
336
+ alias_method :html!, :wedge_html
337
+
307
338
  def method_missing(method, *args, &block)
308
339
  if config.scope.respond_to?(method, true)
309
340
  config.scope.send method, *args, &block
data/lib/wedge/config.rb CHANGED
@@ -29,6 +29,8 @@ class Wedge
29
29
  on_block: [],
30
30
  on_block_count: 0,
31
31
  server_methods: [],
32
+ initialize_args: [],
33
+ before_compile: [],
32
34
  plugins: [],
33
35
  allowed_client_data: %w(name path method_args method_called store tmpl key cache_assets assets_key assets_url assets_url_with_host)
34
36
  }.merge(opts))
data/lib/wedge/dom.rb CHANGED
@@ -15,6 +15,7 @@ class Wedge
15
15
 
16
16
  def initialize html
17
17
  html = '' if html.nil?
18
+ html = html.to_html if html.is_a? HTML::DSL
18
19
 
19
20
  @raw_html = html
20
21
 
data/lib/wedge/events.rb CHANGED
@@ -20,7 +20,7 @@ class Wedge
20
20
  # fix: there is a bug in opal where even though it's only including a
21
21
  # module once it is loading the class twice. So this stops on events being
22
22
  # double added
23
- return if events[:on_count] >= Wedge[wedge_name].class.wedge_on_count
23
+ return if events[:on_count] >= Wedge.config.component_class[wedge_name].wedge_on_count
24
24
  events[:on_count] += 1
25
25
 
26
26
  event = {
data/lib/wedge/html.rb CHANGED
@@ -2,6 +2,8 @@ class Wedge
2
2
  module HTML
3
3
  include Methods
4
4
 
5
+ INDENT = ' '
6
+
5
7
  class << self
6
8
  # Parse HTML into a Nokogiri object
7
9
  # @param raw_html [String]
@@ -25,5 +27,42 @@ class Wedge
25
27
  end
26
28
  end
27
29
  end
30
+
31
+ # http://erikonrails.snowedin.net/?p=379
32
+ class DSL
33
+ def initialize(tag, *args, &block)
34
+ @tag = tag
35
+ @content = args.find {|a| a.instance_of? String}
36
+ @attributes = args.find{|a| a.instance_of? Hash}
37
+ @attr_string = []
38
+ self.instance_eval &block if block_given?
39
+ end
40
+
41
+ def to_html
42
+ @attr_string << " #{@attributes.map {|k,v| "#{k}=#{v.to_s.inspect}" }.join(" ")}" if @attributes
43
+ "<#{@tag}#{@attr_string.join}>#{@content}#{children.map(&:to_html).join}</#{@tag}>"
44
+ end
45
+
46
+ def children
47
+ @children ||= []
48
+ end
49
+
50
+ # Some of these are Kernel or Object methods or whatever that we need to explicitly override
51
+ [:p, :select].each do |name|
52
+ define_method name do |*args, &block|
53
+ send :method_missing, name, *args, &block
54
+ end
55
+ end
56
+
57
+ def method_missing(tag, *args, &block)
58
+ child = DSL.new(tag.to_s, *args, &block)
59
+ children << child
60
+ child
61
+ end
62
+
63
+ def self.method_missing(tag, *args, &block)
64
+ DSL.new(tag.to_s, *args, &block)
65
+ end
66
+ end
28
67
  end
29
68
  end
@@ -28,20 +28,20 @@ class Wedge
28
28
 
29
29
  case extension
30
30
  when 'map'
31
- ::Wedge.source_map wedge_path
31
+ body << ::Wedge.source_map(wedge_path)
32
32
  when 'rb'
33
33
  if wedge_path =~ /^wedge/
34
34
  path = ::Wedge.config.path.gsub(/\/wedge.rb$/, '')
35
- File.read("#{path}/#{wedge_path}.rb")
35
+ body << File.read("#{path}/#{wedge_path}.rb")
36
36
  else
37
- File.read("#{ROOT_PATH}/#{wedge_path}.rb")
37
+ body << File.read("#{ROOT_PATH}/#{wedge_path}.rb")
38
38
  end if Wedge.config.debug
39
39
  when 'call'
40
- body = scope.request.body.read
41
- data = scope.request.params
40
+ body_data = scope.request.body.read
41
+ data = scope.request.params
42
42
 
43
43
  begin
44
- data.merge!(body ? JSON.parse(body) : {})
44
+ data.merge!(body_data ? JSON.parse(body_data) : {})
45
45
  rescue
46
46
  # can't be parsed by json
47
47
  end
@@ -53,18 +53,21 @@ class Wedge
53
53
 
54
54
  if method_args == 'wedge_data' && data
55
55
  method_args = [data]
56
- res = Wedge.scope!(app)[name].send(method_called, *method_args) || ''
56
+ body << Wedge.scope!(app)[name].send(method_called, *method_args) || ''
57
57
  else
58
- res = Wedge.scope!(app)[name, data].send(method_called, *method_args) || ''
58
+ # This used to send things like init, we need a better way to
59
+ # send client config data to the server
60
+ # res = scope.wedge(name, data).send(method_called, *method_args) || ''
61
+ body << Wedge.scope!(app)[name].send(method_called, *method_args) || ''
59
62
  end
60
63
 
61
- headers["WEDGE-CSRF-TOKEN"] = scope.csrf_token if scope.methods.include? :csrf_token
64
+ # headers["WEDGE-CSRF-TOKEN"] = scope.csrf_token if scope.methods.include? :csrf_token
62
65
 
63
66
  if res.is_a? Hash
64
67
  headers["Content-Type"] = 'application/json; charset=UTF-8'
65
- body = res.to_json
68
+ body << res.to_json
66
69
  else
67
- body = res.to_s
70
+ body << res.to_s
68
71
  end
69
72
  else
70
73
  headers['Content-Type'] = 'application/javascript; charset=UTF-8'
@@ -72,7 +75,6 @@ class Wedge
72
75
  if Wedge.config.debug
73
76
  body << "#{Wedge.javascript(wedge_path)}\n//# sourceMappingURL=#{Wedge.assets_url}/#{wedge_path}.map"
74
77
  else
75
- binding.pry
76
78
  body << Wedge.javascript(wedge_path)
77
79
  end
78
80
  end
@@ -0,0 +1,287 @@
1
+ class Wedge
2
+ module Plugins
3
+ class Uploader < Component
4
+ name :uploader, :uploader_plugin
5
+ before_compile do
6
+ settings = Wedge.config.settings[:uploader]
7
+ store[:settings] = settings.select do |k, v|
8
+ client?? %w(aws_access_key_id bucket).include?(k) : true
9
+ end if settings
10
+ end
11
+
12
+ class S3Signature < Struct.new(:policy_data, :settings)
13
+ def policy
14
+ Base64.encode64(policy_data.to_json).gsub("\n", "")
15
+ end
16
+
17
+ def signature
18
+ # The presence of the “headers” property in the JSON request alerts your server to the fact that this is a request to sign a REST/multipart request and not a policy document.
19
+ # Your server only needs to return the following in the body of an “application/json” response:
20
+ encode_string = policy_data["headers"].present? ? policy_data["headers"] : policy
21
+
22
+ Base64.encode64(
23
+ OpenSSL::HMAC.digest(
24
+ OpenSSL::Digest.new('sha1'),
25
+ settings[:aws_secret_access_key], encode_string
26
+ )
27
+ ).gsub("\n", "")
28
+ end
29
+ end
30
+
31
+ def signature policy_data
32
+ s3 = S3Signature.new policy_data, settings
33
+
34
+ {
35
+ policy: s3.policy,
36
+ signature: s3.signature
37
+ }.to_json
38
+ end
39
+
40
+ def success options = {}
41
+ options = options.indifferent
42
+ wedge_name = options.delete :wedge_name
43
+ wedge_method = options.delete :wedge_method
44
+
45
+ if wedge_name
46
+ response.headers["Content-Type"] = 'application/json; charset=UTF-8'
47
+ {
48
+ success: true,
49
+ wedge_name: wedge_name,
50
+ wedge_method: wedge_method,
51
+ wedge_response: wedge(wedge_name).to_js(wedge_method, options),
52
+ dom_file_id: options[:dom_file_id]
53
+ }.to_json
54
+ end
55
+ end
56
+
57
+ def delete options = {}
58
+ options = options.indifferent
59
+ wedge_name = options.delete :wedge_name
60
+ wedge_method = options.delete :delete_method
61
+
62
+ if wedge_name
63
+ response.headers["Content-Type"] = 'application/json; charset=UTF-8'
64
+ {
65
+ success: true,
66
+ wedge_name: wedge_name,
67
+ wedge_method: wedge_method,
68
+ wedge_response: wedge(wedge_name).to_js(wedge_method, options)
69
+ }.to_json
70
+ end
71
+ end
72
+
73
+ def button el, options = {}
74
+ options = { multiple: false }.merge options
75
+ drag_n_drop el, options
76
+ end
77
+
78
+ def drag_n_drop el, options = {}
79
+ id = el.attr 'id'
80
+ container_id = "#{id}-container"
81
+ template_id = "#{id}-tmpl"
82
+ key = options.delete(:aws_name) || '{name}-{uuid}'
83
+
84
+ # add s3 container
85
+ el.after drag_n_drop_tmpl template_id
86
+ el.after "<div id='#{container_id}'></div>"
87
+
88
+ container = dom.find("##{container_id}")
89
+
90
+ uploader = el.fine_uploader_dnd({
91
+ classes: {
92
+ dropActive: "cssClassToAddToDropZoneOnEnter"
93
+ }
94
+ })
95
+
96
+ uploader.on('processingDroppedFiles') do |event|
97
+ # todo: display some sort of a "processing" or spinner graphic
98
+ end
99
+
100
+ uploader.on('processingDroppedFilesComplete') do |event, files, dropTarget|
101
+ # todo: hide spinner/processing graphic
102
+ container.fine_uploader_s3('addFiles', files)
103
+ end
104
+
105
+ uploader_settings = {
106
+ objectProperties: {
107
+ key: function { |key_id|
108
+ promise = Native(`new qq.Promise()`)
109
+ @this.setName(key_id, @this.getName(key_id).gsub(/[^0-9A-Za-z_\.\s-]/, '').gsub(/\s{1,}/,'_'));
110
+ uuid = @this.getUuid(key_id).split('-').last
111
+ ext = @this.getName(key_id).split('.').last
112
+ promise.success(key.gsub('{uuid}', uuid).gsub('{name}', @this.getName(key_id)).gsub('{ext}',ext));
113
+ promise.to_n
114
+ }
115
+ },
116
+ request: {
117
+ # // REQUIRED: We are using a custom domain
118
+ # // for our S3 bucket, in this case. You can
119
+ # // use any valid URL that points to your bucket.
120
+ endpoint: "https://#{settings[:bucket]}.s3.amazonaws.com",
121
+ # // REQUIRED: The AWS public key for the client-side user
122
+ # // we provisioned.
123
+ accessKey: settings[:aws_access_key_id]
124
+ },
125
+
126
+ template: template_id,
127
+
128
+ # // REQUIRED: Path to our local server where requests
129
+ # // can be signed.
130
+ signature: {
131
+ endpoint: "#{Wedge.assets_url}/wedge/plugins/uploader.call?__wedge_method__=signature&__wedge_args__=__wedge_data__&__wedge_name__=uploader_plugin",
132
+ customHeaders: {'X-CSRF-Token' => Element.find('head > meta[name="_csrf"]').attr('content') }
133
+ },
134
+
135
+ # // OPTIONAL: An endopint for Fine Uploader to POST to
136
+ # // after the file has been successfully uploaded.
137
+ # // Server-side, we can declare this upload a failure
138
+ # // if something is wrong with the file.
139
+ uploadSuccess: {
140
+ endpoint: "#{Wedge.assets_url}/wedge/plugins/uploader.call?__wedge_method__=success&__wedge_args__=__wedge_data__&__wedge_name__=uploader_plugin",
141
+ customHeaders: {'X-CSRF-Token' => Element.find('head > meta[name="_csrf"]').attr('content') }
142
+ },
143
+
144
+ # // optional feature
145
+ chunking: {
146
+ enabled: true
147
+ },
148
+
149
+ # // optional feature
150
+ resume: {
151
+ enabled: true
152
+ },
153
+
154
+ thumbnails: {
155
+ placeholders: {
156
+ # notAvailablePath: "assets/not_available-generic.png",
157
+ # waitingPath: "assets/waiting-generic.png"
158
+ }
159
+ },
160
+
161
+ callbacks: {
162
+ onSubmitted: function { |fu_id|
163
+ params = options
164
+ button = Native(@this._buttons[0])
165
+ el = Element.find(button.getInput).closest('.s3-uploader');
166
+ params[:dom_id] = el.attr('id')
167
+ params[:dom_file_id] = fu_id
168
+
169
+ if `qq.supportedFeatures.canDetermineSize`
170
+ size = @this.getSize(fu_id)
171
+ params[:size] = size
172
+ end
173
+
174
+ @this.setUploadSuccessParams(params, fu_id)
175
+ }
176
+ }
177
+ }
178
+
179
+ if options[:delete_method]
180
+ uploader_settings[:deleteFile] = {
181
+ enabled: true,
182
+ forceConfirm: true,
183
+ endpoint: "#{Wedge.assets_url}/wedge/plugins/uploader.call?__wedge_method__=delete&__wedge_args__=__wedge_data__&__wedge_name__=uploader_plugin",
184
+ params: options,
185
+ customHeaders: {
186
+ 'X-CSRF-Token' => Element.find('head > meta[name="_csrf"]').attr('content'),
187
+ 'Accept' => '*/*;q=0.5, text/javascript, application/javascript, application/ecmascript, application/x-ecmascript'
188
+ }
189
+ }
190
+ end
191
+
192
+ if options[:accept_files]
193
+ uploader_settings[:validation] = {
194
+ acceptFiles: options[:accept_files]
195
+ }
196
+ end
197
+
198
+ # if options[:resume_method]
199
+ # uploader_settings[:session] = {
200
+ # endpoint: "#{Wedge.assets_url}/app/components/#{options[:wedge_name]}.call?wedge_method=#{options[:resume_method]}&wedge_method_args=wedge_data&wedge_name=registration",
201
+ # params: options
202
+ # }
203
+ # end
204
+ if !options[:multiple].nil?
205
+ uploader_settings[:multiple] = options.delete(:multiple)
206
+ end
207
+ fine_uploader = container.fine_uploader_s3(uploader_settings)
208
+
209
+ fine_uploader.on('complete') do |event, _, name, response|
210
+ return unless response
211
+
212
+ name = `response.wedge_name`
213
+ dom_file_id = `response.dom_file_id`
214
+ method_called = `response.wedge_method`
215
+ # fix: we should be able to get the object better than this
216
+ data = JSON.parse(`JSON.stringify(response.wedge_response)`)
217
+
218
+ wedge(name).send(method_called, data)
219
+
220
+ dom.find(".qq-file-id-#{dom_file_id}").remove unless options[:preserve_upload]
221
+ end
222
+ end
223
+
224
+ def drag_n_drop_tmpl id
225
+ <<-EOF
226
+ <script type="text/template" id="#{id}">
227
+ <div class="qq-uploader-selector qq-uploader">
228
+ <div class="qq-upload-button-selector qq-upload-button">
229
+ <div>Upload a file</div>
230
+ </div>
231
+ <div class="qq-upload-drop-area-selector qq-upload-drop-area" qq-hide-dropzone>
232
+ <span>Drop file here to upload</span> </div>
233
+ <span class="qq-drop-processing-selector qq-drop-processing">
234
+ <span>Processing dropped files...</span>
235
+ <span class="qq-drop-processing-spinner-selector qq-drop-processing-spinner"></span>
236
+ </span>
237
+ <ul class="qq-upload-list-selector qq-upload-list">
238
+ <li>
239
+ <div class="qq-progress-bar-container-selector">
240
+ <div class="qq-progress-bar-selector qq-progress-bar"></div>
241
+ </div>
242
+ <span class="qq-upload-spinner-selector qq-upload-spinner"></span>
243
+ <img class="qq-thumbnail-selector" qq-max-size="100" qq-server-scale>
244
+ <span class="qq-edit-filename-icon-selector qq-edit-filename-icon"></span>
245
+ <span class="qq-upload-file-selector qq-upload-file"></span>
246
+ <input class="qq-edit-filename-selector qq-edit-filename" tabindex="0" type="text">
247
+ <span class="qq-upload-size-selector qq-upload-size"></span>
248
+ <a class="qq-upload-cancel-selector btn-small btn-warning" href="#">Cancel</a>
249
+ <a class="qq-upload-retry-selector btn-small btn-info" href="#">Retry</a>
250
+ <a class="qq-upload-delete-selector btn-small btn-warning" href="#">Delete</a>
251
+ <a class="qq-upload-pause-selector btn-small btn-info" href="#">Pause</a>
252
+ <a class="qq-upload-continue-selector btn-small btn-info" href="#">Continue</a>
253
+ <span class="qq-upload-status-text-selector qq-upload-status-text"></span>
254
+ <a class="view-btn btn-small btn-info hide" target="_blank">View</a>
255
+ </li>
256
+ </ul>
257
+ </div>
258
+ </script>
259
+ EOF
260
+ end
261
+
262
+ def settings
263
+ @settings ||= store[:settings].dup
264
+ end
265
+ end
266
+ end
267
+ end
268
+
269
+ if RUBY_ENGINE == 'opal'
270
+ class Element
271
+ alias_native :fine_uploader, :fineUploader
272
+
273
+ def fine_uploader_dnd options = {}
274
+ options = options.to_n
275
+ `self.fineUploaderDnd(options)`
276
+ end
277
+
278
+ def fine_uploader_s3 type, options = false
279
+ if !options
280
+ options = type.to_n
281
+ `self.fineUploaderS3(options)`
282
+ else
283
+ `self.fineUploaderS3(type, options)`
284
+ end
285
+ end
286
+ end
287
+ end