This repository has been archived on 2023-08-30. You can view files and clone it, but cannot push or open issues/pull-requests.
bytedo
/
anot
Archived
1
0
Fork 0

一大波更新

master
宇天 2020-08-14 18:46:34 +08:00
parent eb3d4f82fc
commit 8b21f0a800
36 changed files with 386 additions and 631 deletions

View File

@ -2,10 +2,9 @@
//http://www.cnblogs.com/rubylouvre/archive/2012/12/17/2818540.html //http://www.cnblogs.com/rubylouvre/archive/2012/12/17/2818540.html
import { Anot, directives, getLongID as markID } from '../seed/core' import { Anot, directives, getLongID as markID } from '../seed/core'
function classNames() { function classNames(...args) {
var classes = [] var classes = []
for (var i = 0; i < arguments.length; i++) { for (let arg of args) {
var arg = arguments[i]
var argType = typeof arg var argType = typeof arg
if (argType === 'string' || argType === 'number' || arg === true) { if (argType === 'string' || argType === 'number' || arg === true) {
classes.push(arg) classes.push(arg)

View File

@ -8,11 +8,11 @@ var cssDir = Anot.directive('css', {
//转换成对象 //转换成对象
var b = {} var b = {}
newVal.forEach(function(el) { newVal.forEach(function(el) {
el && Anot.shadowCopy(b, el) el && Object.assign(b, el)
}) })
newVal = b newVal = b
if (!arrayWarn[this.type]) { if (!arrayWarn[this.type]) {
Anot.warn('ms-' + this.type + '指令的值不建议使用数组形式了!') console.warn('ms-' + this.type + '指令的值不建议使用数组形式了!')
arrayWarn[this.type] = 1 arrayWarn[this.type] = 1
} }
} }

View File

@ -36,7 +36,7 @@ export var updateDataActions = {
var field = this var field = this
var array = field.value var array = field.value
if (!Array.isArray(array)) { if (!Array.isArray(array)) {
Anot.warn('ms-duplex应用于checkbox上要对应一个数组') console.warn('ms-duplex应用于checkbox上要对应一个数组')
array = [array] array = [array]
} }
var method = field.dom.checked ? 'ensure' : 'remove' var method = field.dom.checked ? 'ensure' : 'remove'

View File

@ -19,7 +19,7 @@ Anot.directive('for', {
str = str.replace(rforAs, function(a, b) { str = str.replace(rforAs, function(a, b) {
/* istanbul ignore if */ /* istanbul ignore if */
if (!rident.test(b) || rinvalid.test(b)) { if (!rident.test(b) || rinvalid.test(b)) {
Anot.error( console.error(
'alias ' + 'alias ' +
b + b +
' is invalid --- must be a valid JS identifier which is not a reserved name.' ' 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) { function resetVM(vm, a, b) {
if (Anot.config.inProxyMode) {
vm.$accessors[a].value = NaN vm.$accessors[a].value = NaN
} else {
vm.$accessors[a].set(NaN)
}
} }
function updateList(instance) { function updateList(instance) {

View File

@ -55,6 +55,6 @@ function continueScan(instance, vdom) {
instance.fragment, instance.fragment,
instance.vm instance.vm
)) ))
Anot.shadowCopy(vdom, innerRender.root) Object.assign(vdom, innerRender.root)
delete vdom.nodeValue delete vdom.nodeValue
} }

View File

@ -31,7 +31,7 @@ Anot.directive('on', {
'\tvar __vmodel__ = this;', '\tvar __vmodel__ = this;',
'\t' + filters, '\t' + filters,
'\treturn ' + body, '\treturn ' + body,
'}catch(e){Anot.log(e, "in on dir")}' '}catch(e){console.log(e, "in on dir")}'
].filter(function(el) { ].filter(function(el) {
return /\S/.test(el) return /\S/.test(el)
}) })

View File

@ -33,7 +33,7 @@ function isCorrectDate(value) {
return false return false
} }
//https://github.com/adform/validator.js/blob/master/validator.js //https://github.com/adform/validator.js/blob/master/validator.js
Anot.shadowCopy(Anot.validators, { Object.assign(Anot.validators, {
pattern: { pattern: {
message: '必须匹配{{pattern}}这样的格式', message: '必须匹配{{pattern}}这样的格式',
get: function(value, field, next) { get: function(value, field, next) {

View File

@ -5,7 +5,7 @@ Anot.directive('text', {
init: function() { init: function() {
var node = this.node var node = this.node
if (node.isVoidTag) { if (node.isVoidTag) {
Anot.error('自闭合元素不能使用ms-text') console.error('自闭合元素不能使用ms-text')
} }
var child = { nodeName: '#text', nodeValue: this.getValue() } var child = { nodeName: '#text', nodeValue: this.getValue() }
node.children.splice(0, node.children.length, child) node.children.splice(0, node.children.length, child)

View File

@ -44,7 +44,7 @@ var valiDir = Anot.directive('validate', {
var fn = (vmValidator.onManual = onManual.bind(vmValidator)) var fn = (vmValidator.onManual = onManual.bind(vmValidator))
validator.onManual = fn validator.onManual = fn
} catch (e) { } catch (e) {
Anot.warn( console.warn(
'要想使用onManual方法必须在validate对象预定义一个空的onManual函数' '要想使用onManual方法必须在validate对象预定义一个空的onManual函数'
) )
} }
@ -94,12 +94,7 @@ var valiDir = Anot.directive('validate', {
var value = field.value var value = field.value
var elem = field.dom var elem = field.dom
/* istanbul ignore if */ /* 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 */ /* istanbul ignore if */
if (elem.disabled) return if (elem.disabled) return
var rules = field.vdom.rules var rules = field.vdom.rules

View File

@ -13,7 +13,7 @@ import { Anot, rnowhite, rword } from '../../seed/core'
} }
}) })
Anot.shadowCopy(Anot.fn, { Object.assign(Anot.fn, {
hasClass: function(cls) { hasClass: function(cls) {
var el = this[0] || {} var el = this[0] || {}
//IE10+, chrome8+, firefox3.6+, safari5.1+,opera11.5+支持classList, //IE10+, chrome8+, firefox3.6+, safari5.1+,opera11.5+支持classList,

View File

@ -1,4 +1,4 @@
import { Anot, oneObject, cssHooks } from '../../seed/core' import { Anot, root, oneObject, cssHooks } from '../../seed/core'
var cssMap = oneObject('float', 'cssFloat') var cssMap = oneObject('float', 'cssFloat')
export { cssMap, cssHooks } export { cssMap, cssHooks }
@ -11,7 +11,7 @@ Anot.cssName = function(name, host, camelCase) {
if (cssMap[name]) { if (cssMap[name]) {
return cssMap[name] return cssMap[name]
} }
host = host || Anot.root.style || {} host = host || root.style || {}
for (var i = 0, n = prefixes.length; i < n; i++) { for (var i = 0, n = prefixes.length; i < n; i++) {
camelCase = Anot.camelize(prefixes[i] + name) camelCase = Anot.camelize(prefixes[i] + name)
if (camelCase in host) { if (camelCase in host) {
@ -103,7 +103,7 @@ Anot.fn.offsetParent = function() {
while (offsetParent && Anot.css(offsetParent, 'position') === 'static') { while (offsetParent && Anot.css(offsetParent, 'position') === 'static') {
offsetParent = offsetParent.offsetParent offsetParent = offsetParent.offsetParent
} }
return Anot(offsetParent || Anot.root) return Anot(offsetParent || root)
} }
/* istanbul ignore next */ /* istanbul ignore next */

View File

@ -18,7 +18,7 @@ Anot.fireDom = function(elem, type, opts) {
if (document.createEvent) { if (document.createEvent) {
var hackEvent = document.createEvent('Events') var hackEvent = document.createEvent('Events')
hackEvent.initEvent(type, true, true, opts) hackEvent.initEvent(type, true, true, opts)
Anot.shadowCopy(hackEvent, opts) Object.assign(hackEvent, opts)
elem.dispatchEvent(hackEvent) elem.dispatchEvent(hackEvent)
} }
} }

View File

@ -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' import { canBubbleUp } from './canBubbleUp'
/* istanbul ignore if */ /* istanbul ignore if */
var hackSafari = document.ontouchstart 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]) { if (this[0]) {
var args = _slice.call(arguments)
args.unshift(this[0])
Anot.unbind.apply(0, args) Anot.unbind.apply(0, args)
} }
return this return this

View File

@ -1,4 +1,4 @@
import { Anot, Cache } from '../seed/core' import { Anot, Cache, root } from '../seed/core'
import { cssDiff } from '../directives/css' import { cssDiff } from '../directives/css'
import { import {
css3, css3,
@ -16,7 +16,7 @@ var effectDir = Anot.directive('effect', {
this.value = effect = { this.value = effect = {
is: effect is: effect
} }
Anot.warn('ms-effect的指令值不再支持字符串,必须是一个对象') console.warn('ms-effect的指令值不再支持字符串,必须是一个对象')
} }
this.value = vdom.effect = effect this.value = vdom.effect = effect
var ok = cssDiff.call(this, effect, this.oldValue) var ok = cssDiff.call(this, effect, this.oldValue)
@ -42,13 +42,13 @@ var effectDir = Anot.directive('effect', {
var globalOption = Anot.effects[is] var globalOption = Anot.effects[is]
if (!globalOption) { if (!globalOption) {
//如果没有定义特效 //如果没有定义特效
Anot.warn(is + ' effect is undefined') console.warn(is + ' effect is undefined')
return return
} }
var finalOption = {} var finalOption = {}
var action = actionMaps[option.action] var action = actionMaps[option.action]
if (typeof Effect.prototype[action] !== 'function') { if (typeof Effect.prototype[action] !== 'function') {
Anot.warn('action is undefined') console.warn('action is undefined')
return return
} }
//必须预定义特效 //必须预定义特效
@ -202,7 +202,7 @@ function createAction(action) {
} }
setTimeout(function() { setTimeout(function() {
//用xxx-active代替xxx类名的方式 触发CSS3动画 //用xxx-active代替xxx类名的方式 触发CSS3动画
var time = Anot.root.offsetWidth === NaN var time = root.offsetWidth === NaN
elem.addClass(option[lower + 'ActiveClass']) elem.addClass(option[lower + 'ActiveClass'])
//计算动画时长 //计算动画时长
time = getAnimationTime(dom) time = getAnimationTime(dom)
@ -237,7 +237,7 @@ Anot.applyEffect = function(dom, vdom, opts) {
} }
} }
getAction(opts) getAction(opts)
Anot.directives.effect.update(vdom, curEffect, Anot.shadowCopy({}, opts)) Anot.directives.effect.update(vdom, curEffect, Object.assign({}, opts))
} else if (cb) { } else if (cb) {
cb(dom) cb(dom)
} }

View File

@ -1,4 +1,4 @@
import { Anot } from '../seed/core' import { Anot, escapeRegExp } from '../seed/core'
import { $$skipArray } from '../vmodel/reserved' 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) var type = Anot.type(array)
if (type !== 'array' && type !== 'object') throw 'filterBy只能处理对象或数组' if (type !== 'array' && type !== 'object') {
var args = Anot.slice(arguments, 2) throw 'filterBy只能处理对象或数组'
}
var stype = Anot.type(search) var stype = Anot.type(search)
if (stype === 'function') { if (stype === 'function') {
var criteria = search._orig || search var criteria = search._orig || search
@ -75,7 +76,7 @@ export function filterBy(array, search) {
if (search === '') { if (search === '') {
return array return array
} else { } else {
var reg = new RegExp(Anot.escapeRegExp(search), 'i') var reg = new RegExp(escapeRegExp(search), 'i')
criteria = function(el) { criteria = function(el) {
return reg.test(el) return reg.test(el)
} }

View File

@ -1,218 +1,100 @@
function toInt(str) { if (!Date.prototype.getFullWeek) {
return parseInt(str, 10) || 0 //获取当天是本年度第几周
} Object.defineProperty(Date.prototype, 'getFullWeek', {
value: function() {
function padNumber(num, digits, trim) { let thisYear = this.getFullYear()
var neg = '' let that = new Date(thisYear, 0, 1)
/* istanbul ignore if*/ let firstDay = that.getDay() || 1
if (num < 0) { let numsOfToday = (this - that) / 86400000
neg = '-' return Math.ceil((numsOfToday + firstDay) / 7)
num = -num },
} enumerable: false
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 Object.defineProperty(Date.prototype, 'getWeek', {
dateSetter.apply(oDate, dateArray.slice(0, 3)) value: function() {
timeSetter.apply(oDate, dateArray.slice(3)) let today = this.getDate()
date = oDate let thisMonth = this.getMonth()
} let thisYear = this.getFullYear()
} let firstDay = new Date(thisYear, thisMonth, 1).getDay()
if (typeof date === 'number') { return Math.ceil((today + firstDay) / 7)
date = new Date(date) },
} enumerable: false
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, "'")
}) })
return text
} }
var locate = { if (!Date.isDate) {
AMPMS: { Object.defineProperty(Date, 'isDate', {
0: '上午', value: function(obj) {
1: '下午' return typeof obj === 'object' && obj.getTime ? true : false
}, },
DAY: { enumerable: false
0: '星期日', })
1: '星期一', }
2: '星期二',
3: '星期三', //时间格式化
4: '星期四', if (!Date.prototype.format) {
5: '星期五', Object.defineProperty(Date.prototype, 'format', {
6: '星期六' value: function(str) {
}, str = str || 'Y-m-d H:i:s'
MONTH: { var week = ['一', '二', '三', '四', '五', '六', '日']
0: '1月', var dt = {
1: '2月', fullyear: this.getFullYear(),
2: '3月', year: this.getYear(),
3: '4月', fullweek: this.getFullWeek(),
4: '5月', week: this.getWeek(),
5: '6月', month: this.getMonth() + 1,
6: '7月', date: this.getDate(),
7: '8月', day: week[this.getDay()],
8: '9月', hours: this.getHours(),
9: '10月', minutes: this.getMinutes(),
10: '11月', seconds: this.getSeconds()
11: '12月' }
}, var re
SHORTDAY: {
'0': '周日', dt.g = dt.hours > 12 ? dt.hours - 12 : dt.hours
'1': '周一',
'2': '周二', re = {
'3': '周三', Y: dt.fullyear,
'4': '周四', y: dt.year,
'5': '周五', m: dt.month < 10 ? '0' + dt.month : dt.month,
'6': '周六' n: dt.month,
}, d: dt.date < 10 ? '0' + dt.date : dt.date,
fullDate: 'y年M月d日EEEE', j: dt.date,
longDate: 'y年M月d日', H: dt.hours < 10 ? '0' + dt.hours : dt.hours,
medium: 'yyyy-M-d H:mm:ss', h: dt.g < 10 ? '0' + dt.g : dt.g,
mediumDate: 'yyyy-M-d', G: dt.hours,
mediumTime: 'H:mm:ss', g: dt.g,
short: 'yy-M-d ah:mm', i: dt.minutes < 10 ? '0' + dt.minutes : dt.minutes,
shortDate: 'yy-M-d', s: dt.seconds < 10 ? '0' + dt.seconds : dt.seconds,
shortTime: 'ah:mm' 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

View File

@ -19,15 +19,13 @@ var keys = {
right: 39, right: 39,
down: 40 down: 40
} }
for (var name in keys) { for (let name in keys) {
;(function(filter, key) { eventFilters[name] = function(e) {
eventFilters[filter] = function(e) { if (e.which !== keys[name]) {
if (e.which !== key) {
e.$return = true e.$return = true
} }
return e return e
} }
})(name, keys[name])
} }
export { eventFilters } export { eventFilters }

View File

@ -1,17 +1,16 @@
import { Anot } from '../seed/core' import { Anot } from '../seed/core'
import { numberFilter } from './number' import { numberFilter } from './number'
import { sanitizeFilter } from './sanitize' import { xss } from './xss'
import { dateFilter } from './date' import { dateFilter } from './date'
import { filterBy, orderBy, selectBy, limitBy } from './array' import { filterBy, orderBy, selectBy, limitBy } from './array'
import { eventFilters } from './event' // import { eventFilters } from './event'
import { escapeFilter } from './escape' import { escapeFilter } from './escape'
var filters = (Anot.filters = {}) var filters = (Anot.filters = {})
Anot.composeFilters = function() { Anot.composeFilters = function(...args) {
var args = arguments
return function(value) { return function(value) {
for (var i = 0, arr; (arr = args[i++]); ) { for (let arr of args) {
var name = arr[0] var name = arr[0]
var filter = Anot.filters[name] var filter = Anot.filters[name]
if (typeof filter === 'function') { if (typeof filter === 'function') {
@ -36,37 +35,25 @@ Anot.mix(
lowercase(str) { lowercase(str) {
return String(str).toLowerCase() return String(str).toLowerCase()
}, },
truncate(str, length, end) { truncate(str, len, mark) {
//length新字符串长度truncation新字符串的结尾的字段,返回新字符串 len = len || 30
if (!str) { mark = typeof mark === 'string' ? mark : '...'
return '' return str.slice(0, len) + (str.length <= len ? '' : mark)
}
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
}, },
camelize: Anot.camelize, camelize: Anot.camelize,
date: dateFilter, date: dateFilter,
escape: escapeFilter, escape: escapeFilter,
sanitize: sanitizeFilter, xss,
number: numberFilter, number: numberFilter,
currency(amount, symbol, fractionSize) { currency(amount, symbol, fractionSize) {
return ( return (
(symbol || '\u00a5') + (symbol || '\u00a5') +
numberFilter( numberFilter(amount, isFinite(fractionSize) ? fractionSize : 2)
amount,
isFinite(fractionSize) ? /* istanbul ignore else*/ fractionSize : 2
)
) )
} }
}, },
{ filterBy, orderBy, selectBy, limitBy }, { filterBy, orderBy, selectBy, limitBy }
eventFilters // eventFilters
) )
export { Anot } export { Anot }

View File

@ -1,34 +1,18 @@
import { Anot } from '../seed/core' /**
function toFixedFix(n, prec) { * @number 必需要格式化的数字
var k = Math.pow(10, prec) * @decimals 可选规定多少个小数位
return '' + (Math.round(n * k) / k).toFixed(prec) * @thousands 可选规定用作千位分隔符的字符串默认为 , 如果设置了该参数那么所有其他参数都是必需的
} */
export function numberFilter(number, decimals, point, thousands) { export function numberFilter(number, decimals = 0, thousands = '') {
//https://github.com/txgruppi/number_format var num = +number || 0
//form http://phpjs.org/functions/number_format/ var d = !isFinite(+decimals) ? 3 : Math.abs(decimals)
//number 必需,要格式化的数字 var t = typeof thousands === 'string' ? thousands : ','
//decimals 可选,规定多少个小数位。 var tmp
//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 = ''
// Fix for IE parseFloat(0.55).toFixed(0) = 0; tmp = ((d ? num.toFixed(d) : Math.round(num)) + '').split('.')
s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.') if (tmp[0].length > 3) {
if (s[0].length > 3) { tmp[0] = tmp[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, t)
s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep)
} }
/** //好像没有用
var s1 = s[1] || ''
if (s1.length < prec) { return tmp.join('.')
s1 += new Array(prec - s[1].length + 1).join('0')
s[1] = s1
}
**/
return s.join(dec)
} }

View File

@ -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&#x09;ascript:alert('XSS');">IE67chrome</a> // <a href="jav&#x09;ascript:alert('XSS');">IE67chrome</a>
// <a href="jav&#x0A;ascript:alert('XSS');">IE67chrome</a> // <a href="jav&#x0A;ascript:alert('XSS');">IE67chrome</a>
export function sanitizeFilter(str) { export function xss(str) {
return str.replace(rscripts, '').replace(ropen, function(a, b) { return str.replace(rscripts, '').replace(ropen, function(a, b) {
var match = a.toLowerCase().match(/<(\w+)\s/) var match = a.toLowerCase().match(/<(\w+)\s/)
if (match) { if (match) {

View File

@ -1,5 +1,6 @@
import { root } from '../seed/core'
import { Recognizer } from './recognizer' import { Recognizer } from './recognizer'
var root = Anot.root
var supportPointer = !!navigator.pointerEnabled || !!navigator.msPointerEnabled var supportPointer = !!navigator.pointerEnabled || !!navigator.msPointerEnabled
// 支持pointer的设备可用样式来取消click事件的300毫秒延迟 // 支持pointer的设备可用样式来取消click事件的300毫秒延迟
if (supportPointer) { if (supportPointer) {

View File

@ -89,7 +89,7 @@ export function addScope(expr, type) {
} }
return '' return ''
}) })
var arg = '[' + Anot.quote(filter.trim()) + bracketArgs + ']' var arg = '[' + JSON.stringify(filter.trim()) + bracketArgs + ']'
return arg return arg
}) })
filters = 'Anot.composeFilters(' + filters + ')(__value__)' filters = 'Anot.composeFilters(' + filters + ')(__value__)'
@ -119,7 +119,7 @@ export function createGetter(expr, type) {
return new Function('__vmodel__', 'return ' + body + ';') return new Function('__vmodel__', 'return ' + body + ';')
/* istanbul ignore next */ /* istanbul ignore next */
} catch (e) { } catch (e) {
Anot.log('parse getter: [', expr, body, ']error') console.log('parse getter: [', expr, body, ']error')
return Anot.noop return Anot.noop
} }
} }
@ -131,12 +131,12 @@ export function createGetter(expr, type) {
export function createSetter(expr, type) { export function createSetter(expr, type) {
var arr = addScope(expr, type) var arr = addScope(expr, type)
var body = 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 { try {
return new Function('__vmodel__', '__value__', body + ';') return new Function('__vmodel__', '__value__', body + ';')
/* istanbul ignore next */ /* istanbul ignore next */
} catch (e) { } catch (e) {
Anot.log('parse setter: ', expr, ' error') console.log('parse setter: ', expr, ' error')
return Anot.noop return Anot.noop
} }
} }

View File

@ -1,4 +1,4 @@
import { Anot, config } from '../seed/core' import { Anot, config, _decode } from '../seed/core'
import { addScope } from './index' import { addScope } from './index'
var rimprovePriority = /[+-\?]/ var rimprovePriority = /[+-\?]/
var rinnerValue = /__value__\)$/ var rinnerValue = /__value__\)$/
@ -12,7 +12,7 @@ export function parseInterpolate(dir) {
index = index === -1 ? str.length : index index = index === -1 ? str.length : index
var value = str.slice(0, index) var value = str.slice(0, index)
if (/\S/.test(value)) { if (/\S/.test(value)) {
tokens.push(Anot.quote(Anot._decode(value))) tokens.push(JSON.stringify(_decode(value)))
} }
str = str.slice(index + config.openTag.length) str = str.slice(index + config.openTag.length)
if (str) { if (str) {

View File

@ -50,7 +50,9 @@ Render.prototype = {
} else if (typeof this.root === 'string') { } else if (typeof this.root === 'string') {
vnodes = fromString(this.root) //转换虚拟DOM vnodes = fromString(this.root) //转换虚拟DOM
} else { } 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] this.root = vnodes[0]
@ -136,7 +138,7 @@ Render.prototype = {
var type = attr.match(/\w+/g)[1] var type = attr.match(/\w+/g)[1]
type = eventMap[type] || type type = eventMap[type] || type
if (!directives[type]) { if (!directives[type]) {
Anot.warn(attr + ' has not registered!') console.warn(attr + ' has not registered!')
} }
hasDir = true hasDir = true
} }
@ -155,7 +157,7 @@ Render.prototype = {
var templateCaches = Anot.serverTemplates var templateCaches = Anot.serverTemplates
var temp = templateCaches && templateCaches[$id] var temp = templateCaches && templateCaches[$id]
if (temp) { if (temp) {
Anot.log('前端再次渲染后端传过来的模板') console.log('前端再次渲染后端传过来的模板')
var node = fromString(temp)[0] var node = fromString(temp)[0]
for (var i in node) { for (var i in node) {
vdom[i] = node[i] vdom[i] = node[i]

View File

@ -13,12 +13,6 @@ Anot.init = function(el) {
Anot.fn = Anot.prototype = Anot.init.prototype 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 rword = /[^, ]+/g
export var rnowhite = /\S+/g //存在非空字符 export var rnowhite = /\S+/g //存在非空字符
export var platform = {} //用于放置平台差异的方法与属性 export var platform = {} //用于放置平台差异的方法与属性
@ -39,34 +33,16 @@ export function oneObject(array, val) {
} }
var op = Object.prototype var op = Object.prototype
export function quote(str) {
return Anot._quote(str)
}
export var inspect = op.toString export var inspect = op.toString
export var ohasOwn = op.hasOwnProperty export var ohasOwn = op.hasOwnProperty
export var ap = Array.prototype 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 { 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 noop() {}
export function isObject(a) { export function isObject(a) {
return a !== null && typeof a === 'object' return a && typeof a === 'object'
} }
export function range(start, end, step) { export function range(start, end, step) {
@ -104,18 +80,14 @@ export function camelize(target) {
}) })
} }
export var _slice = ap.slice export function makeHashCode(prefix = 'anot') {
export function slice(nodes, start, end) { return (
return _slice.call(nodes, start, end) prefix +
} crypto
.getRandomValues(new Uint8Array(8))
var rhashcode = /\d\.\d{4}/ .reduce((a, b) => a + b.toString(16), '')
//生成UUID http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript .slice(0, 12)
export function makeHashCode(prefix) { )
/* istanbul ignore next*/
prefix = prefix || 'Anot'
/* istanbul ignore next*/
return String(Math.random() + Math.random()).replace(rhashcode, prefix)
} }
//生成事件回调的UUID(用户通过ms-on指令) //生成事件回调的UUID(用户通过ms-on指令)
export function getLongID(fn) { export function getLongID(fn) {
@ -148,9 +120,32 @@ export function createFragment() {
return document.createDocumentFragment() 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 rentities = /&[a-z0-9#]{2,10};/
var temp = document.createElement('div') 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: { Array: {
merge: function(target, other) { merge: function(target, other) {
//合并两个数组 Anot2新增 //合并两个数组 Anot2新增
@ -176,78 +171,22 @@ shadowCopy(Anot, {
evaluatorPool: new Cache(888), evaluatorPool: new Cache(888),
parsers: { parsers: {
number: function(a) { number: function(a) {
return a === '' ? '' : parseFloat(a) || 0 return a === '' ? '' : +a || 0
}, },
string: function(a) { string: function(a) {
return a === null || a === void 0 ? '' : a + '' return a === null || a === void 0 ? '' : a + ''
}, },
boolean: function(a) { boolean: function(a) {
if (a === '') return a if (a === '') {
return a
}
return a === 'true' || a === '1' 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, oneObject,
inspect, inspect,
ohasOwn, ohasOwn,
rword,
version: 1,
vmodels: {}, vmodels: {},
directives, directives,
@ -258,23 +197,12 @@ shadowCopy(Anot, {
validators, validators,
cssHooks, cssHooks,
log,
noop, noop,
warn,
error,
config,
root,
document,
window,
isObject, isObject,
range, range,
slice,
hyphen, hyphen,
camelize, camelize,
escapeRegExp,
quote,
makeHashCode makeHashCode
}) })

View File

@ -4,7 +4,7 @@ export var directives = {}
export function directive(name, opts) { export function directive(name, opts) {
if (directives[name]) { if (directives[name]) {
Anot.warn(name, 'directive have defined! ') console.warn(name, 'directive have defined! ')
} }
directives[name] = opts directives[name] = opts
if (!opts.update) { if (!opts.update) {

View File

@ -24,8 +24,6 @@ Anot.type = function(obj) {
: typeof obj : typeof obj
} }
Anot._quote = JSON.stringify
Anot.isFunction = function(fn) { Anot.isFunction = function(fn) {
return typeof fn === 'function' return typeof fn === 'function'
} }
@ -112,8 +110,9 @@ Anot.mix = Anot.fn.mix = function() {
export function isArrayLike(obj) { export function isArrayLike(obj) {
/* istanbul ignore if*/ /* istanbul ignore if*/
if (obj && typeof obj === 'object') { if (obj && typeof obj === 'object') {
var n = obj.length, var n = obj.length
str = inspect.call(obj) var str = inspect.call(obj)
if (rarraylike.test(str)) { if (rarraylike.test(str)) {
return true return true
} else if (str === '[object Object]' && n === n >>> 0) { } else if (str === '[object Object]' && n === n >>> 0) {
@ -129,7 +128,9 @@ Anot.each = function(obj, fn) {
var i = 0 var i = 0
if (isArrayLike(obj)) { if (isArrayLike(obj)) {
for (var n = obj.length; i < n; i++) { for (var n = obj.length; i < n; i++) {
if (fn(i, obj[i]) === false) break if (fn(i, obj[i]) === false) {
break
}
} }
} else { } else {
for (i in obj) { for (i in obj) {

View File

@ -58,7 +58,7 @@ VElement.prototype = {
for (var i in props) { for (var i in props) {
var val = props[i] var val = props[i]
if (skipFalseAndFunction(val)) { if (skipFalseAndFunction(val)) {
arr.push(i + '=' + Anot.quote(props[i] + '')) arr.push(i + '=' + JSON.stringify(props[i] + ''))
} }
} }
arr = arr.length ? ' ' + arr.join(' ') : '' arr = arr.length ? ' ' + arr.join(' ') : ''

View File

@ -1,4 +1,4 @@
import { Anot } from '../seed/core' import { Anot, _decode } from '../seed/core'
export function VText(text) { export function VText(text) {
this.nodeName = '#text' this.nodeName = '#text'
@ -10,7 +10,7 @@ VText.prototype = {
toDOM() { toDOM() {
/* istanbul ignore if*/ /* istanbul ignore if*/
if (this.dom) return this.dom if (this.dom) return this.dom
var v = Anot._decode(this.nodeValue) var v = _decode(this.nodeValue)
return (this.dom = document.createTextNode(v)) return (this.dom = document.createTextNode(v))
}, },
toHTML() { toHTML() {

View File

@ -43,7 +43,7 @@ Action.prototype = {
try { try {
return this.getter.call(scope, scope) return this.getter.call(scope, scope)
} catch (e) { } catch (e) {
Anot.log(this.getter + ' exec error') console.log(this.getter + ' exec error')
} }
}, },

View File

@ -79,9 +79,9 @@ export var Computed = (function(_super) {
} }
return true return true
} }
cp.set = function() { cp.set = function(...args) {
if (this.setter) { if (this.setter) {
Anot.transaction(this.setter, this.vm, arguments) Anot.transaction(this.setter, this.vm, args)
} }
} }
cp.get = function() { cp.get = function() {

View File

@ -55,7 +55,7 @@ Mutation.prototype = {
}, },
collect() { collect() {
Anot.track(name, '被收集') // Anot.track(name, '被收集')
reportObserved(this) reportObserved(this)
}, },

View File

@ -4,9 +4,6 @@ import { Mutation } from './Mutation'
import { Computed } from './Computed' import { Computed } from './Computed'
import { IProxy, canHijack, createProxy } from './share' import { IProxy, canHijack, createProxy } from './share'
if (typeof Proxy === 'function') {
Anot.config.inProxyMode = true
platform.modelFactory = function modelFactory(definition, dd) { platform.modelFactory = function modelFactory(definition, dd) {
var clone = {} var clone = {}
for (let i in definition) { for (let i in definition) {
@ -135,10 +132,7 @@ if (typeof Proxy === 'function') {
target.$track = arr.sort().join('☥') target.$track = arr.sort().join('☥')
} }
Anot.itemFactory = platform.itemFactory = function itemFactory( Anot.itemFactory = platform.itemFactory = function itemFactory(before, after) {
before,
after
) {
var definition = before.$model var definition = before.$model
definition.$proxyItemBackdoor = true definition.$proxyItemBackdoor = true
definition.$id = definition.$id =
@ -158,4 +152,3 @@ if (typeof Proxy === 'function') {
definition.$accessors = Anot.mix({}, before.$accessors, after.$accessors) definition.$accessors = Anot.mix({}, before.$accessors, after.$accessors)
return platform.modelFactory(definition) return platform.modelFactory(definition)
} }
}

View File

@ -18,17 +18,17 @@ import { Computed } from './Computed'
Anot.define = function(definition) { Anot.define = function(definition) {
var $id = definition.$id var $id = definition.$id
if (!$id) { if (!$id) {
Anot.error('vm.$id must be specified') console.error('vm.$id must be specified')
} }
if (Anot.vmodels[$id]) { if (Anot.vmodels[$id]) {
Anot.warn('error:[' + $id + '] had defined!') console.warn('error:[' + $id + '] had defined!')
} }
var vm = platform.modelFactory(definition) var vm = platform.modelFactory(definition)
return (Anot.vmodels[$id] = vm) return (Anot.vmodels[$id] = vm)
} }
/** /**
* 在未来的版本,Anot改用Proxy来创建VM,因此 * Anot改用Proxy来创建VM,因此
*/ */
export function IProxy(definition, dd) { export function IProxy(definition, dd) {
@ -39,16 +39,12 @@ export function IProxy(definition, dd) {
this.$events = { this.$events = {
__dep__: dd || new Mutation(this.$id) __dep__: dd || new Mutation(this.$id)
} }
if (Anot.config.inProxyMode) {
delete this.$mutations delete this.$mutations
this.$accessors = {} this.$accessors = {}
this.$computed = {} this.$computed = {}
this.$track = '' this.$track = ''
} else {
this.$accessors = {
$model: modelAccessor
}
}
if (dd === void 0) { if (dd === void 0) {
this.$watch = platform.watchFactory(this.$events) this.$watch = platform.watchFactory(this.$events)
this.$fire = platform.fireFactory(this.$events) this.$fire = platform.fireFactory(this.$events)
@ -106,14 +102,14 @@ export function canHijack(key, val, $proxyItemBackdoor) {
if ($proxyItemBackdoor) { if ($proxyItemBackdoor) {
if (!$proxyItemBackdoorMap[key]) { if (!$proxyItemBackdoorMap[key]) {
$proxyItemBackdoorMap[key] = 1 $proxyItemBackdoorMap[key] = 1
Anot.warn(`ms-for中的变量${key}不再建议以$为前缀`) console.warn(`ms-for中的变量${key}不再建议以$为前缀`)
} }
return true return true
} }
return false return false
} }
if (val == null) { if (val == null) {
Anot.warn('定义vmodel时' + key + '的属性值不能为null undefine') console.warn('定义vmodel时' + key + '的属性值不能为null undefine')
return true return true
} }
if (/error|date|function|regexp/.test(Anot.type(val))) { if (/error|date|function|regexp/.test(Anot.type(val))) {
@ -140,7 +136,7 @@ platform.createProxy = createProxy
platform.itemFactory = function itemFactory(before, after) { platform.itemFactory = function itemFactory(before, after) {
var keyMap = before.$model var keyMap = before.$model
var core = new IProxy(keyMap) 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 var data = after.data
//core是包含系统属性的对象 //core是包含系统属性的对象
//keyMap是不包含系统属性的对象, keys //keyMap是不包含系统属性的对象, keys

View File

@ -1,14 +1,8 @@
import { Anot, config } from '../seed/core' import { Anot } from '../seed/core'
Anot.pendingActions = [] Anot.pendingActions = []
Anot.uniqActions = {} Anot.uniqActions = {}
Anot.inTransaction = 0 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. * 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) { export function reportObserved(target) {
var action = Anot.trackingAction || null var action = Anot.trackingAction || null
if (action !== null) { if (action !== null) {
Anot.track('征收到', target.expr) // Anot.track('征收到', target.expr)
action.mapIDs[target.uuid] = target action.mapIDs[target.uuid] = target
} }
} }
@ -52,7 +46,7 @@ export function collectDeps(action, getter) {
targetStack.push(preAction) targetStack.push(preAction)
} }
Anot.trackingAction = action Anot.trackingAction = action
Anot.track('【action】', action.type, action.expr, '开始征收依赖项') // Anot.track('【action】', action.type, action.expr, '开始征收依赖项')
//多个observe持有同一个action //多个observe持有同一个action
action.mapIDs = {} //重新收集依赖 action.mapIDs = {} //重新收集依赖
var hasError = true, var hasError = true,
@ -62,7 +56,7 @@ export function collectDeps(action, getter) {
hasError = false hasError = false
} finally { } finally {
if (hasError) { if (hasError) {
Anot.warn('collectDeps fail', getter + '') console.warn('collectDeps fail', getter + '')
action.mapIDs = {} action.mapIDs = {}
Anot.trackingAction = preAction Anot.trackingAction = preAction
} else { } else {
@ -71,7 +65,7 @@ export function collectDeps(action, getter) {
try { try {
resetDeps(action) resetDeps(action)
} catch (e) { } catch (e) {
Anot.warn(e) console.warn(e)
} }
} }
return result return result

View File

@ -7,13 +7,13 @@ export function validateDOMNesting(parent, child) {
if (parentChild) { if (parentChild) {
if (parentTag === 'p') { if (parentTag === 'p') {
if (pNestChild[tag]) { if (pNestChild[tag]) {
Anot.warn( console.warn(
'P element can not add these childlren:\n' + Object.keys(pNestChild) 'P element can not add these childlren:\n' + Object.keys(pNestChild)
) )
return false return false
} }
} else if (!parentChild[tag]) { } else if (!parentChild[tag]) {
Anot.warn( console.warn(
parentTag.toUpperCase() + parentTag.toUpperCase() +
'element only add these children:\n' + 'element only add these children:\n' +
Object.keys(parentChild) + Object.keys(parentChild) +