corn_js 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,9 +1,19 @@
1
1
  # Popcorn
2
2
 
3
- Popcorm is a pop up library that will handle list and menu associated
3
+ Popcorn is a pop up library that will handle list and menu associated
4
4
  with an HTML control
5
5
 
6
6
  # npm
7
7
  use
8
8
  npm install popcorn
9
- to get popcorn from npm repository
9
+ to get popcorn from npm repository
10
+
11
+ # Testing
12
+ To run tests with jasmine you just have to launch
13
+
14
+ ```bash
15
+ $ bundle exec rake app:jasmine
16
+ ```
17
+
18
+ And then launch a browser at the url http://localhost:8888
19
+
@@ -1,2 +1,3 @@
1
-
2
- //= require_tree .
1
+ //= require corn_js/popcorn
2
+ //= require corn_js/activemetadata
3
+ //= require corn_js/fileuploader
@@ -0,0 +1,493 @@
1
+ var exports = window.exports || {};
2
+
3
+ (function (exports) {
4
+
5
+ var Popcorn = exports.Popcorn;
6
+
7
+ var FP = exports.FatPopcorn = function ($element, defaults) {
8
+ var self = this;
9
+
10
+ function _anOptionIsMissingIn(options) {
11
+ if (!options.autoWrap) options.autoWrap = false;
12
+ return options.current_user === undefined;
13
+ }
14
+
15
+ if (_anOptionIsMissingIn(defaults)) throw("parameter [current_user] is required");
16
+
17
+ self.$element = $element;
18
+ self.defaults = defaults;
19
+ self.defaults.modelName = "#";
20
+ self.baseName = "fatpopcorn";
21
+ self.baseCssClass = ".fatpopcorn";
22
+ };
23
+
24
+ FP.prototype = new Popcorn();
25
+
26
+ FP.baseCssClass = function () { return '.fatpopcorn'; };
27
+
28
+ FP.prototype.init = function () {
29
+ var self = this;
30
+ self.setupFormAction();
31
+ self.setupFormToken();
32
+ self.setupStreamUrl();
33
+ self.setupHistoryUrl();
34
+ self.setupEditForm();
35
+ self.setupWatchlistUrl();
36
+ self.bindRemoteEvents();
37
+ if (self.hasStream()) {
38
+ $(self.baseCssClass + ' .stream-tab').click();
39
+ }
40
+ else {
41
+ $(self.baseCssClass + ' .edit-tab').click();
42
+ }
43
+ };
44
+
45
+ FP.prototype.setupStreamUrl = function () {
46
+ var self = this;
47
+ $(self.baseCssClass + ' .stream').attr('data-url', self.streamUrl());
48
+ };
49
+ FP.prototype.setupEditForm = function () {
50
+ var self = this;
51
+ self.createAttachmentButton(self.attachmentsUrl());
52
+ $(self.baseCssClass + ' .edit').attr('data-attach-url', this.attachmentsUrl());
53
+ $(self.baseCssClass + ' .on-off label.' + this.$element.attr('data-watching')).click();
54
+ $(self.baseCssClass + ' .on-off input#watchlist_' + this.$element.attr('data-watching')).click();
55
+ };
56
+ FP.prototype.setupWatchlistUrl = function () {
57
+ $(this.baseCssClass + ' .edit').attr('data-url', this.watchlistUrl());
58
+ };
59
+ FP.prototype.setupHistoryUrl = function () {
60
+ $(this.baseCssClass + ' .history').attr('data-url', this.historyUrl());
61
+ };
62
+ FP.prototype.setupFormAction = function () {
63
+ $(this.baseCssClass + ' #notes_form').attr('action', this.actionUrl());
64
+ $(this.baseCssClass + ' .edit').attr('data-note-url', this.actionUrl());
65
+ };
66
+ FP.prototype.setupFormToken = function () {
67
+ $(this.baseCssClass + ' #notes_form input[name="authenticity_token"]').val(FP.formToken());
68
+ };
69
+ FP.prototype.actionUrl = function () {
70
+ return this.urlPrefix() + '/notes';
71
+ };
72
+ FP.prototype.streamUrl = function () {
73
+ var url = this.urlPrefix() + '/stream';
74
+ if(this.defaults.groupedStream){
75
+ url = "/active_metadata/groups/" + this.defaults.group + "/stream"
76
+ }
77
+ if(this.defaults.starredStream){
78
+ url += "?starred=true"
79
+ }
80
+ return url;
81
+ };
82
+ FP.prototype.attachmentsUrl = function () {
83
+ return this.urlPrefix() + '/attachments';
84
+ };
85
+ FP.prototype.watchlistUrl = function () {
86
+ return this.urlPrefix() + '/watchers/' + this.defaults.current_user;
87
+ };
88
+ FP.prototype.historyUrl = function () {
89
+ return this.urlPrefix() + '/histories';
90
+ };
91
+ FP.prototype.urlPrefix = function () {
92
+ return '/active_metadata/' + this.$element.attr('data-model') + '/' + this.$element.attr('data-model-id') + '/' + this.$element.attr('data-label');
93
+ };
94
+ FP.prototype.hasStream = function () {
95
+ return parseInt(this.$element.attr('data-stream')) > 0;
96
+ };
97
+ FP.prototype.hideContainer = function () {
98
+ $(window).off('resize');
99
+ return this.containerOf().hide();
100
+ };
101
+ FP.prototype.containerOf = function () {
102
+ return $(this.baseCssClass).first();
103
+ };
104
+
105
+ FP.prototype.decorateContainerWithHtml = function () {
106
+ var self = this;
107
+
108
+ function _html() {
109
+ return '<div class="fatpopcorn"><div class="popcorn-body"><div class="header"><ul><li class="stream-tab"><div>stream</div></li>' +
110
+ '<li class="edit-tab"><div>edit</div></li><li class="history-tab"><div>history</div></li></ul></div>' +
111
+ '<div class="stream"><div class="content"></div></div><div class="history"><div class="content"></div></div>' +
112
+ '<div class="edit"><div class="watchlist"><h1>Watchlist</h1><div class="on-off _23states"><input name="watchlist" id="fatpopcorn_watchlist_true" value="true" type="radio"><label class="true" for="fatpopcorn_watchlist_true"><span>On</span></label><input checked="checked" name="watchlist" id="fatpopcorn_watchlist_false" value="false" type="radio"><label class="false" for="fatpopcorn_watchlist_false"><span>Off</span></label></div></div><hr/>' +
113
+ '<div class="note"><h1>Nota</h1><form action="" method="post" id="notes_form"><div style="margin:0;padding:0;display:inline"><input type="hidden" value="✓" name="utf8"><input type="hidden" value="' + self['token'] + '" name="authenticity_token"></div>' +
114
+ '<textarea id="note_text" name="note" rows="4"></textarea><a id="send_note">Inserisci</a></form></div><hr/>' +
115
+ '<div class="attachment"><h1>Allegati</h1><div class="edit-attach"></div><div id="attach_output"></div></div>' +
116
+ '<div class="info"><h1>Info</h1><p>Lorem ipsum...</p></div></div></div><div class="popcorn-tail"></div><span class="loader"></span></div>';
117
+ }
118
+
119
+ if (self.containerOf().size() == 0) { $('body').append(_html()); }
120
+
121
+ self.containerOf().hide();
122
+ };
123
+
124
+ FP.prototype.addGripToElement = function () {
125
+ var self = this;
126
+ if (!self.$element.parent().is('span.fatpopcorn_grip') && this.defaults.autoWrap) {
127
+ self.$element.wrap('<span class="fatpopcorn_grip"/>')
128
+ }
129
+ return self.$element.parent();
130
+ };
131
+ FP.prototype.gripOf = function () { return this.$element.parent(); };
132
+
133
+ FP.prototype.activateTheClickedTab = function () {
134
+ var self = this;
135
+ $(self.baseCssClass + ' .header > ul > li').unbind('click').click(
136
+ function (e) {
137
+ var that = this;
138
+
139
+ function _currentTabName() { return _tabBodyName($(that).attr('class')); }
140
+ function _tabBodyName(tabName) { return tabName.split('-')[0].trim(); }
141
+ function _currentTab() { return $(self.baseCssClass + ' .' + _currentTabName()); }
142
+ function _currentTabMethod() { return _currentTabName() + "Event"; }
143
+
144
+ e.stopPropagation();
145
+ e.preventDefault();
146
+
147
+ $(self.baseCssClass + ' .active').removeClass('active');
148
+ $(self.baseCssClass + ' .popcorn-body > div:not(.header)').hide();
149
+
150
+ _currentTab().show();
151
+
152
+ $(that).addClass('active');
153
+ self[_currentTabMethod()].call(self);
154
+ });
155
+ };
156
+
157
+ FP.prototype.streamEvent = function () {
158
+ var self = this;
159
+ $.ajax($(self.baseCssClass + ' .stream').attr('data-url')).success(function(e){self.getStreamSuccess.call(self,e)});
160
+ };
161
+ FP.prototype.editEvent = function () {
162
+ // should do something?
163
+ };
164
+ FP.prototype.historyEvent = function () {
165
+ var self = this;
166
+ $.ajax($(this.baseCssClass + ' .history').attr('data-url')).success(function(e){self.getHistorySuccess.call(self,e)});
167
+ };
168
+ FP.prototype.containerVisible = function () {
169
+ return this.containerOf().is(':visible');
170
+ };
171
+
172
+ FP.formToken = function () {return $('meta[name="csrf-token"]').attr('content'); };
173
+
174
+ FP.prototype.createAttachmentButton = function (actionUrl) {
175
+ var self = this;
176
+
177
+ delete self.uploader;
178
+ var params = { authenticity_token:FP.formToken(), target:"attach_output"};
179
+
180
+ if (self.defaults.group !== undefined) {
181
+ params.group= self.defaults.group;
182
+ }
183
+ if (self.defaults.starOnCreate) {
184
+ params.starred = true;
185
+ }
186
+
187
+ self.uploader = new qq.FileUploader({
188
+ element:$(self.baseCssClass + ' .edit-attach').get(0),
189
+ allowedExtensions:[],
190
+ params:params,
191
+ uploadButtonText:'Inserisci',
192
+ action:actionUrl,
193
+ multiple:true,
194
+ onComplete: function (id, fileName, response, qq) {
195
+ if (qq.getQueue().length == 1) {
196
+ $('.qq-upload-list').empty();
197
+ }
198
+ if (!response.success) {
199
+ FP.displayFailure("Si è verificato un errore.");
200
+ return;
201
+ }
202
+ self.newNoteOrAttachmentSuccess(response);
203
+ }
204
+ });
205
+ };
206
+
207
+ FP.prototype.bindRemoteEvents = function () {
208
+ var self = this;
209
+ function _startWatching(e) { _callWatchlistService({authenticity_token:FP.formToken() }); }
210
+ function _stopWatching(e) { _callWatchlistService({_method:'delete', authenticity_token:FP.formToken() }); }
211
+ function _callWatchlistService(data) {
212
+ var url = $(self.baseCssClass + ' .edit').attr('data-url');
213
+ $.post(url, data, {dataType:'script'}).done(FP.watchingServiceSuccess).error(FP.watchingServiceFail);
214
+ }
215
+
216
+ $(self.baseCssClass).unbind('click').click(function (e) { e.stopPropagation(); });
217
+ $('#' + self.baseName + '_watchlist_true').unbind('click').click(function (e) { _startWatching.call(self,e); });
218
+ $('#' + self.baseName + '_watchlist_false').unbind('click').click(function (e) { _stopWatching.call(self,e); });
219
+ $(self.baseCssClass + ' #send_note').unbind('click').click(function () {
220
+ function data() {
221
+ var qs = $(self.baseCssClass + ' form#notes_form').serialize();
222
+
223
+ if (self.defaults.group !== undefined) {
224
+ qs = qs + "&group=" + self.defaults.group;
225
+ }
226
+ if (self.defaults.starOnCreate) {
227
+ qs = qs + "&starred=true";
228
+ }
229
+ return qs;
230
+ }
231
+
232
+ if ($(self.baseCssClass + ' #note_text').val() == '') return false;
233
+
234
+ $.post($(self.baseCssClass + ' form#notes_form').attr('action'), data())
235
+ .success('success.rails', function(e){self.newNoteOrAttachmentSuccess.call(self,e);})
236
+ .fail(function () { FP.displayFailure("Si è verificato un errore.") });
237
+ });
238
+ $(self.baseCssClass + ' .loader').ajaxSend(function () { $(this).show(); });
239
+ $(self.baseCssClass + ' .loader').ajaxComplete(function () { $(this).hide(); });
240
+ };
241
+
242
+ /********
243
+ Notifier
244
+ ********/
245
+ FP.notifier = {
246
+ notify:function (type, message) {
247
+ type = type || "notice";
248
+ this.removeBox();
249
+ var $messageBox = $(FP.baseCssClass() + ' .info h1').after('<p class="' + type + ' messageBox">' + message + '</p>').next();
250
+ var self = this;
251
+ $messageBox.bind('click', function () {
252
+ self.removeBox();
253
+ });
254
+ },
255
+
256
+ notice:function (message) {
257
+ this.notify("notice", message);
258
+ },
259
+
260
+ error:function (message) {
261
+ this.notify("error", message);
262
+ },
263
+
264
+ removeBox:function () {
265
+ $(FP.baseCssClass() + ' .info p.messageBox').remove();
266
+ }
267
+ };
268
+
269
+ /****************
270
+ * Error Handling
271
+ ****************/
272
+ FP.displayFailure = function (message) {
273
+ FP.notifier.error(message);
274
+ };
275
+
276
+ /* ajax callbacks */
277
+ FP.watchingServiceSuccess = function (jqxhr) {
278
+ var data = eval(jqxhr);
279
+ //remove the error/notice messageBox
280
+ FP.notifier.removeBox();
281
+ FP.item(data).attr('data-watching', data.watching);
282
+ };
283
+ FP.watchingServiceFail = function (data) {
284
+ FP.displayFailure("Si è verificato un errore.");
285
+ };
286
+
287
+ FP.item = function (data) {
288
+ return $('[data-model="' + data.modelName + '"][data-label="' + data.fieldName + '"]');
289
+ };
290
+
291
+ FP.prototype.newNoteOrAttachmentSuccess = function (dataString) {
292
+ var data = eval(dataString);
293
+ //remove the error/notice messageBox
294
+ FP.notifier.removeBox();
295
+
296
+ FP.item(data).attr('data-stream', data.streamItemsCount);
297
+
298
+ if (data.streamItemsCount > 0) {
299
+ FP.item(data).parents('.fatpopcorn_grip').addClass('has-stream');
300
+ FP.item(data).siblings('.stream-items-count').text(data.streamItemsCount);
301
+
302
+ if (data.streamItemsCount > 9)
303
+ FP.item(data).siblings('.stream-items-count').addClass('two-digits');
304
+ else
305
+ FP.item(data).siblings('.stream-items-count').removeClass('two-digits');
306
+ } else {
307
+ FP.item(data).parents('.fatpopcorn_grip').removeClass('has-stream');
308
+ FP.item(data).siblings('.stream-items-count').empty();
309
+ }
310
+ $(this.baseCssClass + ' textarea#note_text').val('');
311
+ $(this.baseCssClass + ' .active').removeClass('active');
312
+ $(this.baseCssClass + ' .popcorn-body > div:not(.header)').hide();
313
+ $(this.baseCssClass + ' .stream').show();
314
+ $(this.baseCssClass + ' .stream-tab').addClass('active');
315
+
316
+ if (this.defaults.groupedStream) {
317
+ $(this.baseCssClass + ' .stream-tab').click();
318
+ } else {
319
+ this.getStreamSuccess(data.streamBody);
320
+ }
321
+ };
322
+
323
+ FP.prototype.getStreamSuccess = function (data) {
324
+ var self = this;
325
+ $(this.baseCssClass + ' .stream .content').html(data);
326
+ $(this.baseCssClass + ' .stream .attachment span.delete').click(function(e){self.deleteAttachment.call(self, e)});
327
+ $(this.baseCssClass + ' .stream .note span.delete').click(function(e){self.deleteNote.call(self, e)});
328
+
329
+ if (this.defaults.groupedStream) {
330
+ $(this.baseCssClass + ' .stream span.star').remove();
331
+ return;
332
+ }
333
+
334
+ $(this.baseCssClass + ' .stream span.star').click(function(e){self.starUnstar.call(self, e)});
335
+ };
336
+
337
+ FP.prototype.deleteAttachment = function (e) {
338
+ if (confirm("Sei sicuro?")) {
339
+ this.deleteStream(e, $(this.baseCssClass + ' .edit').attr('data-attach-url'));
340
+ }
341
+ };
342
+
343
+ FP.prototype.deleteNote = function (e) {
344
+ if (confirm("Sei sicuro?")) {
345
+ this.deleteStream(e, $(this.baseCssClass + ' .edit').attr('data-note-url'));
346
+ }
347
+ };
348
+
349
+ FP.prototype.deleteStream = function (e, urlPrefix) {
350
+ var self = this;
351
+ function _url() { return urlPrefix + '/' + $(e.target).parent().attr('data-id'); }
352
+ $.post(_url(), {_method:'delete'}).success('success.rails', function(e){
353
+ self.newNoteOrAttachmentSuccess.call(self,e);
354
+ $(window).trigger("active_metadata.afterDelete");
355
+ }).fail(FP.deleteFailure);
356
+ };
357
+
358
+ FP.prototype.starUnstar = function (e, urlPrefix) {
359
+ var self = this;
360
+ var url = $(e.target).attr('data-url');
361
+
362
+ $.post(url, {_method:'put'}).
363
+ success('success.rails', function (data) {
364
+ self.getStreamSuccess(data.streamBody);
365
+ $(window).trigger("active_metadata.afterStarUnstar") }
366
+ ).fail(FP.deleteFailure);
367
+ };
368
+
369
+ FP.deleteFailure = function () {
370
+ };
371
+
372
+ FP.prototype.getHistorySuccess = function (data) {
373
+ $(this.baseCssClass + ' .history .content').empty();
374
+ $(this.baseCssClass + ' .history .content').append(data);
375
+ };
376
+
377
+ var SC = exports.StickyCorn = function ($element, defaults) {
378
+ this.$element = $element;
379
+ if (defaults.current_user === undefined) throw("parameter [current_user] is required");
380
+ this.defaults = defaults;
381
+ this.baseName = "stickycorn";
382
+ this.baseCssClass = ".stickycorn";
383
+
384
+ };
385
+
386
+ SC.prototype = new FP(null, {current_user:-1});
387
+
388
+ SC.baseCssClass = function () {
389
+ return '.stickycorn';
390
+ };
391
+
392
+ SC.prototype.decorateContainerWithHtml = function () {
393
+ var self = this;
394
+
395
+ function _html() {
396
+ return '<div class="stickycorn"><div class="popcorn-body"><div class="header"><ul><li class="stream-tab"><div>stream</div></li>' +
397
+ '<li class="edit-tab"><div>edit</div></li></ul></div>' +
398
+ '<div class="stream"><div class="content"></div></div><div class="history"><div class="content"></div></div>' +
399
+ '<div class="edit"><div class="watchlist"><h1>Watchlist</h1><div class="on-off _23states"><input name="watchlist" id="stickycorn_watchlist_true" value="true" type="radio"><label class="true" for="stickycorn_watchlist_true"><span>On</span></label><input checked="checked" name="watchlist" id="stickycorn_watchlist_false" value="false" type="radio"><label class="false" for="stickycorn_watchlist_false"><span>Off</span></label></div></div><hr/>' +
400
+ '<div class="note"><h1>Nota</h1><form action="" method="post" id="notes_form"><div style="margin:0;padding:0;display:inline"><input type="hidden" value="✓" name="utf8"><input type="hidden" value="' + self['token'] + '" name="authenticity_token"></div>' +
401
+ '<textarea id="note_text" name="note" rows="4"></textarea><a id="send_note">Inserisci</a></form></div><hr/>' +
402
+ '<div class="attachment"><h1>Allegati</h1><div class="edit-attach"></div><div id="attach_output"></div></div>' +
403
+ '</div><span class="loader"></span></div></div>';
404
+ }
405
+
406
+ self.$element.append(_html());
407
+ };
408
+
409
+ return exports;
410
+
411
+ })(window.exports);
412
+
413
+ (function ($, FatPopcorn, StickyCorn) {
414
+
415
+ $.fn.stickycorn = function (defaults) {
416
+ var self = this;
417
+
418
+
419
+ function _setUpElement() {
420
+ var $element = $(this), stickycorn = new StickyCorn($element, defaults);
421
+
422
+ stickycorn.decorateContainerWithHtml();
423
+ stickycorn.activateTheClickedTab();
424
+ stickycorn.bindRemoteEvents();
425
+ stickycorn.init();
426
+
427
+ return this;
428
+ }
429
+
430
+ return self.each(_setUpElement);
431
+ };
432
+
433
+ $.fn.fatpopcorn = function (options) {
434
+
435
+ // plugin default options
436
+ var self = this, defaults = {
437
+ marginBorder:4,
438
+ arrowWidth:24,
439
+ marginArrow:11,
440
+ verticalOffsetFromElement:26
441
+ };
442
+
443
+ // extends defaults with options provided
444
+ if (options) {
445
+ $.extend(defaults, options);
446
+ }
447
+
448
+ function _setUpElement() {
449
+ var $element = $(this), fatpopcorn = new FatPopcorn($element, defaults);
450
+ $(window).click(function () {
451
+ fatpopcorn.hideContainer();
452
+ FatPopcorn.notifier.removeBox();
453
+ });
454
+
455
+ fatpopcorn.decorateContainerWithHtml();
456
+ fatpopcorn.activateTheClickedTab();
457
+ fatpopcorn.addGripToElement();
458
+
459
+ fatpopcorn.gripOf().children().click(function (e) {
460
+ $(e.target).data('elementMatched', true);
461
+ });
462
+
463
+ $('.fatpopcorn_grip .stream-items-count').click(function (e) {
464
+ $(e.target).data('elementMatched', false);
465
+ });
466
+
467
+ fatpopcorn.gripOf().click(function (e) {
468
+ if ($(e.target).data('elementMatched')) return;
469
+
470
+ e.stopPropagation();
471
+ e.preventDefault();
472
+ fatpopcorn.init();
473
+ if (fatpopcorn.containerVisible()) {
474
+ fatpopcorn.hideContainer();
475
+ return;
476
+ }
477
+
478
+ fatpopcorn.inferPositionType();
479
+ fatpopcorn.setContainerPosition();
480
+ fatpopcorn.decorateContainerWithArrow();
481
+ fatpopcorn.containerOf().show();
482
+
483
+ $(window).on('resize', function () {
484
+ if (fatpopcorn.containerVisible()) fatpopcorn.setContainerPosition();
485
+ });
486
+ });
487
+
488
+ return this;
489
+ }
490
+
491
+ return self.each(_setUpElement);
492
+ };
493
+ })(jQuery, exports.FatPopcorn, exports.StickyCorn);