-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgetSet.js
120 lines (116 loc) · 4.68 KB
/
getSet.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
function getSet(parentObject, propertyPath, setValueOrOption, optionValue) {
'use strict';
var argsLen = arguments.length;
var usingOption = argsLen === 4;
var optionOr = setValueOrOption === 'or' && usingOption;
var optionAs = setValueOrOption === 'as' && usingOption;
var optionAddition = setValueOrOption === '+=' && usingOption;
var optionSubtraction = setValueOrOption === '-=' && usingOption;
var optionSpecified = optionOr || optionAs || optionAddition || optionSubtraction;
var pathRequired = argsLen === 3 || optionOr || optionAddition || optionSubtraction;
var path = String((propertyPath && propertyPath.join) ? propertyPath.join('.') : propertyPath).replace(/\[(?:'|")?(.+?)(?:'|")?\]/g, '.$1');
var pathOrig = path;
var loop = 0;
var winConsole = window.console;
function getType(obj) {
var type = Object.prototype.toString.call(obj).slice(8, -1);
if (type === 'Number') {
if (!isFinite(obj)) {
type = 'Infinity';
if (isNaN(obj)) {
type = 'NaN';
}
}
}
return type;
}
function isFunction(obj) {
var type = typeof obj;
return obj && (type === 'function' || (type === 'object' && (/^\s*function/i).test(obj + '')));
}
function isObject(obj) {
return obj && (typeof obj === 'object' || isFunction(obj));
}
function typeErrMsg(cycle, obj, operation) {
return 'getSet: Could not ' + operation + ' \'' + path.slice(0, cycle + 1).join('.') + '\'. \'' + (path.slice(0, cycle).join('.') || 'parentObject') + '\' is of type \'' + getType(obj) + '\'.';
}
function consoleMsg(msg) {
if (winConsole) {
winConsole.log(msg);
}
}
function result(obj) {
var typeProvided = getType(optionValue);
if (optionAs && typeProvided !== getType(obj)) {
if (!path.length) {
path = ['parentObject'];
loop = 1;
}
consoleMsg(typeErrMsg(loop, obj, 'get as \'' + typeProvided + '\';'));
obj = optionValue;
}
return obj;
}
if ((path === '' && (!optionSpecified || optionOr)) || !(/String|Array/).test(getType(propertyPath))) {
path = argsLen === 0 ? ['parentObject'] : ['propertyPath'];
throw new TypeError(typeErrMsg(1, argsLen === 0 ? parentObject : propertyPath, 'determine argument'));
}
if (usingOption && !optionSpecified) {
path = ['setValueOrOption'];
consoleMsg(typeErrMsg(1, setValueOrOption, 'determine argument \'' + setValueOrOption + '\' in'));
path = pathOrig;
}
path = (path && path.split) ? path.split('.') : [];
var len = path.length;
var property;
for (loop = 0; loop < len; loop += 1) {
property = path[loop];
if (pathRequired) {
if (!parentObject.hasOwnProperty(property)) {
if (isObject(parentObject)) {
if (loop + 1 < len) {
parentObject[property] = {};
}
} else {
throw new TypeError(typeErrMsg(loop, parentObject, 'create'));
}
}
if (loop + 1 === len) {
if (optionSpecified) {
if (optionAddition || optionSubtraction) {
if (!parentObject.hasOwnProperty(property)) {
parentObject[property] = getType(optionValue) === 'Number' ? 0 : '';
}
if (optionAddition) {
parentObject[property] += optionValue;
} else {
parentObject[property] -= optionValue;
}
} else {
if (optionOr) {
parentObject[property] = parentObject[property] || optionValue;
}
}
} else {
parentObject[property] = setValueOrOption;
}
}
}
if (isObject(parentObject)) {
if (!(optionAs && loop + 1 < len && !isObject(parentObject[property]))) {
if (loop + 1 < len) {
if (parentObject[property]) {
parentObject = parentObject[property];
}
} else {
parentObject = parentObject[property];
}
}
} else {
if (!optionAs) {
throw new TypeError(typeErrMsg(loop, parentObject, 'read'));
}
}
}
return result(parentObject);
}