-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
/
Copy pathutils.js
235 lines (214 loc) · 5.91 KB
/
utils.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
var config = require('./config'),
attrs = config.attrs,
toString = Object.prototype.toString,
join = Array.prototype.join,
console = window.console,
hasClassList = 'classList' in document.documentElement,
ViewModel // late def
var defer =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.setTimeout
/**
* Create a prototype-less object
* which is a better hash/map
*/
function makeHash () {
return Object.create(null)
}
var utils = module.exports = {
hash: makeHash,
// global storage for user-registered
// vms, partials and transitions
components : makeHash(),
partials : makeHash(),
transitions : makeHash(),
/**
* get an attribute and remove it.
*/
attr: function (el, type, noRemove) {
var attr = attrs[type],
val = el.getAttribute(attr)
if (!noRemove && val !== null) el.removeAttribute(attr)
return val
},
/**
* Define an ienumerable property
* This avoids it being included in JSON.stringify
* or for...in loops.
*/
defProtected: function (obj, key, val, enumerable, configurable) {
if (obj.hasOwnProperty(key)) return
Object.defineProperty(obj, key, {
value : val,
enumerable : !!enumerable,
configurable : !!configurable
})
},
/**
* Accurate type check
* internal use only, so no need to check for NaN
*/
typeOf: function (obj) {
return toString.call(obj).slice(8, -1)
},
/**
* Most simple bind
* enough for the usecase and fast than native bind()
*/
bind: function (fn, ctx) {
return function (arg) {
return fn.call(ctx, arg)
}
},
/**
* Make sure only strings, booleans, numbers and
* objects are output to html. otherwise, ouput empty string.
*/
toText: function (value) {
/* jshint eqeqeq: false */
var type = typeof value
return (type === 'string' ||
type === 'boolean' ||
(type === 'number' && value == value)) // deal with NaN
? value
: type === 'object' && value !== null
? JSON.stringify(value)
: ''
},
/**
* simple extend
*/
extend: function (obj, ext, protective) {
for (var key in ext) {
if (protective && obj[key]) continue
obj[key] = ext[key]
}
},
/**
* filter an array with duplicates into uniques
*/
unique: function (arr) {
var hash = utils.hash(),
i = arr.length,
key, res = []
while (i--) {
key = arr[i]
if (hash[key]) continue
hash[key] = 1
res.push(key)
}
return res
},
/**
* Convert a string template to a dom fragment
*/
toFragment: function (template) {
if (typeof template !== 'string') {
return template
}
if (template.charAt(0) === '#') {
var templateNode = document.getElementById(template.slice(1))
if (!templateNode) return
template = templateNode.innerHTML
}
var node = document.createElement('div'),
frag = document.createDocumentFragment(),
child
node.innerHTML = template.trim()
/* jshint boss: true */
while (child = node.firstChild) {
frag.appendChild(child)
}
return frag
},
/**
* Convert the object to a ViewModel constructor
* if it is not already one
*/
toConstructor: function (obj) {
ViewModel = ViewModel || require('./viewmodel')
return utils.typeOf(obj) === 'Object'
? ViewModel.extend(obj)
: typeof obj === 'function'
? obj
: null
},
/**
* convert certain option values to the desired format.
*/
processOptions: function (options) {
var components = options.components,
partials = options.partials,
template = options.template,
key
if (components) {
for (key in components) {
components[key] = utils.toConstructor(components[key])
}
}
if (partials) {
for (key in partials) {
partials[key] = utils.toFragment(partials[key])
}
}
if (template) {
options.template = utils.toFragment(template)
}
},
/**
* log for debugging
*/
log: function () {
if (config.debug && console) {
console.log(join.call(arguments, ' '))
}
},
/**
* warnings, traces by default
* can be suppressed by `silent` option.
*/
warn: function() {
if (!config.silent && console) {
console.warn(join.call(arguments, ' '))
if (config.debug) {
console.trace()
}
}
},
/**
* used to defer batch updates
*/
nextTick: function (cb) {
defer(cb, 0)
},
/**
* add class for IE9
* uses classList if available
*/
addClass: function (el, cls) {
if (hasClassList) {
el.classList.add(cls)
} else {
var cur = ' ' + el.className + ' '
if (cur.indexOf(' ' + cls + ' ') < 0) {
el.className = (cur + cls).trim()
}
}
},
/**
* remove class for IE9
*/
removeClass: function (el, cls) {
if (hasClassList) {
el.classList.remove(cls)
} else {
var cur = ' ' + el.className + ' ',
tar = ' ' + cls + ' '
while (cur.indexOf(tar) >= 0) {
cur = cur.replace(tar, ' ')
}
el.className = cur.trim()
}
}
}