romo 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile +9 -1
  3. data/README.md +1 -1
  4. data/assets/css/romo/_mixins.scss +486 -0
  5. data/assets/css/romo/_vars.scss +159 -0
  6. data/assets/css/romo/base.scss +454 -0
  7. data/assets/css/romo/buttons.scss +211 -0
  8. data/assets/css/romo/datepicker.scss +73 -0
  9. data/assets/css/romo/dropdown.scss +33 -0
  10. data/assets/css/romo/forms.scss +193 -0
  11. data/assets/css/romo/grid.scss +271 -0
  12. data/assets/css/romo/grid_table.scss +129 -0
  13. data/assets/css/romo/labels.scss +41 -0
  14. data/assets/css/romo/lists.scss +37 -0
  15. data/assets/css/romo/modal.scss +32 -0
  16. data/assets/css/romo/normalize.scss +425 -0
  17. data/assets/css/romo/select.scss +89 -0
  18. data/assets/css/romo/sortable.scss +14 -0
  19. data/assets/css/romo/table.scss +99 -0
  20. data/assets/css/romo/tabs.scss +71 -0
  21. data/assets/css/romo/tooltip.scss +89 -0
  22. data/assets/css/romo/z_index.scss +26 -0
  23. data/assets/js/romo/base.js +177 -0
  24. data/assets/js/romo/datepicker.js +541 -0
  25. data/assets/js/romo/dropdown.js +309 -0
  26. data/assets/js/romo/dropdown_form.js +92 -0
  27. data/assets/js/romo/form.js +182 -0
  28. data/assets/js/romo/indicator.js +88 -0
  29. data/assets/js/romo/inline.js +77 -0
  30. data/assets/js/romo/inline_form.js +86 -0
  31. data/assets/js/romo/invoke.js +87 -0
  32. data/assets/js/romo/modal.js +311 -0
  33. data/assets/js/romo/modal_form.js +101 -0
  34. data/assets/js/romo/select.js +139 -0
  35. data/assets/js/romo/select_dropdown.js +325 -0
  36. data/assets/js/romo/sortable.js +201 -0
  37. data/assets/js/romo/tooltip.js +258 -0
  38. data/lib/romo/dassets.rb +64 -0
  39. data/lib/romo/version.rb +1 -1
  40. data/lib/romo.rb +9 -0
  41. data/romo.gemspec +4 -2
  42. data/test/support/.gitkeep +0 -0
  43. data/test/system/.gitkeep +0 -0
  44. data/test/unit/dassets_tests.rb +67 -0
  45. data/test/unit/romo_tests.rb +21 -0
  46. metadata +53 -10
