social_stream-events 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. data/app/assets/javascripts/0_init.js +4 -0
  2. data/app/assets/javascripts/events.js.coffee +66 -0
  3. data/app/assets/stylesheets/events.css.scss +37 -0
  4. data/app/controllers/events_controller.rb +40 -0
  5. data/app/controllers/rooms_controller.rb +7 -0
  6. data/app/models/event.rb +53 -0
  7. data/app/models/room.rb +8 -0
  8. data/app/views/events/_event.html.erb +1 -0
  9. data/app/views/events/_new.html.erb +40 -0
  10. data/app/views/events/_sidebar_calendar.html.erb +26 -0
  11. data/app/views/events/create.js.erb +21 -0
  12. data/app/views/events/destroy.js.erb +1 -0
  13. data/app/views/events/index.html.erb +96 -0
  14. data/app/views/rooms/_form.html.erb +31 -0
  15. data/app/views/rooms/_index.html.erb +10 -0
  16. data/app/views/rooms/_settings.html.erb +23 -0
  17. data/app/views/rooms/create.js.erb +7 -0
  18. data/app/views/rooms/destroy.js.erb +1 -0
  19. data/config/locales/en.yml +34 -4
  20. data/config/locales/es.yml +34 -4
  21. data/config/routes.rb +1 -0
  22. data/db/migrate/20111101193523_create_events.rb +13 -0
  23. data/db/migrate/20111120104349_create_rooms.rb +26 -0
  24. data/db/migrate/20111204155637_add_scheduler.rb +33 -0
  25. data/db/migrate/20111218203314_change_scheduler.rb +11 -0
  26. data/lib/social_stream-events.rb +15 -0
  27. data/lib/social_stream/events/ability.rb +13 -0
  28. data/lib/social_stream/events/engine.rb +17 -0
  29. data/lib/social_stream/events/models/actor.rb +13 -0
  30. data/lib/social_stream/events/version.rb +1 -1
  31. data/lib/social_stream/views/settings/events.rb +18 -0
  32. data/social_stream-events.gemspec +6 -10
  33. data/vendor/assets/images/boxy-ne.png +0 -0
  34. data/vendor/assets/images/boxy-nw.png +0 -0
  35. data/vendor/assets/images/boxy-se.png +0 -0
  36. data/vendor/assets/images/boxy-sw.png +0 -0
  37. data/vendor/assets/javascripts/fullcalendar.js +12 -10
  38. data/vendor/assets/javascripts/gcal.js +2 -2
  39. data/vendor/assets/javascripts/jquery.boxy.js +570 -0
  40. data/vendor/assets/javascripts/sprintf.js +183 -0
  41. data/vendor/assets/stylesheets/boxy.css +49 -0
  42. data/vendor/assets/stylesheets/fullcalendar.css +7 -10
  43. data/vendor/assets/stylesheets/fullcalendar.print.css +4 -4
  44. metadata +81 -175
  45. data/db/migrate/20110910161707_create_social_stream_events.rb +0 -54
  46. data/db/migrate/20111102145626_add_more_fields_to_events.rb +0 -20
  47. data/db/migrate/20111104165944_add_more_fields_to_sessions.rb +0 -13
  48. data/db/migrate/20111104182420_add_details_to_events.rb +0 -18
  49. data/db/migrate/20111209120019_reset_events.rb +0 -18
  50. data/vendor/assets/javascripts/jquery.ad-gallery.js +0 -850
  51. data/vendor/assets/javascripts/jquery.ad-gallery.pack.js +0 -10
  52. data/vendor/assets/stylesheets/ad_next.png +0 -0
  53. data/vendor/assets/stylesheets/ad_prev.png +0 -0
  54. data/vendor/assets/stylesheets/ad_scroll_back.png +0 -0
  55. data/vendor/assets/stylesheets/ad_scroll_forward.png +0 -0
  56. data/vendor/assets/stylesheets/jquery.ad-gallery.css +0 -171
  57. data/vendor/assets/stylesheets/loader.gif +0 -0
  58. data/vendor/assets/stylesheets/social_stream-events.css +0 -273
