一大波更新
parent
eb3d4f82fc
commit
8b21f0a800
|
@ -2,10 +2,9 @@
|
|||
//http://www.cnblogs.com/rubylouvre/archive/2012/12/17/2818540.html
|
||||
import { Anot, directives, getLongID as markID } from '../seed/core'
|
||||
|
||||
function classNames() {
|
||||
function classNames(...args) {
|
||||
var classes = []
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
var arg = arguments[i]
|
||||
for (let arg of args) {
|
||||
var argType = typeof arg
|
||||
if (argType === 'string' || argType === 'number' || arg === true) {
|
||||
classes.push(arg)
|
||||
|
|
|
@ -8,11 +8,11 @@ var cssDir = Anot.directive('css', {
|
|||
//转换成对象
|
||||
var b = {}
|
||||
newVal.forEach(function(el) {
|
||||
el && Anot.shadowCopy(b, el)
|
||||
el && Object.assign(b, el)
|
||||
})
|
||||
newVal = b
|
||||
if (!arrayWarn[this.type]) {
|
||||
Anot.warn('ms-' + this.type + '指令的值不建议使用数组形式了!')
|
||||
console.warn('ms-' + this.type + '指令的值不建议使用数组形式了!')
|
||||
arrayWarn[this.type] = 1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ export var updateDataActions = {
|
|||
var field = this
|
||||
var array = field.value
|
||||
if (!Array.isArray(array)) {
|
||||
Anot.warn('ms-duplex应用于checkbox上要对应一个数组')
|
||||
console.warn('ms-duplex应用于checkbox上要对应一个数组')
|
||||
array = [array]
|
||||
}
|
||||
var method = field.dom.checked ? 'ensure' : 'remove'
|
||||
|
|
|
@ -19,7 +19,7 @@ Anot.directive('for', {
|
|||
str = str.replace(rforAs, function(a, b) {
|
||||
/* istanbul ignore if */
|
||||
if (!rident.test(b) || rinvalid.test(b)) {
|
||||
Anot.error(
|
||||
console.error(
|
||||
'alias ' +
|
||||
b +
|
||||
' is invalid --- must be a valid JS identifier which is not a reserved name.'
|
||||
|
@ -226,11 +226,7 @@ function updateItemVm(vm, top) {
|
|||
}
|
||||
|
||||
function resetVM(vm, a, b) {
|
||||
if (Anot.config.inProxyMode) {
|
||||
vm.$accessors[a].value = NaN
|
||||
} else {
|
||||
vm.$accessors[a].set(NaN)
|
||||
}
|
||||
vm.$accessors[a].value = NaN
|
||||
}
|
||||
|
||||
function updateList(instance) {
|
||||
|
|
|
@ -55,6 +55,6 @@ function continueScan(instance, vdom) {
|
|||
instance.fragment,
|
||||
instance.vm
|
||||
))
|
||||
Anot.shadowCopy(vdom, innerRender.root)
|
||||
Object.assign(vdom, innerRender.root)
|
||||
delete vdom.nodeValue
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ Anot.directive('on', {
|
|||
'\tvar __vmodel__ = this;',
|
||||
'\t' + filters,
|
||||
'\treturn ' + body,
|
||||
'}catch(e){Anot.log(e, "in on dir")}'
|
||||
'}catch(e){console.log(e, "in on dir")}'
|
||||
].filter(function(el) {
|
||||
return /\S/.test(el)
|
||||
})
|
||||
|
|
|
@ -33,7 +33,7 @@ function isCorrectDate(value) {
|
|||
return false
|
||||
}
|
||||
//https://github.com/adform/validator.js/blob/master/validator.js
|
||||
Anot.shadowCopy(Anot.validators, {
|
||||
Object.assign(Anot.validators, {
|
||||
pattern: {
|
||||
message: '必须匹配{{pattern}}这样的格式',
|
||||
get: function(value, field, next) {
|
||||
|
|
|
@ -5,7 +5,7 @@ Anot.directive('text', {
|
|||
init: function() {
|
||||
var node = this.node
|
||||
if (node.isVoidTag) {
|
||||
Anot.error('自闭合元素不能使用ms-text')
|
||||
console.error('自闭合元素不能使用ms-text')
|
||||
}
|
||||
var child = { nodeName: '#text', nodeValue: this.getValue() }
|
||||
node.children.splice(0, node.children.length, child)
|
||||
|
|
|
@ -44,7 +44,7 @@ var valiDir = Anot.directive('validate', {
|
|||
var fn = (vmValidator.onManual = onManual.bind(vmValidator))
|
||||
validator.onManual = fn
|
||||
} catch (e) {
|
||||
Anot.warn(
|
||||
console.warn(
|
||||
'要想使用onManual方法,必须在validate对象预定义一个空的onManual函数'
|
||||
)
|
||||
}
|
||||
|
@ -94,12 +94,7 @@ var valiDir = Anot.directive('validate', {
|
|||
var value = field.value
|
||||
var elem = field.dom
|
||||
/* istanbul ignore if */
|
||||
if (typeof Promise !== 'function') {
|
||||
//Anot-promise不支持phantomjs
|
||||
Anot.warn(
|
||||
'浏览器不支持原生Promise,请下载并<script src=url>引入\nhttps://github.com/RubyLouvre/Anot/blob/master/test/promise.js'
|
||||
)
|
||||
}
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (elem.disabled) return
|
||||
var rules = field.vdom.rules
|
||||
|
|
|
@ -13,7 +13,7 @@ import { Anot, rnowhite, rword } from '../../seed/core'
|
|||
}
|
||||
})
|
||||
|
||||
Anot.shadowCopy(Anot.fn, {
|
||||
Object.assign(Anot.fn, {
|
||||
hasClass: function(cls) {
|
||||
var el = this[0] || {}
|
||||
//IE10+, chrome8+, firefox3.6+, safari5.1+,opera11.5+支持classList,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Anot, oneObject, cssHooks } from '../../seed/core'
|
||||
import { Anot, root, oneObject, cssHooks } from '../../seed/core'
|
||||
|
||||
var cssMap = oneObject('float', 'cssFloat')
|
||||
export { cssMap, cssHooks }
|
||||
|
@ -11,7 +11,7 @@ Anot.cssName = function(name, host, camelCase) {
|
|||
if (cssMap[name]) {
|
||||
return cssMap[name]
|
||||
}
|
||||
host = host || Anot.root.style || {}
|
||||
host = host || root.style || {}
|
||||
for (var i = 0, n = prefixes.length; i < n; i++) {
|
||||
camelCase = Anot.camelize(prefixes[i] + name)
|
||||
if (camelCase in host) {
|
||||
|
@ -103,7 +103,7 @@ Anot.fn.offsetParent = function() {
|
|||
while (offsetParent && Anot.css(offsetParent, 'position') === 'static') {
|
||||
offsetParent = offsetParent.offsetParent
|
||||
}
|
||||
return Anot(offsetParent || Anot.root)
|
||||
return Anot(offsetParent || root)
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
|
|
|
@ -18,7 +18,7 @@ Anot.fireDom = function(elem, type, opts) {
|
|||
if (document.createEvent) {
|
||||
var hackEvent = document.createEvent('Events')
|
||||
hackEvent.initEvent(type, true, true, opts)
|
||||
Anot.shadowCopy(hackEvent, opts)
|
||||
Object.assign(hackEvent, opts)
|
||||
elem.dispatchEvent(hackEvent)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Anot, _slice, eventHooks, root, getShortID } from '../../seed/core'
|
||||
import { Anot, eventHooks, root, getShortID } from '../../seed/core'
|
||||
import { canBubbleUp } from './canBubbleUp'
|
||||
/* istanbul ignore if */
|
||||
var hackSafari = document.ontouchstart
|
||||
|
@ -11,10 +11,8 @@ Anot.fn.bind = function(type, fn, phase) {
|
|||
}
|
||||
}
|
||||
|
||||
Anot.fn.unbind = function(type, fn, phase) {
|
||||
Anot.fn.unbind = function(...args) {
|
||||
if (this[0]) {
|
||||
var args = _slice.call(arguments)
|
||||
args.unshift(this[0])
|
||||
Anot.unbind.apply(0, args)
|
||||
}
|
||||
return this
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Anot, Cache } from '../seed/core'
|
||||
import { Anot, Cache, root } from '../seed/core'
|
||||
import { cssDiff } from '../directives/css'
|
||||
import {
|
||||
css3,
|
||||
|
@ -16,7 +16,7 @@ var effectDir = Anot.directive('effect', {
|
|||
this.value = effect = {
|
||||
is: effect
|
||||
}
|
||||
Anot.warn('ms-effect的指令值不再支持字符串,必须是一个对象')
|
||||
console.warn('ms-effect的指令值不再支持字符串,必须是一个对象')
|
||||
}
|
||||
this.value = vdom.effect = effect
|
||||
var ok = cssDiff.call(this, effect, this.oldValue)
|
||||
|
@ -42,13 +42,13 @@ var effectDir = Anot.directive('effect', {
|
|||
var globalOption = Anot.effects[is]
|
||||
if (!globalOption) {
|
||||
//如果没有定义特效
|
||||
Anot.warn(is + ' effect is undefined')
|
||||
console.warn(is + ' effect is undefined')
|
||||
return
|
||||
}
|
||||
var finalOption = {}
|
||||
var action = actionMaps[option.action]
|
||||
if (typeof Effect.prototype[action] !== 'function') {
|
||||
Anot.warn('action is undefined')
|
||||
console.warn('action is undefined')
|
||||
return
|
||||
}
|
||||
//必须预定义特效
|
||||
|
@ -202,7 +202,7 @@ function createAction(action) {
|
|||
}
|
||||
setTimeout(function() {
|
||||
//用xxx-active代替xxx类名的方式 触发CSS3动画
|
||||
var time = Anot.root.offsetWidth === NaN
|
||||
var time = root.offsetWidth === NaN
|
||||
elem.addClass(option[lower + 'ActiveClass'])
|
||||
//计算动画时长
|
||||
time = getAnimationTime(dom)
|
||||
|
@ -237,7 +237,7 @@ Anot.applyEffect = function(dom, vdom, opts) {
|
|||
}
|
||||
}
|
||||
getAction(opts)
|
||||
Anot.directives.effect.update(vdom, curEffect, Anot.shadowCopy({}, opts))
|
||||
Anot.directives.effect.update(vdom, curEffect, Object.assign({}, opts))
|
||||
} else if (cb) {
|
||||
cb(dom)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Anot } from '../seed/core'
|
||||
import { Anot, escapeRegExp } from '../seed/core'
|
||||
import { $$skipArray } from '../vmodel/reserved'
|
||||
|
||||
/*
|
||||
|
@ -64,10 +64,11 @@ function __repeat(array, isArray, cb) {
|
|||
}
|
||||
}
|
||||
}
|
||||
export function filterBy(array, search) {
|
||||
export function filterBy(array, search, ...args) {
|
||||
var type = Anot.type(array)
|
||||
if (type !== 'array' && type !== 'object') throw 'filterBy只能处理对象或数组'
|
||||
var args = Anot.slice(arguments, 2)
|
||||
if (type !== 'array' && type !== 'object') {
|
||||
throw 'filterBy只能处理对象或数组'
|
||||
}
|
||||
var stype = Anot.type(search)
|
||||
if (stype === 'function') {
|
||||
var criteria = search._orig || search
|
||||
|
@ -75,7 +76,7 @@ export function filterBy(array, search) {
|
|||
if (search === '') {
|
||||
return array
|
||||
} else {
|
||||
var reg = new RegExp(Anot.escapeRegExp(search), 'i')
|
||||
var reg = new RegExp(escapeRegExp(search), 'i')
|
||||
criteria = function(el) {
|
||||
return reg.test(el)
|
||||
}
|
||||
|
|
|
@ -1,218 +1,100 @@
|
|||
function toInt(str) {
|
||||
return parseInt(str, 10) || 0
|
||||
}
|
||||
|
||||
function padNumber(num, digits, trim) {
|
||||
var neg = ''
|
||||
/* istanbul ignore if*/
|
||||
if (num < 0) {
|
||||
neg = '-'
|
||||
num = -num
|
||||
}
|
||||
num = '' + num
|
||||
while (num.length < digits) {
|
||||
num = '0' + num
|
||||
}
|
||||
if (trim) {
|
||||
num = num.substr(num.length - digits)
|
||||
}
|
||||
return neg + num
|
||||
}
|
||||
|
||||
function dateGetter(name, size, offset, trim) {
|
||||
return function(date) {
|
||||
var value = date['get' + name]()
|
||||
if (offset > 0 || value > -offset) value += offset
|
||||
if (value === 0 && offset === -12) {
|
||||
/* istanbul ignore next*/
|
||||
value = 12
|
||||
}
|
||||
return padNumber(value, size, trim)
|
||||
}
|
||||
}
|
||||
|
||||
function dateStrGetter(name, shortForm) {
|
||||
return function(date, formats) {
|
||||
var value = date['get' + name]()
|
||||
var get = (shortForm ? 'SHORT' + name : name).toUpperCase()
|
||||
return formats[get][value]
|
||||
}
|
||||
}
|
||||
|
||||
function timeZoneGetter(date) {
|
||||
var zone = -1 * date.getTimezoneOffset()
|
||||
var paddedZone = zone >= 0 ? '+' : ''
|
||||
paddedZone +=
|
||||
padNumber(Math[zone > 0 ? 'floor' : 'ceil'](zone / 60), 2) +
|
||||
padNumber(Math.abs(zone % 60), 2)
|
||||
return paddedZone
|
||||
}
|
||||
//取得上午下午
|
||||
function ampmGetter(date, formats) {
|
||||
return date.getHours() < 12 ? formats.AMPMS[0] : formats.AMPMS[1]
|
||||
}
|
||||
var DATE_FORMATS = {
|
||||
yyyy: dateGetter('FullYear', 4),
|
||||
yy: dateGetter('FullYear', 2, 0, true),
|
||||
y: dateGetter('FullYear', 1),
|
||||
MMMM: dateStrGetter('Month'),
|
||||
MMM: dateStrGetter('Month', true),
|
||||
MM: dateGetter('Month', 2, 1),
|
||||
M: dateGetter('Month', 1, 1),
|
||||
dd: dateGetter('Date', 2),
|
||||
d: dateGetter('Date', 1),
|
||||
HH: dateGetter('Hours', 2),
|
||||
H: dateGetter('Hours', 1),
|
||||
hh: dateGetter('Hours', 2, -12),
|
||||
h: dateGetter('Hours', 1, -12),
|
||||
mm: dateGetter('Minutes', 2),
|
||||
m: dateGetter('Minutes', 1),
|
||||
ss: dateGetter('Seconds', 2),
|
||||
s: dateGetter('Seconds', 1),
|
||||
sss: dateGetter('Milliseconds', 3),
|
||||
EEEE: dateStrGetter('Day'),
|
||||
EEE: dateStrGetter('Day', true),
|
||||
a: ampmGetter,
|
||||
Z: timeZoneGetter
|
||||
}
|
||||
var rdateFormat = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/
|
||||
var raspnetjson = /^\/Date\((\d+)\)\/$/
|
||||
export function dateFilter(date, format) {
|
||||
var locate = dateFilter.locate,
|
||||
text = '',
|
||||
parts = [],
|
||||
fn,
|
||||
match
|
||||
format = format || 'mediumDate'
|
||||
format = locate[format] || format
|
||||
if (typeof date === 'string') {
|
||||
if (/^\d+$/.test(date)) {
|
||||
date = toInt(date)
|
||||
} else if (raspnetjson.test(date)) {
|
||||
date = +RegExp.$1
|
||||
} else {
|
||||
var trimDate = date.trim()
|
||||
var dateArray = [0, 0, 0, 0, 0, 0, 0]
|
||||
var oDate = new Date(0)
|
||||
//取得年月日
|
||||
trimDate = trimDate.replace(/^(\d+)\D(\d+)\D(\d+)/, function(_, a, b, c) {
|
||||
var array = c.length === 4 ? [c, a, b] : [a, b, c]
|
||||
dateArray[0] = toInt(array[0]) //年
|
||||
dateArray[1] = toInt(array[1]) - 1 //月
|
||||
dateArray[2] = toInt(array[2]) //日
|
||||
return ''
|
||||
})
|
||||
var dateSetter = oDate.setFullYear
|
||||
var timeSetter = oDate.setHours
|
||||
trimDate = trimDate.replace(/[T\s](\d+):(\d+):?(\d+)?\.?(\d)?/, function(
|
||||
_,
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
d
|
||||
) {
|
||||
dateArray[3] = toInt(a) //小时
|
||||
dateArray[4] = toInt(b) //分钟
|
||||
dateArray[5] = toInt(c) //秒
|
||||
if (d) {
|
||||
//毫秒
|
||||
dateArray[6] = Math.round(parseFloat('0.' + d) * 1000)
|
||||
}
|
||||
return ''
|
||||
})
|
||||
var tzHour = 0
|
||||
var tzMin = 0
|
||||
trimDate = trimDate.replace(/Z|([+-])(\d\d):?(\d\d)/, function(
|
||||
z,
|
||||
symbol,
|
||||
c,
|
||||
d
|
||||
) {
|
||||
dateSetter = oDate.setUTCFullYear
|
||||
timeSetter = oDate.setUTCHours
|
||||
if (symbol) {
|
||||
tzHour = toInt(symbol + c)
|
||||
tzMin = toInt(symbol + d)
|
||||
}
|
||||
return ''
|
||||
})
|
||||
|
||||
dateArray[3] -= tzHour
|
||||
dateArray[4] -= tzMin
|
||||
dateSetter.apply(oDate, dateArray.slice(0, 3))
|
||||
timeSetter.apply(oDate, dateArray.slice(3))
|
||||
date = oDate
|
||||
}
|
||||
}
|
||||
if (typeof date === 'number') {
|
||||
date = new Date(date)
|
||||
}
|
||||
|
||||
while (format) {
|
||||
match = rdateFormat.exec(format)
|
||||
/* istanbul ignore else */
|
||||
if (match) {
|
||||
parts = parts.concat(match.slice(1))
|
||||
format = parts.pop()
|
||||
} else {
|
||||
parts.push(format)
|
||||
format = null
|
||||
}
|
||||
}
|
||||
parts.forEach(function(value) {
|
||||
fn = DATE_FORMATS[value]
|
||||
text += fn
|
||||
? fn(date, locate)
|
||||
: value.replace(/(^'|'$)/g, '').replace(/''/g, "'")
|
||||
if (!Date.prototype.getFullWeek) {
|
||||
//获取当天是本年度第几周
|
||||
Object.defineProperty(Date.prototype, 'getFullWeek', {
|
||||
value: function() {
|
||||
let thisYear = this.getFullYear()
|
||||
let that = new Date(thisYear, 0, 1)
|
||||
let firstDay = that.getDay() || 1
|
||||
let numsOfToday = (this - that) / 86400000
|
||||
return Math.ceil((numsOfToday + firstDay) / 7)
|
||||
},
|
||||
enumerable: false
|
||||
})
|
||||
|
||||
//获取当天是本月第几周
|
||||
Object.defineProperty(Date.prototype, 'getWeek', {
|
||||
value: function() {
|
||||
let today = this.getDate()
|
||||
let thisMonth = this.getMonth()
|
||||
let thisYear = this.getFullYear()
|
||||
let firstDay = new Date(thisYear, thisMonth, 1).getDay()
|
||||
return Math.ceil((today + firstDay) / 7)
|
||||
},
|
||||
enumerable: false
|
||||
})
|
||||
return text
|
||||
}
|
||||
|
||||
var locate = {
|
||||
AMPMS: {
|
||||
0: '上午',
|
||||
1: '下午'
|
||||
},
|
||||
DAY: {
|
||||
0: '星期日',
|
||||
1: '星期一',
|
||||
2: '星期二',
|
||||
3: '星期三',
|
||||
4: '星期四',
|
||||
5: '星期五',
|
||||
6: '星期六'
|
||||
},
|
||||
MONTH: {
|
||||
0: '1月',
|
||||
1: '2月',
|
||||
2: '3月',
|
||||
3: '4月',
|
||||
4: '5月',
|
||||
5: '6月',
|
||||
6: '7月',
|
||||
7: '8月',
|
||||
8: '9月',
|
||||
9: '10月',
|
||||
10: '11月',
|
||||
11: '12月'
|
||||
},
|
||||
SHORTDAY: {
|
||||
'0': '周日',
|
||||
'1': '周一',
|
||||
'2': '周二',
|
||||
'3': '周三',
|
||||
'4': '周四',
|
||||
'5': '周五',
|
||||
'6': '周六'
|
||||
},
|
||||
fullDate: 'y年M月d日EEEE',
|
||||
longDate: 'y年M月d日',
|
||||
medium: 'yyyy-M-d H:mm:ss',
|
||||
mediumDate: 'yyyy-M-d',
|
||||
mediumTime: 'H:mm:ss',
|
||||
short: 'yy-M-d ah:mm',
|
||||
shortDate: 'yy-M-d',
|
||||
shortTime: 'ah:mm'
|
||||
if (!Date.isDate) {
|
||||
Object.defineProperty(Date, 'isDate', {
|
||||
value: function(obj) {
|
||||
return typeof obj === 'object' && obj.getTime ? true : false
|
||||
},
|
||||
enumerable: false
|
||||
})
|
||||
}
|
||||
|
||||
//时间格式化
|
||||
if (!Date.prototype.format) {
|
||||
Object.defineProperty(Date.prototype, 'format', {
|
||||
value: function(str) {
|
||||
str = str || 'Y-m-d H:i:s'
|
||||
var week = ['一', '二', '三', '四', '五', '六', '日']
|
||||
var dt = {
|
||||
fullyear: this.getFullYear(),
|
||||
year: this.getYear(),
|
||||
fullweek: this.getFullWeek(),
|
||||
week: this.getWeek(),
|
||||
month: this.getMonth() + 1,
|
||||
date: this.getDate(),
|
||||
day: week[this.getDay()],
|
||||
hours: this.getHours(),
|
||||
minutes: this.getMinutes(),
|
||||
seconds: this.getSeconds()
|
||||
}
|
||||
var re
|
||||
|
||||
dt.g = dt.hours > 12 ? dt.hours - 12 : dt.hours
|
||||
|
||||
re = {
|
||||
Y: dt.fullyear,
|
||||
y: dt.year,
|
||||
m: dt.month < 10 ? '0' + dt.month : dt.month,
|
||||
n: dt.month,
|
||||
d: dt.date < 10 ? '0' + dt.date : dt.date,
|
||||
j: dt.date,
|
||||
H: dt.hours < 10 ? '0' + dt.hours : dt.hours,
|
||||
h: dt.g < 10 ? '0' + dt.g : dt.g,
|
||||
G: dt.hours,
|
||||
g: dt.g,
|
||||
i: dt.minutes < 10 ? '0' + dt.minutes : dt.minutes,
|
||||
s: dt.seconds < 10 ? '0' + dt.seconds : dt.seconds,
|
||||
W: dt.fullweek,
|
||||
w: dt.week,
|
||||
D: dt.day
|
||||
}
|
||||
|
||||
for (let i in re) {
|
||||
str = str.replace(new RegExp(i, 'g'), re[i])
|
||||
}
|
||||
return str
|
||||
},
|
||||
enumerable: false
|
||||
})
|
||||
}
|
||||
|
||||
export function dateFilter(stamp, format) {
|
||||
var oDate = stamp
|
||||
|
||||
if (!Date.isDate(oDate)) {
|
||||
var tmp = +oDate
|
||||
if (tmp === tmp) {
|
||||
oDate = tmp
|
||||
}
|
||||
|
||||
oDate = new Date(oDate)
|
||||
if (oDate.toString() === 'Invalid Date') {
|
||||
return 'Invalid Date'
|
||||
}
|
||||
}
|
||||
return oDate.format(str)
|
||||
}
|
||||
locate.SHORTMONTH = locate.MONTH
|
||||
dateFilter.locate = locate
|
||||
|
|
|
@ -19,15 +19,13 @@ var keys = {
|
|||
right: 39,
|
||||
down: 40
|
||||
}
|
||||
for (var name in keys) {
|
||||
;(function(filter, key) {
|
||||
eventFilters[filter] = function(e) {
|
||||
if (e.which !== key) {
|
||||
e.$return = true
|
||||
}
|
||||
return e
|
||||
for (let name in keys) {
|
||||
eventFilters[name] = function(e) {
|
||||
if (e.which !== keys[name]) {
|
||||
e.$return = true
|
||||
}
|
||||
})(name, keys[name])
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
export { eventFilters }
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
import { Anot } from '../seed/core'
|
||||
|
||||
import { numberFilter } from './number'
|
||||
import { sanitizeFilter } from './sanitize'
|
||||
import { xss } from './xss'
|
||||
import { dateFilter } from './date'
|
||||
import { filterBy, orderBy, selectBy, limitBy } from './array'
|
||||
import { eventFilters } from './event'
|
||||
// import { eventFilters } from './event'
|
||||
import { escapeFilter } from './escape'
|
||||
var filters = (Anot.filters = {})
|
||||
|
||||
Anot.composeFilters = function() {
|
||||
var args = arguments
|
||||
Anot.composeFilters = function(...args) {
|
||||
return function(value) {
|
||||
for (var i = 0, arr; (arr = args[i++]); ) {
|
||||
for (let arr of args) {
|
||||
var name = arr[0]
|
||||
var filter = Anot.filters[name]
|
||||
if (typeof filter === 'function') {
|
||||
|
@ -36,37 +35,25 @@ Anot.mix(
|
|||
lowercase(str) {
|
||||
return String(str).toLowerCase()
|
||||
},
|
||||
truncate(str, length, end) {
|
||||
//length,新字符串长度,truncation,新字符串的结尾的字段,返回新字符串
|
||||
if (!str) {
|
||||
return ''
|
||||
}
|
||||
str = String(str)
|
||||
if (isNaN(length)) {
|
||||
length = 30
|
||||
}
|
||||
end = typeof end === 'string' ? end : '...'
|
||||
return str.length > length
|
||||
? str.slice(0, length - end.length) + end /* istanbul ignore else*/
|
||||
: str
|
||||
truncate(str, len, mark) {
|
||||
len = len || 30
|
||||
mark = typeof mark === 'string' ? mark : '...'
|
||||
return str.slice(0, len) + (str.length <= len ? '' : mark)
|
||||
},
|
||||
camelize: Anot.camelize,
|
||||
date: dateFilter,
|
||||
escape: escapeFilter,
|
||||
sanitize: sanitizeFilter,
|
||||
xss,
|
||||
number: numberFilter,
|
||||
currency(amount, symbol, fractionSize) {
|
||||
return (
|
||||
(symbol || '\u00a5') +
|
||||
numberFilter(
|
||||
amount,
|
||||
isFinite(fractionSize) ? /* istanbul ignore else*/ fractionSize : 2
|
||||
)
|
||||
numberFilter(amount, isFinite(fractionSize) ? fractionSize : 2)
|
||||
)
|
||||
}
|
||||
},
|
||||
{ filterBy, orderBy, selectBy, limitBy },
|
||||
eventFilters
|
||||
{ filterBy, orderBy, selectBy, limitBy }
|
||||
// eventFilters
|
||||
)
|
||||
|
||||
export { Anot }
|
||||
|
|
|
@ -1,34 +1,18 @@
|
|||
import { Anot } from '../seed/core'
|
||||
function toFixedFix(n, prec) {
|
||||
var k = Math.pow(10, prec)
|
||||
return '' + (Math.round(n * k) / k).toFixed(prec)
|
||||
}
|
||||
export function numberFilter(number, decimals, point, thousands) {
|
||||
//https://github.com/txgruppi/number_format
|
||||
//form http://phpjs.org/functions/number_format/
|
||||
//number 必需,要格式化的数字
|
||||
//decimals 可选,规定多少个小数位。
|
||||
//point 可选,规定用作小数点的字符串(默认为 . )。
|
||||
//thousands 可选,规定用作千位分隔符的字符串(默认为 , ),如果设置了该参数,那么所有其他参数都是必需的。
|
||||
number = (number + '').replace(/[^0-9+\-Ee.]/g, '')
|
||||
var n = !isFinite(+number) ? 0 : +number,
|
||||
prec = !isFinite(+decimals) ? 3 : Math.abs(decimals),
|
||||
sep = typeof thousands === 'string' ? thousands : ',',
|
||||
dec = point || '.',
|
||||
s = ''
|
||||
/**
|
||||
* @number 必需,要格式化的数字
|
||||
* @decimals 可选,规定多少个小数位。
|
||||
* @thousands 可选,规定用作千位分隔符的字符串(默认为 , ),如果设置了该参数,那么所有其他参数都是必需的。
|
||||
*/
|
||||
export function numberFilter(number, decimals = 0, thousands = '') {
|
||||
var num = +number || 0
|
||||
var d = !isFinite(+decimals) ? 3 : Math.abs(decimals)
|
||||
var t = typeof thousands === 'string' ? thousands : ','
|
||||
var tmp
|
||||
|
||||
// Fix for IE parseFloat(0.55).toFixed(0) = 0;
|
||||
s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.')
|
||||
if (s[0].length > 3) {
|
||||
s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep)
|
||||
tmp = ((d ? num.toFixed(d) : Math.round(num)) + '').split('.')
|
||||
if (tmp[0].length > 3) {
|
||||
tmp[0] = tmp[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, t)
|
||||
}
|
||||
/** //好像没有用
|
||||
var s1 = s[1] || ''
|
||||
|
||||
if (s1.length < prec) {
|
||||
s1 += new Array(prec - s[1].length + 1).join('0')
|
||||
s[1] = s1
|
||||
}
|
||||
**/
|
||||
return s.join(dec)
|
||||
return tmp.join('.')
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ var rsanitize = {
|
|||
// <a href="jav ascript:alert('XSS');">IE67chrome</a>
|
||||
// <a href="jav	ascript:alert('XSS');">IE67chrome</a>
|
||||
// <a href="jav
ascript:alert('XSS');">IE67chrome</a>
|
||||
export function sanitizeFilter(str) {
|
||||
export function xss(str) {
|
||||
return str.replace(rscripts, '').replace(ropen, function(a, b) {
|
||||
var match = a.toLowerCase().match(/<(\w+)\s/)
|
||||
if (match) {
|
|
@ -1,5 +1,6 @@
|
|||
import { root } from '../seed/core'
|
||||
import { Recognizer } from './recognizer'
|
||||
var root = Anot.root
|
||||
|
||||
var supportPointer = !!navigator.pointerEnabled || !!navigator.msPointerEnabled
|
||||
// 支持pointer的设备可用样式来取消click事件的300毫秒延迟
|
||||
if (supportPointer) {
|
||||
|
|
|
@ -89,7 +89,7 @@ export function addScope(expr, type) {
|
|||
}
|
||||
return ''
|
||||
})
|
||||
var arg = '[' + Anot.quote(filter.trim()) + bracketArgs + ']'
|
||||
var arg = '[' + JSON.stringify(filter.trim()) + bracketArgs + ']'
|
||||
return arg
|
||||
})
|
||||
filters = 'Anot.composeFilters(' + filters + ')(__value__)'
|
||||
|
@ -119,7 +119,7 @@ export function createGetter(expr, type) {
|
|||
return new Function('__vmodel__', 'return ' + body + ';')
|
||||
/* istanbul ignore next */
|
||||
} catch (e) {
|
||||
Anot.log('parse getter: [', expr, body, ']error')
|
||||
console.log('parse getter: [', expr, body, ']error')
|
||||
return Anot.noop
|
||||
}
|
||||
}
|
||||
|
@ -131,12 +131,12 @@ export function createGetter(expr, type) {
|
|||
export function createSetter(expr, type) {
|
||||
var arr = addScope(expr, type)
|
||||
var body =
|
||||
'try{ ' + arr[0] + ' = __value__}catch(e){Anot.log(e, "in on dir")}'
|
||||
'try{ ' + arr[0] + ' = __value__}catch(e){console.log(e, "in on dir")}'
|
||||
try {
|
||||
return new Function('__vmodel__', '__value__', body + ';')
|
||||
/* istanbul ignore next */
|
||||
} catch (e) {
|
||||
Anot.log('parse setter: ', expr, ' error')
|
||||
console.log('parse setter: ', expr, ' error')
|
||||
return Anot.noop
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Anot, config } from '../seed/core'
|
||||
import { Anot, config, _decode } from '../seed/core'
|
||||
import { addScope } from './index'
|
||||
var rimprovePriority = /[+-\?]/
|
||||
var rinnerValue = /__value__\)$/
|
||||
|
@ -12,7 +12,7 @@ export function parseInterpolate(dir) {
|
|||
index = index === -1 ? str.length : index
|
||||
var value = str.slice(0, index)
|
||||
if (/\S/.test(value)) {
|
||||
tokens.push(Anot.quote(Anot._decode(value)))
|
||||
tokens.push(JSON.stringify(_decode(value)))
|
||||
}
|
||||
str = str.slice(index + config.openTag.length)
|
||||
if (str) {
|
||||
|
|
|
@ -50,7 +50,9 @@ Render.prototype = {
|
|||
} else if (typeof this.root === 'string') {
|
||||
vnodes = fromString(this.root) //转换虚拟DOM
|
||||
} else {
|
||||
return Anot.warn('Anot.scan first argument must element or HTML string')
|
||||
return console.warn(
|
||||
'Anot.scan first argument must element or HTML string'
|
||||
)
|
||||
}
|
||||
|
||||
this.root = vnodes[0]
|
||||
|
@ -136,7 +138,7 @@ Render.prototype = {
|
|||
var type = attr.match(/\w+/g)[1]
|
||||
type = eventMap[type] || type
|
||||
if (!directives[type]) {
|
||||
Anot.warn(attr + ' has not registered!')
|
||||
console.warn(attr + ' has not registered!')
|
||||
}
|
||||
hasDir = true
|
||||
}
|
||||
|
@ -155,7 +157,7 @@ Render.prototype = {
|
|||
var templateCaches = Anot.serverTemplates
|
||||
var temp = templateCaches && templateCaches[$id]
|
||||
if (temp) {
|
||||
Anot.log('前端再次渲染后端传过来的模板')
|
||||
console.log('前端再次渲染后端传过来的模板')
|
||||
var node = fromString(temp)[0]
|
||||
for (var i in node) {
|
||||
vdom[i] = node[i]
|
||||
|
|
150
src/seed/core.js
150
src/seed/core.js
|
@ -13,12 +13,6 @@ Anot.init = function(el) {
|
|||
|
||||
Anot.fn = Anot.prototype = Anot.init.prototype
|
||||
|
||||
export function shadowCopy(destination, source) {
|
||||
for (var property in source) {
|
||||
destination[property] = source[property]
|
||||
}
|
||||
return destination
|
||||
}
|
||||
export var rword = /[^, ]+/g
|
||||
export var rnowhite = /\S+/g //存在非空字符
|
||||
export var platform = {} //用于放置平台差异的方法与属性
|
||||
|
@ -39,34 +33,16 @@ export function oneObject(array, val) {
|
|||
}
|
||||
|
||||
var op = Object.prototype
|
||||
export function quote(str) {
|
||||
return Anot._quote(str)
|
||||
}
|
||||
|
||||
export var inspect = op.toString
|
||||
export var ohasOwn = op.hasOwnProperty
|
||||
export var ap = Array.prototype
|
||||
|
||||
var hasConsole = typeof console === 'object'
|
||||
Anot.config = { debug: true }
|
||||
export function log() {
|
||||
if (hasConsole && Anot.config.debug) {
|
||||
Function.apply.call(console.log, console, arguments)
|
||||
}
|
||||
}
|
||||
export { Cache, directive, directives, delayCompileNodes, root }
|
||||
export function warn() {
|
||||
if (hasConsole && Anot.config.debug) {
|
||||
var method = console.warn || console.log
|
||||
// http://qiang106.iteye.com/blog/1721425
|
||||
Function.apply.call(method, console, arguments)
|
||||
}
|
||||
}
|
||||
export function error(str, e) {
|
||||
throw (e || Error)(str)
|
||||
}
|
||||
|
||||
export function noop() {}
|
||||
export function isObject(a) {
|
||||
return a !== null && typeof a === 'object'
|
||||
return a && typeof a === 'object'
|
||||
}
|
||||
|
||||
export function range(start, end, step) {
|
||||
|
@ -104,18 +80,14 @@ export function camelize(target) {
|
|||
})
|
||||
}
|
||||
|
||||
export var _slice = ap.slice
|
||||
export function slice(nodes, start, end) {
|
||||
return _slice.call(nodes, start, end)
|
||||
}
|
||||
|
||||
var rhashcode = /\d\.\d{4}/
|
||||
//生成UUID http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
|
||||
export function makeHashCode(prefix) {
|
||||
/* istanbul ignore next*/
|
||||
prefix = prefix || 'Anot'
|
||||
/* istanbul ignore next*/
|
||||
return String(Math.random() + Math.random()).replace(rhashcode, prefix)
|
||||
export function makeHashCode(prefix = 'anot') {
|
||||
return (
|
||||
prefix +
|
||||
crypto
|
||||
.getRandomValues(new Uint8Array(8))
|
||||
.reduce((a, b) => a + b.toString(16), '')
|
||||
.slice(0, 12)
|
||||
)
|
||||
}
|
||||
//生成事件回调的UUID(用户通过ms-on指令)
|
||||
export function getLongID(fn) {
|
||||
|
@ -148,9 +120,32 @@ export function createFragment() {
|
|||
return document.createDocumentFragment()
|
||||
}
|
||||
|
||||
export function _decode(str) {
|
||||
if (rentities.test(str)) {
|
||||
temp.innerHTML = str
|
||||
return temp.innerText || temp.textContent
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
var rentities = /&[a-z0-9#]{2,10};/
|
||||
var temp = document.createElement('div')
|
||||
shadowCopy(Anot, {
|
||||
|
||||
//============== config ============
|
||||
export var config = {
|
||||
openTag: '{{',
|
||||
closeTag: '}}',
|
||||
rtext: /\{\{(.+?)\}\}/g,
|
||||
rexpr: /\{\{([\s\S]*)\}\}/
|
||||
}
|
||||
|
||||
export function createAnchor(nodeValue) {
|
||||
return document.createComment(nodeValue)
|
||||
}
|
||||
|
||||
//============ config ============
|
||||
|
||||
Object.assign(Anot, {
|
||||
Array: {
|
||||
merge: function(target, other) {
|
||||
//合并两个数组 Anot2新增
|
||||
|
@ -176,78 +171,22 @@ shadowCopy(Anot, {
|
|||
evaluatorPool: new Cache(888),
|
||||
parsers: {
|
||||
number: function(a) {
|
||||
return a === '' ? '' : parseFloat(a) || 0
|
||||
return a === '' ? '' : +a || 0
|
||||
},
|
||||
string: function(a) {
|
||||
return a === null || a === void 0 ? '' : a + ''
|
||||
},
|
||||
boolean: function(a) {
|
||||
if (a === '') return a
|
||||
if (a === '') {
|
||||
return a
|
||||
}
|
||||
return a === 'true' || a === '1'
|
||||
}
|
||||
},
|
||||
_decode: function _decode(str) {
|
||||
if (rentities.test(str)) {
|
||||
temp.innerHTML = str
|
||||
return temp.innerText || temp.textContent
|
||||
}
|
||||
return str
|
||||
}
|
||||
})
|
||||
|
||||
//============== config ============
|
||||
export function config(settings) {
|
||||
for (var p in settings) {
|
||||
var val = settings[p]
|
||||
if (typeof config.plugins[p] === 'function') {
|
||||
config.plugins[p](val)
|
||||
} else {
|
||||
config[p] = val
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
var plugins = {
|
||||
interpolate: function(array) {
|
||||
var openTag = array[0]
|
||||
var closeTag = array[1]
|
||||
if (openTag === closeTag) {
|
||||
throw new SyntaxError('interpolate openTag cannot equal to closeTag')
|
||||
}
|
||||
var str = openTag + 'test' + closeTag
|
||||
|
||||
if (/[<>]/.test(str)) {
|
||||
throw new SyntaxError('interpolate cannot contains "<" or ">"')
|
||||
}
|
||||
|
||||
config.openTag = openTag
|
||||
config.closeTag = closeTag
|
||||
var o = escapeRegExp(openTag)
|
||||
var c = escapeRegExp(closeTag)
|
||||
|
||||
config.rtext = new RegExp(o + '(.+?)' + c, 'g')
|
||||
config.rexpr = new RegExp(o + '([\\s\\S]*)' + c)
|
||||
}
|
||||
}
|
||||
export function createAnchor(nodeValue) {
|
||||
return document.createComment(nodeValue)
|
||||
}
|
||||
config.plugins = plugins
|
||||
config({
|
||||
interpolate: ['{{', '}}'],
|
||||
debug: true
|
||||
})
|
||||
//============ config ============
|
||||
|
||||
shadowCopy(Anot, {
|
||||
shadowCopy,
|
||||
|
||||
oneObject,
|
||||
inspect,
|
||||
ohasOwn,
|
||||
rword,
|
||||
version: 1,
|
||||
vmodels: {},
|
||||
|
||||
directives,
|
||||
|
@ -258,23 +197,12 @@ shadowCopy(Anot, {
|
|||
validators,
|
||||
cssHooks,
|
||||
|
||||
log,
|
||||
noop,
|
||||
warn,
|
||||
error,
|
||||
config,
|
||||
|
||||
root,
|
||||
document,
|
||||
window,
|
||||
|
||||
isObject,
|
||||
range,
|
||||
slice,
|
||||
hyphen,
|
||||
camelize,
|
||||
escapeRegExp,
|
||||
quote,
|
||||
|
||||
makeHashCode
|
||||
})
|
||||
|
|
|
@ -4,7 +4,7 @@ export var directives = {}
|
|||
|
||||
export function directive(name, opts) {
|
||||
if (directives[name]) {
|
||||
Anot.warn(name, 'directive have defined! ')
|
||||
console.warn(name, 'directive have defined! ')
|
||||
}
|
||||
directives[name] = opts
|
||||
if (!opts.update) {
|
||||
|
|
|
@ -24,8 +24,6 @@ Anot.type = function(obj) {
|
|||
: typeof obj
|
||||
}
|
||||
|
||||
Anot._quote = JSON.stringify
|
||||
|
||||
Anot.isFunction = function(fn) {
|
||||
return typeof fn === 'function'
|
||||
}
|
||||
|
@ -112,8 +110,9 @@ Anot.mix = Anot.fn.mix = function() {
|
|||
export function isArrayLike(obj) {
|
||||
/* istanbul ignore if*/
|
||||
if (obj && typeof obj === 'object') {
|
||||
var n = obj.length,
|
||||
str = inspect.call(obj)
|
||||
var n = obj.length
|
||||
var str = inspect.call(obj)
|
||||
|
||||
if (rarraylike.test(str)) {
|
||||
return true
|
||||
} else if (str === '[object Object]' && n === n >>> 0) {
|
||||
|
@ -129,7 +128,9 @@ Anot.each = function(obj, fn) {
|
|||
var i = 0
|
||||
if (isArrayLike(obj)) {
|
||||
for (var n = obj.length; i < n; i++) {
|
||||
if (fn(i, obj[i]) === false) break
|
||||
if (fn(i, obj[i]) === false) {
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i in obj) {
|
||||
|
|
|
@ -58,7 +58,7 @@ VElement.prototype = {
|
|||
for (var i in props) {
|
||||
var val = props[i]
|
||||
if (skipFalseAndFunction(val)) {
|
||||
arr.push(i + '=' + Anot.quote(props[i] + ''))
|
||||
arr.push(i + '=' + JSON.stringify(props[i] + ''))
|
||||
}
|
||||
}
|
||||
arr = arr.length ? ' ' + arr.join(' ') : ''
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Anot } from '../seed/core'
|
||||
import { Anot, _decode } from '../seed/core'
|
||||
|
||||
export function VText(text) {
|
||||
this.nodeName = '#text'
|
||||
|
@ -10,7 +10,7 @@ VText.prototype = {
|
|||
toDOM() {
|
||||
/* istanbul ignore if*/
|
||||
if (this.dom) return this.dom
|
||||
var v = Anot._decode(this.nodeValue)
|
||||
var v = _decode(this.nodeValue)
|
||||
return (this.dom = document.createTextNode(v))
|
||||
},
|
||||
toHTML() {
|
||||
|
|
|
@ -43,7 +43,7 @@ Action.prototype = {
|
|||
try {
|
||||
return this.getter.call(scope, scope)
|
||||
} catch (e) {
|
||||
Anot.log(this.getter + ' exec error')
|
||||
console.log(this.getter + ' exec error')
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -79,9 +79,9 @@ export var Computed = (function(_super) {
|
|||
}
|
||||
return true
|
||||
}
|
||||
cp.set = function() {
|
||||
cp.set = function(...args) {
|
||||
if (this.setter) {
|
||||
Anot.transaction(this.setter, this.vm, arguments)
|
||||
Anot.transaction(this.setter, this.vm, args)
|
||||
}
|
||||
}
|
||||
cp.get = function() {
|
||||
|
|
|
@ -55,7 +55,7 @@ Mutation.prototype = {
|
|||
},
|
||||
|
||||
collect() {
|
||||
Anot.track(name, '被收集')
|
||||
// Anot.track(name, '被收集')
|
||||
reportObserved(this)
|
||||
},
|
||||
|
||||
|
|
|
@ -4,158 +4,151 @@ import { Mutation } from './Mutation'
|
|||
import { Computed } from './Computed'
|
||||
import { IProxy, canHijack, createProxy } from './share'
|
||||
|
||||
if (typeof Proxy === 'function') {
|
||||
Anot.config.inProxyMode = true
|
||||
platform.modelFactory = function modelFactory(definition, dd) {
|
||||
var clone = {}
|
||||
for (let i in definition) {
|
||||
clone[i] = definition[i]
|
||||
delete definition[i]
|
||||
}
|
||||
|
||||
platform.modelFactory = function modelFactory(definition, dd) {
|
||||
var clone = {}
|
||||
for (let i in definition) {
|
||||
clone[i] = definition[i]
|
||||
delete definition[i]
|
||||
}
|
||||
definition.$id = clone.$id
|
||||
var proxy = new IProxy(definition, dd)
|
||||
|
||||
definition.$id = clone.$id
|
||||
var proxy = new IProxy(definition, dd)
|
||||
|
||||
var vm = toProxy(proxy)
|
||||
//先添加普通属性与监控属性
|
||||
for (let i in clone) {
|
||||
vm[i] = clone[i]
|
||||
}
|
||||
var $computed = clone.$computed
|
||||
//再添加计算属性
|
||||
if ($computed) {
|
||||
delete clone.$computed
|
||||
for (let i in $computed) {
|
||||
let val = $computed[i]
|
||||
if (typeof val === 'function') {
|
||||
let _val = val
|
||||
val = { get: _val }
|
||||
}
|
||||
if (val && val.get) {
|
||||
val.getter = val.get
|
||||
//在set方法中的target是IProxy,需要重写成Proxy,才能依赖收集
|
||||
val.vm = vm
|
||||
if (val.set) val.setter = val.set
|
||||
$computed[i] = val
|
||||
delete clone[i] //去掉重名的监控属性
|
||||
} else {
|
||||
delete $computed[i]
|
||||
}
|
||||
var vm = toProxy(proxy)
|
||||
//先添加普通属性与监控属性
|
||||
for (let i in clone) {
|
||||
vm[i] = clone[i]
|
||||
}
|
||||
var $computed = clone.$computed
|
||||
//再添加计算属性
|
||||
if ($computed) {
|
||||
delete clone.$computed
|
||||
for (let i in $computed) {
|
||||
let val = $computed[i]
|
||||
if (typeof val === 'function') {
|
||||
let _val = val
|
||||
val = { get: _val }
|
||||
}
|
||||
for (let i in $computed) {
|
||||
vm[i] = $computed[i]
|
||||
if (val && val.get) {
|
||||
val.getter = val.get
|
||||
//在set方法中的target是IProxy,需要重写成Proxy,才能依赖收集
|
||||
val.vm = vm
|
||||
if (val.set) val.setter = val.set
|
||||
$computed[i] = val
|
||||
delete clone[i] //去掉重名的监控属性
|
||||
} else {
|
||||
delete $computed[i]
|
||||
}
|
||||
}
|
||||
|
||||
return vm
|
||||
}
|
||||
|
||||
//https://developer.mozilla.org/en-US/docs/Archive/Web/Old_Proxy_API
|
||||
function toProxy(definition) {
|
||||
return Proxy.create
|
||||
? Proxy.create(definition, traps)
|
||||
: new Proxy(definition, traps)
|
||||
}
|
||||
|
||||
function wrapIt(str) {
|
||||
return '☥' + str + '☥'
|
||||
}
|
||||
var traps = {
|
||||
deleteProperty(target, name) {
|
||||
if (target.hasOwnProperty(name)) {
|
||||
//移除一个属性,分三昌:
|
||||
//1. 移除监听器
|
||||
//2. 移除真实对象的对应属性
|
||||
//3. 移除$track中的键名
|
||||
delete target.$accessors[name]
|
||||
delete target[name]
|
||||
target.$track = wrapIt(target.$track)
|
||||
.replace(wrapIt(name), '')
|
||||
.slice(1, -1)
|
||||
}
|
||||
return true
|
||||
},
|
||||
get(target, name) {
|
||||
if (name === '$model') {
|
||||
return platform.toJson(target)
|
||||
}
|
||||
//收集依赖
|
||||
var m = target.$accessors[name]
|
||||
if (m && m.get) {
|
||||
return m.get()
|
||||
}
|
||||
|
||||
return target[name]
|
||||
},
|
||||
set(target, name, value) {
|
||||
if (name === '$model' || name === '$track') {
|
||||
return true
|
||||
}
|
||||
if (name in $$skipArray) {
|
||||
target[name] = value
|
||||
return true
|
||||
}
|
||||
|
||||
var ac = target.$accessors
|
||||
var oldValue = ac[name] ? ac[name].value : target[name]
|
||||
|
||||
if (oldValue !== value) {
|
||||
if (!target.hasOwnProperty(name)) {
|
||||
updateTrack(target, name)
|
||||
}
|
||||
if (canHijack(name, value, target.$proxyItemBackdoor)) {
|
||||
var $computed = target.$computed || {}
|
||||
//如果是新属性
|
||||
if (!ac[name]) {
|
||||
target[name] = value //必须设置,用于hasOwnProperty
|
||||
var isComputed = !!$computed[name]
|
||||
var Observable = isComputed ? Computed : Mutation
|
||||
ac[name] = new Observable(name, value, target)
|
||||
return true
|
||||
}
|
||||
var mutation = ac[name]
|
||||
//创建子对象
|
||||
mutation.set(value)
|
||||
target[name] = mutation.value
|
||||
} else {
|
||||
target[name] = value
|
||||
}
|
||||
}
|
||||
// set方法必须返回true, 告诉Proxy已经成功修改了这个值,否则会抛
|
||||
//'set' on proxy: trap returned falsish for property xxx 错误
|
||||
return true
|
||||
for (let i in $computed) {
|
||||
vm[i] = $computed[i]
|
||||
}
|
||||
//has 只能用于 in 操作符,没什么用删去
|
||||
}
|
||||
|
||||
function updateTrack(target, name) {
|
||||
var arr = target.$track.match(/[^☥]+/g) || []
|
||||
arr.push(name)
|
||||
target.$track = arr.sort().join('☥')
|
||||
}
|
||||
|
||||
Anot.itemFactory = platform.itemFactory = function itemFactory(
|
||||
before,
|
||||
after
|
||||
) {
|
||||
var definition = before.$model
|
||||
definition.$proxyItemBackdoor = true
|
||||
definition.$id =
|
||||
before.$hashcode + String(after.hashcode || Math.random()).slice(6)
|
||||
definition.$accessors = Anot.mix({}, before.$accessors)
|
||||
var vm = platform.modelFactory(definition)
|
||||
vm.$track = before.$track
|
||||
for (var i in after.data) {
|
||||
vm[i] = after.data[i]
|
||||
}
|
||||
return vm
|
||||
}
|
||||
|
||||
platform.fuseFactory = function fuseFactory(before, after) {
|
||||
var definition = Anot.mix(before.$model, after.$model)
|
||||
definition.$id = before.$hashcode + after.$hashcode
|
||||
definition.$accessors = Anot.mix({}, before.$accessors, after.$accessors)
|
||||
return platform.modelFactory(definition)
|
||||
}
|
||||
return vm
|
||||
}
|
||||
|
||||
//https://developer.mozilla.org/en-US/docs/Archive/Web/Old_Proxy_API
|
||||
function toProxy(definition) {
|
||||
return Proxy.create
|
||||
? Proxy.create(definition, traps)
|
||||
: new Proxy(definition, traps)
|
||||
}
|
||||
|
||||
function wrapIt(str) {
|
||||
return '☥' + str + '☥'
|
||||
}
|
||||
var traps = {
|
||||
deleteProperty(target, name) {
|
||||
if (target.hasOwnProperty(name)) {
|
||||
//移除一个属性,分三昌:
|
||||
//1. 移除监听器
|
||||
//2. 移除真实对象的对应属性
|
||||
//3. 移除$track中的键名
|
||||
delete target.$accessors[name]
|
||||
delete target[name]
|
||||
target.$track = wrapIt(target.$track)
|
||||
.replace(wrapIt(name), '')
|
||||
.slice(1, -1)
|
||||
}
|
||||
return true
|
||||
},
|
||||
get(target, name) {
|
||||
if (name === '$model') {
|
||||
return platform.toJson(target)
|
||||
}
|
||||
//收集依赖
|
||||
var m = target.$accessors[name]
|
||||
if (m && m.get) {
|
||||
return m.get()
|
||||
}
|
||||
|
||||
return target[name]
|
||||
},
|
||||
set(target, name, value) {
|
||||
if (name === '$model' || name === '$track') {
|
||||
return true
|
||||
}
|
||||
if (name in $$skipArray) {
|
||||
target[name] = value
|
||||
return true
|
||||
}
|
||||
|
||||
var ac = target.$accessors
|
||||
var oldValue = ac[name] ? ac[name].value : target[name]
|
||||
|
||||
if (oldValue !== value) {
|
||||
if (!target.hasOwnProperty(name)) {
|
||||
updateTrack(target, name)
|
||||
}
|
||||
if (canHijack(name, value, target.$proxyItemBackdoor)) {
|
||||
var $computed = target.$computed || {}
|
||||
//如果是新属性
|
||||
if (!ac[name]) {
|
||||
target[name] = value //必须设置,用于hasOwnProperty
|
||||
var isComputed = !!$computed[name]
|
||||
var Observable = isComputed ? Computed : Mutation
|
||||
ac[name] = new Observable(name, value, target)
|
||||
return true
|
||||
}
|
||||
var mutation = ac[name]
|
||||
//创建子对象
|
||||
mutation.set(value)
|
||||
target[name] = mutation.value
|
||||
} else {
|
||||
target[name] = value
|
||||
}
|
||||
}
|
||||
// set方法必须返回true, 告诉Proxy已经成功修改了这个值,否则会抛
|
||||
//'set' on proxy: trap returned falsish for property xxx 错误
|
||||
return true
|
||||
}
|
||||
//has 只能用于 in 操作符,没什么用删去
|
||||
}
|
||||
|
||||
function updateTrack(target, name) {
|
||||
var arr = target.$track.match(/[^☥]+/g) || []
|
||||
arr.push(name)
|
||||
target.$track = arr.sort().join('☥')
|
||||
}
|
||||
|
||||
Anot.itemFactory = platform.itemFactory = function itemFactory(before, after) {
|
||||
var definition = before.$model
|
||||
definition.$proxyItemBackdoor = true
|
||||
definition.$id =
|
||||
before.$hashcode + String(after.hashcode || Math.random()).slice(6)
|
||||
definition.$accessors = Anot.mix({}, before.$accessors)
|
||||
var vm = platform.modelFactory(definition)
|
||||
vm.$track = before.$track
|
||||
for (var i in after.data) {
|
||||
vm[i] = after.data[i]
|
||||
}
|
||||
return vm
|
||||
}
|
||||
|
||||
platform.fuseFactory = function fuseFactory(before, after) {
|
||||
var definition = Anot.mix(before.$model, after.$model)
|
||||
definition.$id = before.$hashcode + after.$hashcode
|
||||
definition.$accessors = Anot.mix({}, before.$accessors, after.$accessors)
|
||||
return platform.modelFactory(definition)
|
||||
}
|
||||
|
|
|
@ -18,17 +18,17 @@ import { Computed } from './Computed'
|
|||
Anot.define = function(definition) {
|
||||
var $id = definition.$id
|
||||
if (!$id) {
|
||||
Anot.error('vm.$id must be specified')
|
||||
console.error('vm.$id must be specified')
|
||||
}
|
||||
if (Anot.vmodels[$id]) {
|
||||
Anot.warn('error:[' + $id + '] had defined!')
|
||||
console.warn('error:[' + $id + '] had defined!')
|
||||
}
|
||||
var vm = platform.modelFactory(definition)
|
||||
return (Anot.vmodels[$id] = vm)
|
||||
}
|
||||
|
||||
/**
|
||||
* 在未来的版本,Anot改用Proxy来创建VM,因此
|
||||
* Anot改用Proxy来创建VM,因此
|
||||
*/
|
||||
|
||||
export function IProxy(definition, dd) {
|
||||
|
@ -39,16 +39,12 @@ export function IProxy(definition, dd) {
|
|||
this.$events = {
|
||||
__dep__: dd || new Mutation(this.$id)
|
||||
}
|
||||
if (Anot.config.inProxyMode) {
|
||||
delete this.$mutations
|
||||
this.$accessors = {}
|
||||
this.$computed = {}
|
||||
this.$track = ''
|
||||
} else {
|
||||
this.$accessors = {
|
||||
$model: modelAccessor
|
||||
}
|
||||
}
|
||||
|
||||
delete this.$mutations
|
||||
this.$accessors = {}
|
||||
this.$computed = {}
|
||||
this.$track = ''
|
||||
|
||||
if (dd === void 0) {
|
||||
this.$watch = platform.watchFactory(this.$events)
|
||||
this.$fire = platform.fireFactory(this.$events)
|
||||
|
@ -106,14 +102,14 @@ export function canHijack(key, val, $proxyItemBackdoor) {
|
|||
if ($proxyItemBackdoor) {
|
||||
if (!$proxyItemBackdoorMap[key]) {
|
||||
$proxyItemBackdoorMap[key] = 1
|
||||
Anot.warn(`ms-for中的变量${key}不再建议以$为前缀`)
|
||||
console.warn(`ms-for中的变量${key}不再建议以$为前缀`)
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
if (val == null) {
|
||||
Anot.warn('定义vmodel时' + key + '的属性值不能为null undefine')
|
||||
console.warn('定义vmodel时' + key + '的属性值不能为null undefine')
|
||||
return true
|
||||
}
|
||||
if (/error|date|function|regexp/.test(Anot.type(val))) {
|
||||
|
@ -140,7 +136,7 @@ platform.createProxy = createProxy
|
|||
platform.itemFactory = function itemFactory(before, after) {
|
||||
var keyMap = before.$model
|
||||
var core = new IProxy(keyMap)
|
||||
var state = Anot.shadowCopy(core.$accessors, before.$accessors) //防止互相污染
|
||||
var state = Object.assign(core.$accessors, before.$accessors) //防止互相污染
|
||||
var data = after.data
|
||||
//core是包含系统属性的对象
|
||||
//keyMap是不包含系统属性的对象, keys
|
||||
|
|
|
@ -1,14 +1,8 @@
|
|||
import { Anot, config } from '../seed/core'
|
||||
import { Anot } from '../seed/core'
|
||||
|
||||
Anot.pendingActions = []
|
||||
Anot.uniqActions = {}
|
||||
Anot.inTransaction = 0
|
||||
config.trackDeps = false
|
||||
Anot.track = function() {
|
||||
if (config.trackDeps) {
|
||||
Anot.log.apply(Anot, arguments)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch is a pseudotransaction, just for purposes of memoizing ComputedValues when nothing else does.
|
||||
|
@ -38,7 +32,7 @@ export function propagateChanged(target) {
|
|||
export function reportObserved(target) {
|
||||
var action = Anot.trackingAction || null
|
||||
if (action !== null) {
|
||||
Anot.track('征收到', target.expr)
|
||||
// Anot.track('征收到', target.expr)
|
||||
action.mapIDs[target.uuid] = target
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +46,7 @@ export function collectDeps(action, getter) {
|
|||
targetStack.push(preAction)
|
||||
}
|
||||
Anot.trackingAction = action
|
||||
Anot.track('【action】', action.type, action.expr, '开始征收依赖项')
|
||||
// Anot.track('【action】', action.type, action.expr, '开始征收依赖项')
|
||||
//多个observe持有同一个action
|
||||
action.mapIDs = {} //重新收集依赖
|
||||
var hasError = true,
|
||||
|
@ -62,7 +56,7 @@ export function collectDeps(action, getter) {
|
|||
hasError = false
|
||||
} finally {
|
||||
if (hasError) {
|
||||
Anot.warn('collectDeps fail', getter + '')
|
||||
console.warn('collectDeps fail', getter + '')
|
||||
action.mapIDs = {}
|
||||
Anot.trackingAction = preAction
|
||||
} else {
|
||||
|
@ -71,7 +65,7 @@ export function collectDeps(action, getter) {
|
|||
try {
|
||||
resetDeps(action)
|
||||
} catch (e) {
|
||||
Anot.warn(e)
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
|
|
@ -7,13 +7,13 @@ export function validateDOMNesting(parent, child) {
|
|||
if (parentChild) {
|
||||
if (parentTag === 'p') {
|
||||
if (pNestChild[tag]) {
|
||||
Anot.warn(
|
||||
console.warn(
|
||||
'P element can not add these childlren:\n' + Object.keys(pNestChild)
|
||||
)
|
||||
return false
|
||||
}
|
||||
} else if (!parentChild[tag]) {
|
||||
Anot.warn(
|
||||
console.warn(
|
||||
parentTag.toUpperCase() +
|
||||
'element only add these children:\n' +
|
||||
Object.keys(parentChild) +
|
||||
|
|
Reference in New Issue