一大波更新
parent
ebbd93cd97
commit
23b83143fb
|
@ -1,10 +1,12 @@
|
|||
import Anot from '../seed/index'
|
||||
|
||||
//https://github.com/RubyLouvre/avalon/issues/1834
|
||||
Anot.directive('expr', {
|
||||
update: function(vdom, value) {
|
||||
value = value == null || value === '' ? '\u200b' : value
|
||||
vdom.nodeValue = value
|
||||
//https://github.com/RubyLouvre/Anot/issues/1834
|
||||
if (vdom.dom) vdom.dom.data = value
|
||||
if (vdom.dom) {
|
||||
vdom.dom.data = value
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
} from '../seed/core'
|
||||
|
||||
import { VFragment } from '../vdom/VFragment'
|
||||
import { $$skipArray } from '../vmodel/reserved'
|
||||
import { SYS_SKIP } from '../vmodel/reserved'
|
||||
|
||||
import { addScope, makeHandle } from '../parser/index'
|
||||
import { updateView } from './duplex/share'
|
||||
|
@ -145,7 +145,7 @@ function createFragments(instance, obj) {
|
|||
instance.fragments = fragments
|
||||
} else {
|
||||
Anot.each(obj, function(key, value) {
|
||||
if (!(key in $$skipArray)) {
|
||||
if (!(key in SYS_SKIP)) {
|
||||
var k = array ? getTraceKey(value) : key
|
||||
fragments.push(new VFragment([], k, value, i++))
|
||||
ids.push(k)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { Anot, escapeRegExp, isObject } from '../seed/core'
|
||||
import { $$skipArray } from '../vmodel/reserved'
|
||||
|
||||
export function orderBy(array, by, decend) {
|
||||
var type = Anot.type(array)
|
||||
|
|
|
@ -9,7 +9,7 @@ import { orphanTag } from '../vtree/orphanTag'
|
|||
import { parseAttributes, eventMap } from '../parser/attributes'
|
||||
import { parseInterpolate } from '../parser/interpolate'
|
||||
|
||||
import { startWith, groupTree, dumpTree, getRange } from './share'
|
||||
import { groupTree, dumpTree, getRange } from './share'
|
||||
|
||||
var viewID
|
||||
|
||||
|
@ -110,7 +110,7 @@ class Render {
|
|||
* @returns {undefined}
|
||||
*/
|
||||
scanComment(vdom, scope, parentChildren) {
|
||||
if (startWith(vdom.nodeValue, 'ms-for:')) {
|
||||
if (vdom.nodeValue.startsWith('ms-for:')) {
|
||||
this.getForBinding(vdom, scope, parentChildren)
|
||||
}
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ class Render {
|
|||
if (attr.charAt(0) === ':') {
|
||||
attr = 'ms-' + attr.slice(1)
|
||||
}
|
||||
if (startWith(attr, 'ms-')) {
|
||||
if (attr.startsWith('ms-')) {
|
||||
dirs[attr] = value
|
||||
var type = attr.match(/\w+/g)[1]
|
||||
type = eventMap[type] || type
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
function serverRender(vm, str) {
|
||||
var nodes = Anot.lexer(str)
|
||||
var templates = {}
|
||||
collectTemplate(nodes, templates)
|
||||
var render = Anot.scan(str)
|
||||
var html = Anot.vdom(render.root, 'toHTML', false)
|
||||
return {
|
||||
templates: templates,
|
||||
html: html
|
||||
}
|
||||
}
|
||||
|
||||
function collectTemplate(vdoms, obj) {
|
||||
for (var i = 0, el; (el = vdoms[i++]); ) {
|
||||
var props = el.props
|
||||
if (props) {
|
||||
var id =
|
||||
props['ms-controller'] ||
|
||||
props[':controller'] ||
|
||||
props['ms-important'] ||
|
||||
props[':important']
|
||||
if (id) {
|
||||
obj[id] = Anot.VElement.prototype.toHTML.call(el, true)
|
||||
continue
|
||||
}
|
||||
}
|
||||
if (el.children) {
|
||||
collectTemplate(el.children, obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof module === 'object') module.exports = serverRender
|
|
@ -60,14 +60,16 @@ export function dumpTree(elem) {
|
|||
|
||||
export function getRange(childNodes, node) {
|
||||
var i = childNodes.indexOf(node) + 1
|
||||
var deep = 1,
|
||||
nodes = [],
|
||||
end
|
||||
var deep = 1
|
||||
var nodes = []
|
||||
var end
|
||||
|
||||
nodes.start = i
|
||||
|
||||
while ((node = childNodes[i++])) {
|
||||
nodes.push(node)
|
||||
if (node.nodeName === '#comment') {
|
||||
if (startWith(node.nodeValue, 'ms-for:')) {
|
||||
if (node.nodeValue.startsWith('ms-for:')) {
|
||||
deep++
|
||||
} else if (node.nodeValue === 'ms-for-end:') {
|
||||
deep--
|
||||
|
@ -83,10 +85,6 @@ export function getRange(childNodes, node) {
|
|||
return nodes
|
||||
}
|
||||
|
||||
export function startWith(long, short) {
|
||||
return long.indexOf(short) === 0
|
||||
}
|
||||
|
||||
var appendChildMayThrowError = {
|
||||
'#text': 1,
|
||||
'#comment': 1,
|
||||
|
|
|
@ -158,7 +158,9 @@ Object.assign(Anot, {
|
|||
remove: function(target, item) {
|
||||
//移除数组中第一个匹配传参的那个元素,返回布尔表示成功与否
|
||||
var index = target.indexOf(item)
|
||||
if (~index) return Anot.Array.removeAt(target, index)
|
||||
if (~index) {
|
||||
return Anot.Array.removeAt(target, index)
|
||||
}
|
||||
return false
|
||||
}
|
||||
},
|
||||
|
|
|
@ -7,15 +7,16 @@ var rarraylike = /(Array|List|Collection|Map|Arguments|Set)\]$/
|
|||
|
||||
// Anot.type
|
||||
var class2type = {}
|
||||
'Boolean,Number,String,Function,Array,Date,RegExp,Object,Error,AsyncFunction,Promise,Generator,GeneratorFunction'
|
||||
var types =
|
||||
'Boolean,Number,String,Function,Array,Date,RegExp,Object,Error,AsyncFunction,Promise,Generator,GeneratorFunction'
|
||||
|
||||
types
|
||||
.split(',')
|
||||
.forEach(function(name) {
|
||||
class2type['[object ' + name + ']'] = name.toLowerCase()
|
||||
})
|
||||
.forEach(name => (class2type[`[object ${name}]`] = name.toLowerCase()))
|
||||
|
||||
Anot.type = function(obj) {
|
||||
if (obj) {
|
||||
// 早期的webkit内核浏览器实现了已废弃的ecma262v4标准,可以将正则字面量当作函数使用,因此typeof在判定正则时会返回function
|
||||
if (obj) {
|
||||
return typeof obj === 'object' || typeof obj === 'function'
|
||||
? class2type[inspect.call(obj)] || 'object'
|
||||
: typeof obj
|
||||
|
@ -23,20 +24,10 @@ Anot.type = function(obj) {
|
|||
return String(obj)
|
||||
}
|
||||
|
||||
Anot.isFunction = function(fn) {
|
||||
return typeof fn === 'function'
|
||||
}
|
||||
|
||||
Anot.isWindow = function(obj) {
|
||||
return rwindow.test(inspect.call(obj))
|
||||
}
|
||||
|
||||
/*判定是否是一个朴素的javascript对象(Object),不是DOM对象,不是BOM对象,不是自定义类的实例*/
|
||||
Anot.isPlainObject = function(obj) {
|
||||
// 简单的 typeof obj === 'object'检测,会致使用isPlainObject(window)在opera下通不过
|
||||
return (
|
||||
inspect.call(obj) === '[object Object]' &&
|
||||
Object.getPrototypeOf(obj) === Object.prototype
|
||||
typeof obj === 'object' && Object.getPrototypeOf(obj) === Object.prototype
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -75,24 +66,26 @@ Anot.init = function(source) {
|
|||
throw new Error(`vm实例[${id}]已经存在`)
|
||||
}
|
||||
vm = platform.modelFactory(source)
|
||||
|
||||
console.log('+++++++++++', vm)
|
||||
Anot.vmodels[id] = vm
|
||||
|
||||
Anot.nextTick(function() {
|
||||
let $elem = document.querySelector('[anot=' + vm.$id + ']')
|
||||
if ($elem) {
|
||||
if ($elem === document.body) {
|
||||
Anot.scan($elem)
|
||||
} else {
|
||||
let _parent = $elem
|
||||
while ((_parent = _parent.parentNode)) {
|
||||
if (_parent.__VM__) {
|
||||
break
|
||||
}
|
||||
}
|
||||
Anot.scan($elem.parentNode, _parent && _parent.__VM__)
|
||||
}
|
||||
}
|
||||
})
|
||||
// Anot.nextTick(function() {
|
||||
// let $elem = document.querySelector('[anot=' + vm.$id + ']')
|
||||
// if ($elem) {
|
||||
// if ($elem === document.body) {
|
||||
// Anot.scan($elem)
|
||||
// } else {
|
||||
// let _parent = $elem
|
||||
// while ((_parent = _parent.parentNode)) {
|
||||
// if (_parent.__VM__) {
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// Anot.scan($elem.parentNode, _parent && _parent.__VM__)
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
}
|
||||
return vm
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Anot, platform } from '../seed/core'
|
||||
import { $$skipArray } from './reserved'
|
||||
import { SYS_SKIP } from './reserved'
|
||||
import { Action } from './Action'
|
||||
import './share'
|
||||
import './ProxyArray'
|
||||
|
@ -58,7 +58,7 @@ export function fireFactory(core) {
|
|||
export function afterCreate(vm, core, keys, bindThis) {
|
||||
var ac = vm.$accessors
|
||||
//隐藏系统属性
|
||||
for (var key in $$skipArray) {
|
||||
for (var key in SYS_SKIP) {
|
||||
hideProperty(vm, key, vm[key])
|
||||
}
|
||||
//为不可监听的属性或方法赋值
|
||||
|
|
|
@ -1,63 +1,9 @@
|
|||
import { Anot, platform, isObject } from '../seed/core'
|
||||
import { $$skipArray } from './reserved'
|
||||
import { SYS_SKIP } from './reserved'
|
||||
import { Mutation } from './Mutation'
|
||||
import { Computed } from './Computed'
|
||||
import { IProxy, canHijack, createProxy } from './share'
|
||||
|
||||
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)
|
||||
|
||||
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]
|
||||
}
|
||||
}
|
||||
for (let i in $computed) {
|
||||
vm[i] = $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)) {
|
||||
|
@ -89,7 +35,7 @@ var traps = {
|
|||
if (name === '$model' || name === '$track') {
|
||||
return true
|
||||
}
|
||||
if (name in $$skipArray) {
|
||||
if (name in SYS_SKIP) {
|
||||
target[name] = value
|
||||
return true
|
||||
}
|
||||
|
@ -126,13 +72,68 @@ var traps = {
|
|||
//has 只能用于 in 操作符,没什么用删去
|
||||
}
|
||||
|
||||
function wrapIt(str) {
|
||||
return '☥' + str + '☥'
|
||||
}
|
||||
|
||||
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) {
|
||||
platform.modelFactory = function(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)
|
||||
|
||||
var vm = new Proxy(proxy, traps)
|
||||
var { state, props, watch, methods, mounted, computed } = clone
|
||||
|
||||
console.log('--------------', vm)
|
||||
//先添加普通属性与监控属性
|
||||
for (let i in state) {
|
||||
vm[i] = state[i]
|
||||
}
|
||||
for (let i in methods) {
|
||||
vm[i] = methods[i]
|
||||
}
|
||||
//再添加计算属性
|
||||
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 state[i] //去掉重名的监控属性
|
||||
} else {
|
||||
delete computed[i]
|
||||
}
|
||||
}
|
||||
for (let i in computed) {
|
||||
vm[i] = computed[i]
|
||||
}
|
||||
}
|
||||
|
||||
return vm
|
||||
}
|
||||
|
||||
Anot.itemFactory = platform.itemFactory = function(before, after) {
|
||||
var definition = before.$model
|
||||
definition.$proxyItemBackdoor = true
|
||||
definition.$id =
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
$$skipArray:是系统级通用的不可监听属性
|
||||
SYS_SKIP:是系统级通用的不可监听属性
|
||||
$skipArray: 是当前对象特有的不可监听属性
|
||||
|
||||
不同点是
|
||||
|
@ -7,7 +7,7 @@ $skipArray: 是当前对象特有的不可监听属性
|
|||
$skipArray被hasOwnProperty后返回true
|
||||
*/
|
||||
var falsy
|
||||
export var $$skipArray = {
|
||||
export var SYS_SKIP = {
|
||||
$id: falsy,
|
||||
$render: falsy,
|
||||
$track: falsy,
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
import { Anot, platform, isObject, makeHashCode } from '../seed/core'
|
||||
import { $$skipArray } from './reserved'
|
||||
import { SYS_SKIP } from './reserved'
|
||||
import { Mutation } from './Mutation'
|
||||
import { Computed } from './Computed'
|
||||
|
||||
var $proxyItemBackdoorMap = {}
|
||||
|
||||
/**
|
||||
* 这里放置ViewModel模块的共用方法
|
||||
* IProxy, 基本用户数据产生的一个数据对象,基于$model与vmodel之间的形态
|
||||
* modelFactory: 生成用户VM
|
||||
* canHijack: 判定此属性是否该被劫持,加入数据监听与分发的的逻辑
|
||||
* createProxy: listFactory与modelFactory的封装
|
||||
* createAccessor: 实现数据监听与分发的重要对象
|
||||
* itemFactory: ms-for循环中产生的代理VM的生成工厂
|
||||
* fuseFactory: 两个ms-controller间产生的代理VM的生成工厂
|
||||
*/
|
||||
|
@ -18,21 +19,25 @@ import { Computed } from './Computed'
|
|||
* Anot改用Proxy来创建VM,因此
|
||||
*/
|
||||
|
||||
export function IProxy(definition, dd) {
|
||||
Anot.mix(this, definition)
|
||||
Anot.mix(this, $$skipArray)
|
||||
export function IProxy(source, dd) {
|
||||
// var { state, props, watch, methods, mounted } = source
|
||||
|
||||
// console.log(state, methods)
|
||||
Anot.mix(this, source)
|
||||
Anot.mix(this, SYS_SKIP)
|
||||
this.$hashcode = makeHashCode('$')
|
||||
this.$id = this.$id || this.$hashcode
|
||||
this.$events = {
|
||||
__dep__: dd || new Mutation(this.$id)
|
||||
}
|
||||
|
||||
// console.log('***********', this.$id)
|
||||
delete this.$mutations
|
||||
|
||||
this.$accessors = {}
|
||||
this.$computed = {}
|
||||
this.$track = ''
|
||||
|
||||
if (dd === void 0) {
|
||||
if (dd === undefined) {
|
||||
this.$watch = platform.watchFactory(this.$events)
|
||||
this.$fire = platform.fireFactory(this.$events)
|
||||
} else {
|
||||
|
@ -41,50 +46,10 @@ export function IProxy(definition, dd) {
|
|||
}
|
||||
}
|
||||
|
||||
platform.modelFactory = function modelFactory(definition, dd) {
|
||||
var $computed = definition.$computed || {}
|
||||
delete definition.$computed
|
||||
var core = new IProxy(definition, dd)
|
||||
var $accessors = core.$accessors
|
||||
var keys = []
|
||||
|
||||
platform.hideProperty(core, '$mutations', {})
|
||||
|
||||
for (let key in definition) {
|
||||
if (key in $$skipArray) continue
|
||||
var val = definition[key]
|
||||
keys.push(key)
|
||||
if (canHijack(key, val)) {
|
||||
$accessors[key] = createAccessor(key, val)
|
||||
}
|
||||
}
|
||||
for (let key in $computed) {
|
||||
if (key in $$skipArray) continue
|
||||
var val = $computed[key]
|
||||
if (typeof val === 'function') {
|
||||
val = {
|
||||
get: val
|
||||
}
|
||||
}
|
||||
if (val && val.get) {
|
||||
val.getter = val.get
|
||||
val.setter = val.set
|
||||
Anot.Array.ensure(keys, key)
|
||||
$accessors[key] = createAccessor(key, val, true)
|
||||
}
|
||||
}
|
||||
//将系统API以unenumerable形式加入vm,
|
||||
//添加用户的其他不可监听属性或方法
|
||||
//重写$track
|
||||
//并在IE6-8中增添加不存在的hasOwnPropert方法
|
||||
var vm = platform.createViewModel(core, $accessors, core)
|
||||
platform.afterCreate(vm, core, keys, !dd)
|
||||
return vm
|
||||
}
|
||||
var $proxyItemBackdoorMap = {}
|
||||
|
||||
export function canHijack(key, val, $proxyItemBackdoor) {
|
||||
if (key in $$skipArray) return false
|
||||
if (key in SYS_SKIP) {
|
||||
return false
|
||||
}
|
||||
if (key.charAt(0) === '$') {
|
||||
if ($proxyItemBackdoor) {
|
||||
if (!$proxyItemBackdoorMap[key]) {
|
||||
|
@ -120,60 +85,6 @@ export function createProxy(target, dd) {
|
|||
|
||||
platform.createProxy = createProxy
|
||||
|
||||
platform.itemFactory = function itemFactory(before, after) {
|
||||
var keyMap = before.$model
|
||||
var core = new IProxy(keyMap)
|
||||
var state = Object.assign(core.$accessors, before.$accessors) //防止互相污染
|
||||
var data = after.data
|
||||
//core是包含系统属性的对象
|
||||
//keyMap是不包含系统属性的对象, keys
|
||||
for (var key in data) {
|
||||
var val = (keyMap[key] = core[key] = data[key])
|
||||
state[key] = createAccessor(key, val)
|
||||
}
|
||||
var keys = Object.keys(keyMap)
|
||||
var vm = platform.createViewModel(core, state, core)
|
||||
platform.afterCreate(vm, core, keys)
|
||||
return vm
|
||||
}
|
||||
|
||||
function createAccessor(key, val, isComputed) {
|
||||
var mutation = null
|
||||
var Accessor = isComputed ? Computed : Mutation
|
||||
return {
|
||||
get: function Getter() {
|
||||
if (!mutation) {
|
||||
mutation = new Accessor(key, val, this)
|
||||
}
|
||||
return mutation.get()
|
||||
},
|
||||
set: function Setter(newValue) {
|
||||
if (!mutation) {
|
||||
mutation = new Accessor(key, val, this)
|
||||
}
|
||||
mutation.set(newValue)
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
}
|
||||
}
|
||||
|
||||
platform.fuseFactory = function fuseFactory(before, after) {
|
||||
var keyMap = Anot.mix(before.$model, after.$model)
|
||||
var core = new IProxy(
|
||||
Anot.mix(keyMap, {
|
||||
$id: before.$id + after.$id
|
||||
})
|
||||
)
|
||||
var state = Anot.mix(core.$accessors, before.$accessors, after.$accessors) //防止互相污染
|
||||
|
||||
var keys = Object.keys(keyMap)
|
||||
//将系统API以unenumerable形式加入vm,并在IE6-8中添加hasOwnPropert方法
|
||||
var vm = platform.createViewModel(core, state, core)
|
||||
platform.afterCreate(vm, core, keys, false)
|
||||
return vm
|
||||
}
|
||||
|
||||
function toJson(val) {
|
||||
var xtype = Anot.type(val)
|
||||
if (xtype === 'array') {
|
||||
|
|
Reference in New Issue