util.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. var config = require('./config')
  2. var slice = [].slice
  3. var defer =
  4. win.requestAnimationFrame ||
  5. win.webkitRequestAnimationFrame ||
  6. win.setTimeout
  7. /**
  8. * Defer a task to the start of the next event loop
  9. *
  10. * @param {Function} fn
  11. */
  12. exports.nextTick = function (fn) {
  13. return defer(fn, 0)
  14. }
  15. /**
  16. * Convert an Array-like object to a real Array.
  17. *
  18. * @param {Array-like} list
  19. * @param {Number} [i] - start index
  20. */
  21. exports.toArray = function (list, i) {
  22. return slice.call(list, i || 0)
  23. }
  24. /**
  25. * Mix properties into target object.
  26. *
  27. * @param {Object} to
  28. * @param {Object} from
  29. */
  30. exports.mixin = function (to, from) {
  31. for (var key in from) {
  32. if (to[key] !== from[key]) {
  33. to[key] = from[key]
  34. }
  35. }
  36. }
  37. /**
  38. * Mixin including non-enumerables, and copy property descriptors.
  39. *
  40. * @param {Object} to
  41. * @param {Object} from
  42. */
  43. exports.deepMixin = function (to, from) {
  44. Object.getOwnPropertyNames(from).forEach(function (key) {
  45. var descriptor = Object.getOwnPropertyDescriptor(from, key)
  46. Object.defineProperty(to, key, descriptor)
  47. })
  48. }
  49. /**
  50. * Proxy a property on one object to another.
  51. *
  52. * @param {Object} to
  53. * @param {Object} from
  54. * @param {String} key
  55. */
  56. exports.proxy = function (to, from, key) {
  57. if (to.hasOwnProperty(key)) return
  58. Object.defineProperty(to, key, {
  59. enumerable: true,
  60. configurable: true,
  61. get: function () {
  62. return from[key]
  63. },
  64. set: function (val) {
  65. from[key] = val
  66. }
  67. })
  68. }
  69. /**
  70. * Object type check. Only returns true
  71. * for plain JavaScript objects.
  72. *
  73. * @param {*} obj
  74. * @return {Boolean}
  75. */
  76. exports.isObject = function (obj) {
  77. return Object.prototype.toString.call(obj) === '[object Object]'
  78. }
  79. /**
  80. * Array type check.
  81. *
  82. * @param {*} obj
  83. * @return {Boolean}
  84. */
  85. exports.isArray = function (obj) {
  86. return Array.isArray(obj)
  87. }
  88. /**
  89. * Define a non-enumerable property
  90. *
  91. * @param {Object} obj
  92. * @param {String} key
  93. * @param {*} val
  94. * @param {Boolean} [enumerable]
  95. */
  96. exports.define = function (obj, key, val, enumerable) {
  97. Object.defineProperty(obj, key, {
  98. value : val,
  99. enumerable : !!enumerable,
  100. writable : true,
  101. configurable : true
  102. })
  103. }
  104. /**
  105. * Augment an target Object or Array by either
  106. * intercepting the prototype chain using __proto__,
  107. * or copy over property descriptors
  108. *
  109. * @param {Object|Array} target
  110. * @param {Object} proto
  111. */
  112. if ('__proto__' in {}) {
  113. exports.augment = function (target, proto) {
  114. target.__proto__ = proto
  115. }
  116. } else {
  117. exports.augment = exports.deepMixin
  118. }
  119. /**
  120. * Merge two option objects.
  121. *
  122. * @param {Object} parent
  123. * @param {Object} child
  124. * @param {Boolean} noRecurse
  125. */
  126. exports.mergeOptions = function (parent, child, noRecurse) {
  127. // TODO
  128. // - merge lifecycle hooks
  129. // - merge asset registries
  130. // - else override
  131. // - use prototypal inheritance where appropriate
  132. }
  133. /**
  134. * Insert el before target
  135. *
  136. * @param {Element} el
  137. * @param {Element} target
  138. */
  139. exports.before = function (el, target) {
  140. target.parentNode.insertBefore(el, target)
  141. }
  142. /**
  143. * Insert el after target
  144. *
  145. * @param {Element} el
  146. * @param {Element} target
  147. */
  148. exports.after = function (el, target) {
  149. if (target.nextSibling) {
  150. exports.before(el, target.nextSibling)
  151. } else {
  152. target.parentNode.appendChild(el)
  153. }
  154. }
  155. /**
  156. * Remove el from DOM
  157. *
  158. * @param {Element} el
  159. */
  160. exports.remove = function (el) {
  161. el.parentNode.removeChild(el)
  162. }
  163. /**
  164. * Prepend el to target
  165. *
  166. * @param {Element} el
  167. * @param {Element} target
  168. */
  169. exports.prepend = function (el, target) {
  170. if (target.firstChild) {
  171. exports.before(el, target.firstChild)
  172. } else {
  173. target.appendChild(el)
  174. }
  175. }
  176. /**
  177. * Copy attributes from one element to another.
  178. *
  179. * @param {Element} from
  180. * @param {Element} to
  181. */
  182. exports.copyAttributes = function (from, to) {
  183. if (from.hasAttributes()) {
  184. var attrs = from.attributes
  185. for (var i = 0, l = attrs.length; i < l; i++) {
  186. var attr = attrs[i]
  187. to.setAttribute(attr.name, attr.value)
  188. }
  189. }
  190. }
  191. /**
  192. * Enable debug utilities. The enableDebug() function and all
  193. * _.log() & _.warn() calls will be dropped in the minified
  194. * production build.
  195. */
  196. enableDebug()
  197. function enableDebug () {
  198. var hasConsole = typeof console !== 'undefined'
  199. /**
  200. * Log a message.
  201. *
  202. * @param {String} msg
  203. */
  204. exports.log = function (msg) {
  205. if (hasConsole && config.debug) {
  206. console.log(msg)
  207. }
  208. }
  209. /**
  210. * We've got a problem here.
  211. *
  212. * @param {String} msg
  213. */
  214. exports.warn = function (msg) {
  215. if (hasConsole && !config.silent) {
  216. console.warn(msg)
  217. if (config.debug && console.trace) {
  218. console.trace(msg)
  219. }
  220. }
  221. }
  222. }