yet-another-js-utils 0.0.7 → 0.0.8
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.
- package/js-utils.js +267 -271
- package/package.json +2 -2
package/js-utils.js
CHANGED
@@ -1,303 +1,299 @@
|
|
1
|
+
module.exports = {
|
2
|
+
// # Nil
|
1
3
|
|
2
|
-
//
|
3
|
-
|
4
|
-
//
|
5
|
-
//
|
6
|
-
//
|
7
|
-
// - 3-letters name n
|
8
|
-
// - single argument
|
4
|
+
// I like the NOT operator
|
5
|
+
// I like strict type checking
|
6
|
+
// Hence a strictly typed equivalent:
|
7
|
+
// - 3-letters name n
|
8
|
+
// - single argument
|
9
9
|
|
10
|
-
/**
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
}
|
10
|
+
/**
|
11
|
+
* Nil
|
12
|
+
* Neither null nor undefined
|
13
|
+
* @param { boolean } exp
|
14
|
+
* @returns { boolean }
|
15
|
+
*/
|
16
|
+
nil(exp) { // values implicitly considered functions
|
17
|
+
if (
|
18
|
+
exp === null
|
19
|
+
|| typeof exp === 'undefined'
|
20
|
+
) {
|
21
|
+
return true;
|
22
|
+
} else {
|
23
|
+
return false;
|
24
|
+
}
|
25
|
+
},
|
26
26
|
|
27
|
-
// # Hack
|
27
|
+
// # Hack
|
28
28
|
|
29
|
-
// .slice() uses a closed-open interval
|
30
|
-
// the mathematical convention goes closed-closed
|
29
|
+
// .slice() uses a closed-open interval
|
30
|
+
// the mathematical convention goes closed-closed
|
31
31
|
|
32
|
-
/**
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
}
|
32
|
+
/**
|
33
|
+
* Hack
|
34
|
+
* @param { number } start
|
35
|
+
* @param { number } end
|
36
|
+
* @returns
|
37
|
+
*/
|
38
|
+
hack(array, start, end) {
|
39
|
+
return array.slice(start, end + 1);
|
40
|
+
},
|
41
41
|
|
42
|
-
// # Prune/Pick
|
42
|
+
// # Prune/Pick
|
43
43
|
|
44
|
-
// Javascript inherited spreadsheet-like .filter()
|
45
|
-
// It felt confusing there
|
46
|
-
// It feels confusing here too
|
44
|
+
// Javascript inherited spreadsheet-like .filter()
|
45
|
+
// It felt confusing there
|
46
|
+
// It feels confusing here too
|
47
47
|
|
48
|
-
/**
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
}
|
48
|
+
/**
|
49
|
+
* Pick
|
50
|
+
* @param {*} array
|
51
|
+
* @param {*} pruningFunction
|
52
|
+
* @returns
|
53
|
+
*/
|
54
|
+
pick(array, pruningFunction) {
|
55
|
+
return array.filter(pruningFunction);
|
56
|
+
},
|
57
57
|
|
58
|
-
/**
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
}
|
58
|
+
/**
|
59
|
+
* Prune
|
60
|
+
* The inverse of filter()
|
61
|
+
* @param {*} array
|
62
|
+
* @param {*} filteringFunction
|
63
|
+
* @returns
|
64
|
+
*/
|
65
|
+
prune(array, filteringFunction) {
|
66
|
+
return array.filter(function (x) {
|
67
|
+
return !filteringFunction(x);
|
68
|
+
});
|
69
|
+
},
|
70
70
|
|
71
|
-
// # Check
|
71
|
+
// # Check
|
72
72
|
|
73
|
-
// .every() just sounds weird
|
74
|
-
/**
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
}
|
73
|
+
// .every() just sounds weird
|
74
|
+
/**
|
75
|
+
* Check
|
76
|
+
* @param {*} array
|
77
|
+
* @param {*} checkingFunction
|
78
|
+
* @returns
|
79
|
+
*/
|
80
|
+
check(array, checkingFunction) {
|
81
|
+
return array.every(checkingFunction);
|
82
|
+
},
|
83
83
|
|
84
|
-
/**
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
}
|
84
|
+
/**
|
85
|
+
* Escape
|
86
|
+
* @param { string } string
|
87
|
+
* @returns
|
88
|
+
*/
|
89
|
+
escape(string) {
|
90
|
+
return string
|
91
|
+
.replace(/&/g, '&')
|
92
|
+
.replace(/</g, '<')
|
93
|
+
.replace(/>/g, '>')
|
94
|
+
.replace(/"/g, '"')
|
95
|
+
.replace(/'/g, ''');
|
96
|
+
},
|
97
97
|
|
98
|
-
/**
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
}
|
98
|
+
/**
|
99
|
+
* DOM-rendering template tag
|
100
|
+
* @param {Array} strings
|
101
|
+
* @returns {object} a DocumentFragment
|
102
|
+
*/
|
103
|
+
html(strings) {
|
104
|
+
let output = strings[0], // assumes empty string start?
|
105
|
+
max = Math.max(strings.length, arguments.length - 1);
|
106
|
+
for (let i = 1; i < max; i++) {
|
107
|
+
output += arguments[i];
|
108
|
+
output += strings[i];
|
109
|
+
}
|
110
|
+
let fragment = document.createDocumentFragment();
|
111
|
+
fragment.innerHTML = output;
|
112
|
+
return fragment;
|
113
|
+
},
|
114
114
|
|
115
|
-
/**
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
115
|
+
/**
|
116
|
+
* Basic contents updater
|
117
|
+
* Assuming:
|
118
|
+
* - secondNode already holds states updates
|
119
|
+
* - rendering applied event-listeners already
|
120
|
+
* @param {*} firstNode
|
121
|
+
* @param {*} secondNode
|
122
|
+
*/
|
123
|
+
replaceChildren(firstNode, secondNode) {
|
124
|
+
let firstNodeChildren = firstNode.childNodes,
|
125
|
+
secondNodeChildren = secondNode.childNodes;
|
126
|
+
for (let i = 0, c = firstNodeChildren.length; i < c; i++) {
|
127
|
+
if (
|
128
|
+
secondNodeChildren[i]
|
129
|
+
&& firstNodeChildren[i].outerHTML !== secondNodeChildren[i].outerHTML
|
130
|
+
) {
|
131
|
+
firstNodeChildren[i].parentNode.replaceChild(firstNodeChildren[i], secondNodeChildren[i]);
|
132
|
+
}
|
132
133
|
}
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
134
|
+
if (firstNodeChildren.length < secondNodeChildren.length) {
|
135
|
+
for (let i = firstNodeChildren.length, c = secondNodeChildren.length; i < c; i++) {
|
136
|
+
firstNodeChildren[i].parentNode.appendChild(secondNodeChildren[i])
|
137
|
+
}
|
137
138
|
}
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
139
|
+
if (firstNodeChildren.length > secondNodeChildren.length) {
|
140
|
+
for (let i = firstNodeChildren.length - 1; i > secondNodeChildren.length - 1; i--) {
|
141
|
+
firstNodeChildren[i].remove();
|
142
|
+
}
|
142
143
|
}
|
143
|
-
}
|
144
|
-
}
|
144
|
+
},
|
145
145
|
|
146
|
-
// # DATA-STATE
|
146
|
+
// # DATA-STATE
|
147
147
|
|
148
|
-
// Alternative CSS state management
|
149
|
-
// - using data-attributes instead of classes
|
150
|
-
// - easier to match model and vue
|
151
|
-
// - dataset over classlist allows specialization
|
152
|
-
// - classes work as booleans (".walked")
|
153
|
-
// - you need to notice abscence
|
154
|
-
// - data-state work as a string type you can dedicate to store state only, and more than one state
|
148
|
+
// Alternative CSS state management
|
149
|
+
// - using data-attributes instead of classes
|
150
|
+
// - easier to match model and vue
|
151
|
+
// - dataset over classlist allows specialization
|
152
|
+
// - classes work as booleans (".walked")
|
153
|
+
// - you need to notice abscence
|
154
|
+
// - data-state work as a string type you can dedicate to store state only, and more than one state
|
155
155
|
|
156
|
-
/**
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
}
|
156
|
+
/**
|
157
|
+
* Add
|
158
|
+
* @param { object } element
|
159
|
+
* @param { string } state
|
160
|
+
*/
|
161
|
+
addDataState(element, state) {
|
162
|
+
let stateArray = [];
|
163
|
+
if (
|
164
|
+
element.dataset.state
|
165
|
+
&& element.dataset.state.indexOf(' ') > -1
|
166
|
+
) {
|
167
|
+
stateArray = element.dataset.state.split(' ');
|
168
|
+
} else {
|
169
|
+
stateArray = [element.dataset.state];
|
170
|
+
}
|
171
|
+
if (stateArray.indexOf(state) === -1) {
|
172
|
+
stateArray.push(state);
|
173
|
+
element.dataset.state = stateArray.join(' ');
|
174
|
+
}
|
175
|
+
},
|
176
176
|
|
177
|
-
/**
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
}
|
177
|
+
/**
|
178
|
+
* Remove
|
179
|
+
* @param { object } element
|
180
|
+
* @param { string } state
|
181
|
+
*/
|
182
|
+
removeDataState(element, state) {
|
183
|
+
let stateArray = [];
|
184
|
+
if (
|
185
|
+
element.dataset.state
|
186
|
+
&& element.dataset.state.indexOf(' ') > -1
|
187
|
+
) {
|
188
|
+
stateArray = element.dataset.state.split(' ');
|
189
|
+
} else {
|
190
|
+
stateArray = [element.dataset.state];
|
191
|
+
}
|
192
|
+
element.dataset.state =
|
193
|
+
stateArray
|
194
|
+
.filter(element => (element !== state))
|
195
|
+
.join(' ');
|
196
|
+
},
|
197
197
|
|
198
|
-
/**
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
}
|
198
|
+
/**
|
199
|
+
* Replace
|
200
|
+
* @param { object } element
|
201
|
+
* @param { string } stateToRemove
|
202
|
+
* @param { string } stateToAdd
|
203
|
+
*/
|
204
|
+
replaceDataState(element, stateToRemove, stateToAdd) {
|
205
|
+
this.removeDataState(element, stateToRemove);
|
206
|
+
this.addDataState(element, stateToAdd);
|
207
|
+
},
|
208
208
|
|
209
|
-
/**
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
}
|
209
|
+
/**
|
210
|
+
* Toggle
|
211
|
+
* @param { object } element
|
212
|
+
* @param { string } state
|
213
|
+
*/
|
214
|
+
toggleDataState(element, state) {
|
215
|
+
let stateArray = element.dataset.state.split(' ');
|
216
|
+
if (stateArray.indexOf(state) == -1) {
|
217
|
+
this.addDataState(element, state);
|
218
|
+
} else {
|
219
|
+
this.removeDataState(element, state);
|
220
|
+
}
|
221
|
+
},
|
222
222
|
|
223
|
-
//# AJAX Functions
|
223
|
+
//# AJAX Functions
|
224
224
|
|
225
|
-
/**
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
225
|
+
/**
|
226
|
+
* AJAX GET
|
227
|
+
* @param {string} url The target url
|
228
|
+
* @param {function} callback
|
229
|
+
* @param {boolean} isJson Response contains json
|
230
|
+
* @param {object} callbackContext
|
231
|
+
*/
|
232
|
+
ajaxGet(url, callback, isJson, callbackContext) {
|
233
|
+
var req = new XMLHttpRequest();
|
234
|
+
req.open("GET", url);
|
235
|
+
req.addEventListener("load", function () {
|
236
|
+
if (req.status >= 200 && req.status < 400) {
|
237
|
+
if (isJson) {
|
238
|
+
var json = {};
|
239
|
+
try {
|
240
|
+
json = JSON.parse(req.responseText);
|
241
|
+
} catch (error) {
|
242
|
+
console.error("Get request returned invalid JSON.")
|
243
|
+
}
|
244
|
+
callbackContext === undefined ? callback(json) : callback.apply(callbackContext, [json]);
|
245
|
+
} else {
|
246
|
+
callbackContext === undefined ? callback(req.responseText) : callback.apply(callbackContext, [req.responseText]);
|
243
247
|
}
|
244
|
-
callbackContext === undefined ? callback(json) : callback.apply(callbackContext, [json]);
|
245
248
|
} else {
|
246
|
-
|
249
|
+
console.error(req.status + " " + req.statusText + " " + url);
|
247
250
|
}
|
248
|
-
}
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
});
|
255
|
-
req.send(null);
|
256
|
-
}
|
251
|
+
});
|
252
|
+
req.addEventListener("error", function () {
|
253
|
+
console.error("Network error trying to access: " + url);
|
254
|
+
});
|
255
|
+
req.send(null);
|
256
|
+
},
|
257
257
|
|
258
|
-
/**
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
258
|
+
/**
|
259
|
+
* AJAX POST
|
260
|
+
* @param {string} url
|
261
|
+
* @param {string} data
|
262
|
+
* @param {function} successCallback
|
263
|
+
* @param {function} failureCallback
|
264
|
+
* @param {boolean} isJson
|
265
|
+
* @param {object} successCallbackContext
|
266
|
+
* @param {object} failureCallbackContext
|
267
|
+
*/
|
268
|
+
ajaxPost(url, data, successCallback, failureCallback, isJson, successCallbackContext, failureCallbackContext) {
|
269
|
+
var req = new XMLHttpRequest();
|
270
|
+
req.open("POST", url);
|
271
|
+
req.addEventListener("load", function () {
|
272
|
+
if (req.status >= 200 && req.status < 400) {
|
273
|
+
successCallbackContext === undefined ? successCallback(req) : successCallback.apply(successCallbackContext, [req]);
|
274
|
+
} else {
|
275
|
+
failureCallbackContext === undefined ? failureCallback(req) : failureCallback.apply(failureCallbackContext, [req]);
|
276
|
+
console.error(req.status + " " + req.statusText + " " + url);
|
277
|
+
}
|
278
|
+
});
|
279
|
+
req.addEventListener("error", function () {
|
280
|
+
console.error("Network error trying to access: " + url);
|
281
|
+
});
|
282
|
+
if (isJson) {
|
283
|
+
req.setRequestHeader("Content-Type", "application/json");
|
284
|
+
data = JSON.stringify(data);
|
277
285
|
}
|
278
|
-
|
279
|
-
|
280
|
-
console.error("Network error trying to access: " + url);
|
281
|
-
});
|
282
|
-
if (isJson) {
|
283
|
-
req.setRequestHeader("Content-Type", "application/json");
|
284
|
-
data = JSON.stringify(data);
|
285
|
-
}
|
286
|
-
req.send(data);
|
287
|
-
}
|
286
|
+
req.send(data);
|
287
|
+
},
|
288
288
|
|
289
|
-
/**
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
289
|
+
/**
|
290
|
+
* Pipe
|
291
|
+
* Function piping with initial input
|
292
|
+
* @param {*} functions
|
293
|
+
* @param {*} input
|
294
|
+
* @returns {*}
|
295
|
+
*/
|
296
|
+
pipe(input, ...functions) {
|
297
|
+
return functions.reduce((res, fun) => fun(res), input);
|
298
|
+
}
|
298
299
|
}
|
299
|
-
|
300
|
-
module.exports = {
|
301
|
-
nil, hack, pick, prune, check, escape, html, replaceChildren, addDataState, removeDataState, replaceDataState,
|
302
|
-
toggleDataState, ajaxGet, ajaxPost, pipe
|
303
|
-
};
|
package/package.json
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
"name": "yet-another-js-utils",
|
3
3
|
"description": "Basic javascript utils",
|
4
4
|
"authors": "Adrian Turcev",
|
5
|
-
"version": "0.0.
|
5
|
+
"version": "0.0.8",
|
6
6
|
"license": "MPL-2.0",
|
7
7
|
"homepage": "https://github.com/adrianturcev/js-utils",
|
8
8
|
"repository": {
|
@@ -13,7 +13,7 @@
|
|
13
13
|
"url": "https://github.com/adrianturcev/js-utils/issues"
|
14
14
|
},
|
15
15
|
"keywords": ["javascript", "utils"],
|
16
|
-
"main": ".js",
|
16
|
+
"main": "js-utils.js",
|
17
17
|
"scripts": {
|
18
18
|
"watch": "npx grunt watch",
|
19
19
|
"test": "npx grunt test",
|