omi/packages/obaa/index.js

263 lines
7.0 KiB
JavaScript
Raw Normal View History

2018-12-12 17:46:17 +08:00
/* obaa 1.0.0
2018-12-12 16:57:28 +08:00
* By dntzhang
* Github: https://github.com/Tencent/omi
* MIT Licensed.
*/
2018-12-12 17:46:17 +08:00
;(function(win) {
var obaa = function(target, arr, callback) {
var _observe = function(target, arr, callback) {
if (!target.$observer) target.$observer = this
var $observer = target.$observer
var eventPropArr = []
2018-12-12 16:57:28 +08:00
if (obaa.isArray(target)) {
if (target.length === 0) {
2018-12-12 17:46:17 +08:00
target.$observeProps = {}
target.$observeProps.$observerPath = '#'
2018-12-12 16:57:28 +08:00
}
2018-12-12 17:46:17 +08:00
$observer.mock(target)
2018-12-12 16:57:28 +08:00
}
for (var prop in target) {
if (target.hasOwnProperty(prop)) {
if (callback) {
if (obaa.isArray(arr) && obaa.isInArray(arr, prop)) {
2018-12-12 17:46:17 +08:00
eventPropArr.push(prop)
$observer.watch(target, prop)
2018-12-12 16:57:28 +08:00
} else if (obaa.isString(arr) && prop == arr) {
2018-12-12 17:46:17 +08:00
eventPropArr.push(prop)
$observer.watch(target, prop)
2018-12-12 16:57:28 +08:00
}
} else {
2018-12-12 17:46:17 +08:00
eventPropArr.push(prop)
$observer.watch(target, prop)
2018-12-12 16:57:28 +08:00
}
}
}
2018-12-12 17:46:17 +08:00
$observer.target = target
if (!$observer.propertyChangedHandler)
$observer.propertyChangedHandler = []
var propChanged = callback ? callback : arr
$observer.propertyChangedHandler.push({
all: !callback,
propChanged: propChanged,
eventPropArr: eventPropArr
})
}
2018-12-12 16:57:28 +08:00
_observe.prototype = {
2018-12-12 17:46:17 +08:00
onPropertyChanged: function(prop, value, oldValue, target, path) {
2018-12-12 16:57:28 +08:00
if (value !== oldValue && this.propertyChangedHandler) {
2018-12-12 17:46:17 +08:00
var rootName = obaa._getRootName(prop, path)
for (
var i = 0, len = this.propertyChangedHandler.length;
i < len;
i++
) {
var handler = this.propertyChangedHandler[i]
if (
handler.all ||
obaa.isInArray(handler.eventPropArr, rootName) ||
rootName.indexOf('Array-') === 0
) {
handler.propChanged.call(this.target, prop, value, oldValue, path)
2018-12-12 16:57:28 +08:00
}
}
}
2018-12-12 17:46:17 +08:00
if (prop.indexOf('Array-') !== 0 && typeof value === 'object') {
this.watch(target, prop, target.$observeProps.$observerPath)
2018-12-12 16:57:28 +08:00
}
},
2018-12-12 17:46:17 +08:00
mock: function(target) {
var self = this
obaa.methods.forEach(function(item) {
target[item] = function() {
var old = Array.prototype.slice.call(this, 0)
var result = Array.prototype[item].apply(
this,
Array.prototype.slice.call(arguments)
)
if (new RegExp('\\b' + item + '\\b').test(obaa.triggerStr)) {
2018-12-12 16:57:28 +08:00
for (var cprop in this) {
2018-12-12 17:46:17 +08:00
if (
this.hasOwnProperty(cprop) &&
!obaa.isFunction(this[cprop])
) {
self.watch(this, cprop, this.$observeProps.$observerPath)
2018-12-12 16:57:28 +08:00
}
}
//todo
2018-12-12 17:46:17 +08:00
self.onPropertyChanged(
'Array-' + item,
this,
old,
this,
this.$observeProps.$observerPath
)
2018-12-12 16:57:28 +08:00
}
2018-12-12 17:46:17 +08:00
return result
}
target[
'pure' + item.substring(0, 1).toUpperCase() + item.substring(1)
] = function() {
return Array.prototype[item].apply(
this,
Array.prototype.slice.call(arguments)
)
}
})
2018-12-12 16:57:28 +08:00
},
2018-12-12 17:46:17 +08:00
watch: function(target, prop, path) {
if (prop === '$observeProps' || prop === '$observer') return
if (obaa.isFunction(target[prop])) return
if (!target.$observeProps) target.$observeProps = {}
2018-12-12 16:57:28 +08:00
if (path !== undefined) {
2018-12-12 17:46:17 +08:00
target.$observeProps.$observerPath = path
2018-12-12 16:57:28 +08:00
} else {
2018-12-12 17:46:17 +08:00
target.$observeProps.$observerPath = '#'
2018-12-12 16:57:28 +08:00
}
2018-12-12 17:46:17 +08:00
var self = this
var currentValue = (target.$observeProps[prop] = target[prop])
2018-12-12 16:57:28 +08:00
Object.defineProperty(target, prop, {
2018-12-12 17:46:17 +08:00
get: function() {
return this.$observeProps[prop]
2018-12-12 16:57:28 +08:00
},
2018-12-12 17:46:17 +08:00
set: function(value) {
var old = this.$observeProps[prop]
this.$observeProps[prop] = value
self.onPropertyChanged(
prop,
value,
old,
this,
target.$observeProps.$observerPath
)
2018-12-12 16:57:28 +08:00
}
2018-12-12 17:46:17 +08:00
})
if (typeof currentValue == 'object') {
2018-12-12 16:57:28 +08:00
if (obaa.isArray(currentValue)) {
2018-12-12 17:46:17 +08:00
this.mock(currentValue)
2018-12-12 16:57:28 +08:00
if (currentValue.length === 0) {
2018-12-12 17:46:17 +08:00
if (!currentValue.$observeProps) currentValue.$observeProps = {}
2018-12-12 16:57:28 +08:00
if (path !== undefined) {
2018-12-12 17:46:17 +08:00
currentValue.$observeProps.$observerPath = path
2018-12-12 16:57:28 +08:00
} else {
2018-12-12 17:46:17 +08:00
currentValue.$observeProps.$observerPath = '#'
2018-12-12 16:57:28 +08:00
}
}
}
for (var cprop in currentValue) {
if (currentValue.hasOwnProperty(cprop)) {
2018-12-12 17:46:17 +08:00
this.watch(
currentValue,
cprop,
target.$observeProps.$observerPath + '-' + prop
)
2018-12-12 16:57:28 +08:00
}
}
}
}
2018-12-12 17:46:17 +08:00
}
2018-12-12 16:57:28 +08:00
return new _observe(target, arr, callback)
2018-12-12 17:46:17 +08:00
}
2018-12-12 16:57:28 +08:00
2018-12-12 17:46:17 +08:00
obaa.methods = [
'concat',
'copyWithin',
'entries',
'every',
'fill',
'filter',
'find',
'findIndex',
'forEach',
'includes',
'indexOf',
'join',
'keys',
'lastIndexOf',
'map',
'pop',
'push',
'reduce',
'reduceRight',
'reverse',
'shift',
'slice',
'some',
'sort',
'splice',
'toLocaleString',
'toString',
'unshift',
'values',
'size'
]
obaa.triggerStr = [
'concat',
'copyWithin',
'fill',
'pop',
'push',
'reverse',
'shift',
'sort',
'splice',
'unshift',
'size'
].join(',')
2018-12-12 16:57:28 +08:00
2018-12-12 17:46:17 +08:00
obaa.isArray = function(obj) {
return Object.prototype.toString.call(obj) === '[object Array]'
}
2018-12-12 16:57:28 +08:00
2018-12-12 17:46:17 +08:00
obaa.isString = function(obj) {
return typeof obj === 'string'
}
2018-12-12 16:57:28 +08:00
2018-12-12 17:46:17 +08:00
obaa.isInArray = function(arr, item) {
for (var i = arr.length; --i > -1; ) {
if (item === arr[i]) return true
2018-12-12 16:57:28 +08:00
}
2018-12-12 17:46:17 +08:00
return false
}
2018-12-12 16:57:28 +08:00
2018-12-12 17:46:17 +08:00
obaa.isFunction = function(obj) {
return Object.prototype.toString.call(obj) == '[object Function]'
}
2018-12-12 16:57:28 +08:00
2018-12-12 17:46:17 +08:00
obaa._getRootName = function(prop, path) {
if (path === '#') {
return prop
2018-12-12 16:57:28 +08:00
}
2018-12-12 17:46:17 +08:00
return path.split('-')[1]
}
2018-12-12 16:57:28 +08:00
2018-12-12 17:46:17 +08:00
obaa.add = function(obj, prop) {
var $observer = obj.$observer
$observer.watch(obj, prop)
}
2018-12-12 16:57:28 +08:00
2018-12-12 17:46:17 +08:00
obaa.set = function(obj, prop, value, exec) {
2018-12-12 16:57:28 +08:00
if (!exec) {
2018-12-12 17:46:17 +08:00
obj[prop] = value
2018-12-12 16:57:28 +08:00
}
2018-12-12 17:46:17 +08:00
var $observer = obj.$observer
$observer.watch(obj, prop)
2018-12-12 16:57:28 +08:00
if (exec) {
2018-12-12 17:46:17 +08:00
obj[prop] = value
2018-12-12 16:57:28 +08:00
}
2018-12-12 17:46:17 +08:00
}
2018-12-12 16:57:28 +08:00
2018-12-12 17:46:17 +08:00
Array.prototype.size = function(length) {
this.length = length
}
2018-12-12 16:57:28 +08:00
2018-12-12 17:46:17 +08:00
if (
typeof module != 'undefined' &&
2018-12-19 10:11:13 +08:00
module.exports) {
2018-12-12 17:46:17 +08:00
module.exports = obaa
} else if (typeof define === 'function' && define.amd) {
define(obaa)
} else {
win.obaa = obaa
}
})(Function('return this')())