mack-javascript 0.8.2 → 0.8.3
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.
- 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
|