romo 0.19.10 → 0.20.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.
- checksums.yaml +4 -4
- data/assets/css/romo/buttons.scss +1 -0
- data/assets/css/romo/modal.scss +5 -0
- data/assets/js/romo/ajax.js +75 -89
- data/assets/js/romo/base.js +699 -274
- data/assets/js/romo/currency_text_input.js +93 -83
- data/assets/js/romo/date.js +3 -3
- data/assets/js/romo/datepicker.js +227 -234
- data/assets/js/romo/dropdown.js +235 -344
- data/assets/js/romo/dropdown_form.js +77 -76
- data/assets/js/romo/form.js +215 -159
- data/assets/js/romo/indicator_text_input.js +64 -95
- data/assets/js/romo/inline.js +66 -59
- data/assets/js/romo/inline_form.js +74 -73
- data/assets/js/romo/modal.js +218 -294
- data/assets/js/romo/modal_form.js +83 -82
- data/assets/js/romo/onkey.js +25 -22
- data/assets/js/romo/option_list_dropdown.js +318 -298
- data/assets/js/romo/picker.js +175 -181
- data/assets/js/romo/select.js +177 -165
- data/assets/js/romo/select_dropdown.js +86 -93
- data/assets/js/romo/selected_options_list.js +66 -76
- data/assets/js/romo/sortable.js +154 -120
- data/assets/js/romo/{indicator.js → spinner.js} +74 -89
- data/assets/js/romo/tooltip.js +257 -271
- data/assets/js/romo/word_boundary_filter.js +7 -10
- data/lib/romo/dassets.rb +1 -1
- data/lib/romo/version.rb +1 -1
- data/test/unit/dassets_tests.rb +1 -1
- metadata +3 -3
data/assets/js/romo/base.js
CHANGED
@@ -1,16 +1,12 @@
|
|
1
1
|
var Romo = function() {
|
2
|
-
this.
|
2
|
+
this.popupStack = new RomoPopupStack();
|
3
|
+
this.parentChildElems = new RomoParentChildElems();
|
3
4
|
}
|
4
5
|
|
5
|
-
// TODO: rework w/o jQuery
|
6
6
|
Romo.prototype.doInit = function() {
|
7
|
-
this.
|
8
|
-
|
9
|
-
|
10
|
-
$('body').on(eventCallback.eventName, eventCallback.callback);
|
11
|
-
});
|
12
|
-
|
13
|
-
this.triggerInitUI($('body'));
|
7
|
+
this.popupStack.doInit();
|
8
|
+
this.parentChildElems.doInit();
|
9
|
+
this.initElems(Romo.f('body'));
|
14
10
|
}
|
15
11
|
|
16
12
|
// element finders
|
@@ -19,42 +15,78 @@ Romo.prototype.f = function(selector) {
|
|
19
15
|
return this.array(document.querySelectorAll(selector));
|
20
16
|
}
|
21
17
|
|
22
|
-
Romo.prototype.find = function(
|
23
|
-
return this.array(
|
18
|
+
Romo.prototype.find = function(parentElems, selector) {
|
19
|
+
return this.array(parentElems).reduce(
|
20
|
+
Romo.proxy(function(foundElems, parentElem) {
|
21
|
+
return foundElems.concat(this.array(parentElem.querySelectorAll(selector)));
|
22
|
+
}, this),
|
23
|
+
[]
|
24
|
+
);
|
24
25
|
}
|
25
26
|
|
26
|
-
Romo.prototype.
|
27
|
-
return
|
27
|
+
Romo.prototype.is = function(elem, selector) {
|
28
|
+
return (
|
29
|
+
elem.matches ||
|
30
|
+
elem.matchesSelector ||
|
31
|
+
elem.msMatchesSelector ||
|
32
|
+
elem.mozMatchesSelector ||
|
33
|
+
elem.webkitMatchesSelector ||
|
34
|
+
elem.oMatchesSelector
|
35
|
+
).call(elem, selector);
|
36
|
+
};
|
37
|
+
|
38
|
+
Romo.prototype.children = function(parentElem, selector) {
|
39
|
+
var childElems = this.array(parentElem.children);
|
40
|
+
if (selector) {
|
41
|
+
return childElems.filter(function(childElem) {
|
42
|
+
return Romo.is(childElem, selector);
|
43
|
+
});
|
44
|
+
} else {
|
45
|
+
return childElems;
|
46
|
+
}
|
28
47
|
}
|
29
48
|
|
30
49
|
Romo.prototype.parent = function(childElem) {
|
31
50
|
return childElem.parentNode;
|
32
51
|
}
|
33
52
|
|
34
|
-
Romo.prototype.
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
53
|
+
Romo.prototype.parents = function(childElem, selector) {
|
54
|
+
var parentElem = this.parent(childElem);
|
55
|
+
if (parentElem && parentElem !== document) {
|
56
|
+
if (!selector || Romo.is(parentElem, selector)) {
|
57
|
+
if (Romo.is(parentElem, 'body')) {
|
58
|
+
return [parentElem];
|
59
|
+
} else {
|
60
|
+
return [parentElem].concat(this.parents(parentElem, selector));
|
61
|
+
}
|
62
|
+
} else {
|
63
|
+
if (Romo.is(parentElem, 'body')) {
|
64
|
+
return [];
|
65
|
+
} else {
|
66
|
+
return this.parents(parentElem, selector);
|
67
|
+
}
|
68
|
+
}
|
69
|
+
} else {
|
70
|
+
return [];
|
71
|
+
}
|
42
72
|
}
|
43
73
|
|
44
|
-
Romo.prototype.
|
45
|
-
return
|
74
|
+
Romo.prototype.scrollableParents = function(childElem, selector) {
|
75
|
+
return Romo.parents(childElem, selector).filter(function(parentElem) {
|
76
|
+
return (
|
77
|
+
Romo._overflowScrollableRegex.test(Romo.css(parentElem, 'overflow')) ||
|
78
|
+
Romo._overflowScrollableRegex.test(Romo.css(parentElem, 'overflow-y')) ||
|
79
|
+
Romo._overflowScrollableRegex.test(Romo.css(parentElem, 'overflow-x'))
|
80
|
+
);
|
81
|
+
});
|
46
82
|
}
|
47
83
|
|
48
84
|
Romo.prototype.closest = function(fromElem, selector) {
|
49
85
|
if (fromElem.closest) {
|
50
86
|
return fromElem.closest(selector);
|
51
87
|
} else {
|
52
|
-
var matchesSelector = fromElem.matches ||
|
53
|
-
fromElem.webkitMatchesSelector ||
|
54
|
-
fromElem.mozMatchesSelector ||
|
55
|
-
fromElem.msMatchesSelector;
|
56
88
|
while (fromElem) {
|
57
|
-
if (
|
89
|
+
if (Romo.is(fromElem, selector)) {
|
58
90
|
return fromElem;
|
59
91
|
} else {
|
60
92
|
fromElem = fromElem.parentElement;
|
@@ -64,80 +96,133 @@ Romo.prototype.closest = function(fromElem, selector) {
|
|
64
96
|
}
|
65
97
|
}
|
66
98
|
|
67
|
-
|
68
|
-
Romo.
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
99
|
+
Romo.prototype.siblings = function(elem, selector) {
|
100
|
+
return Romo.children(Romo.parent(elem), selector).filter(function(childElem) {
|
101
|
+
return childElem !== elem;
|
102
|
+
});
|
103
|
+
}
|
104
|
+
|
105
|
+
Romo.prototype.prev = function(fromElem, selector) {
|
106
|
+
var elem = fromElem.previousElementSibling;
|
107
|
+
if (elem === null) {
|
108
|
+
elem = undefined;
|
109
|
+
}
|
110
|
+
|
111
|
+
while(elem) {
|
112
|
+
if (!selector || Romo.is(elem, selector)) {
|
113
|
+
return elem;
|
114
|
+
}
|
115
|
+
elem = elem.previousElementSibling;
|
116
|
+
if (elem === null) {
|
117
|
+
elem = undefined;
|
75
118
|
}
|
76
|
-
el = el.next();
|
77
119
|
}
|
78
|
-
return
|
120
|
+
return elem;
|
79
121
|
}
|
80
122
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
123
|
+
Romo.prototype.next = function(fromElem, selector) {
|
124
|
+
var elem = fromElem.nextElementSibling;
|
125
|
+
if (elem === null) {
|
126
|
+
elem = undefined;
|
127
|
+
}
|
128
|
+
|
129
|
+
while(elem) {
|
130
|
+
if (!selector || Romo.is(elem, selector)) {
|
131
|
+
return elem;
|
132
|
+
}
|
133
|
+
elem = elem.nextElementSibling;
|
134
|
+
if (elem === null) {
|
135
|
+
elem = undefined;
|
89
136
|
}
|
90
|
-
el = el.prev();
|
91
137
|
}
|
92
|
-
return
|
138
|
+
return elem;
|
93
139
|
}
|
94
140
|
|
95
141
|
// attributes, styles, classes
|
96
142
|
|
97
143
|
Romo.prototype.attr = function(elem, attrName) {
|
98
|
-
|
144
|
+
var a = elem.getAttribute(attrName);
|
145
|
+
if (a === null) {
|
146
|
+
return undefined;
|
147
|
+
} else {
|
148
|
+
return a;
|
149
|
+
}
|
99
150
|
}
|
100
151
|
|
101
|
-
Romo.prototype.setAttr = function(
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
152
|
+
Romo.prototype.setAttr = function(elems, attrName, attrValue) {
|
153
|
+
var v = String(attrValue);
|
154
|
+
Romo.array(elems).forEach(function(elem) {
|
155
|
+
elem.setAttribute(attrName, v);
|
156
|
+
});
|
157
|
+
return v;
|
158
|
+
}
|
159
|
+
|
160
|
+
Romo.prototype.rmAttr = function(elems, attrName) {
|
161
|
+
Romo.array(elems).forEach(function(elem) {
|
162
|
+
elem.removeAttribute(attrName);
|
163
|
+
});
|
106
164
|
}
|
107
165
|
|
108
166
|
Romo.prototype.data = function(elem, dataName) {
|
109
167
|
return this._deserializeValue(this.attr(elem, "data-"+dataName));
|
110
168
|
}
|
111
169
|
|
112
|
-
Romo.prototype.setData = function(
|
113
|
-
return this.setAttr(
|
170
|
+
Romo.prototype.setData = function(elems, dataName, dataValue) {
|
171
|
+
return this.setAttr(elems, "data-"+dataName, dataValue);
|
172
|
+
}
|
173
|
+
|
174
|
+
Romo.prototype.rmData = function(elems, dataName) {
|
175
|
+
this.rmAttr(elems, "data-"+dataName);
|
114
176
|
}
|
115
177
|
|
116
178
|
Romo.prototype.style = function(elem, styleName) {
|
117
179
|
return elem.style[styleName];
|
118
180
|
}
|
119
181
|
|
120
|
-
Romo.prototype.setStyle = function(
|
121
|
-
elem
|
182
|
+
Romo.prototype.setStyle = function(elems, styleName, styleValue) {
|
183
|
+
Romo.array(elems).forEach(function(elem) {
|
184
|
+
elem.style[styleName] = styleValue;
|
185
|
+
});
|
122
186
|
return styleValue;
|
123
187
|
}
|
124
188
|
|
189
|
+
Romo.prototype.rmStyle = function(elems, styleName) {
|
190
|
+
Romo.array(elems).forEach(function(elem) {
|
191
|
+
elem.style[styleName] = '';
|
192
|
+
});
|
193
|
+
}
|
194
|
+
|
125
195
|
Romo.prototype.css = function(elem, styleName) {
|
126
196
|
return window.getComputedStyle(elem, null).getPropertyValue(styleName);
|
127
197
|
}
|
128
198
|
|
129
|
-
Romo.prototype.addClass = function(
|
130
|
-
|
199
|
+
Romo.prototype.addClass = function(elems, className) {
|
200
|
+
var classNames = className.split(' ').filter(function(n){ return n; });
|
201
|
+
Romo.array(elems).forEach(function(elem) {
|
202
|
+
classNames.forEach(function(name) {
|
203
|
+
elem.classList.add(name);
|
204
|
+
});
|
205
|
+
});
|
131
206
|
return className;
|
132
207
|
}
|
133
208
|
|
134
|
-
Romo.prototype.removeClass = function(
|
135
|
-
|
209
|
+
Romo.prototype.removeClass = function(elems, className) {
|
210
|
+
var classNames = className.split(' ').filter(function(n){ return n; });
|
211
|
+
Romo.array(elems).forEach(function(elem) {
|
212
|
+
classNames.forEach(function(name) {
|
213
|
+
elem.classList.remove(name);
|
214
|
+
});
|
215
|
+
});
|
136
216
|
return className;
|
137
217
|
}
|
138
218
|
|
139
|
-
Romo.prototype.toggleClass = function(
|
140
|
-
|
219
|
+
Romo.prototype.toggleClass = function(elems, className) {
|
220
|
+
var classNames = className.split(' ').filter(function(n){ return n; });
|
221
|
+
Romo.array(elems).forEach(function(elem) {
|
222
|
+
classNames.forEach(function(name) {
|
223
|
+
elem.classList.toggle(name);
|
224
|
+
});
|
225
|
+
});
|
141
226
|
return className;
|
142
227
|
}
|
143
228
|
|
@@ -145,19 +230,24 @@ Romo.prototype.hasClass = function(elem, className) {
|
|
145
230
|
return elem.classList.contains(className);
|
146
231
|
}
|
147
232
|
|
148
|
-
Romo.prototype.show = function(
|
149
|
-
|
233
|
+
Romo.prototype.show = function(elems) {
|
234
|
+
Romo.array(elems).forEach(function(elem) {
|
235
|
+
elem.style.display = '';
|
236
|
+
});
|
150
237
|
}
|
151
238
|
|
152
|
-
Romo.prototype.hide = function(
|
153
|
-
|
239
|
+
Romo.prototype.hide = function(elems) {
|
240
|
+
Romo.array(elems).forEach(function(elem) {
|
241
|
+
elem.style.display = 'none';
|
242
|
+
});
|
154
243
|
}
|
155
244
|
|
156
245
|
Romo.prototype.offset = function(elem) {
|
157
|
-
var
|
246
|
+
var elemRect = elem.getBoundingClientRect();
|
247
|
+
var bodyRect = document.body.getBoundingClientRect();
|
158
248
|
return {
|
159
|
-
top:
|
160
|
-
left:
|
249
|
+
top: elemRect.top - bodyRect.top,
|
250
|
+
left: elemRect.left - bodyRect.left
|
161
251
|
};
|
162
252
|
}
|
163
253
|
|
@@ -169,28 +259,26 @@ Romo.prototype.scrollLeft = function(elem) {
|
|
169
259
|
return ('scrollLeft' in elem) ? elem.scrollLeft : elem.pageXOffset;
|
170
260
|
}
|
171
261
|
|
172
|
-
Romo.prototype.setScrollTop = function(
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
}
|
179
|
-
|
180
|
-
Romo.prototype.setScrollLeft = function(elem, value) {
|
181
|
-
if ('scrollLeft' in elem) {
|
182
|
-
elem.scrollLeft = value;
|
183
|
-
} else {
|
184
|
-
elem.scrollTo(value, elem.scrollY);
|
185
|
-
}
|
262
|
+
Romo.prototype.setScrollTop = function(elems, value) {
|
263
|
+
Romo.array(elems).forEach(function(elem) {
|
264
|
+
if ('scrollTop' in elem) {
|
265
|
+
elem.scrollTop = value;
|
266
|
+
} else {
|
267
|
+
elem.scrollTo(elem.scrollX, value);
|
268
|
+
}
|
269
|
+
});
|
186
270
|
}
|
187
271
|
|
188
|
-
|
189
|
-
Romo.
|
190
|
-
|
272
|
+
Romo.prototype.setScrollLeft = function(elems, value) {
|
273
|
+
Romo.array(elems).forEach(function(elem) {
|
274
|
+
if ('scrollLeft' in elem) {
|
275
|
+
elem.scrollLeft = value;
|
276
|
+
} else {
|
277
|
+
elem.scrollTo(value, elem.scrollY);
|
278
|
+
}
|
279
|
+
});
|
191
280
|
}
|
192
281
|
|
193
|
-
// TODO: rework w/o jQuery
|
194
282
|
Romo.prototype.parseZIndex = function(elem) {
|
195
283
|
// for the case where z-index is set directly on the elem
|
196
284
|
var val = this.parseElemZIndex(elem);
|
@@ -199,27 +287,26 @@ Romo.prototype.parseZIndex = function(elem) {
|
|
199
287
|
}
|
200
288
|
|
201
289
|
// for the case where z-index is inherited from a parent elem
|
202
|
-
var
|
203
|
-
|
204
|
-
if (pval
|
205
|
-
|
290
|
+
var pval = 0;
|
291
|
+
var parentIndexes = Romo.parents(elem).forEach(Romo.proxy(function(parentElem) {
|
292
|
+
if (pval === 0) {
|
293
|
+
pval = this.parseElemZIndex(parentElem);
|
206
294
|
}
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
return
|
295
|
+
}, this));
|
296
|
+
|
297
|
+
// z-index is 'auto' all the way up
|
298
|
+
return pval;
|
211
299
|
}
|
212
300
|
|
213
|
-
// TODO: rework w/o jQuery
|
214
301
|
Romo.prototype.parseElemZIndex = function(elem) {
|
215
|
-
var val = parseInt(this.
|
302
|
+
var val = parseInt(this.css(elem, "z-index"), 10);
|
216
303
|
if (!isNaN(val)) {
|
217
304
|
return val;
|
218
305
|
}
|
219
306
|
return 0;
|
220
307
|
}
|
221
308
|
|
222
|
-
//
|
309
|
+
// elems init
|
223
310
|
|
224
311
|
Romo.prototype.elems = function(htmlString) {
|
225
312
|
var context = document.implementation.createHTMLDocument();
|
@@ -230,12 +317,46 @@ Romo.prototype.elems = function(htmlString) {
|
|
230
317
|
base.href = document.location.href;
|
231
318
|
context.head.appendChild(base);
|
232
319
|
|
233
|
-
|
234
|
-
|
320
|
+
var results = Romo._elemsTagNameRegEx.exec(htmlString);
|
321
|
+
if (!results){ return []; }
|
322
|
+
|
323
|
+
var tagName = results[1].toLowerCase();
|
324
|
+
var wrap = Romo._elemsWrapMap[tagName];
|
325
|
+
if (!wrap) {
|
326
|
+
context.body.innerHTML = htmlString;
|
327
|
+
return this.array(context.body.children);
|
328
|
+
} else {
|
329
|
+
context.body.innerHTML = wrap[1] + htmlString + wrap[2];
|
330
|
+
var parentElem = context.body;
|
331
|
+
var i = wrap[0];
|
332
|
+
while(i-- !== 0) {
|
333
|
+
parentElem = parentElem.lastChild;
|
334
|
+
}
|
335
|
+
return this.array(parentElem.children)
|
336
|
+
}
|
337
|
+
}
|
338
|
+
|
339
|
+
Romo.prototype.addElemsInitSelector = function(selector, componentClass) {
|
340
|
+
this._elemsInitComponents[selector] = componentClass;
|
341
|
+
}
|
342
|
+
|
343
|
+
Romo.prototype.initElems = function(elems) {
|
344
|
+
return this._elemsInitTrigger(Romo.array(elems));
|
345
|
+
}
|
346
|
+
|
347
|
+
Romo.prototype.initElemsHtml = function(htmlString) {
|
348
|
+
return this.initElems(this.elems(htmlString));
|
235
349
|
}
|
236
350
|
|
237
|
-
|
238
|
-
|
351
|
+
// DOM manipulation
|
352
|
+
|
353
|
+
Romo.prototype.remove = function(elems) {
|
354
|
+
return Romo.array(elems).map(function(elem) {
|
355
|
+
if (elem.parentNode) {
|
356
|
+
elem.parentNode.removeChild(elem);
|
357
|
+
}
|
358
|
+
return elem;
|
359
|
+
});
|
239
360
|
}
|
240
361
|
|
241
362
|
Romo.prototype.replace = function(elem, replacementElem) {
|
@@ -244,131 +365,200 @@ Romo.prototype.replace = function(elem, replacementElem) {
|
|
244
365
|
}
|
245
366
|
|
246
367
|
Romo.prototype.replaceHtml = function(elem, htmlString) {
|
247
|
-
|
368
|
+
var replacementElem = Romo.elems(htmlString)[0];
|
369
|
+
if (replacementElem === undefined && (typeof(htmlString) !== 'string' || htmlString.trim() !== '')) {
|
370
|
+
throw new Error("Invalid HTML string, doesn't contain an HTML element.");
|
371
|
+
}
|
372
|
+
return this.replace(elem, replacementElem);
|
373
|
+
}
|
374
|
+
|
375
|
+
Romo.prototype.initReplace = function(elem, replacementElem) {
|
376
|
+
return this.initElems(this.replace(elem, replacementElem))[0];
|
377
|
+
}
|
378
|
+
|
379
|
+
Romo.prototype.initReplaceHtml = function(elem, htmlString) {
|
380
|
+
return this.initElems(this.replaceHtml(elem, htmlString))[0];
|
248
381
|
}
|
249
382
|
|
250
383
|
Romo.prototype.update = function(elem, childElems) {
|
251
384
|
elem.innerHTML = '';
|
252
|
-
return childElems.map(function(childElem) {
|
385
|
+
return Romo.array(childElems).map(function(childElem) {
|
253
386
|
return elem.appendChild(childElem);
|
254
387
|
});
|
255
388
|
}
|
256
389
|
|
257
390
|
Romo.prototype.updateHtml = function(elem, htmlString) {
|
258
|
-
|
391
|
+
var childElems = Romo.elems(htmlString);
|
392
|
+
if (childElems.length === 0 && (typeof(htmlString) !== 'string' || htmlString.trim() !== '')) {
|
393
|
+
throw new Error("Invalid HTML string, doesn't contain any HTML elements.");
|
394
|
+
}
|
395
|
+
return this.update(elem, childElems);
|
396
|
+
}
|
397
|
+
|
398
|
+
Romo.prototype.updateText = function(elem, textString) {
|
399
|
+
elem.innerText = textString;
|
400
|
+
}
|
401
|
+
|
402
|
+
Romo.prototype.initUpdate = function(elem, childElems) {
|
403
|
+
return this.initElems(this.update(elem, childElems));
|
404
|
+
}
|
405
|
+
|
406
|
+
Romo.prototype.initUpdateHtml = function(elem, htmlString) {
|
407
|
+
return this.initElems(this.updateHtml(elem, htmlString));
|
259
408
|
}
|
260
409
|
|
261
410
|
Romo.prototype.prepend = function(elem, childElems) {
|
262
411
|
var refElem = elem.firstChild;
|
263
|
-
return childElems.reverse().map(function(childElem) {
|
412
|
+
return Romo.array(childElems).reverse().map(function(childElem) {
|
264
413
|
refElem = elem.insertBefore(childElem, refElem);
|
265
414
|
return refElem;
|
266
415
|
}).reverse();
|
267
416
|
}
|
268
417
|
|
269
418
|
Romo.prototype.prependHtml = function(elem, htmlString) {
|
270
|
-
|
419
|
+
var childElems = Romo.elems(htmlString);
|
420
|
+
if (childElems.length === 0 && (typeof(htmlString) !== 'string' || htmlString.trim() !== '')) {
|
421
|
+
throw new Error("Invalid HTML string, doesn't contain any HTML elements.");
|
422
|
+
}
|
423
|
+
return this.prepend(elem, childElems);
|
424
|
+
}
|
425
|
+
|
426
|
+
Romo.prototype.initPrepend = function(elem, childElems) {
|
427
|
+
return this.initElems(this.prepend(elem, childElems));
|
428
|
+
}
|
429
|
+
|
430
|
+
Romo.prototype.initPrependHtml = function(elem, htmlString) {
|
431
|
+
return this.initElems(this.prependHtml(elem, htmlString));
|
271
432
|
}
|
272
433
|
|
273
434
|
Romo.prototype.append = function(elem, childElems) {
|
274
|
-
return childElems.map(function(childElem) {
|
435
|
+
return Romo.array(childElems).map(function(childElem) {
|
275
436
|
return elem.appendChild(childElem);
|
276
437
|
});
|
277
438
|
}
|
278
439
|
|
279
440
|
Romo.prototype.appendHtml = function(elem, htmlString) {
|
280
|
-
|
441
|
+
var childElems = Romo.elems(htmlString);
|
442
|
+
if (childElems.length === 0 && (typeof(htmlString) !== 'string' || htmlString.trim() !== '')) {
|
443
|
+
throw new Error("Invalid HTML string, doesn't contain any HTML elements.");
|
444
|
+
}
|
445
|
+
return this.append(elem, childElems);
|
446
|
+
}
|
447
|
+
|
448
|
+
Romo.prototype.initAppend = function(elem, childElems) {
|
449
|
+
return this.initElems(this.append(elem, childElems));
|
450
|
+
}
|
451
|
+
|
452
|
+
Romo.prototype.initAppendHtml = function(elem, htmlString) {
|
453
|
+
return this.initElems(this.appendHtml(elem, htmlString));
|
281
454
|
}
|
282
455
|
|
283
456
|
Romo.prototype.before = function(elem, siblingElems) {
|
284
457
|
var refElem = elem;
|
285
458
|
var parentElem = elem.parentNode;
|
286
|
-
return siblingElems.reverse().map(function(siblingElem) {
|
459
|
+
return Romo.array(siblingElems).reverse().map(function(siblingElem) {
|
287
460
|
refElem = parentElem.insertBefore(siblingElem, refElem);
|
288
461
|
return refElem;
|
289
462
|
}).reverse();
|
290
463
|
}
|
291
464
|
|
292
465
|
Romo.prototype.beforeHtml = function(elem, htmlString) {
|
293
|
-
|
466
|
+
var siblingElems = Romo.elems(htmlString);
|
467
|
+
if (siblingElems.length === 0 && (typeof(htmlString) !== 'string' || htmlString.trim() !== '')) {
|
468
|
+
throw new Error("Invalid HTML string, doesn't contain any HTML elements.");
|
469
|
+
}
|
470
|
+
return this.before(elem, siblingElems);
|
471
|
+
}
|
472
|
+
|
473
|
+
Romo.prototype.initBefore = function(elem, siblingElems) {
|
474
|
+
return this.initElems(this.before(elem, siblingElems));
|
475
|
+
}
|
476
|
+
|
477
|
+
Romo.prototype.initBeforeHtml = function(elem, htmlString) {
|
478
|
+
return this.initElems(this.beforeHtml(elem, htmlString));
|
294
479
|
}
|
295
480
|
|
296
481
|
Romo.prototype.after = function(elem, siblingElems) {
|
297
482
|
var refElem = this.next(elem);
|
298
483
|
var parentElem = elem.parentNode;
|
299
|
-
return siblingElems.map(function(siblingElem) {
|
484
|
+
return Romo.array(siblingElems).map(function(siblingElem) {
|
300
485
|
return parentElem.insertBefore(siblingElem, refElem);
|
301
486
|
});
|
302
487
|
}
|
303
488
|
|
304
489
|
Romo.prototype.afterHtml = function(elem, htmlString) {
|
305
|
-
|
490
|
+
var siblingElems = Romo.elems(htmlString);
|
491
|
+
if (siblingElems.length === 0 && (typeof(htmlString) !== 'string' || htmlString.trim() !== '')) {
|
492
|
+
throw new Error("Invalid HTML string, doesn't contain any HTML elements.");
|
493
|
+
}
|
494
|
+
return this.after(elem, siblingElems);
|
306
495
|
}
|
307
496
|
|
308
|
-
|
309
|
-
|
310
|
-
Romo.prototype.onInitUI = function(callback) {
|
311
|
-
this._addEventCallback('romo:initUI', callback);
|
497
|
+
Romo.prototype.initAfter = function(elem, siblingElems) {
|
498
|
+
return this.initElems(this.after(elem, siblingElems));
|
312
499
|
}
|
313
500
|
|
314
|
-
Romo.prototype.
|
315
|
-
|
501
|
+
Romo.prototype.initAfterHtml = function(elem, htmlString) {
|
502
|
+
return this.initElems(this.afterHtml(elem, htmlString));
|
316
503
|
}
|
317
504
|
|
318
|
-
|
319
|
-
var elems = $(e.target).find(selector).get();
|
320
|
-
if ($(e.target).is(selector)) {
|
321
|
-
elems.push(e.target)
|
322
|
-
}
|
323
|
-
return $(elems);
|
324
|
-
}
|
505
|
+
// events
|
325
506
|
|
326
|
-
Romo.prototype.
|
327
|
-
|
328
|
-
var
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
}
|
507
|
+
Romo.prototype.on = function(elems, eventName, fn) {
|
508
|
+
var proxyFn = function(e) {
|
509
|
+
var result = fn.apply(e.target, e.detail === undefined ? [e] : [e].concat(e.detail));
|
510
|
+
if (result === false) {
|
511
|
+
e.preventDefault();
|
512
|
+
e.stopPropagation();
|
513
|
+
}
|
514
|
+
return result;
|
515
|
+
}
|
516
|
+
proxyFn._romofid = this._fn(fn)._romofid;
|
333
517
|
|
334
|
-
Romo.
|
335
|
-
|
336
|
-
var
|
337
|
-
|
338
|
-
|
518
|
+
Romo.array(elems).forEach(Romo.proxy(function(elem) {
|
519
|
+
elem.addEventListener(eventName, proxyFn);
|
520
|
+
var key = this._handlerKey(elem, eventName, proxyFn);
|
521
|
+
if (this._handlers[key] === undefined) {
|
522
|
+
this._handlers[key] = [];
|
523
|
+
}
|
524
|
+
this._handlers[key].push(proxyFn);
|
339
525
|
}, this));
|
340
526
|
}
|
341
527
|
|
342
|
-
Romo.prototype.
|
343
|
-
elems.
|
344
|
-
var
|
345
|
-
|
346
|
-
|
528
|
+
Romo.prototype.off = function(elems, eventName, fn) {
|
529
|
+
Romo.array(elems).forEach(Romo.proxy(function(elem) {
|
530
|
+
var key = this._handlerKey(elem, eventName, fn);
|
531
|
+
(this._handlers[key] || []).forEach(function(proxyFn) {
|
532
|
+
elem.removeEventListener(eventName, proxyFn);
|
533
|
+
});
|
534
|
+
this._handlers[key] = [];
|
347
535
|
}, this));
|
348
536
|
}
|
349
537
|
|
350
|
-
Romo.prototype.
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
538
|
+
Romo.prototype.trigger = function(elems, customEventName, args) {
|
539
|
+
var event = undefined;
|
540
|
+
if (typeof window.CustomEvent === "function") {
|
541
|
+
event = new CustomEvent(customEventName, { detail: args });
|
542
|
+
} else {
|
543
|
+
event = document.createEvent('CustomEvent');
|
544
|
+
event.initCustomEvent(customEventName, false, false, args);
|
545
|
+
}
|
546
|
+
Romo.array(elems).forEach(function(elem) {
|
547
|
+
elem.dispatchEvent(event);
|
548
|
+
});
|
356
549
|
}
|
357
550
|
|
358
|
-
Romo.prototype.
|
359
|
-
|
360
|
-
|
361
|
-
$(elem).before(insertedElem);
|
362
|
-
this.triggerInitUI(insertedElem);
|
363
|
-
}, this));
|
551
|
+
Romo.prototype.pushFn = function(fn) {
|
552
|
+
// push the function to delay running until the end of the reactor stack
|
553
|
+
setTimeout(fn, 1);
|
364
554
|
}
|
365
555
|
|
366
|
-
Romo.prototype.
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
this.
|
371
|
-
}
|
556
|
+
Romo.prototype.ready = function(eventHandlerFn) {
|
557
|
+
if (document.readyState === 'complete' || document.readyState !== 'loading') {
|
558
|
+
eventHandlerFn();
|
559
|
+
} else {
|
560
|
+
this.on(document, 'DOMContentLoaded', eventHandlerFn);
|
561
|
+
}
|
372
562
|
}
|
373
563
|
|
374
564
|
// page handling
|
@@ -381,20 +571,43 @@ Romo.prototype.redirectPage = function(redirectUrl) {
|
|
381
571
|
window.location = redirectUrl;
|
382
572
|
}
|
383
573
|
|
384
|
-
// param serialization
|
574
|
+
// param serialization
|
575
|
+
|
576
|
+
// Romo.param({ a: 2, b: 'three', c: 4 }); #=> "a=2&b=three&c=4"
|
577
|
+
// Romo.param({ a: [ 2, 3, 4 ] }); #=> "a[]=2&a[]=3&a[]=4"
|
578
|
+
// Romo.param({ a: 2, b: '', c: 4 }); #=> "a=2&b=&c=4"
|
579
|
+
// Romo.param({ a: 2, b: '', c: 4 }, { removeEmpty: true }); #=> "a=2&c=4"
|
580
|
+
// Romo.param({ a: [ 2, 3, 4 ], b: [''] }); #=> "a[]=2&a[]=3&a[]=4&b[]="
|
581
|
+
// Romo.param({ a: [ 2, 3, 4 ], b: [''] }, { removeEmpty: true }); #=> "a[]=2&a[]=3&a[]=4"
|
582
|
+
// Romo.param({ a: '123-ABC' }); #=> "a=123%2DABC"
|
583
|
+
// Romo.param({ a: '123-ABC' }, { decodeValues: true }); #=> "a=123-ABC"
|
385
584
|
|
386
585
|
Romo.prototype.param = function(data, opts) {
|
387
|
-
var
|
586
|
+
var keyValues = [];
|
587
|
+
|
588
|
+
var processKeyValue = function(keyValues, key, value, opts) {
|
589
|
+
var v = String(value);
|
590
|
+
if (!opts || !opts.removeEmpty || v !== '') {
|
591
|
+
keyValues.push([key, v]);
|
592
|
+
}
|
593
|
+
}
|
388
594
|
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
595
|
+
for (var key in data) {
|
596
|
+
var value = data[key];
|
597
|
+
if (Array.isArray(value)) {
|
598
|
+
if (!opts || !opts.removeEmpty || value.length !== 0) {
|
599
|
+
value.forEach(function(listValue) {
|
600
|
+
processKeyValue(keyValues, key+'[]', listValue, opts);
|
601
|
+
})
|
393
602
|
}
|
394
|
-
}
|
603
|
+
} else {
|
604
|
+
processKeyValue(keyValues, key, value, opts);
|
605
|
+
}
|
395
606
|
}
|
396
607
|
|
397
|
-
var paramString =
|
608
|
+
var paramString = keyValues.map(function(keyValue){
|
609
|
+
return keyValue.join('=');
|
610
|
+
}).join('&');
|
398
611
|
|
399
612
|
if (opts && opts.decodeValues) {
|
400
613
|
paramString = this.decodeParam(paramString);
|
@@ -443,13 +656,25 @@ Romo.prototype.decodeParamMap = [
|
|
443
656
|
Romo.prototype.ajax = function(settings) {
|
444
657
|
var httpMethod = (settings.type || 'GET').toUpperCase();
|
445
658
|
var xhrUrl = settings.url || window.location.toString();
|
446
|
-
var xhrData = settings.data ? settings.data :
|
447
|
-
if (xhrData &&
|
448
|
-
|
449
|
-
|
450
|
-
|
659
|
+
var xhrData = settings.data ? settings.data : undefined
|
660
|
+
if (xhrData && Object.keys(xhrData).length > 0) {
|
661
|
+
if (httpMethod === 'GET') {
|
662
|
+
var xhrQuery = Romo.param(xhrData);
|
663
|
+
if (xhrQuery !== '') {
|
664
|
+
xhrUrl = (xhrUrl + '&' + xhrQuery).replace(/[&?]{1,2}/, '?');
|
665
|
+
}
|
666
|
+
xhrData = undefined;
|
667
|
+
} else {
|
668
|
+
var formData = new FormData;
|
669
|
+
for (var name in xhrData) {
|
670
|
+
Romo.array(xhrData[name]).forEach(function(value){
|
671
|
+
formData.append(name, value)
|
672
|
+
});
|
673
|
+
}
|
674
|
+
xhrData = formData;
|
451
675
|
}
|
452
|
-
|
676
|
+
} else {
|
677
|
+
xhrData = undefined;
|
453
678
|
}
|
454
679
|
|
455
680
|
var xhr = new XMLHttpRequest();
|
@@ -466,13 +691,13 @@ Romo.prototype.ajax = function(settings) {
|
|
466
691
|
}
|
467
692
|
xhr.onreadystatechange = function() {
|
468
693
|
if (xhr.readyState === 4) {
|
469
|
-
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
|
694
|
+
if (settings.success !== undefined && ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304)) {
|
470
695
|
if (xhr.responseType === 'arraybuffer' || xhr.responseType === 'blob') {
|
471
696
|
settings.success.call(window, xhr.response, xhr.status, xhr, settings);
|
472
697
|
} else {
|
473
698
|
settings.success.call(window, xhr.responseText, xhr.status, xhr, settings);
|
474
699
|
}
|
475
|
-
} else {
|
700
|
+
} else if(settings.error !== undefined) {
|
476
701
|
settings.error.call(window, xhr.statusText || null, xhr.status, xhr, settings);
|
477
702
|
}
|
478
703
|
}
|
@@ -480,67 +705,84 @@ Romo.prototype.ajax = function(settings) {
|
|
480
705
|
xhr.send(xhrData);
|
481
706
|
},
|
482
707
|
|
483
|
-
//
|
708
|
+
// utils
|
484
709
|
|
485
|
-
Romo.prototype.
|
486
|
-
//
|
487
|
-
//
|
488
|
-
//
|
489
|
-
//
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
// elem.addEventListener(eventName, proxyFn);
|
499
|
-
// this._handlers[key] = proxyFn;
|
500
|
-
// }
|
501
|
-
|
502
|
-
// Giant Hack to temporarily support jQuery and non-jQuery triggers
|
503
|
-
// see: https://bugs.jquery.com/ticket/11047
|
504
|
-
$(elem).on(eventName, fn);
|
505
|
-
}
|
506
|
-
|
507
|
-
Romo.prototype.off = function(elem, eventName, fn) {
|
508
|
-
// var key = this._handlerKey(elem, eventName, fn);
|
509
|
-
// var proxyFn = this._handlers[key];
|
510
|
-
// if (proxyFn) {
|
511
|
-
// elem.removeEventListener(eventName, proxyFn);
|
512
|
-
// this._handlers[key] = undefined;
|
513
|
-
// }
|
514
|
-
|
515
|
-
// Giant Hack to temporarily support jQuery and non-jQuery triggers
|
516
|
-
// see: https://bugs.jquery.com/ticket/11047
|
517
|
-
$(elem).off(eventName, fn);
|
518
|
-
}
|
519
|
-
|
520
|
-
Romo.prototype.trigger = function(elem, customEventName, args) {
|
521
|
-
// var event = undefined;
|
522
|
-
// if (typeof window.CustomEvent === "function") {
|
523
|
-
// event = new CustomEvent(customEventName, { detail: args });
|
524
|
-
// } else {
|
525
|
-
// event = document.createEvent('CustomEvent');
|
526
|
-
// event.initCustomEvent(customEventName, false, false, args);
|
527
|
-
// }
|
528
|
-
// elem.dispatchEvent(event);
|
529
|
-
$(elem).trigger(customEventName, args);
|
530
|
-
}
|
710
|
+
Romo.prototype.array = function(value) {
|
711
|
+
// short circuit `Romo.f`, `Romo.find`, and `Romo.elems` calls (and others
|
712
|
+
// that return NodeList or HTMLCollection objects), this ensures these calls
|
713
|
+
// remain fast and don't run through all of the logic to detect if an object
|
714
|
+
// is like an array
|
715
|
+
var valString = Object.prototype.toString.call(value);
|
716
|
+
if (
|
717
|
+
valString === '[object NodeList]' ||
|
718
|
+
valString === '[object HTMLCollection]' ||
|
719
|
+
Array.isArray(value)
|
720
|
+
) {
|
721
|
+
return Array.prototype.slice.call(value)
|
722
|
+
}
|
531
723
|
|
532
|
-
|
533
|
-
|
534
|
-
|
724
|
+
// short circuit for passing individual elems and "not truthy" values, this
|
725
|
+
// ensures these remain fast (the individual elems) and avoids running into
|
726
|
+
// the is like an array logic; this fixes issues with select and form elems
|
727
|
+
// being like an array and returning unexpected results. This also fixes
|
728
|
+
// passing in null/undefined values.
|
729
|
+
if (!value || typeof(value.nodeType) === 'number') {
|
730
|
+
return [value];
|
731
|
+
}
|
732
|
+
|
733
|
+
var object = Object(value)
|
734
|
+
var length = undefined;
|
735
|
+
if (!!object && 'length' in object) {
|
736
|
+
length = object.length;
|
737
|
+
}
|
738
|
+
|
739
|
+
// some browsers return 'function' for HTML elements
|
740
|
+
var isFunction = (
|
741
|
+
typeof(object) === 'function' &&
|
742
|
+
typeof(object.nodeType) !== 'number'
|
743
|
+
);
|
744
|
+
var likeArray = (
|
745
|
+
typeof(value) !== 'string' &&
|
746
|
+
!isFunction &&
|
747
|
+
object !== window &&
|
748
|
+
( Array.isArray(object) ||
|
749
|
+
length === 0 ||
|
750
|
+
( typeof(length) === 'number' &&
|
751
|
+
length > 0 &&
|
752
|
+
(length - 1) in object
|
753
|
+
)
|
754
|
+
)
|
755
|
+
);
|
756
|
+
if(likeArray) {
|
757
|
+
return Array.prototype.slice.call(value);
|
535
758
|
} else {
|
536
|
-
|
759
|
+
return [value];
|
537
760
|
}
|
538
761
|
}
|
539
762
|
|
540
|
-
|
763
|
+
Romo.prototype.assign = function(target) {
|
764
|
+
if(Object.assign) {
|
765
|
+
return Object.assign.apply(Object, arguments);
|
766
|
+
} else {
|
767
|
+
if (target == null) { // TypeError if undefined or null
|
768
|
+
throw new TypeError('Cannot convert undefined or null to object');
|
769
|
+
}
|
770
|
+
var to = Object(target);
|
771
|
+
|
772
|
+
for (var index = 1; index < arguments.length; index++) {
|
773
|
+
var nextSource = arguments[index];
|
541
774
|
|
542
|
-
|
543
|
-
|
775
|
+
if (nextSource != null) { // Skip over if undefined or null
|
776
|
+
for (var nextKey in nextSource) {
|
777
|
+
// Avoid bugs when hasOwnProperty is shadowed
|
778
|
+
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
|
779
|
+
to[nextKey] = nextSource[nextKey];
|
780
|
+
}
|
781
|
+
}
|
782
|
+
}
|
783
|
+
}
|
784
|
+
return to;
|
785
|
+
}
|
544
786
|
}
|
545
787
|
|
546
788
|
Romo.prototype.proxy = function(fn, context) {
|
@@ -550,12 +792,6 @@ Romo.prototype.proxy = function(fn, context) {
|
|
550
792
|
return proxyFn;
|
551
793
|
}
|
552
794
|
|
553
|
-
// TODO: rework w/o jQuery
|
554
|
-
Romo.prototype.toArray = function(elems) {
|
555
|
-
// converts a collection of elements `$()` to an array of nodes
|
556
|
-
return $.map(elems, function(node){ return node; })
|
557
|
-
}
|
558
|
-
|
559
795
|
Romo.prototype.nonInputTextKeyCodes = function() {
|
560
796
|
// https://css-tricks.com/snippets/javascript/javascript-keycodes/
|
561
797
|
return [
|
@@ -603,9 +839,13 @@ Romo.prototype._eid = 1;
|
|
603
839
|
Romo.prototype._fid = 1;
|
604
840
|
|
605
841
|
Romo.prototype._el = function(elem) {
|
606
|
-
elem._romoeid
|
607
|
-
|
608
|
-
|
842
|
+
if (!elem._romoeid) {
|
843
|
+
if (elem !== window && elem !== document) {
|
844
|
+
elem._romoeid = (this.data(elem, 'romo-eid') || this.setData(elem, 'romo-eid', this._eid++));
|
845
|
+
} else {
|
846
|
+
elem._romoeid = elem === window ? 'window' : 'document';
|
847
|
+
}
|
848
|
+
}
|
609
849
|
return elem;
|
610
850
|
}
|
611
851
|
|
@@ -622,66 +862,252 @@ Romo.prototype._handlerKey = function(elem, eventName, fn) {
|
|
622
862
|
|
623
863
|
Romo.prototype._deserializeValue = function(value) {
|
624
864
|
try {
|
625
|
-
if (value === "true") { return true;
|
626
|
-
if (value === "false") { return false;
|
627
|
-
if (value === "undefined") { return undefined;
|
628
|
-
if (value === "null") { return null;
|
629
|
-
if (
|
630
|
-
if (
|
631
|
-
return value;
|
865
|
+
if (value === "true") { return true; } // "true" => true
|
866
|
+
if (value === "false") { return false; } // "false" => false
|
867
|
+
if (value === "undefined") { return undefined; } // "undefined" => undefined
|
868
|
+
if (value === "null") { return null; } // "null" => null
|
869
|
+
if (value === null) { return undefined; } // null => undefined
|
870
|
+
if (+value+"" === value) { return +value; } // "42.5" => 42.5
|
871
|
+
if (/^[\[\{]/.test(value)) { return JSON.parse(value); } // JSON => parse if valid
|
872
|
+
return value; // String => self
|
632
873
|
} catch(e) {
|
633
874
|
return value
|
634
875
|
}
|
635
876
|
}
|
636
877
|
|
637
|
-
|
638
|
-
Romo.prototype.
|
639
|
-
|
878
|
+
Romo.prototype._overflowScrollableRegex = /(auto|scroll)/;
|
879
|
+
Romo.prototype._elemsTagNameRegEx = /<([a-z0-9-]+)[\s\/>]+/i;
|
880
|
+
|
881
|
+
Romo.prototype._elemsWrapMap = {
|
882
|
+
'caption': [1, "<table>", "</table>"],
|
883
|
+
'colgroup': [1, "<table>", "</table>"],
|
884
|
+
'col': [2, "<table><colgroup>", "</colgroup></table>"],
|
885
|
+
'thead': [1, "<table>", "</table>"],
|
886
|
+
'tbody': [1, "<table>", "</table>"],
|
887
|
+
'tfoot': [1, "<table>", "</table>"],
|
888
|
+
'tr': [2, "<table><tbody>", "</tbody></table>"],
|
889
|
+
'th': [3, "<table><tbody><tr>", "</tr></tbody></table>"],
|
890
|
+
'td': [3, "<table><tbody><tr>", "</tr></tbody></table>"]
|
891
|
+
};
|
892
|
+
|
893
|
+
Romo.prototype._elemsInitComponents = {};
|
894
|
+
|
895
|
+
Romo.prototype._elemsInitTrigger = function(onElems) {
|
896
|
+
for (var selector in this._elemsInitComponents) {
|
897
|
+
var componentClass = this._elemsInitComponents[selector];
|
898
|
+
this._elemsInitFind(onElems, selector).forEach(function(initElem){ new componentClass(initElem); });
|
899
|
+
}
|
900
|
+
return onElems;
|
901
|
+
}
|
902
|
+
|
903
|
+
Romo.prototype._elemsInitFind = function(onElems, selector) {
|
904
|
+
var elems = onElems.filter(function(onElem){ return Romo.is(onElem, selector); });
|
905
|
+
return elems.concat(Romo.find(onElems, selector));;
|
906
|
+
}
|
907
|
+
|
908
|
+
// RomoComponent
|
909
|
+
|
910
|
+
var RomoComponent = function(constructorFn) {
|
911
|
+
var component = function() {
|
912
|
+
RomoComponent.addEventFunctions(this);
|
913
|
+
constructorFn.apply(this, arguments);
|
914
|
+
}
|
915
|
+
component.prototype.romoEvFn = {};
|
916
|
+
component.prototype.doInit = function() {} // override as needed
|
917
|
+
return component;
|
918
|
+
}
|
919
|
+
|
920
|
+
RomoComponent.addEventFunctions = function(klassInstance) {
|
921
|
+
for(var name in klassInstance.romoEvFn) {
|
922
|
+
klassInstance[name] = RomoComponent.eventProxyFn(klassInstance.romoEvFn[name]);
|
923
|
+
}
|
924
|
+
}
|
925
|
+
|
926
|
+
RomoComponent.eventProxyFn = function(fn) {
|
927
|
+
return function(){ return fn.apply(this, arguments); };
|
928
|
+
}
|
929
|
+
|
930
|
+
// RomoPopupStack
|
931
|
+
|
932
|
+
var RomoPopupStack = function() {
|
933
|
+
this.popupSelector = undefined;
|
934
|
+
this.styleClasses = [];
|
935
|
+
this.items = [];
|
936
|
+
|
937
|
+
this._buildItemClass();
|
938
|
+
}
|
939
|
+
|
940
|
+
RomoPopupStack.prototype.doInit = function(styleClass) {
|
941
|
+
this.bodyElem = Romo.f('body')[0];
|
942
|
+
Romo.on(this.bodyElem, 'click', Romo.proxy(this._onBodyClick, this));
|
943
|
+
Romo.on(this.bodyElem, 'keyup', Romo.proxy(this._onBodyKeyUp, this));
|
944
|
+
Romo.on(window, 'resize', Romo.proxy(this._onWindowResize, this));
|
945
|
+
Romo.on(window, 'scroll', Romo.proxy(this._onWindowScroll, this));
|
946
|
+
}
|
947
|
+
|
948
|
+
RomoPopupStack.prototype.addStyleClass = function(styleClass) {
|
949
|
+
this.styleClasses.push(styleClass);
|
950
|
+
this.popupSelector = this.styleClasses.map(function(s){ return '.'+s; }).join(', ');
|
951
|
+
}
|
952
|
+
|
953
|
+
RomoPopupStack.prototype.addElem = function(popupElem, boundOpenFn, boundCloseFn, boundPlaceFn) {
|
954
|
+
this.items.push(new this.itemClass(popupElem, boundCloseFn, boundPlaceFn));
|
955
|
+
|
956
|
+
// allow any body click events to propagate and run first. This ensures
|
957
|
+
// any existing stack is in the appropriate state before opening a new popup.
|
958
|
+
Romo.pushFn(boundOpenFn);
|
959
|
+
}
|
960
|
+
|
961
|
+
RomoPopupStack.prototype.closeThru = function(popupElem) {
|
962
|
+
// allow any body click events to propagate and run first. This ensures
|
963
|
+
// any existing stack is in the appropriate state before opening a new popup.
|
964
|
+
Romo.pushFn(Romo.proxy(function() {
|
965
|
+
if (this._includes(popupElem)) {
|
966
|
+
this.closeTo(popupElem);
|
967
|
+
this._closeTop();
|
968
|
+
}
|
969
|
+
}, this));
|
970
|
+
}
|
971
|
+
|
972
|
+
RomoPopupStack.prototype.closeTo = function(popupElem) {
|
973
|
+
if (this._includes(popupElem)) {
|
974
|
+
while (this.items.length > 0 && !this.items[this.items.length-1].isFor(popupElem)) {
|
975
|
+
this._closeTop();
|
976
|
+
}
|
977
|
+
}
|
978
|
+
}
|
979
|
+
|
980
|
+
RomoPopupStack.prototype.placeAllPopups = function(includingFixed) {
|
981
|
+
this.items.filter(function(item) {
|
982
|
+
return includingFixed || Romo.css(item.popupElem, 'position') !== 'fixed';
|
983
|
+
}).forEach(function(item){
|
984
|
+
item.placeFn();
|
985
|
+
});
|
640
986
|
}
|
641
987
|
|
642
|
-
//
|
988
|
+
// private
|
989
|
+
|
990
|
+
RomoPopupStack.prototype._buildItemClass = function() {
|
991
|
+
this.itemClass = function(popupElem, closeFn, placeFn) {
|
992
|
+
this.popupElem = popupElem;
|
993
|
+
this.closeFn = closeFn;
|
994
|
+
this.placeFn = placeFn;
|
995
|
+
}
|
996
|
+
this.itemClass.prototype.isFor = function(popupElem) {
|
997
|
+
return this.popupElem === popupElem;
|
998
|
+
}
|
999
|
+
}
|
1000
|
+
|
1001
|
+
RomoPopupStack.prototype._closeTop = function() {
|
1002
|
+
var item;
|
1003
|
+
if (this.items.length > 0) {
|
1004
|
+
item = this.items.pop();
|
1005
|
+
item.closeFn();
|
1006
|
+
Romo.trigger(this.bodyElem, 'romoPopupStack:popupClose', [item.popupElem, this]);
|
1007
|
+
Romo.trigger(item.popupElem, 'romoPopupStack:popupClose', [this]);
|
1008
|
+
}
|
1009
|
+
return item;
|
1010
|
+
}
|
1011
|
+
|
1012
|
+
RomoPopupStack.prototype._closeAll = function() {
|
1013
|
+
while (this.items.length > 0) {
|
1014
|
+
this._closeTop();
|
1015
|
+
}
|
1016
|
+
}
|
1017
|
+
|
1018
|
+
RomoPopupStack.prototype._includes = function(popupElem) {
|
1019
|
+
return this.items.reduce(function(included, item) {
|
1020
|
+
return included || item.isFor(popupElem);
|
1021
|
+
}, false);
|
1022
|
+
}
|
1023
|
+
|
1024
|
+
RomoPopupStack.prototype._onBodyClick = function(e) {
|
1025
|
+
var popupElem = undefined;
|
1026
|
+
if (Romo.is(e.target, this.popupSelector)) {
|
1027
|
+
popupElem = e.target;
|
1028
|
+
} else {
|
1029
|
+
popupElem = Romo.parents(e.target, this.popupSelector)[0];
|
1030
|
+
}
|
1031
|
+
|
1032
|
+
if (popupElem === undefined || !this._includes(popupElem)) {
|
1033
|
+
this._closeAll();
|
1034
|
+
} else {
|
1035
|
+
this.closeTo(popupElem);
|
1036
|
+
}
|
1037
|
+
}
|
1038
|
+
|
1039
|
+
RomoPopupStack.prototype._onBodyKeyUp = function(e) {
|
1040
|
+
var closedItem;
|
1041
|
+
if (e.keyCode === 27 /* Esc */) {
|
1042
|
+
closedItem = this._closeTop();
|
1043
|
+
if (closedItem) {
|
1044
|
+
Romo.trigger(closedItem.popupElem, 'romoPopupStack:popupClosedByEsc', [this]);
|
1045
|
+
}
|
1046
|
+
}
|
1047
|
+
}
|
1048
|
+
|
1049
|
+
RomoPopupStack.prototype._onWindowResize = function(e) {
|
1050
|
+
this.placeAllPopups(true);
|
1051
|
+
}
|
1052
|
+
|
1053
|
+
RomoPopupStack.prototype._onWindowScroll = function(e) {
|
1054
|
+
this.placeAllPopups();
|
1055
|
+
}
|
1056
|
+
|
1057
|
+
// RomoParentChildElems
|
643
1058
|
|
644
1059
|
var RomoParentChildElems = function() {
|
645
1060
|
this.attrName = 'romo-parent-elem-id';
|
646
1061
|
this.elemId = 0;
|
647
1062
|
this.elems = {};
|
1063
|
+
}
|
648
1064
|
|
649
|
-
|
650
|
-
|
1065
|
+
RomoParentChildElems.prototype.doInit = function(parentElem, childElems) {
|
1066
|
+
var parentRemovedObserver = new MutationObserver(Romo.proxy(function(mutationRecords) {
|
1067
|
+
mutationRecords.forEach(Romo.proxy(function(mutationRecord) {
|
651
1068
|
if (mutationRecord.type === 'childList' && mutationRecord.removedNodes.length > 0) {
|
652
|
-
|
653
|
-
this.remove(
|
1069
|
+
mutationRecord.removedNodes.forEach(Romo.proxy(function(removedNode) {
|
1070
|
+
this.remove(removedNode);
|
654
1071
|
}, this));
|
655
1072
|
}
|
656
1073
|
}, this));
|
657
1074
|
}, this));
|
658
1075
|
|
659
|
-
parentRemovedObserver.observe(
|
1076
|
+
parentRemovedObserver.observe(Romo.f('body')[0], {
|
660
1077
|
childList: true,
|
661
1078
|
subtree: true
|
662
1079
|
});
|
663
1080
|
}
|
664
1081
|
|
665
1082
|
RomoParentChildElems.prototype.add = function(parentElem, childElems) {
|
666
|
-
|
1083
|
+
// delay adding b/c the parent elem may be manipulated in the DOM resulting in the parent elem
|
1084
|
+
// being removed and then re-added to the DOM. if the child elems are associated immediately,
|
1085
|
+
// any "remove" from DOM manipulation would incorrectly remove the popup.
|
1086
|
+
Romo.pushFn(Romo.proxy(function() {
|
1087
|
+
Romo.setData(parentElem, this.attrName, this._push(childElems, Romo.data(parentElem, this.attrName)));
|
1088
|
+
}, this));
|
667
1089
|
}
|
668
1090
|
|
669
|
-
RomoParentChildElems.prototype.remove = function(
|
670
|
-
if (
|
671
|
-
|
672
|
-
|
1091
|
+
RomoParentChildElems.prototype.remove = function(elemNode) {
|
1092
|
+
if (elemNode.nodeType !== Node.ELEMENT_NODE){ return false; }
|
1093
|
+
|
1094
|
+
if (Romo.data(elemNode, 'romo-parent-removed-observer-disabled') !== true) {
|
1095
|
+
if (Romo.data(elemNode, this.attrName) !== undefined) {
|
1096
|
+
// node is a parent elem itself
|
1097
|
+
this._removeChildElems(elemNode);
|
673
1098
|
}
|
674
|
-
|
675
|
-
this._removeChildElems(
|
1099
|
+
Romo.find(elemNode, '[data-'+this.attrName+']').forEach(Romo.proxy(function(childParentElem) {
|
1100
|
+
this._removeChildElems(childParentElem);
|
676
1101
|
}, this));
|
677
1102
|
}
|
678
1103
|
}
|
679
1104
|
|
680
|
-
// private
|
1105
|
+
// private
|
681
1106
|
|
682
1107
|
RomoParentChildElems.prototype._removeChildElems = function(parentElem) {
|
683
|
-
|
684
|
-
|
1108
|
+
this._pop(Romo.data(parentElem, this.attrName)).forEach(function(childElem) {
|
1109
|
+
Romo.remove(childElem);
|
1110
|
+
Romo.trigger(childElem, 'romoParentChildElems:childRemoved', [childElem]);
|
685
1111
|
});
|
686
1112
|
};
|
687
1113
|
|
@@ -692,7 +1118,8 @@ RomoParentChildElems.prototype._push = function(items, id) {
|
|
692
1118
|
if (this.elems[id] === undefined) {
|
693
1119
|
this.elems[id] = []
|
694
1120
|
}
|
695
|
-
|
1121
|
+
this.elems[id] = this.elems[id].concat(items);
|
1122
|
+
|
696
1123
|
return id;
|
697
1124
|
};
|
698
1125
|
|
@@ -704,9 +1131,7 @@ RomoParentChildElems.prototype._pop = function(id) {
|
|
704
1131
|
|
705
1132
|
// Init
|
706
1133
|
|
707
|
-
|
708
|
-
|
709
|
-
// TODO: rework w/o jQuery
|
710
|
-
$(function() {
|
1134
|
+
var Romo = new Romo();
|
1135
|
+
Romo.ready(function() {
|
711
1136
|
Romo.doInit();
|
712
|
-
})
|
1137
|
+
});
|