@@ -0,0 +1,139 @@
1
+ $.fn.romoSelect = function() {
2
+ return $.map(this, function(element) {
3
+ return new RomoSelect(element);
4
+ });
5
+ }
6
+
7
+ var RomoSelect = function(element) {
8
+ this.elem = $(element);
9
+
10
+ this.doInit();
11
+ this.doBindSelectDropdown();
12
+ this.doRefreshUI();
13
+
14
+ if (this.elem.attr('id') !== undefined) {
15
+ $('label[for="'+this.elem.attr('id')+'"]').on('click', $.proxy(function(e) {
16
+ this.romoSelectDropdown.elem.focus();
17
+ }, this));
18
+ }
19
+
20
+ $(window).on("pageshow", $.proxy(function(e) {
21
+ var selectedVal = this.elem.find('option[selected]').attr('value');
22
+ if (selectedVal === undefined) {
23
+ selectedVal = '';
24
+ }
25
+ if (selectedVal !== this.elem[0].value) {
26
+ this.romoSelectDropdown.doSetNewValue(selectedVal);
27
+ this._setNewValue(selectedVal);
28
+ }
29
+ }, this));
30
+
31
+ this.elem.trigger('select:ready', [this]);
32
+ }
33
+
34
+ RomoSelect.prototype.doInit = function() {
35
+ // override as needed
36
+ }
37
+
38
+ RomoSelect.prototype.doBindSelectDropdown = function() {
39
+ this.romoSelectDropdown = this._buildSelectDropdownElem().romoSelectDropdown(this.elem)[0];
40
+
41
+ this.romoSelectDropdown.elem.on('selectDropdown:dropdown:toggle', $.proxy(function(e, dropdown, selectDropdown) {
42
+ this.elem.trigger('select:dropdown:toggle', [dropdown, this]);
43
+ }, this));
44
+ this.romoSelectDropdown.elem.on('selectDropdown:dropdown:popupOpen', $.proxy(function(e, dropdown, selectDropdown) {
45
+ this.elem.trigger('select:dropdown:popupOpen', [dropdown, this]);
46
+ }, this));
47
+ this.romoSelectDropdown.elem.on('selectDropdown:dropdown:popupClose', $.proxy(function(e, dropdown, selectDropdown) {
48
+ this.elem.trigger('select:dropdown:popupClose', [dropdown, this]);
49
+ }, this));
50
+
51
+ this.romoSelectDropdown.elem.on('selectDropdown:itemSelected', $.proxy(function(e, newValue, prevValue, selectDropdown) {
52
+ this.romoSelectDropdown.elem.focus();
53
+ this.elem.trigger('select:itemSelected', [newValue, prevValue, this]);
54
+ }, this));
55
+ this.romoSelectDropdown.elem.on('selectDropdown:change', $.proxy(function(e, newValue, prevValue, selectDropdown) {
56
+ this._setNewValue(newValue);
57
+ this.elem.trigger('change');
58
+ this.elem.trigger('select:change', [newValue, prevValue, this]);
59
+ }, this));
60
+
61
+ this.elem.on('select:triggerToggle', $.proxy(function(e) {
62
+ this.romoSelectDropdown.elem.trigger('selectDropdown:triggerToggle', []);
63
+ }, this));
64
+ this.elem.on('select:triggerPopupOpen', $.proxy(function(e) {
65
+ this.romoSelectDropdown.elem.trigger('selectDropdown:triggerPopupOpen', []);
66
+ }, this));
67
+ this.elem.on('select:triggerPopupClose', $.proxy(function(e) {
68
+ this.romoSelectDropdown.elem.trigger('selectDropdown:triggerPopupClose', []);
69
+ }, this));
70
+ }
71
+
72
+ RomoSelect.prototype.doRefreshUI = function() {
73
+ var text = this.romoSelectDropdown.selectedListing().text() || ' ';
74
+ this.romoSelectDropdown.elem.find('.romo-select-text').html(text);
75
+ }
76
+
77
+ RomoSelect.prototype.onCaretClick = function(e) {
78
+ if (this.elem.prop('disabled') === false) {
79
+ this.romoSelectDropdown.elem.focus();
80
+ this.elem.trigger('select:triggerPopupOpen');
81
+ }
82
+ }
83
+
84
+ RomoSelect.prototype._setNewValue = function(newValue) {
85
+ this.elem[0].value = newValue;
86
+ this.doRefreshUI();
87
+ }
88
+
89
+ RomoSelect.prototype._buildSelectDropdownElem = function() {
90
+ var romoSelectDropdownElem = $('<div class="romo-select romo-btn" tabindex="0"><span class="romo-select-text"></span></div>');
91
+
92
+ romoSelectDropdownElem.attr('data-romo-dropdown-position', this.elem.data('romo-select-dropdown-position'));
93
+ romoSelectDropdownElem.attr('data-romo-dropdown-style-class', this.elem.data('romo-select-dropdown-style-class'));
94
+ romoSelectDropdownElem.attr('data-romo-dropdown-min-height', this.elem.data('romo-select-dropdown-min-height'));
95
+ romoSelectDropdownElem.attr('data-romo-dropdown-max-height', this.elem.data('romo-select-dropdown-max-height'));
96
+ romoSelectDropdownElem.attr('data-romo-dropdown-height', this.elem.data('romo-select-dropdown-height'));
97
+ romoSelectDropdownElem.attr('data-romo-dropdown-overflow-x', 'hidden');
98
+ romoSelectDropdownElem.attr('data-romo-dropdown-width', 'elem');
99
+ if (romoSelectDropdownElem.data('romo-dropdown-max-height') === undefined) {
100
+ romoSelectDropdownElem.attr('data-romo-dropdown-max-height', 'detect');
101
+ }
102
+
103
+ var classList = this.elem.attr('class') !== undefined ? this.elem.attr('class').split(/\s+/) : [];
104
+ $.each(classList, function(idx, classItem) {
105
+ romoSelectDropdownElem.addClass(classItem);
106
+ });
107
+ if (this.elem.attr('style') !== undefined) {
108
+ romoSelectDropdownElem.attr('style', this.elem.attr('style'));
109
+ }
110
+ romoSelectDropdownElem.css({'width': this.elem.css('width')});
111
+ if (this.elem.attr('disabled') !== undefined) {
112
+ this.romoSelectDropdown.elem.attr('disabled', this.elem.attr('disabled'));
113
+ }
114
+
115
+ this.elem.after(romoSelectDropdownElem);
116
+ this.elem.hide();
117
+
118
+ this.elemWrapper = $('<div class="romo-select-wrapper"></div>');
119
+ if (this.elem.data('romo-select-btn-group') === true) {
120
+ this.elemWrapper.addClass('romo-btn-group');
121
+ }
122
+ romoSelectDropdownElem.before(this.elemWrapper);
123
+ this.elemWrapper.append(romoSelectDropdownElem);
124
+
125
+ var caretClass = this.elem.data('romo-select-caret') || this.defaultCaretClass;
126
+ if (caretClass !== undefined && caretClass !== 'none') {
127
+ var caret = $('<i class="romo-select-caret '+caretClass+'"></i>');
128
+ caret.css({'line-height': romoSelectDropdownElem.css('line-height')});
129
+ caret.on('click', $.proxy(this.onCaretClick, this));
130
+ romoSelectDropdownElem.css({'padding-right': '22px'});
131
+ romoSelectDropdownElem.append(caret);
132
+ }
133
+
134
+ return romoSelectDropdownElem;
135
+ }
136
+
137
+ Romo.onInitUI(function(e) {
138
+ Romo.initUIElems(e, '[data-romo-select-auto="true"]').romoSelect();
139
+ });
@@ -0,0 +1,325 @@
1
+ $.fn.romoSelectDropdown = function(optionElemsParent) {
2
+ return $.map(this, function(element) {
3
+ return new RomoSelectDropdown(element, optionElemsParent);
4
+ });
5
+ }
6
+
7
+ var RomoSelectDropdown = function(element, optionElemsParent) {
8
+ this.elem = $(element);
9
+ this.defaultCaretClass = '';
10
+ this.itemSelector = 'LI[data-romo-select-item="opt"]:not(.disabled)';
11
+ this.prevValue = undefined;
12
+
13
+ var optsParent = (optionElemsParent || this.elem.find('.romo-select-dropdown-options-parent'));
14
+ this.optionElems = optsParent.children();
15
+ this.optionList = this._buildOptionList(this.optionElems);
16
+
17
+ this.doInit();
18
+ this.doBindDropdown();
19
+
20
+ if (this.elem.attr('id') !== undefined) {
21
+ $('label[for="'+this.elem.attr('id')+'"]').on('click', $.proxy(function(e) {
22
+ this.elem.focus();
23
+ }, this));
24
+ }
25
+
26
+ this.elem.trigger('selectDropdown:ready', [this]);
27
+ }
28
+
29
+ RomoSelectDropdown.prototype.selectedListing = function() {
30
+ return this.romoDropdown.bodyElem.find('LI.selected');
31
+ }
32
+
33
+ RomoSelectDropdown.prototype.doInit = function() {
34
+ // override as needed
35
+ }
36
+
37
+ RomoSelectDropdown.prototype.doSetNewValue = function(newValue) {
38
+ this.selectedListing().removeClass('selected');
39
+ this.romoDropdown.bodyElem.find('LI[data-romo-select-option-value="'+newValue+'"]').addClass('selected');
40
+
41
+ this.prevValue = newValue;
42
+ }
43
+
44
+ RomoSelectDropdown.prototype.doBindDropdown = function() {
45
+ this.romoDropdown = this.elem.romoDropdown()[0];
46
+ this.romoDropdown.doSetPopupZIndex(this.elem);
47
+ this.romoDropdown.bodyElem.addClass('romo-select-option-list');
48
+ this.romoDropdown.elem.on('dropdown:popupOpen', $.proxy(this.onPopupOpen, this));
49
+ this.romoDropdown.elem.on('dropdown:popupClose', $.proxy(this.onPopupClose, this));
50
+ this.romoDropdown.elem.on('blur', $.proxy(function(e) {
51
+ this.blurTimeoutId = setTimeout($.proxy(function() {
52
+ if (this.popupMouseDown !== true) {
53
+ this.romoDropdown.elem.trigger('dropdown:triggerPopupClose', []);
54
+ }
55
+ }, this), 10);
56
+ }, this));
57
+ this.romoDropdown.elem.on('keydown', $.proxy(this.onElemKeyDown, this));
58
+ this.romoDropdown.popupElem.on('keydown', $.proxy(this.onElemKeyDown, this));
59
+
60
+ this.romoDropdown.elem.on('dropdown:toggle', $.proxy(function(e, dropdown) {
61
+ this.elem.trigger('selectDropdown:dropdown:toggle', [dropdown, this]);
62
+ }, this));
63
+ this.romoDropdown.elem.on('dropdown:popupOpen', $.proxy(function(e, dropdown) {
64
+ this.elem.trigger('selectDropdown:dropdown:popupOpen', [dropdown, this]);
65
+ }, this));
66
+ this.romoDropdown.elem.on('dropdown:popupClose', $.proxy(function(e, dropdown) {
67
+ this.elem.trigger('selectDropdown:dropdown:popupClose', [dropdown, this]);
68
+ }, this));
69
+
70
+ this.elem.on('selectDropdown:triggerToggle', $.proxy(function(e) {
71
+ this.romoDropdown.elem.trigger('dropdown:triggerToggle', []);
72
+ }, this));
73
+ this.elem.on('selectDropdown:triggerPopupOpen', $.proxy(function(e) {
74
+ this.romoDropdown.elem.trigger('dropdown:triggerPopupOpen', []);
75
+ }, this));
76
+ this.elem.on('selectDropdown:triggerPopupClose', $.proxy(function(e) {
77
+ this.romoDropdown.elem.trigger('dropdown:triggerPopupClose', []);
78
+ }, this));
79
+
80
+ this.romoDropdown.bodyElem.html('');
81
+ this.romoDropdown.bodyElem.append(this.optionList);
82
+
83
+ this.romoDropdown.bodyElem.find(this.itemSelector).on('hover', $.proxy(this.onItemHover, this));
84
+ this.romoDropdown.bodyElem.find(this.itemSelector).on('click', $.proxy(this.onItemClick, this));
85
+
86
+ this.romoDropdown.popupElem.on('mousedown', $.proxy(this.onPopupMouseDown, this));
87
+ this.romoDropdown.popupElem.on('mouseup', $.proxy(this.onPopupMouseUp, this));
88
+ }
89
+
90
+ RomoSelectDropdown.prototype.doSelectHighlightedItem = function() {
91
+ var prevValue = this.prevValue;
92
+ var newValue = this.romoDropdown.bodyElem.find('LI.romo-select-highlight').data('romo-select-option-value');
93
+
94
+ this.romoDropdown.doPopupClose();
95
+ this.elem.trigger('selectDropdown:itemSelected', [newValue, prevValue, this]);
96
+
97
+ if (newValue !== prevValue) {
98
+ this.doSetNewValue(newValue);
99
+ this.elem.trigger('selectDropdown:change', [newValue, prevValue, this]);
100
+ }
101
+ }
102
+
103
+ RomoSelectDropdown.prototype.onPopupOpen = function(e) {
104
+ if (this.elem.hasClass('disabled') === false) {
105
+ this._highlightItem(this.selectedListing());
106
+ this._scrollTopToItem(this.selectedListing());
107
+ }
108
+ $('body').on('keydown', $.proxy(this.onPopupOpenBodyKeyDown, this));
109
+ }
110
+
111
+ RomoSelectDropdown.prototype.onPopupClose = function(e) {
112
+ this._highlightItem($());
113
+ $('body').off('keydown', $.proxy(this.onPopupOpenBodyKeyDown, this));
114
+ }
115
+
116
+ RomoSelectDropdown.prototype.onItemHover = function(e) {
117
+ if (e !== undefined) {
118
+ e.preventDefault();
119
+ e.stopPropagation();
120
+ }
121
+ this._highlightItem($(e.target));
122
+ }
123
+
124
+ RomoSelectDropdown.prototype.onItemClick = function(e) {
125
+ if (this.blurTimeoutId !== undefined) {
126
+ clearTimeout(this.blurTimeoutId);
127
+ this.blurTimeoutId = undefined;
128
+ }
129
+ if (e !== undefined) {
130
+ e.preventDefault();
131
+ e.stopPropagation();
132
+ }
133
+ this.doSelectHighlightedItem();
134
+ }
135
+
136
+ RomoSelectDropdown.prototype.onPopupMouseDown = function(e) {
137
+ this.popupMouseDown = true;
138
+ }
139
+
140
+ RomoSelectDropdown.prototype.onPopupMouseUp = function(e) {
141
+ this.popupMouseDown = false;
142
+ }
143
+
144
+ RomoSelectDropdown.prototype.onPopupOpenBodyKeyDown = function(e) {
145
+ if (e !== undefined) {
146
+ e.stopPropagation();
147
+ }
148
+
149
+ var scroll = this.romoDropdown.bodyElem;
150
+
151
+ if (e.keyCode === 38 /* Up */) {
152
+ var prev = this._prevListItem();
153
+
154
+ this._highlightItem(prev);
155
+ if (scroll.offset().top > prev.offset().top) {
156
+ this._scrollTopToItem(prev);
157
+ } else if ((scroll.offset().top + scroll.height()) < prev.offset().top) {
158
+ this._scrollTopToItem(prev);
159
+ }
160
+
161
+ return false;
162
+ } else if(e.keyCode === 40 /* Down */) {
163
+ var next = this._nextListItem();
164
+
165
+ this._highlightItem(next);
166
+ if ((scroll.offset().top + scroll.height()) < next.offset().top + next.height()) {
167
+ this._scrollBottomToItem(next);
168
+ } else if (scroll.offset().top > next.offset().top) {
169
+ this._scrollTopToItem(next);
170
+ }
171
+
172
+ return false;
173
+ } else if (e.keyCode === 13 /* Enter */ ) {
174
+ this.doSelectHighlightedItem();
175
+ return false;
176
+ } else {
177
+ return true;
178
+ }
179
+ }
180
+
181
+ RomoSelectDropdown.prototype.onElemKeyDown = function(e) {
182
+ if (this.elem.hasClass('disabled') === false) {
183
+ if (this.romoDropdown.popupElem.hasClass('romo-dropdown-open') === false) {
184
+ if(e.keyCode === 40 /* Down */ ) {
185
+ this.romoDropdown.doPopupOpen();
186
+ return false;
187
+ } else {
188
+ return true;
189
+ }
190
+ }
191
+ }
192
+ return true;
193
+ }
194
+
195
+ RomoSelectDropdown.prototype._scrollTopToItem = function(item) {
196
+ if (item.size() > 0) {
197
+ var scroll = this.romoDropdown.bodyElem;
198
+ scroll.scrollTop(0);
199
+
200
+ var scrollOffsetTop = scroll.offset().top;
201
+ var selOffsetTop = item.offset().top;
202
+ var selOffset = item.height() / 2;
203
+
204
+ scroll.scrollTop(selOffsetTop - scrollOffsetTop - selOffset);
205
+ }
206
+ }
207
+
208
+ RomoSelectDropdown.prototype._scrollBottomToItem = function(item) {
209
+ if (item.size() > 0) {
210
+ var scroll = this.romoDropdown.bodyElem;
211
+ scroll.scrollTop(0);
212
+
213
+ var scrollOffsetTop = scroll.offset().top;
214
+ var selOffsetTop = item.offset().top;
215
+ var selOffset = scroll[0].offsetHeight - item.height();
216
+
217
+ scroll.scrollTop(selOffsetTop - scrollOffsetTop - selOffset);
218
+ }
219
+ }
220
+
221
+ RomoSelectDropdown.prototype._buildOptionList = function(optionElems, listClass) {
222
+ var list = $('<ul></ul>');
223
+ list.addClass(listClass);
224
+ $.each(optionElems, $.proxy(function(idx, elem) {
225
+ if (elem.tagName === "OPTION") {
226
+ list.append(this._buildOptionListItem(elem));
227
+ } else if (elem.tagName === "OPTGROUP") {
228
+ list.append(this._buildOptGroupListItem(elem));
229
+ list.append(this._buildOptionList($(elem).children(), 'romo-select-optgroup'));
230
+ }
231
+ }, this));
232
+ return list;
233
+ }
234
+
235
+ RomoSelectDropdown.prototype._buildOptionListItem = function(optionElem) {
236
+ var opt = $(optionElem);
237
+ var item = $('<li data-romo-select-item="opt"></li>');
238
+
239
+ item.attr('data-romo-select-option-value', opt.attr('value'));
240
+ item.html(opt.text().trim() || '&nbsp;');
241
+ if (opt.prop('selected')) {
242
+ item.addClass('selected');
243
+ }
244
+ if (opt.attr('disabled') !== undefined) {
245
+ item.addClass('disabled');
246
+ }
247
+
248
+ return item;
249
+ }
250
+
251
+ RomoSelectDropdown.prototype._buildOptGroupListItem = function(optGroupElem) {
252
+ var optgroup = $(optGroupElem);
253
+ var item = $('<li data-romo-select-item="optgroup"></li>');
254
+
255
+ item.text(optgroup.attr('label'));
256
+
257
+ return item;
258
+ }
259
+
260
+ RomoSelectDropdown.prototype._nextListItem = function() {
261
+ var listOrItemSelector = 'UL, '+this.itemSelector;
262
+ var curr = this.romoDropdown.bodyElem.find('LI.romo-select-highlight');
263
+ var next = this._nextAll(curr, listOrItemSelector).first();
264
+
265
+ if (next.size() === 0) {
266
+ next = this._nextAll(curr.closest('UL'), listOrItemSelector).first();
267
+ }
268
+ if (next.size() !== 0 && next[0].tagName === 'UL') {
269
+ next = next.find(this.itemSelector).first()
270
+ }
271
+ if (next.size() === 0) {
272
+ next = this.romoDropdown.bodyElem.find(this.itemSelector).first();
273
+ }
274
+ return next;
275
+ }
276
+
277
+ RomoSelectDropdown.prototype._prevListItem = function() {
278
+ var listOrItemSelector = 'UL, '+this.itemSelector;
279
+ var curr = this.romoDropdown.bodyElem.find('LI.romo-select-highlight');
280
+ var prev = this._prevAll(curr, listOrItemSelector).last();
281
+
282
+ if (prev.size() === 0) {
283
+ prev = this._prevAll(curr.closest('UL'), listOrItemSelector).last();
284
+ }
285
+ if (prev.size() !== 0 && prev[0].tagName === 'UL') {
286
+ prev = prev.find(this.itemSelector).last()
287
+ }
288
+ if (prev.size() === 0) {
289
+ prev = this.romoDropdown.bodyElem.find(this.itemSelector).last();
290
+ }
291
+ return prev;
292
+ }
293
+
294
+ RomoSelectDropdown.prototype._nextAll = function(elem, selector) {
295
+ var els = $();
296
+ var el = elem.next();
297
+ while( el.length ) {
298
+ if (selector === undefined || el.is(selector)) {
299
+ els = els.add(el);
300
+ }
301
+ el = el.next();
302
+ }
303
+ return els;
304
+ }
305
+
306
+ RomoSelectDropdown.prototype._prevAll = function(elem, selector) {
307
+ var els = $();
308
+ var el = elem.prev();
309
+ while( el.length ) {
310
+ if (selector === undefined || el.is(selector)) {
311
+ els = els.add(el);
312
+ }
313
+ el = el.prev();
314
+ }
315
+ return els;
316
+ }
317
+
318
+ RomoSelectDropdown.prototype._highlightItem = function(item) {
319
+ this.romoDropdown.bodyElem.find('LI.romo-select-highlight').removeClass('romo-select-highlight');
320
+ item.addClass('romo-select-highlight');
321
+ }
322
+
323
+ Romo.onInitUI(function(e) {
324
+ Romo.initUIElems(e, '[data-romo-select-dropdown-auto="true"]').romoSelectDropdown();
325
+ });
@@ -0,0 +1,201 @@
1
+ $.fn.romoSortable = function() {
2
+ return $.map(this, function(element) {
3
+ return new RomoSortable(element);
4
+ });
5
+ }
6
+
7
+ var RomoSortable = function(element) {
8
+ this.elem = $(element);
9
+
10
+ this.draggableSelector = '[data-romo-sortable-item="true"]';
11
+ this.handleSelector = '[data-romo-sortable-handle="true"]';
12
+
13
+ this.draggableElems = this.elem.find(this.draggableSelector);
14
+ this.draggableElems.prop('draggable', 'true');
15
+
16
+ this.draggingClass = this.elem.data('romo-sortable-dragging-class') || '';
17
+ this.dragOverClass = this.elem.data('romo-sortable-dragover-class') || '';
18
+ this.placeholderClass = this.elem.data('romo-sortable-placeholder-class') || '';
19
+
20
+ this.draggedElem = this.draggedIndex = this.draggableSelected = null;
21
+ this.draggedOverElem = this.dragDirection = this.lastY = null;
22
+
23
+ this.elem.on('dragenter', $.proxy(this.onDragEnter, this));
24
+ this.elem.on('dragover', $.proxy(this.onDragOver, this));
25
+ this.elem.on('dragend', $.proxy(this.onDragEnd, this));
26
+ this.elem.on('drop', $.proxy(this.onDragDrop, this));
27
+
28
+ this.draggableElems.on('dragstart', $.proxy(this.onDragStart, this));
29
+ this.draggableElems.on('dragenter', $.proxy(this.onDragEnter, this));
30
+ this.draggableElems.on('dragover', $.proxy(this.onDragOver, this));
31
+ this.draggableElems.on('dragend', $.proxy(this.onDragEnd, this));
32
+ this.draggableElems.on('drop', $.proxy(this.onDragDrop, this));
33
+
34
+ this.draggableElems.on('mousedown', $.proxy(this.onDraggableMouseDown, this));
35
+ var handleElems = this.draggableElems.find(this.handleSelector)
36
+ handleElems.on('mousedown', $.proxy(this.onHandleMouseDown, this));
37
+ $('body').on('mouseup', $.proxy(this.onWindowBodyMouseUp, this));
38
+
39
+ this._resetGrabClasses();
40
+ this.doInit();
41
+ this.doInitPlaceholder();
42
+
43
+ this.elem.trigger('sortable:ready', [this]);
44
+ }
45
+
46
+ RomoSortable.prototype.doInit = function() {
47
+ // override as needed
48
+ }
49
+
50
+ RomoSortable.prototype.doInitPlaceholder = function() {
51
+ var tag;
52
+ try {
53
+ tag = this.draggableElems.get(0).tagName;
54
+ } catch(e) {
55
+ tag = /^ul|ol$/i.test(this.elem.tagName) ? 'li' : 'div';
56
+ }
57
+ this.placeholderElem = $('<' + tag + '/>');
58
+ this.placeholderElem.addClass(this.placeholderClass);
59
+
60
+ this.placeholderElem.on('dragover', $.proxy(this.onDragOver, this));
61
+ this.placeholderElem.on('drop', $.proxy(this.onDragDrop, this));
62
+ }
63
+
64
+ RomoSortable.prototype.onDragStart = function(e) {
65
+ if(!this.draggableSelected){ return false; }
66
+
67
+ e.stopPropagation();
68
+ e.originalEvent.dataTransfer.effectAllowed = 'move';
69
+
70
+ // IE fix
71
+ try {
72
+ // FF fix, it won't drag without some data being set
73
+ e.originalEvent.dataTransfer.setData('text/plain', null);
74
+ } catch(e) {}
75
+
76
+ this.draggedElem = $(e.target);
77
+ this.draggedElem.addClass(this.draggingClass);
78
+ this.draggedIndex = this.draggedElem.index();
79
+
80
+ this.placeholderElem.css({ 'height': this.draggedElem.height() });
81
+
82
+ this.elem.trigger('sortable:dragStart', [this.draggedElem, this]);
83
+ }
84
+
85
+ RomoSortable.prototype.onDragEnter = function(e) {
86
+ e.preventDefault();
87
+ e.stopPropagation();
88
+
89
+ // return if event is fired on the placeholder
90
+ if(this.placeholderElem.get(0) === e.currentTarget){ return; }
91
+
92
+ this.placeholderElem.show();
93
+ this.draggedElem.hide();
94
+
95
+ // if event is not fired on the sortable
96
+ var overSortableElem = this.elem.get(0) === e.currentTarget;
97
+ var clientX = e.originalEvent.clientX;
98
+ var clientY = e.originalEvent.clientY;
99
+ if (!overSortableElem) {
100
+ // if we are in the same elem and moving the same direction, exit out
101
+ var overSameElem = this.draggedOverElem &&
102
+ this.draggedOverElem.get(0) === e.currentTarget;
103
+ var sameDirection = (this.dragDirection === 'down' && clientY > this.lastY) ||
104
+ (this.dragDirection === 'up' && clientY < this.lastY);
105
+ if(overSameElem && sameDirection){ return; }
106
+
107
+ // remove dragged over classes from previous elem
108
+ if(this.draggedOverElem){ this.draggedOverElem.removeClass(this.dragOverClass); }
109
+ this.draggedOverElem = $(e.currentTarget);
110
+ this.lastY = clientY;
111
+ this.draggedOverElem.addClass(this.dragOverClass);
112
+
113
+ // insert the placeholder according to the dragging direction
114
+ if (this.placeholderElem.index() < this.draggedOverElem.index()) {
115
+ this.dragDirection = 'down';
116
+ } else {
117
+ this.dragDirection = 'up';
118
+ }
119
+ var insertMethod = this.dragDirection === 'down' ? 'after' : 'before';
120
+ this.draggedOverElem[insertMethod](this.placeholderElem);
121
+ }
122
+
123
+ this.elem.trigger('sortable:dragMove', [clientX, clientY, this.draggedElem, this]);
124
+ }
125
+
126
+ RomoSortable.prototype.onDragOver = function(e) {
127
+ // This is how you allow an element to receive a drop event.
128
+ e.preventDefault();
129
+ e.stopPropagation();
130
+ }
131
+
132
+ RomoSortable.prototype.onDragEnd = function(e) {
133
+ e.stopPropagation();
134
+ e.preventDefault();
135
+
136
+ if(!this.draggedElem){ return; }
137
+
138
+ this.draggableElems.removeClass(this.dragOverClass);
139
+ this.draggedElem.removeClass(this.draggingClass);
140
+ this.draggedElem.show();
141
+ this.placeholderElem.hide();
142
+ this._resetGrabClasses();
143
+
144
+ this.elem.trigger('sortable:dragStop', [this.draggedElem, this]);
145
+
146
+ this.draggedElem = this.draggedIndex = this.draggableSelected = null;
147
+ this.draggedOverElem = this.dragDirection = this.lastY = null;
148
+ }
149
+
150
+ RomoSortable.prototype.onDragDrop = function(e) {
151
+ e.stopPropagation();
152
+ e.preventDefault();
153
+
154
+ if(!this.draggedElem){ return; }
155
+
156
+ this.draggedElem.insertBefore(this.placeholderElem);
157
+ this.draggedElem.show();
158
+
159
+ var newIndex = this.draggedElem.index();
160
+ if (newIndex !== this.draggedIndex) {
161
+ this.elem.trigger('sortable:change', [this.draggedElem, this]);
162
+ }
163
+ this.elem.trigger('sortable:dragDrop', [this.draggedElem, this]);
164
+ }
165
+
166
+ RomoSortable.prototype.onDraggableMouseDown = function(e) {
167
+ // if our draggable elem doesn't have a handle then it's draggable
168
+ var draggableElem = $(e.currentTarget);
169
+ if(draggableElem.find(this.handleSelector).size() === 0) {
170
+ draggableElem.removeClass('romo-sortable-grab');
171
+ draggableElem.addClass('romo-sortable-grabbing');
172
+ this.draggableSelected = true;
173
+ }
174
+ }
175
+
176
+ RomoSortable.prototype.onHandleMouseDown = function(e) {
177
+ this.draggableSelected = true;
178
+ var handleElem = $(e.currentTarget);
179
+ handleElem.removeClass('romo-sortable-grab');
180
+ handleElem.addClass('romo-sortable-grabbing');
181
+ }
182
+
183
+ RomoSortable.prototype.onWindowBodyMouseUp = function(e) {
184
+ this.draggableSelected = false;
185
+ }
186
+
187
+ RomoSortable.prototype._resetGrabClasses = function() {
188
+ this.draggableElems.each($.proxy(function(index, item) {
189
+
190
+ draggableElem = $(item);
191
+ handleElem = draggableElem.find(this.handleSelector);
192
+ if(handleElem.size() === 0){ handleElem = draggableElem; }
193
+ handleElem.addClass('romo-sortable-grab');
194
+ handleElem.removeClass('romo-sortable-grabbing');
195
+
196
+ }, this));
197
+ }
198
+
199
+ Romo.onInitUI(function(e) {
200
+ $(e.target).find('[data-romo-sortable-auto="true"]').romoSortable();
201
+ });