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-19 19:07:44 +08:00
parent ebbd93cd97
commit 23b83143fb
12 changed files with 120 additions and 247 deletions

View File

@ -1,10 +1,12 @@
import Anot from '../seed/index' import Anot from '../seed/index'
//https://github.com/RubyLouvre/avalon/issues/1834
Anot.directive('expr', { Anot.directive('expr', {
update: function(vdom, value) { update: function(vdom, value) {
value = value == null || value === '' ? '\u200b' : value value = value == null || value === '' ? '\u200b' : value
vdom.nodeValue = value vdom.nodeValue = value
//https://github.com/RubyLouvre/Anot/issues/1834 if (vdom.dom) {
if (vdom.dom) vdom.dom.data = value vdom.dom.data = value
}
} }
}) })

View File

@ -8,7 +8,7 @@ import {
} from '../seed/core' } from '../seed/core'
import { VFragment } from '../vdom/VFragment' import { VFragment } from '../vdom/VFragment'
import { $$skipArray } from '../vmodel/reserved' import { SYS_SKIP } from '../vmodel/reserved'
import { addScope, makeHandle } from '../parser/index' import { addScope, makeHandle } from '../parser/index'
import { updateView } from './duplex/share' import { updateView } from './duplex/share'
@ -145,7 +145,7 @@ function createFragments(instance, obj) {
instance.fragments = fragments instance.fragments = fragments
} else { } else {
Anot.each(obj, function(key, value) { Anot.each(obj, function(key, value) {
if (!(key in $$skipArray)) { if (!(key in SYS_SKIP)) {
var k = array ? getTraceKey(value) : key var k = array ? getTraceKey(value) : key
fragments.push(new VFragment([], k, value, i++)) fragments.push(new VFragment([], k, value, i++))
ids.push(k) ids.push(k)

View File

@ -1,5 +1,4 @@
import { Anot, escapeRegExp, isObject } from '../seed/core' import { Anot, escapeRegExp, isObject } from '../seed/core'
import { $$skipArray } from '../vmodel/reserved'
export function orderBy(array, by, decend) { export function orderBy(array, by, decend) {
var type = Anot.type(array) var type = Anot.type(array)

View File

@ -9,7 +9,7 @@ import { orphanTag } from '../vtree/orphanTag'
import { parseAttributes, eventMap } from '../parser/attributes' import { parseAttributes, eventMap } from '../parser/attributes'
import { parseInterpolate } from '../parser/interpolate' import { parseInterpolate } from '../parser/interpolate'
import { startWith, groupTree, dumpTree, getRange } from './share' import { groupTree, dumpTree, getRange } from './share'
var viewID var viewID
@ -110,7 +110,7 @@ class Render {
* @returns {undefined} * @returns {undefined}
*/ */
scanComment(vdom, scope, parentChildren) { scanComment(vdom, scope, parentChildren) {
if (startWith(vdom.nodeValue, 'ms-for:')) { if (vdom.nodeValue.startsWith('ms-for:')) {
this.getForBinding(vdom, scope, parentChildren) this.getForBinding(vdom, scope, parentChildren)
} }
} }
@ -134,7 +134,7 @@ class Render {
if (attr.charAt(0) === ':') { if (attr.charAt(0) === ':') {
attr = 'ms-' + attr.slice(1) attr = 'ms-' + attr.slice(1)
} }
if (startWith(attr, 'ms-')) { if (attr.startsWith('ms-')) {
dirs[attr] = value dirs[attr] = value
var type = attr.match(/\w+/g)[1] var type = attr.match(/\w+/g)[1]
type = eventMap[type] || type type = eventMap[type] || type

View File

@ -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

View File

@ -60,14 +60,16 @@ export function dumpTree(elem) {
export function getRange(childNodes, node) { export function getRange(childNodes, node) {
var i = childNodes.indexOf(node) + 1 var i = childNodes.indexOf(node) + 1
var deep = 1, var deep = 1
nodes = [], var nodes = []
end var end
nodes.start = i nodes.start = i
while ((node = childNodes[i++])) { while ((node = childNodes[i++])) {
nodes.push(node) nodes.push(node)
if (node.nodeName === '#comment') { if (node.nodeName === '#comment') {
if (startWith(node.nodeValue, 'ms-for:')) { if (node.nodeValue.startsWith('ms-for:')) {
deep++ deep++
} else if (node.nodeValue === 'ms-for-end:') { } else if (node.nodeValue === 'ms-for-end:') {
deep-- deep--
@ -83,10 +85,6 @@ export function getRange(childNodes, node) {
return nodes return nodes
} }
export function startWith(long, short) {
return long.indexOf(short) === 0
}
var appendChildMayThrowError = { var appendChildMayThrowError = {
'#text': 1, '#text': 1,
'#comment': 1, '#comment': 1,

View File

@ -158,7 +158,9 @@ Object.assign(Anot, {
remove: function(target, item) { remove: function(target, item) {
//移除数组中第一个匹配传参的那个元素,返回布尔表示成功与否 //移除数组中第一个匹配传参的那个元素,返回布尔表示成功与否
var index = target.indexOf(item) var index = target.indexOf(item)
if (~index) return Anot.Array.removeAt(target, index) if (~index) {
return Anot.Array.removeAt(target, index)
}
return false return false
} }
}, },

View File

@ -7,15 +7,16 @@ var rarraylike = /(Array|List|Collection|Map|Arguments|Set)\]$/
// Anot.type // Anot.type
var class2type = {} 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(',') .split(',')
.forEach(function(name) { .forEach(name => (class2type[`[object ${name}]`] = name.toLowerCase()))
class2type['[object ' + name + ']'] = name.toLowerCase()
})
Anot.type = function(obj) { Anot.type = function(obj) {
if (obj) {
// 早期的webkit内核浏览器实现了已废弃的ecma262v4标准可以将正则字面量当作函数使用因此typeof在判定正则时会返回function // 早期的webkit内核浏览器实现了已废弃的ecma262v4标准可以将正则字面量当作函数使用因此typeof在判定正则时会返回function
if (obj) {
return typeof obj === 'object' || typeof obj === 'function' return typeof obj === 'object' || typeof obj === 'function'
? class2type[inspect.call(obj)] || 'object' ? class2type[inspect.call(obj)] || 'object'
: typeof obj : typeof obj
@ -23,20 +24,10 @@ Anot.type = function(obj) {
return String(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对象不是自定义类的实例*/ /*判定是否是一个朴素的javascript对象Object不是DOM对象不是BOM对象不是自定义类的实例*/
Anot.isPlainObject = function(obj) { Anot.isPlainObject = function(obj) {
// 简单的 typeof obj === 'object'检测会致使用isPlainObject(window)在opera下通不过
return ( return (
inspect.call(obj) === '[object Object]' && typeof obj === 'object' && Object.getPrototypeOf(obj) === Object.prototype
Object.getPrototypeOf(obj) === Object.prototype
) )
} }
@ -75,24 +66,26 @@ Anot.init = function(source) {
throw new Error(`vm实例[${id}]已经存在`) throw new Error(`vm实例[${id}]已经存在`)
} }
vm = platform.modelFactory(source) vm = platform.modelFactory(source)
console.log('+++++++++++', vm)
Anot.vmodels[id] = vm Anot.vmodels[id] = vm
Anot.nextTick(function() { // Anot.nextTick(function() {
let $elem = document.querySelector('[anot=' + vm.$id + ']') // let $elem = document.querySelector('[anot=' + vm.$id + ']')
if ($elem) { // if ($elem) {
if ($elem === document.body) { // if ($elem === document.body) {
Anot.scan($elem) // Anot.scan($elem)
} else { // } else {
let _parent = $elem // let _parent = $elem
while ((_parent = _parent.parentNode)) { // while ((_parent = _parent.parentNode)) {
if (_parent.__VM__) { // if (_parent.__VM__) {
break // break
} // }
} // }
Anot.scan($elem.parentNode, _parent && _parent.__VM__) // Anot.scan($elem.parentNode, _parent && _parent.__VM__)
} // }
} // }
}) // })
} }
return vm return vm
} }

View File

@ -1,5 +1,5 @@
import { Anot, platform } from '../seed/core' import { Anot, platform } from '../seed/core'
import { $$skipArray } from './reserved' import { SYS_SKIP } from './reserved'
import { Action } from './Action' import { Action } from './Action'
import './share' import './share'
import './ProxyArray' import './ProxyArray'
@ -58,7 +58,7 @@ export function fireFactory(core) {
export function afterCreate(vm, core, keys, bindThis) { export function afterCreate(vm, core, keys, bindThis) {
var ac = vm.$accessors var ac = vm.$accessors
//隐藏系统属性 //隐藏系统属性
for (var key in $$skipArray) { for (var key in SYS_SKIP) {
hideProperty(vm, key, vm[key]) hideProperty(vm, key, vm[key])
} }
//为不可监听的属性或方法赋值 //为不可监听的属性或方法赋值

View File

@ -1,63 +1,9 @@
import { Anot, platform, isObject } from '../seed/core' import { Anot, platform, isObject } from '../seed/core'
import { $$skipArray } from './reserved' import { SYS_SKIP } from './reserved'
import { Mutation } from './Mutation' import { Mutation } from './Mutation'
import { Computed } from './Computed' import { Computed } from './Computed'
import { IProxy, canHijack, createProxy } from './share' 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 = { var traps = {
deleteProperty(target, name) { deleteProperty(target, name) {
if (target.hasOwnProperty(name)) { if (target.hasOwnProperty(name)) {
@ -89,7 +35,7 @@ var traps = {
if (name === '$model' || name === '$track') { if (name === '$model' || name === '$track') {
return true return true
} }
if (name in $$skipArray) { if (name in SYS_SKIP) {
target[name] = value target[name] = value
return true return true
} }
@ -126,13 +72,68 @@ var traps = {
//has 只能用于 in 操作符,没什么用删去 //has 只能用于 in 操作符,没什么用删去
} }
function wrapIt(str) {
return '☥' + str + '☥'
}
function updateTrack(target, name) { function updateTrack(target, name) {
var arr = target.$track.match(/[^☥]+/g) || [] var arr = target.$track.match(/[^☥]+/g) || []
arr.push(name) arr.push(name)
target.$track = arr.sort().join('☥') 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 var definition = before.$model
definition.$proxyItemBackdoor = true definition.$proxyItemBackdoor = true
definition.$id = definition.$id =

View File

@ -1,5 +1,5 @@
/** /**
$$skipArray:是系统级通用的不可监听属性 SYS_SKIP:是系统级通用的不可监听属性
$skipArray: 是当前对象特有的不可监听属性 $skipArray: 是当前对象特有的不可监听属性
不同点是 不同点是
@ -7,7 +7,7 @@ $skipArray: 是当前对象特有的不可监听属性
$skipArray被hasOwnProperty后返回true $skipArray被hasOwnProperty后返回true
*/ */
var falsy var falsy
export var $$skipArray = { export var SYS_SKIP = {
$id: falsy, $id: falsy,
$render: falsy, $render: falsy,
$track: falsy, $track: falsy,

View File

@ -1,15 +1,16 @@
import { Anot, platform, isObject, makeHashCode } from '../seed/core' import { Anot, platform, isObject, makeHashCode } from '../seed/core'
import { $$skipArray } from './reserved' import { SYS_SKIP } from './reserved'
import { Mutation } from './Mutation' import { Mutation } from './Mutation'
import { Computed } from './Computed' import { Computed } from './Computed'
var $proxyItemBackdoorMap = {}
/** /**
* 这里放置ViewModel模块的共用方法 * 这里放置ViewModel模块的共用方法
* IProxy, 基本用户数据产生的一个数据对象,基于$model与vmodel之间的形态 * IProxy, 基本用户数据产生的一个数据对象,基于$model与vmodel之间的形态
* modelFactory: 生成用户VM * modelFactory: 生成用户VM
* canHijack: 判定此属性是否该被劫持,加入数据监听与分发的的逻辑 * canHijack: 判定此属性是否该被劫持,加入数据监听与分发的的逻辑
* createProxy: listFactory与modelFactory的封装 * createProxy: listFactory与modelFactory的封装
* createAccessor: 实现数据监听与分发的重要对象
* itemFactory: ms-for循环中产生的代理VM的生成工厂 * itemFactory: ms-for循环中产生的代理VM的生成工厂
* fuseFactory: 两个ms-controller间产生的代理VM的生成工厂 * fuseFactory: 两个ms-controller间产生的代理VM的生成工厂
*/ */
@ -18,21 +19,25 @@ import { Computed } from './Computed'
* Anot改用Proxy来创建VM,因此 * Anot改用Proxy来创建VM,因此
*/ */
export function IProxy(definition, dd) { export function IProxy(source, dd) {
Anot.mix(this, definition) // var { state, props, watch, methods, mounted } = source
Anot.mix(this, $$skipArray)
// console.log(state, methods)
Anot.mix(this, source)
Anot.mix(this, SYS_SKIP)
this.$hashcode = makeHashCode('$') this.$hashcode = makeHashCode('$')
this.$id = this.$id || this.$hashcode this.$id = this.$id || this.$hashcode
this.$events = { this.$events = {
__dep__: dd || new Mutation(this.$id) __dep__: dd || new Mutation(this.$id)
} }
// console.log('***********', this.$id)
delete this.$mutations delete this.$mutations
this.$accessors = {} this.$accessors = {}
this.$computed = {} this.$computed = {}
this.$track = '' this.$track = ''
if (dd === void 0) { if (dd === undefined) {
this.$watch = platform.watchFactory(this.$events) this.$watch = platform.watchFactory(this.$events)
this.$fire = platform.fireFactory(this.$events) this.$fire = platform.fireFactory(this.$events)
} else { } 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) { export function canHijack(key, val, $proxyItemBackdoor) {
if (key in $$skipArray) return false if (key in SYS_SKIP) {
return false
}
if (key.charAt(0) === '$') { if (key.charAt(0) === '$') {
if ($proxyItemBackdoor) { if ($proxyItemBackdoor) {
if (!$proxyItemBackdoorMap[key]) { if (!$proxyItemBackdoorMap[key]) {
@ -120,60 +85,6 @@ export function createProxy(target, dd) {
platform.createProxy = createProxy 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) { function toJson(val) {
var xtype = Anot.type(val) var xtype = Anot.type(val)
if (xtype === 'array') { if (xtype === 'array') {