wedge 0.1.1 → 0.1.2

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 (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