| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- var config = require('./config'),
- toString = ({}).toString,
- win = window,
- console = win.console,
- timeout = win.setTimeout,
- THIS_RE = /[^\w]this[^\w]/,
- hasClassList = 'classList' in document.documentElement,
- ViewModel // late def
- var utils = module.exports = {
- /**
- * get a value from an object keypath
- */
- get: function (obj, key) {
- /* jshint eqeqeq: false */
- if (key.indexOf('.') < 0) {
- return obj[key]
- }
- var path = key.split('.'),
- d = -1, l = path.length
- while (++d < l && obj != null) {
- obj = obj[path[d]]
- }
- return obj
- },
- /**
- * set a value to an object keypath
- */
- set: function (obj, key, val) {
- /* jshint eqeqeq: false */
- if (key.indexOf('.') < 0) {
- obj[key] = val
- return
- }
- var path = key.split('.'),
- d = -1, l = path.length - 1
- while (++d < l) {
- if (obj[path[d]] == null) {
- obj[path[d]] = {}
- }
- obj = obj[path[d]]
- }
- obj[path[d]] = val
- },
- /**
- * return the base segment of a keypath
- */
- baseKey: function (key) {
- return key.indexOf('.') > 0
- ? key.split('.')[0]
- : key
- },
- /**
- * Create a prototype-less object
- * which is a better hash/map
- */
- hash: function () {
- return Object.create(null)
- },
- /**
- * get an attribute and remove it.
- */
- attr: function (el, type) {
- var attr = config.prefix + '-' + type,
- val = el.getAttribute(attr)
- if (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, writable) {
- if (obj.hasOwnProperty(key)) return
- Object.defineProperty(obj, key, {
- value : val,
- enumerable : !!enumerable,
- writable : !!writable,
- configurable : true
- })
- },
- /**
- * 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 null and undefined output empty string
- */
- guard: function (value) {
- /* jshint eqeqeq: false, eqnull: true */
- return value == null
- ? ''
- : (typeof value == 'object')
- ? JSON.stringify(value)
- : value
- },
- /**
- * When setting value on the VM, parse possible numbers
- */
- checkNumber: function (value) {
- return (isNaN(value) || value === null || typeof value === 'boolean')
- ? value
- : Number(value)
- },
- /**
- * simple extend
- */
- extend: function (obj, ext, protective) {
- for (var key in ext) {
- if ((protective && obj[key]) || obj[key] === ext[key]) continue
- obj[key] = ext[key]
- }
- return obj
- },
- /**
- * 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) {
- if (node.nodeType === 1) {
- 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
- },
- /**
- * Check if a filter function contains references to `this`
- * If yes, mark it as a computed filter.
- */
- checkFilter: function (filter) {
- if (THIS_RE.test(filter.toString())) {
- filter.computed = true
- }
- },
- /**
- * convert certain option values to the desired format.
- */
- processOptions: function (options) {
- var components = options.components,
- partials = options.partials,
- template = options.template,
- filters = options.filters,
- 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 (filters) {
- for (key in filters) {
- utils.checkFilter(filters[key])
- }
- }
- if (template) {
- options.template = utils.toFragment(template)
- }
- },
- /**
- * used to defer batch updates
- */
- nextTick: function (cb) {
- timeout(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()
- }
- },
- /**
- * Convert an object to Array
- * used in v-repeat and array filters
- */
- objectToArray: function (obj) {
- var res = [], val, data
- for (var key in obj) {
- val = obj[key]
- data = utils.typeOf(val) === 'Object'
- ? val
- : { $value: val }
- data.$key = key
- res.push(data)
- }
- return res
- }
- }
- enableDebug()
- function enableDebug () {
- /**
- * log for debugging
- */
- utils.log = function (msg) {
- if (config.debug && console) {
- console.log(msg)
- }
- }
-
- /**
- * warnings, traces by default
- * can be suppressed by `silent` option.
- */
- utils.warn = function (msg) {
- if (!config.silent && console) {
- console.warn(msg)
- if (config.debug && console.trace) {
- console.trace(msg)
- }
- }
- }
- }
|