@@ -0,0 +1,570 @@
1
+ /**
2
+ * Boxy 0.1.4 - Facebook-style dialog, with frills
3
+ *
4
+ * (c) 2008 Jason Frame
5
+ * Licensed under the MIT License (LICENSE)
6
+ */
7
+
8
+ /*
9
+ * jQuery plugin
10
+ *
11
+ * Options:
12
+ * message: confirmation message for form submit hook (default: "Please confirm:")
13
+ *
14
+ * Any other options - e.g. 'clone' - will be passed onto the boxy constructor (or
15
+ * Boxy.load for AJAX operations)
16
+ */
17
+ jQuery.fn.boxy = function(options) {
18
+ options = options || {};
19
+ return this.each(function() {
20
+ var node = this.nodeName.toLowerCase(), self = this;
21
+ if (node == 'a') {
22
+ jQuery(this).click(function() {
23
+ var active = Boxy.linkedTo(this),
24
+ href = this.getAttribute('href'),
25
+ localOptions = jQuery.extend({actuator: this, title: this.title}, options);
26
+
27
+ if (active) {
28
+ active.show();
29
+ } else if (href.indexOf('#') >= 0) {
30
+ var content = jQuery(href.substr(href.indexOf('#'))),
31
+ newContent = content.clone(true);
32
+ content.remove();
33
+ localOptions.unloadOnHide = false;
34
+ new Boxy(newContent, localOptions);
35
+ } else { // fall back to AJAX; could do with a same-origin check
36
+ if (!localOptions.cache) localOptions.unloadOnHide = true;
37
+ Boxy.load(this.href, localOptions);
38
+ }
39
+
40
+ return false;
41
+ });
42
+ } else if (node == 'form') {
43
+ jQuery(this).bind('submit.boxy', function() {
44
+ Boxy.confirm(options.message || 'Please confirm:', function() {
45
+ jQuery(self).unbind('submit.boxy').submit();
46
+ });
47
+ return false;
48
+ });
49
+ }
50
+ });
51
+ };
52
+
53
+ //
54
+ // Boxy Class
55
+
56
+ function Boxy(element, options) {
57
+
58
+ this.boxy = jQuery(Boxy.WRAPPER);
59
+ jQuery.data(this.boxy[0], 'boxy', this);
60
+
61
+ this.visible = false;
62
+ this.options = jQuery.extend({}, Boxy.DEFAULTS, options || {});
63
+
64
+ if (this.options.modal) {
65
+ this.options = jQuery.extend(this.options, {center: true, draggable: false});
66
+ }
67
+
68
+ // options.actuator == DOM element that opened this boxy
69
+ // association will be automatically deleted when this boxy is remove()d
70
+ if (this.options.actuator) {
71
+ jQuery.data(this.options.actuator, 'active.boxy', this);
72
+ }
73
+
74
+ this.setContent(element || "<div></div>");
75
+ this._setupTitleBar();
76
+
77
+ this.boxy.css('display', 'none').appendTo(document.body);
78
+ this.toTop();
79
+
80
+ if (this.options.fixed) {
81
+ if (jQuery.browser.msie && jQuery.browser.version < 7) {
82
+ this.options.fixed = false; // IE6 doesn't support fixed positioning
83
+ } else {
84
+ this.boxy.addClass('fixed');
85
+ }
86
+ }
87
+
88
+ if (this.options.center && Boxy._u(this.options.x, this.options.y)) {
89
+ this.center();
90
+ } else {
91
+ this.moveTo(
92
+ Boxy._u(this.options.x) ? this.options.x : Boxy.DEFAULT_X,
93
+ Boxy._u(this.options.y) ? this.options.y : Boxy.DEFAULT_Y
94
+ );
95
+ }
96
+
97
+ if (this.options.show) this.show();
98
+
99
+ };
100
+
101
+ Boxy.EF = function() {};
102
+
103
+ jQuery.extend(Boxy, {
104
+
105
+ WRAPPER: "<table cellspacing='0' cellpadding='0' border='0' class='boxy-wrapper'>" +
106
+ "<tr><td class='top-left'></td><td class='top'></td><td class='top-right'></td></tr>" +
107
+ "<tr><td class='left'></td><td class='boxy-inner'></td><td class='right'></td></tr>" +
108
+ "<tr><td class='bottom-left'></td><td class='bottom'></td><td class='bottom-right'></td></tr>" +
109
+ "</table>",
110
+
111
+ DEFAULTS: {
112
+ title: null, // titlebar text. titlebar will not be visible if not set.
113
+ closeable: true, // display close link in titlebar?
114
+ draggable: true, // can this dialog be dragged?
115
+ clone: false, // clone content prior to insertion into dialog?
116
+ actuator: null, // element which opened this dialog
117
+ center: true, // center dialog in viewport?
118
+ show: true, // show dialog immediately?
119
+ modal: false, // make dialog modal?
120
+ fixed: true, // use fixed positioning, if supported? absolute positioning used otherwise
121
+ closeText: '[close]', // text to use for default close link
122
+ unloadOnHide: false, // should this dialog be removed from the DOM after being hidden?
123
+ clickToFront: false, // bring dialog to foreground on any click (not just titlebar)?
124
+ behaviours: Boxy.EF, // function used to apply behaviours to all content embedded in dialog.
125
+ afterDrop: Boxy.EF, // callback fired after dialog is dropped. executes in context of Boxy instance.
126
+ afterShow: Boxy.EF, // callback fired after dialog becomes visible. executes in context of Boxy instance.
127
+ afterHide: Boxy.EF, // callback fired after dialog is hidden. executed in context of Boxy instance.
128
+ beforeUnload: Boxy.EF // callback fired after dialog is unloaded. executed in context of Boxy instance.
129
+ },
130
+
131
+ DEFAULT_X: 50,
132
+ DEFAULT_Y: 50,
133
+ zIndex: 1337,
134
+ dragConfigured: false, // only set up one drag handler for all boxys
135
+ resizeConfigured: false,
136
+ dragging: null,
137
+
138
+ // load a URL and display in boxy
139
+ // url - url to load
140
+ // options keys (any not listed below are passed to boxy constructor)
141
+ // type: HTTP method, default: GET
142
+ // cache: cache retrieved content? default: false
143
+ // filter: jQuery selector used to filter remote content
144
+ load: function(url, options) {
145
+
146
+ options = options || {};
147
+
148
+ var ajax = {
149
+ url: url, type: 'GET', dataType: 'html', cache: false, success: function(html) {
150
+ html = jQuery(html);
151
+ if (options.filter) html = jQuery(options.filter, html);
152
+ new Boxy(html, options);
153
+ }
154
+ };
155
+
156
+ jQuery.each(['type', 'cache'], function() {
157
+ if (this in options) {
158
+ ajax[this] = options[this];
159
+ delete options[this];
160
+ }
161
+ });
162
+
163
+ jQuery.ajax(ajax);
164
+
165
+ },
166
+
167
+ // allows you to get a handle to the containing boxy instance of any element
168
+ // e.g. <a href='#' onclick='alert(Boxy.get(this));'>inspect!</a>.
169
+ // this returns the actual instance of the boxy 'class', not just a DOM element.
170
+ // Boxy.get(this).hide() would be valid, for instance.
171
+ get: function(ele) {
172
+ var p = jQuery(ele).parents('.boxy-wrapper');
173
+ return p.length ? jQuery.data(p[0], 'boxy') : null;
174
+ },
175
+
176
+ // returns the boxy instance which has been linked to a given element via the
177
+ // 'actuator' constructor option.
178
+ linkedTo: function(ele) {
179
+ return jQuery.data(ele, 'active.boxy');
180
+ },
181
+
182
+ // displays an alert box with a given message, calling optional callback
183
+ // after dismissal.
184
+ alert: function(message, callback, options) {
185
+ return Boxy.ask(message, ['OK'], callback, options);
186
+ },
187
+
188
+ // displays an alert box with a given message, calling after callback iff
189
+ // user selects OK.
190
+ confirm: function(message, after, options) {
191
+ return Boxy.ask(message, ['OK', 'Cancel'], function(response) {
192
+ if (response == 'OK') after();
193
+ }, options);
194
+ },
195
+
196
+ // asks a question with multiple responses presented as buttons
197
+ // selected item is returned to a callback method.
198
+ // answers may be either an array or a hash. if it's an array, the
199
+ // the callback will received the selected value. if it's a hash,
200
+ // you'll get the corresponding key.
201
+ ask: function(question, answers, callback, options) {
202
+
203
+ options = jQuery.extend({modal: true, closeable: false},
204
+ options || {},
205
+ {show: true, unloadOnHide: true});
206
+
207
+ var body = jQuery('<div></div>').append(jQuery('<div class="question"></div>').html(question));
208
+
209
+ // ick
210
+ var map = {}, answerStrings = [];
211
+ if (answers instanceof Array) {
212
+ for (var i = 0; i < answers.length; i++) {
213
+ map[answers[i]] = answers[i];
214
+ answerStrings.push(answers[i]);
215
+ }
216
+ } else {
217
+ for (var k in answers) {
218
+ map[answers[k]] = k;
219
+ answerStrings.push(answers[k]);
220
+ }
221
+ }
222
+
223
+ var buttons = jQuery('<form class="answers"></form>');
224
+ buttons.html(jQuery.map(answerStrings, function(v) {
225
+ return "<input type='button' value='" + v + "' />";
226
+ }).join(' '));
227
+
228
+ jQuery('input[type=button]', buttons).click(function() {
229
+ var clicked = this;
230
+ Boxy.get(this).hide(function() {
231
+ if (callback) callback(map[clicked.value]);
232
+ });
233
+ });
234
+
235
+ body.append(buttons);
236
+
237
+ new Boxy(body, options);
238
+
239
+ },
240
+
241
+ // returns true if a modal boxy is visible, false otherwise
242
+ isModalVisible: function() {
243
+ return jQuery('.boxy-modal-blackout').length > 0;
244
+ },
245
+
246
+ _u: function() {
247
+ for (var i = 0; i < arguments.length; i++)
248
+ if (typeof arguments[i] != 'undefined') return false;
249
+ return true;
250
+ },
251
+
252
+ _handleResize: function(evt) {
253
+ var d = jQuery(document);
254
+ jQuery('.boxy-modal-blackout').css('display', 'none').css({
255
+ width: d.width(), height: d.height()
256
+ }).css('display', 'block');
257
+ },
258
+
259
+ _handleDrag: function(evt) {
260
+ var d;
261
+ if (d = Boxy.dragging) {
262
+ d[0].boxy.css({left: evt.pageX - d[1], top: evt.pageY - d[2]});
263
+ }
264
+ },
265
+
266
+ _nextZ: function() {
267
+ return Boxy.zIndex++;
268
+ },
269
+
270
+ _viewport: function() {
271
+ var d = document.documentElement, b = document.body, w = window;
272
+ return jQuery.extend(
273
+ jQuery.browser.msie ?
274
+ { left: b.scrollLeft || d.scrollLeft, top: b.scrollTop || d.scrollTop } :
275
+ { left: w.pageXOffset, top: w.pageYOffset },
276
+ !Boxy._u(w.innerWidth) ?
277
+ { width: w.innerWidth, height: w.innerHeight } :
278
+ (!Boxy._u(d) && !Boxy._u(d.clientWidth) && d.clientWidth != 0 ?
279
+ { width: d.clientWidth, height: d.clientHeight } :
280
+ { width: b.clientWidth, height: b.clientHeight }) );
281
+ }
282
+
283
+ });
284
+
285
+ Boxy.prototype = {
286
+
287
+ // Returns the size of this boxy instance without displaying it.
288
+ // Do not use this method if boxy is already visible, use getSize() instead.
289
+ estimateSize: function() {
290
+ this.boxy.css({visibility: 'hidden', display: 'block'});
291
+ var dims = this.getSize();
292
+ this.boxy.css('display', 'none').css('visibility', 'visible');
293
+ return dims;
294
+ },
295
+
296
+ // Returns the dimensions of the entire boxy dialog as [width,height]
297
+ getSize: function() {
298
+ return [this.boxy.width(), this.boxy.height()];
299
+ },
300
+
301
+ // Returns the dimensions of the content region as [width,height]
302
+ getContentSize: function() {
303
+ var c = this.getContent();
304
+ return [c.width(), c.height()];
305
+ },
306
+
307
+ // Returns the position of this dialog as [x,y]
308
+ getPosition: function() {
309
+ var b = this.boxy[0];
310
+ return [b.offsetLeft, b.offsetTop];
311
+ },
312
+
313
+ // Returns the center point of this dialog as [x,y]
314
+ getCenter: function() {
315
+ var p = this.getPosition();
316
+ var s = this.getSize();
317
+ return [Math.floor(p[0] + s[0] / 2), Math.floor(p[1] + s[1] / 2)];
318
+ },
319
+
320
+ // Returns a jQuery object wrapping the inner boxy region.
321
+ // Not much reason to use this, you're probably more interested in getContent()
322
+ getInner: function() {
323
+ return jQuery('.boxy-inner', this.boxy);
324
+ },
325
+
326
+ // Returns a jQuery object wrapping the boxy content region.
327
+ // This is the user-editable content area (i.e. excludes titlebar)
328
+ getContent: function() {
329
+ return jQuery('.boxy-content', this.boxy);
330
+ },
331
+
332
+ // Replace dialog content
333
+ setContent: function(newContent) {
334
+ newContent = jQuery(newContent).css({display: 'block'}).addClass('boxy-content');
335
+ if (this.options.clone) newContent = newContent.clone(true);
336
+ this.getContent().remove();
337
+ this.getInner().append(newContent);
338
+ this._setupDefaultBehaviours(newContent);
339
+ this.options.behaviours.call(this, newContent);
340
+ return this;
341
+ },
342
+
343
+ // Move this dialog to some position, funnily enough
344
+ moveTo: function(x, y) {
345
+ this.moveToX(x).moveToY(y);
346
+ return this;
347
+ },
348
+
349
+ // Move this dialog (x-coord only)
350
+ moveToX: function(x) {
351
+ if (typeof x == 'number') this.boxy.css({left: x});
352
+ else this.centerX();
353
+ return this;
354
+ },
355
+
356
+ // Move this dialog (y-coord only)
357
+ moveToY: function(y) {
358
+ if (typeof y == 'number') this.boxy.css({top: y});
359
+ else this.centerY();
360
+ return this;
361
+ },
362
+
363
+ // Move this dialog so that it is centered at (x,y)
364
+ centerAt: function(x, y) {
365
+ var s = this[this.visible ? 'getSize' : 'estimateSize']();
366
+ if (typeof x == 'number') this.moveToX(x - s[0] / 2);
367
+ if (typeof y == 'number') this.moveToY(y - s[1] / 2);
368
+ return this;
369
+ },
370
+
371
+ centerAtX: function(x) {
372
+ return this.centerAt(x, null);
373
+ },
374
+
375
+ centerAtY: function(y) {
376
+ return this.centerAt(null, y);
377
+ },
378
+
379
+ // Center this dialog in the viewport
380
+ // axis is optional, can be 'x', 'y'.
381
+ center: function(axis) {
382
+ var v = Boxy._viewport();
383
+ var o = this.options.fixed ? [0, 0] : [v.left, v.top];
384
+ if (!axis || axis == 'x') this.centerAt(o[0] + v.width / 2, null);
385
+ if (!axis || axis == 'y') this.centerAt(null, o[1] + v.height / 2);
386
+ return this;
387
+ },
388
+
389
+ // Center this dialog in the viewport (x-coord only)
390
+ centerX: function() {
391
+ return this.center('x');
392
+ },
393
+
394
+ // Center this dialog in the viewport (y-coord only)
395
+ centerY: function() {
396
+ return this.center('y');
397
+ },
398
+
399
+ // Resize the content region to a specific size
400
+ resize: function(width, height, after) {
401
+ if (!this.visible) return;
402
+ var bounds = this._getBoundsForResize(width, height);
403
+ this.boxy.css({left: bounds[0], top: bounds[1]});
404
+ this.getContent().css({width: bounds[2], height: bounds[3]});
405
+ if (after) after(this);
406
+ return this;
407
+ },
408
+
409
+ // Tween the content region to a specific size
410
+ tween: function(width, height, after) {
411
+ if (!this.visible) return;
412
+ var bounds = this._getBoundsForResize(width, height);
413
+ var self = this;
414
+ this.boxy.stop().animate({left: bounds[0], top: bounds[1]});
415
+ this.getContent().stop().animate({width: bounds[2], height: bounds[3]}, function() {
416
+ if (after) after(self);
417
+ });
418
+ return this;
419
+ },
420
+
421
+ // Returns true if this dialog is visible, false otherwise
422
+ isVisible: function() {
423
+ return this.visible;
424
+ },
425
+
426
+ // Make this boxy instance visible
427
+ show: function() {
428
+ if (this.visible) return;
429
+ if (this.options.modal) {
430
+ var self = this;
431
+ if (!Boxy.resizeConfigured) {
432
+ Boxy.resizeConfigured = true;
433
+ jQuery(window).resize(function() { Boxy._handleResize(); });
434
+ }
435
+ this.modalBlackout = jQuery('<div class="boxy-modal-blackout"></div>')
436
+ .css({zIndex: Boxy._nextZ(),
437
+ opacity: 0.7,
438
+ width: jQuery(document).width(),
439
+ height: jQuery(document).height()})
440
+ .appendTo(document.body);
441
+ this.toTop();
442
+ if (this.options.closeable) {
443
+ jQuery(document.body).bind('keypress.boxy', function(evt) {
444
+ var key = evt.which || evt.keyCode;
445
+ if (key == 27) {
446
+ self.hide();
447
+ jQuery(document.body).unbind('keypress.boxy');
448
+ }
449
+ });
450
+ }
451
+ }
452
+ this.boxy.stop().css({opacity: 1}).show();
453
+ this.visible = true;
454
+ this._fire('afterShow');
455
+ return this;
456
+ },
457
+
458
+ // Hide this boxy instance
459
+ hide: function(after) {
460
+ if (!this.visible) return;
461
+ var self = this;
462
+ if (this.options.modal) {
463
+ jQuery(document.body).unbind('keypress.boxy');
464
+ this.modalBlackout.animate({opacity: 0}, function() {
465
+ jQuery(this).remove();
466
+ });
467
+ }
468
+ this.boxy.stop().animate({opacity: 0}, 300, function() {
469
+ self.boxy.css({display: 'none'});
470
+ self.visible = false;
471
+ self._fire('afterHide');
472
+ if (after) after(self);
473
+ if (self.options.unloadOnHide) self.unload();
474
+ });
475
+ return this;
476
+ },
477
+
478
+ toggle: function() {
479
+ this[this.visible ? 'hide' : 'show']();
480
+ return this;
481
+ },
482
+
483
+ hideAndUnload: function(after) {
484
+ this.options.unloadOnHide = true;
485
+ this.hide(after);
486
+ return this;
487
+ },
488
+
489
+ unload: function() {
490
+ this._fire('beforeUnload');
491
+ this.boxy.remove();
492
+ if (this.options.actuator) {
493
+ jQuery.data(this.options.actuator, 'active.boxy', false);
494
+ }
495
+ },
496
+
497
+ // Move this dialog box above all other boxy instances
498
+ toTop: function() {
499
+ this.boxy.css({zIndex: Boxy._nextZ()});
500
+ return this;
501
+ },
502
+
503
+ // Returns the title of this dialog
504
+ getTitle: function() {
505
+ return jQuery('> .title-bar h2', this.getInner()).html();
506
+ },
507
+
508
+ // Sets the title of this dialog
509
+ setTitle: function(t) {
510
+ jQuery('> .title-bar h2', this.getInner()).html(t);
511
+ return this;
512
+ },
513
+
514
+ //
515
+ // Don't touch these privates
516
+
517
+ _getBoundsForResize: function(width, height) {
518
+ var csize = this.getContentSize();
519
+ var delta = [width - csize[0], height - csize[1]];
520
+ var p = this.getPosition();
521
+ return [Math.max(p[0] - delta[0] / 2, 0),
522
+ Math.max(p[1] - delta[1] / 2, 0), width, height];
523
+ },
524
+
525
+ _setupTitleBar: function() {
526
+ if (this.options.title) {
527
+ var self = this;
528
+ var tb = jQuery("<div class='title-bar'></div>").html("<h2>" + this.options.title + "</h2>");
529
+ if (this.options.closeable) {
530
+ tb.append(jQuery("<a href='#' class='close'></a>").html(this.options.closeText));
531
+ }
532
+ if (this.options.draggable) {
533
+ tb[0].onselectstart = function() { return false; }
534
+ tb[0].unselectable = 'on';
535
+ tb[0].style.MozUserSelect = 'none';
536
+ if (!Boxy.dragConfigured) {
537
+ jQuery(document).mousemove(Boxy._handleDrag);
538
+ Boxy.dragConfigured = true;
539
+ }
540
+ tb.mousedown(function(evt) {
541
+ self.toTop();
542
+ Boxy.dragging = [self, evt.pageX - self.boxy[0].offsetLeft, evt.pageY - self.boxy[0].offsetTop];
543
+ jQuery(this).addClass('dragging');
544
+ }).mouseup(function() {
545
+ jQuery(this).removeClass('dragging');
546
+ Boxy.dragging = null;
547
+ self._fire('afterDrop');
548
+ });
549
+ }
550
+ this.getInner().prepend(tb);
551
+ this._setupDefaultBehaviours(tb);
552
+ }
553
+ },
554
+
555
+ _setupDefaultBehaviours: function(root) {
556
+ var self = this;
557
+ if (this.options.clickToFront) {
558
+ root.click(function() { self.toTop(); });
559
+ }
560
+ jQuery('.close', root).click(function() {
561
+ self.hide();
562
+ return false;
563
+ }).mousedown(function(evt) { evt.stopPropagation(); });
564
+ },
565
+
566
+ _fire: function(event) {
567
+ this.options[event].call(this);
568
+ }
569
+
570
+ };