corn_js 0.1.5 → 0.1.6

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/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);