mack-javascript 0.8.2 → 0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/mack-javascript/generators/manifest.yml +3 -15
- data/lib/mack-javascript/generators/templates/javascripts/jquery.js.template +110 -23
- data/lib/mack-javascript/generators/templates/javascripts/prototype.js.template +438 -4219
- data/lib/mack-javascript/helpers/jquery_helper.rb +536 -60
- data/lib/mack-javascript/helpers/prototype_helper.rb +407 -39
- data/lib/mack-javascript/helpers/script_generator.rb +151 -14
- data/lib/mack-javascript/rendering/engine/rjs.rb +6 -2
- data/lib/mack-javascript/view_helpers/html_helpers.rb +18 -5
- data/lib/mack-javascript.rb +2 -11
- metadata +2 -7
- data/lib/mack-javascript/generators/templates/javascripts/controls.js.template +0 -963
- data/lib/mack-javascript/generators/templates/javascripts/dragdrop.js.template +0 -972
- data/lib/mack-javascript/generators/templates/javascripts/effects.js.template +0 -1120
- data/lib/mack-javascript/generators/templates/javascripts/jquery-fx.js.template +0 -28
- data/lib/mack-javascript/generators/templates/javascripts/jquery-ui.js.template +0 -85
@@ -1,50 +1,16 @@
|
|
1
|
+
require File.join_from_here('script_generator')
|
2
|
+
|
1
3
|
module Mack
|
2
4
|
module JavaScript
|
3
5
|
module Framework
|
4
|
-
class
|
6
|
+
class PrototypeAjax
|
5
7
|
@@callbacks = [:uninitialized, :loading, :loaded, :interactive, :complete, :failure, :success ] +
|
6
8
|
[100,101] + (200..206).to_a + (300..307).to_a + (400..417).to_a + (500..505).to_a
|
7
9
|
class << self
|
8
|
-
def insert_html(position, id, html)
|
9
|
-
insertion = position.to_s.camelcase
|
10
|
-
"new Insertion.#{insertion}('#{id}', '#{html}')"
|
11
|
-
end
|
12
|
-
|
13
|
-
def replace_html(id, html)
|
14
|
-
"Element.update('#{id}', '#{html}')"
|
15
|
-
end
|
16
|
-
|
17
|
-
def replace(id, html)
|
18
|
-
"Element.replace('#{id}', '#{html}')"
|
19
|
-
end
|
20
10
|
|
21
|
-
def remove(*ids)
|
22
|
-
"#{ids.to_json}.each(Element.remove)"
|
23
|
-
end
|
24
|
-
|
25
|
-
def show(*ids)
|
26
|
-
"#{ids.to_json}.each(Element.show)"
|
27
|
-
end
|
28
|
-
|
29
|
-
def toggle(*ids)
|
30
|
-
"#{ids.to_json}.each(Element.toggle)"
|
31
|
-
end
|
32
11
|
|
33
|
-
# def draggable(id, options = {})
|
34
|
-
# record @context.send(:draggable_element_js, id, options)
|
35
|
-
# end
|
36
|
-
#
|
37
|
-
# def visual_effect(name, id = nil, options = {})
|
38
|
-
# record @context.send(:visual_effect, name, id, options)
|
39
|
-
# end
|
40
|
-
#
|
41
|
-
# def drop_receiving(id, options = {})
|
42
|
-
# record @context.send(:drop_receiving_element_js, id, options)
|
43
|
-
# end
|
44
|
-
#
|
45
12
|
def remote_function(options)
|
46
13
|
javascript_options = options_for_ajax(options)
|
47
|
-
"new Ajax.Request('#{options[:url]}', #{javascript_options.to_json})"
|
48
14
|
update = ''
|
49
15
|
if options[:update] && options[:update].is_a?(Hash)
|
50
16
|
update = []
|
@@ -82,13 +48,36 @@ module Mack
|
|
82
48
|
|
83
49
|
if options[:form]
|
84
50
|
js_options['parameters'] = 'Form.serialize(this)'
|
85
|
-
elsif options[:submit]
|
86
|
-
js_options['parameters'] = "Form.serialize('#{options[:submit]}')"
|
87
51
|
elsif options[:with]
|
88
52
|
js_options['parameters'] = options[:with]
|
89
53
|
end
|
54
|
+
|
55
|
+
if options[:method].nil? || options[:method].to_sym != :get
|
56
|
+
js_options['method'] = "'post'"
|
57
|
+
else
|
58
|
+
js_options['method'] = "'get'"
|
59
|
+
end
|
60
|
+
|
61
|
+
if options[:method] && options[:method].to_sym == :put || options[:method] == :delete
|
62
|
+
js_options['parameters'] = append_ajax_data(js_options['parameters'], "_method=#{options[:method]}")
|
63
|
+
end
|
64
|
+
|
65
|
+
if js_options['method'] == "'post'" && options[:authenticity_token]
|
66
|
+
js_options['parameters'] = append_ajax_data(js_options['parameters'], "__authenticity_token=#{options.delete(:authenticity_token)}")
|
67
|
+
end
|
68
|
+
|
69
|
+
|
90
70
|
options_for_javascript(js_options.reject {|key, value| value.nil?})
|
91
71
|
end
|
72
|
+
|
73
|
+
def append_ajax_data(data, new_data)
|
74
|
+
if data
|
75
|
+
data << " + '&"
|
76
|
+
else
|
77
|
+
data = "'"
|
78
|
+
end
|
79
|
+
data << "#{new_data}'"
|
80
|
+
end
|
92
81
|
|
93
82
|
def options_for_javascript(options)
|
94
83
|
'{' + options.map {|k, v| "#{k}:#{v}"}.sort.join(', ') + '}'
|
@@ -107,6 +96,385 @@ module Mack
|
|
107
96
|
|
108
97
|
end
|
109
98
|
end
|
99
|
+
|
100
|
+
class PrototypeSelector < Mack::JavaScript::Selector
|
101
|
+
|
102
|
+
def select
|
103
|
+
"$$(#{@selector})"
|
104
|
+
end
|
105
|
+
|
106
|
+
def invoke(arr, options = {})
|
107
|
+
arr.collect! do |arg|
|
108
|
+
if !arg.is_a?(String) || arg =~ /^function/ || arg =~ /^null$/ || arg =~ /^\{.*\}$/
|
109
|
+
arg
|
110
|
+
else
|
111
|
+
"'#{arg}'"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
function = "invoke(#{arr.compact.join(',')})"
|
115
|
+
function << '.flatten().uniq()' if options.delete(:flatten_uniq)
|
116
|
+
add function, options
|
117
|
+
end
|
118
|
+
|
119
|
+
def each(func, options = {})
|
120
|
+
add "each(function(elem){#{func}})", options
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
#--- Tree Walking ---#
|
125
|
+
|
126
|
+
# Will give you the immediate children underneath the selected elements
|
127
|
+
#
|
128
|
+
#
|
129
|
+
# Example:
|
130
|
+
# say you have the following html:
|
131
|
+
#
|
132
|
+
# <div class='rakim'>
|
133
|
+
# <ul>
|
134
|
+
# ...
|
135
|
+
# </ul>
|
136
|
+
# </div>
|
137
|
+
#
|
138
|
+
# <div class='rakim'>
|
139
|
+
# <p>Eric B</p>
|
140
|
+
# <div id='technique'>
|
141
|
+
# ...
|
142
|
+
# </div>
|
143
|
+
# </div>
|
144
|
+
#
|
145
|
+
# page.select('.rakim').children would give you a collection consisting of
|
146
|
+
# the ul element, the p element, and the div with id 'technique'
|
147
|
+
def children
|
148
|
+
invoke ["childElements"], :flatten_uniq => true
|
149
|
+
end
|
150
|
+
|
151
|
+
# returns a collection of the immediate parent of each selected element
|
152
|
+
def parent
|
153
|
+
invoke ["up"], :flatten_uniq => true
|
154
|
+
end
|
155
|
+
|
156
|
+
# returns a collection of every parent up the chain to the root of the document
|
157
|
+
# for each selected element.
|
158
|
+
def ancestors
|
159
|
+
invoke ["ancestors"], :flatten_uniq => true
|
160
|
+
end
|
161
|
+
|
162
|
+
# gets all siblings for each element selected
|
163
|
+
def siblings(selector = nil)
|
164
|
+
invoke ["siblings", selector], :flatten_uniq => true
|
165
|
+
end
|
166
|
+
|
167
|
+
# gets the next immediate sibling for each element selected
|
168
|
+
# Takes an optional selector as an argument
|
169
|
+
def next(selector = nil)
|
170
|
+
invoke ["next", selector], :flatten_uniq => true
|
171
|
+
end
|
172
|
+
|
173
|
+
# gets the previous immediate sibling for each element selected
|
174
|
+
# Takes an optional selector as an argument
|
175
|
+
def previous(selector = nil)
|
176
|
+
invoke ["prev", selector], :flatten_uniq => true
|
177
|
+
end
|
178
|
+
|
179
|
+
# gets every next sibling for each element selected
|
180
|
+
def all_next
|
181
|
+
invoke ["nextSiblings"], :flatten_uniq => true
|
182
|
+
end
|
183
|
+
|
184
|
+
# gets every previous sibling for each element selected
|
185
|
+
def all_previous
|
186
|
+
invoke ["previousSiblings"], :flatten_uniq => true
|
187
|
+
end
|
188
|
+
|
189
|
+
|
190
|
+
#-- Attributes --#
|
191
|
+
|
192
|
+
def add_class(klass)
|
193
|
+
invoke ["addClassName", klass]
|
194
|
+
end
|
195
|
+
|
196
|
+
def remove_class(klass = '')
|
197
|
+
invoke ["removeClassName", klass]
|
198
|
+
end
|
199
|
+
|
200
|
+
def set_attribute(name, value)
|
201
|
+
value = "null" if value.nil?
|
202
|
+
invoke ["writeAttribute", name, value]
|
203
|
+
end
|
204
|
+
|
205
|
+
def remove_attribute(name)
|
206
|
+
set_attribute(name, nil)
|
207
|
+
end
|
208
|
+
|
209
|
+
|
210
|
+
|
211
|
+
#-- DOM Manipulation --#
|
212
|
+
|
213
|
+
# inserts html into the selected place for the specfied elemets
|
214
|
+
#
|
215
|
+
# +position+ may be one of:
|
216
|
+
#
|
217
|
+
# <tt>:top</tt>:: HTML is inserted inside the element, before the
|
218
|
+
# element's existing content.
|
219
|
+
# <tt>:bottom</tt>:: HTML is inserted inside the element, after the
|
220
|
+
# element's existing content.
|
221
|
+
# <tt>:before</tt>:: HTML is inserted immediately preceding the element.
|
222
|
+
# <tt>:after</tt>:: HTML is inserted immediately following the element.
|
223
|
+
#
|
224
|
+
#
|
225
|
+
# Example
|
226
|
+
#
|
227
|
+
# <div class='rakim'>
|
228
|
+
# <ul>
|
229
|
+
# ...
|
230
|
+
# </ul>
|
231
|
+
# </div>
|
232
|
+
#
|
233
|
+
# <div class='rakim'>
|
234
|
+
# <p>Eric B</p>
|
235
|
+
# <div id='technique'>
|
236
|
+
# ...
|
237
|
+
# </div>
|
238
|
+
# </div>
|
239
|
+
#
|
240
|
+
# page.select('.rakim').insert(:before, "<h1> The R </h1>") would result in:
|
241
|
+
#
|
242
|
+
# <h1> The R </h2>
|
243
|
+
# <div class='rakim'>
|
244
|
+
# <ul>
|
245
|
+
# ...
|
246
|
+
# </ul>
|
247
|
+
# </div>
|
248
|
+
#
|
249
|
+
# <h1> The R </h2>
|
250
|
+
# <div class='rakim'>
|
251
|
+
# <p>Eric B</p>
|
252
|
+
# <div id='technique'>
|
253
|
+
# ...
|
254
|
+
# </div>
|
255
|
+
# </div>
|
256
|
+
#
|
257
|
+
#
|
258
|
+
# Tip: use this with a partial containing your html:
|
259
|
+
# page.select('.rakim').insert(:before, render(:partial, 'the_r', :format => :html))
|
260
|
+
def insert(position, html)
|
261
|
+
invoke ["insert", "{#{position.to_s}: '#{escape_javascript(html)}'}"]
|
262
|
+
end
|
263
|
+
|
264
|
+
|
265
|
+
# replaces the selected html.
|
266
|
+
#
|
267
|
+
# +repace+ may be:
|
268
|
+
#
|
269
|
+
# <tt>:inner</tt>:: The inner html of the selected elements
|
270
|
+
# are replaced
|
271
|
+
# <tt>:outer</tt>:: the selected elements themselves are replaced
|
272
|
+
#
|
273
|
+
# Example
|
274
|
+
#
|
275
|
+
# <div class='rakim'>
|
276
|
+
# <p>Dont Sweat the Techinique</p>
|
277
|
+
# </div>
|
278
|
+
# <div class='rakim'>
|
279
|
+
# <p>Follow the Leader</p>
|
280
|
+
# </div>
|
281
|
+
#
|
282
|
+
# page.select('.rakim').replace(:inner, "<p>Paid in Full</p>") would result in
|
283
|
+
#
|
284
|
+
# <div class='rakim'>
|
285
|
+
# <p>Paid in Full</p>
|
286
|
+
# </div>
|
287
|
+
# <div class='rakim'>
|
288
|
+
# <p>Paid in Full</p>
|
289
|
+
# </div>
|
290
|
+
#
|
291
|
+
# if we then did:
|
292
|
+
# page.select('.rakim').replace(:outer, "<div class='schoolyD'><p>SaturdayNight</p></div>")
|
293
|
+
# the result would be
|
294
|
+
#
|
295
|
+
# <div class='schoolyD'>
|
296
|
+
# <p>SaturdayNight</p>
|
297
|
+
# </div>
|
298
|
+
# <div class='schoolyD'>
|
299
|
+
# <p>SaturdayNight</p>
|
300
|
+
# </div>
|
301
|
+
def replace(replace, html)
|
302
|
+
function = {:inner =>"update",:outer => 'replace'}[replace.to_sym]
|
303
|
+
invoke [function, escape_javascript(html)]
|
304
|
+
end
|
305
|
+
|
306
|
+
#removes the selected elements from the DOM
|
307
|
+
def remove
|
308
|
+
invoke ['remove']
|
309
|
+
end
|
310
|
+
|
311
|
+
|
312
|
+
#-- Effects --#
|
313
|
+
#
|
314
|
+
# The methods morph and effect take the same options hash. This can consist of:
|
315
|
+
#
|
316
|
+
# <tt>:duration</tt>:: The duration of the effect in ms.
|
317
|
+
# <tt>:easing</tt>:: see below
|
318
|
+
# <tt>:fps</tt>:: Specifies the frames-per-second value. The default is 25.
|
319
|
+
# <tt>:sync</tt>:: Synchronizes effects when applied in parallel.
|
320
|
+
# <tt>:queue</tt>:: Sets the queuing position for effect queues.
|
321
|
+
#
|
322
|
+
#
|
323
|
+
# --Easing--
|
324
|
+
# This determines the mathematical function your effect will use while transitioning.
|
325
|
+
# For instance, if you do page.select(.rakim).effect(:slideUp, :easing => 'spring'),
|
326
|
+
# every element with class 'rakim' will slide up and when it reaches the top, they will
|
327
|
+
# bounce back down a little then go back up.
|
328
|
+
#
|
329
|
+
# The full list of prototype easing options:
|
330
|
+
# linear, sinoidal, reverse, flicker, wobble, pulse, spring, none, full
|
331
|
+
|
332
|
+
def morph(hsh, options = nil)
|
333
|
+
#hsh is an object of style values
|
334
|
+
invoke ['morph', options_for_javascript(hsh), options_for_effects(options)]
|
335
|
+
end
|
336
|
+
|
337
|
+
# Custom visual effects. Supports the following effect names:
|
338
|
+
# highlight, scale, opacity, move, fade, appear, blindUp, blindDown, slideUp, slideDown,
|
339
|
+
# dropOut, grow, shrink, puff, switchOff, squish, fold, pulsate, shake, scrollTo
|
340
|
+
def effect(name, options = nil)
|
341
|
+
invoke ['visualEffect', name.to_s, options_for_effects(options)]
|
342
|
+
end
|
343
|
+
|
344
|
+
# show() shows an element, hide() hides it, and toggle() shows a hidden and hides a shown.
|
345
|
+
def show()
|
346
|
+
invoke ['show']
|
347
|
+
end
|
348
|
+
|
349
|
+
def hide()
|
350
|
+
invoke ['hide']
|
351
|
+
end
|
352
|
+
|
353
|
+
def toggle()
|
354
|
+
invoke ['toggle']
|
355
|
+
end
|
356
|
+
|
357
|
+
|
358
|
+
|
359
|
+
#-- Events --#
|
360
|
+
|
361
|
+
# adds an event listener to the selected elements. If options[:prevent_default] == true
|
362
|
+
# the default behavior of the event isn't taken
|
363
|
+
#
|
364
|
+
# Example
|
365
|
+
#
|
366
|
+
# page.select('.rakim a').peep 'click', :prevent_default => true do |p|
|
367
|
+
# p.select('#sucka_mcs').effect(:fade)
|
368
|
+
# end
|
369
|
+
#
|
370
|
+
# After running this code, if you click any a tag under any element with the
|
371
|
+
# class 'rakim', the element with id "sucka_mcs" will fade. Because of the option
|
372
|
+
# :prevent_default => true, the default action when clicking the a tag (the browser
|
373
|
+
# goes to its href url) isn't done.
|
374
|
+
# This can also be used in conjunction with trigger to make and call custom events.
|
375
|
+
def peep(event_name, options = {}, &block)
|
376
|
+
invoke ["observe", event_name, event_function(options[:prevent_default], &block)]
|
377
|
+
end
|
378
|
+
|
379
|
+
#takes away any event listeners on the 'event_name' event fot the selected elements
|
380
|
+
def stop_peeping(event_name)
|
381
|
+
invoke ["stopObserving", event_name]
|
382
|
+
end
|
383
|
+
|
384
|
+
# triggers the 'event_name' event on the selected elements.
|
385
|
+
def trigger(event_name)
|
386
|
+
invoke ["fire", event_name]
|
387
|
+
end
|
388
|
+
|
389
|
+
|
390
|
+
|
391
|
+
|
392
|
+
#-- Drag and Drop--#
|
393
|
+
|
394
|
+
# Makes the selected elements draggable.
|
395
|
+
#
|
396
|
+
# options
|
397
|
+
# http://github.com/madrobby/scriptaculous/wikis/draggable
|
398
|
+
# <tt>:revert</tt>:: if true, will revert after being dropped. ‘failure’
|
399
|
+
# will instruct the draggable not to revert if
|
400
|
+
# successfully dropped in a droppable.
|
401
|
+
# <tt>:ghosting</tt>:: if true, will clone the element and drag the clone
|
402
|
+
# <tt>:zindex</tt>:: The css z-index of the draggable item.
|
403
|
+
def draggable(options = nil)
|
404
|
+
each "new Draggable(elem, #{options_for_effects(options)})"
|
405
|
+
end
|
406
|
+
|
407
|
+
# Makes the selected elements droppable.
|
408
|
+
#
|
409
|
+
# options are
|
410
|
+
# http://github.com/madrobby/scriptaculous/wikis/droppables
|
411
|
+
|
412
|
+
# <tt>:accept</tt>:: if set to a css class, the selected elements will only
|
413
|
+
# accept elements dragged to it with that class.
|
414
|
+
# <tt>:hoverclass</tt>:: a droppable element will have this class added to it
|
415
|
+
# when an element is dragged over it.
|
416
|
+
# <tt>:remote</tt>:: takes a hash of ajax options, the same as given to page.ajax
|
417
|
+
# if this options is, an ajax call is made using the specified
|
418
|
+
# options along. Added to the url is an id parameter which
|
419
|
+
# has the id of the element that was dropped
|
420
|
+
#
|
421
|
+
# if a block is given, the blocks code will be executed when a succesful drop is done.
|
422
|
+
#
|
423
|
+
# Example
|
424
|
+
#
|
425
|
+
# options = {:remote => {:url => '/stuff'}}
|
426
|
+
# page.select('#bucket').droppable options do |p|
|
427
|
+
# p.alert('you dropped it!')
|
428
|
+
# end
|
429
|
+
#
|
430
|
+
# This code will make the element with id 'bucket' droppable. If an element is
|
431
|
+
# dropped onto it, an ajax call to the url '/stuff' will be sent with an id
|
432
|
+
# parameter of the id of the dropped element. Then an js alert
|
433
|
+
# box with the message 'you dropped it' will appear.
|
434
|
+
def droppable(options = nil, &block)
|
435
|
+
remote_options = options.delete(:remote)
|
436
|
+
if remote_options || block_given?
|
437
|
+
func = Mack::JavaScript::Function.new(session_id, 'elem')
|
438
|
+
if remote_options
|
439
|
+
remote_options[:with] ||= "'id=' + elem.id"
|
440
|
+
func << Mack::JavaScript::ScriptGenerator.new(session_id).ajax(remote_options)
|
441
|
+
end
|
442
|
+
func.body(&block) if block_given?
|
443
|
+
options.merge!(:onDrop => func)
|
444
|
+
end
|
445
|
+
each "Droppables.add(elem, #{options_for_effects(options)})"
|
446
|
+
end
|
447
|
+
|
448
|
+
|
449
|
+
private
|
450
|
+
|
451
|
+
def build_multiple_selector_string(selector)
|
452
|
+
selector.collect{|s| "'#{s}'"}.join(',')
|
453
|
+
end
|
454
|
+
|
455
|
+
def options_for_effects(options)
|
456
|
+
return nil unless options
|
457
|
+
options[:duration] = (options[:duration]/1000.0) if options[:duration]
|
458
|
+
easing = options.delete(:easing)
|
459
|
+
options[:transition] = "function(){return Effect.Transitions.#{easing}}()" if easing
|
460
|
+
options_for_javascript(options)
|
461
|
+
end
|
462
|
+
|
463
|
+
def options_for_javascript(options)
|
464
|
+
options = options.collect do |key, value|
|
465
|
+
value = "'#{value}'" unless !value.is_a?(String) || value =~ /^function/
|
466
|
+
"#{key}: #{value}"
|
467
|
+
end
|
468
|
+
"{#{options.join(',')}}"
|
469
|
+
end
|
470
|
+
|
471
|
+
def event_function(prevent_default = false, &block)
|
472
|
+
func = Mack::JavaScript::Function.new(session_id, 'event')
|
473
|
+
func << "event.stop()" if prevent_default
|
474
|
+
func.body(&block)
|
475
|
+
end
|
476
|
+
|
477
|
+
end
|
110
478
|
end
|
111
479
|
end
|
112
480
|
end
|
@@ -1,20 +1,52 @@
|
|
1
|
+
require File.join_from_here('..', 'view_helpers', 'string_helpers')
|
2
|
+
|
1
3
|
module Mack
|
2
4
|
module JavaScript
|
3
|
-
class ScriptGenerator
|
4
|
-
|
5
|
-
|
5
|
+
class ScriptGenerator
|
6
|
+
|
7
|
+
attr_reader :session_id
|
8
|
+
|
9
|
+
def initialize(session_id = nil)
|
10
|
+
@lines = []
|
11
|
+
@session_id = session_id
|
12
|
+
end
|
13
|
+
|
14
|
+
# selects elements on the page using css3 selectors
|
15
|
+
# For more info: http://www.w3.org/TR/css3-selectors/
|
16
|
+
# A few useful examples: 'div' would select all divs. '.full' would
|
17
|
+
# select all elements with class 'full'. 'div.blah' would select
|
18
|
+
# all divs with class 'blah'. '#foo' would select the element
|
19
|
+
# with id 'foo'
|
20
|
+
#
|
21
|
+
# select can take multiple selector strings. For instance
|
22
|
+
# page.select('ul.blah', '#foo', '.full') would give you access to
|
23
|
+
# a collection of elements containing all uls with class 'blah', the
|
24
|
+
# element with id 'foo' and every element with class 'full'. See
|
25
|
+
# JquerySelector or PrototypeSelector for available methods on
|
26
|
+
# the returned collection.
|
27
|
+
def select(*selector)
|
28
|
+
self.class.selector_framework.new(self, *selector)
|
6
29
|
end
|
7
30
|
|
8
|
-
def
|
9
|
-
|
31
|
+
def ajax(options)
|
32
|
+
unless configatron.mack.disable_forgery_detector || !session_id
|
33
|
+
options.merge!(:authenticity_token => Mack::Utils::AuthenticityTokenDispenser.instance.dispense_token(session_id))
|
34
|
+
end
|
35
|
+
self << self.class.ajax_framework.remote_function(options)
|
10
36
|
end
|
11
37
|
|
12
|
-
def <<(s)
|
13
|
-
|
38
|
+
def <<(s, options = {})
|
39
|
+
if options[:add_to_last]
|
40
|
+
@lines.last << s
|
41
|
+
else
|
42
|
+
@lines << s
|
43
|
+
end
|
14
44
|
end
|
15
45
|
|
16
46
|
def to_s
|
17
|
-
@lines
|
47
|
+
string = @lines.join(';')
|
48
|
+
string << ';' unless string =~ /;$/
|
49
|
+
string
|
18
50
|
end
|
19
51
|
|
20
52
|
def alert(message)
|
@@ -27,25 +59,82 @@ module Mack
|
|
27
59
|
args.each {|arg| a << arg.to_json}
|
28
60
|
self << s + a.join(',') + ')'
|
29
61
|
end
|
62
|
+
|
63
|
+
def function(*args)
|
64
|
+
Mack::JavaScript::Function.new(session_id, *args)
|
65
|
+
end
|
30
66
|
|
31
67
|
def assign(variable, value)
|
32
68
|
self << "#{variable} = #{value.to_json}"
|
33
69
|
end
|
34
70
|
|
35
71
|
def delay(seconds = 1, &block)
|
36
|
-
self << "setTimeout(function()
|
72
|
+
self << "setTimeout(#{function.body(&block)}, #{(seconds * 1000).to_i})"
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
#-- Deprecated Methods --#
|
77
|
+
|
78
|
+
def insert_html(position, id, html)
|
79
|
+
deprecate_method(:insert_html, 'page.select("#id").insert(position, html)', '0.8.3')
|
80
|
+
self.select("##{id}").insert(position, html)
|
81
|
+
end
|
82
|
+
|
83
|
+
def replace_html(id, html)
|
84
|
+
deprecate_method(:replace_html, 'page.select("#id").replace(:inner, html)', '0.8.3')
|
85
|
+
self.select("##{id}").replace(:inner, html).to_s
|
86
|
+
end
|
87
|
+
|
88
|
+
def replace(id, html)
|
89
|
+
deprecate_method(:replace, 'page.select("#id").replace(:outer, html)', '0.8.3')
|
90
|
+
self.select("##{id}").replace(:outer, html).to_s
|
91
|
+
end
|
92
|
+
|
93
|
+
def remove(*ids)
|
94
|
+
deprecate_method(:remove, 'page.select("#id1", "#id2").remove', '0.8.3')
|
95
|
+
ids = [ids] if ids.is_a? String
|
96
|
+
ids.collect! {|id| "##{id}"}
|
97
|
+
self.select(*ids).remove
|
98
|
+
end
|
99
|
+
|
100
|
+
def show(*ids)
|
101
|
+
deprecate_method(:show, 'page.select("#id1", "#id2").show', '0.8.3')
|
102
|
+
ids = [ids] if ids.is_a? String
|
103
|
+
ids.collect! {|id| "##{id}"}
|
104
|
+
self.select(*ids).show
|
105
|
+
end
|
106
|
+
|
107
|
+
def hide(*ids)
|
108
|
+
deprecate_method(:hide, 'page.select("#id1", "#id2").hide', '0.8.3')
|
109
|
+
ids = [ids] if ids.is_a? String
|
110
|
+
ids.collect! {|id| "##{id}"}
|
111
|
+
self.select(*ids).hide
|
112
|
+
end
|
113
|
+
|
114
|
+
def toggle(*ids)
|
115
|
+
deprecate_method(:toggle, 'page.select("#id1", "#id2").toggle', '0.8.3')
|
116
|
+
ids = [ids] if ids.is_a? String
|
117
|
+
ids.collect! {|id| "##{id}"}
|
118
|
+
self.select(*ids).toggle
|
37
119
|
end
|
38
120
|
|
39
121
|
class << self
|
40
122
|
|
41
|
-
def
|
42
|
-
ivar_cache('
|
43
|
-
"Mack::JavaScript::Framework::#{framework_name}".constantize
|
123
|
+
def ajax_framework
|
124
|
+
ivar_cache('ajax_framework') do
|
125
|
+
"Mack::JavaScript::Framework::#{framework_name}Ajax".constantize
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def selector_framework
|
130
|
+
ivar_cache('selector_framework') do
|
131
|
+
"Mack::JavaScript::Framework::#{framework_name}Selector".constantize
|
44
132
|
end
|
45
133
|
end
|
46
134
|
|
47
135
|
def framework=(args)
|
48
|
-
@
|
136
|
+
@ajax_framework = nil
|
137
|
+
@selector_framework = nil
|
49
138
|
@@framework_name = args.camelcase
|
50
139
|
end
|
51
140
|
|
@@ -54,7 +143,55 @@ module Mack
|
|
54
143
|
@@framework_name ||= configatron.mack.js_framework.camelcase
|
55
144
|
end
|
56
145
|
end
|
146
|
+
end
|
147
|
+
|
148
|
+
class Selector
|
149
|
+
include Mack::ViewHelpers::StringHelpers
|
150
|
+
|
151
|
+
attr_reader :session_id
|
152
|
+
|
153
|
+
def initialize(generator, *sel)
|
154
|
+
@generator = generator
|
155
|
+
@session_id = generator.session_id
|
156
|
+
@selector = sel.first == 'this' ? 'this' : build_multiple_selector_string(sel)
|
157
|
+
@generator << select
|
158
|
+
end
|
159
|
+
|
160
|
+
def add(statement, options = {})
|
161
|
+
@generator.<<(".#{statement}", :add_to_last => true)
|
162
|
+
self
|
163
|
+
end
|
57
164
|
|
58
165
|
end
|
166
|
+
|
167
|
+
|
168
|
+
class Function
|
169
|
+
|
170
|
+
def initialize(session_id = nil, *args)
|
171
|
+
if args.first.is_a? Fixnum
|
172
|
+
args = Array.new(args.first){|i| i + 1}.collect{|x| "obj#{x}"}
|
173
|
+
end
|
174
|
+
@session_id = session_id
|
175
|
+
@arguments = args
|
176
|
+
@generator = Mack::JavaScript::ScriptGenerator.new(session_id)
|
177
|
+
end
|
178
|
+
|
179
|
+
def <<(*args)
|
180
|
+
@generator << args
|
181
|
+
to_s
|
182
|
+
end
|
183
|
+
|
184
|
+
def body(&block)
|
185
|
+
yield @generator
|
186
|
+
to_s
|
187
|
+
end
|
188
|
+
|
189
|
+
|
190
|
+
def to_s
|
191
|
+
"function(#{@arguments.join(', ')}){#{@generator.to_s}}"
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
end
|
59
196
|
end
|
60
|
-
end
|
197
|
+
end
|
@@ -8,10 +8,14 @@ module Mack
|
|
8
8
|
if io.is_a?(File)
|
9
9
|
io = io.read
|
10
10
|
end
|
11
|
-
@_jsp_page = Mack::JavaScript::ScriptGenerator.new
|
11
|
+
@_jsp_page = Mack::JavaScript::ScriptGenerator.new(view_template.controller.session.id)
|
12
12
|
view_template.instance_variable_set("@_jsp_page", @_jsp_page)
|
13
13
|
eval(io, binding)
|
14
|
-
@_jsp_page.to_s
|
14
|
+
resp = @_jsp_page.to_s
|
15
|
+
if Mack.env == 'development'
|
16
|
+
resp = "try {#{resp}}catch(e){alert('RJS error:\\n\\n' + e.toString());throw e};"
|
17
|
+
end
|
18
|
+
resp
|
15
19
|
end
|
16
20
|
|
17
21
|
def extension
|