移除部分兼容处理;移除表单验证指令
parent
8b21f0a800
commit
099378aedd
|
@ -8,13 +8,13 @@ import './text'
|
|||
import './css'
|
||||
import './expr'
|
||||
|
||||
import './attr.modern'
|
||||
import './attr'
|
||||
import './html'
|
||||
import './if'
|
||||
import './on'
|
||||
import './for'
|
||||
|
||||
import './class.hover.active'
|
||||
import './duplex/modern'
|
||||
import './rules'
|
||||
import './validate'
|
||||
import './duplex/index'
|
||||
// import './rules'
|
||||
// import './validate'
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
import { Anot, escapeRegExp } from '../seed/core'
|
||||
import { $$skipArray } from '../vmodel/reserved'
|
||||
|
||||
/*
|
||||
https://github.com/hufyhang/orderBy/blob/master/index.js
|
||||
*/
|
||||
|
||||
export function orderBy(array, by, decend) {
|
||||
var type = Anot.type(array)
|
||||
if (type !== 'array' && type !== 'object') throw 'orderBy只能处理对象或数组'
|
||||
|
@ -88,14 +84,7 @@ export function filterBy(array, search, ...args) {
|
|||
var target = isArray ? [] : {}
|
||||
__repeat(array, isArray, function(key) {
|
||||
var val = array[key]
|
||||
if (
|
||||
criteria.apply(
|
||||
{
|
||||
key: key
|
||||
},
|
||||
[val, key].concat(args)
|
||||
)
|
||||
) {
|
||||
if (criteria.apply({ key }, [val, key].concat(args))) {
|
||||
if (isArray) {
|
||||
target.push(val)
|
||||
} else {
|
||||
|
@ -121,7 +110,9 @@ export function selectBy(data, array, defaults) {
|
|||
|
||||
export function limitBy(input, limit, begin) {
|
||||
var type = Anot.type(input)
|
||||
if (type !== 'array' && type !== 'object') throw 'limitBy只能处理对象或数组'
|
||||
if (type !== 'array' && type !== 'object') {
|
||||
throw 'limitBy只能处理对象或数组'
|
||||
}
|
||||
//必须是数值
|
||||
if (typeof limit !== 'number') {
|
||||
return input
|
||||
|
|
|
@ -3,7 +3,7 @@ import { fromDOM } from '../vtree/fromDOM'
|
|||
import { fromString } from '../vtree/fromString'
|
||||
|
||||
import { VFragment } from '../vdom/VFragment'
|
||||
import { Directive } from './Directive'
|
||||
import { Directive } from './directive'
|
||||
|
||||
import { orphanTag } from '../vtree/orphanTag'
|
||||
import { parseAttributes, eventMap } from '../parser/attributes'
|
||||
|
@ -11,6 +11,8 @@ import { parseInterpolate } from '../parser/interpolate'
|
|||
|
||||
import { startWith, groupTree, dumpTree, getRange } from './share'
|
||||
|
||||
var viewID
|
||||
|
||||
/**
|
||||
* 生成一个渲染器,并作为它第一个遇到的ms-controller对应的VM的$render属性
|
||||
* @param {String|DOM} node
|
||||
|
@ -25,17 +27,18 @@ Anot.scan = function(node, vm, beforeReady) {
|
|||
/**
|
||||
* Anot.scan 的内部实现
|
||||
*/
|
||||
function Render(node, vm, beforeReady) {
|
||||
this.root = node //如果传入的字符串,确保只有一个标签作为根节点
|
||||
this.vm = vm
|
||||
this.beforeReady = beforeReady
|
||||
this.bindings = [] //收集待加工的绑定属性
|
||||
this.callbacks = []
|
||||
this.directives = []
|
||||
this.init()
|
||||
}
|
||||
|
||||
Render.prototype = {
|
||||
class Render {
|
||||
constructor(node, vm, beforeReady) {
|
||||
this.root = node //如果传入的字符串,确保只有一个标签作为根节点
|
||||
this.vm = vm
|
||||
this.beforeReady = beforeReady
|
||||
this.bindings = [] //收集待加工的绑定属性
|
||||
this.callbacks = []
|
||||
this.directives = []
|
||||
this.init()
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始扫描指定区域
|
||||
* 收集绑定属性
|
||||
|
@ -50,15 +53,13 @@ Render.prototype = {
|
|||
} else if (typeof this.root === 'string') {
|
||||
vnodes = fromString(this.root) //转换虚拟DOM
|
||||
} else {
|
||||
return console.warn(
|
||||
'Anot.scan first argument must element or HTML string'
|
||||
)
|
||||
return console.warn('Anot.scan()第1个参数,只能是节点对象或节点字符串')
|
||||
}
|
||||
|
||||
this.root = vnodes[0]
|
||||
this.vnodes = vnodes
|
||||
this.scanChildren(vnodes, this.vm, true)
|
||||
},
|
||||
}
|
||||
|
||||
scanChildren(children, scope, isRoot) {
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
|
@ -81,7 +82,7 @@ Render.prototype = {
|
|||
if (isRoot) {
|
||||
this.complete()
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* 从文本节点获取指令
|
||||
|
@ -99,7 +100,7 @@ Render.prototype = {
|
|||
}
|
||||
])
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* 从注释节点获取指令
|
||||
|
@ -112,7 +113,7 @@ Render.prototype = {
|
|||
if (startWith(vdom.nodeValue, 'ms-for:')) {
|
||||
this.getForBinding(vdom, scope, parentChildren)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* 从元素节点的nodeName与属性中获取指令
|
||||
|
@ -223,7 +224,7 @@ Render.prototype = {
|
|||
) {
|
||||
this.scanChildren(children, scope, false)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* 将绑定属性转换为指令
|
||||
|
@ -245,7 +246,7 @@ Render.prototype = {
|
|||
fn()
|
||||
}
|
||||
this.optimizeDirectives()
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* 将收集到的绑定属性进行深加工,最后转换指令
|
||||
|
@ -276,7 +277,7 @@ Render.prototype = {
|
|||
this.directives.push(directive)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改指令的update与callback方法,让它们以后执行时更加高效
|
||||
|
@ -288,12 +289,13 @@ Render.prototype = {
|
|||
el.update = newUpdate
|
||||
el._isScheduled = false
|
||||
}
|
||||
},
|
||||
update: function() {
|
||||
}
|
||||
|
||||
update() {
|
||||
for (var i = 0, el; (el = this.directives[i++]); ) {
|
||||
el.update()
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁所有指令
|
||||
|
@ -308,7 +310,7 @@ Render.prototype = {
|
|||
for (let i in this) {
|
||||
if (i !== 'dispose') delete this[i]
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* 将循环区域转换为for指令
|
||||
|
@ -341,7 +343,7 @@ Render.prototype = {
|
|||
parentChildren
|
||||
}
|
||||
])
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* 在带ms-for元素节点旁添加两个注释节点,组成循环区域
|
||||
|
@ -370,7 +372,6 @@ Render.prototype = {
|
|||
this.getForBinding(begin, scope, parentChildren, props['data-for-rendered'])
|
||||
}
|
||||
}
|
||||
var viewID
|
||||
|
||||
function newUpdate() {
|
||||
var oldVal = this.beforeUpdate()
|
||||
|
|
|
@ -8,104 +8,98 @@
|
|||
|
||||
removed <-- <-- <-- <-- <-- <-- <-- <-- <-- <-- <-- added
|
||||
*/
|
||||
export function Cache(maxLength) {
|
||||
|
||||
export class Cache {
|
||||
constructor(maxLength) {
|
||||
// 标识当前缓存数组的大小
|
||||
this.size = 0
|
||||
// 标识缓存数组能达到的最大长度
|
||||
// 标识缓存数组能达到的最大长度
|
||||
this.limit = maxLength
|
||||
// head(最不常用的项),tail(最常用的项)全部初始化为undefined
|
||||
// head(最不常用的项),tail(最常用的项)全部初始化为undefined
|
||||
|
||||
this.head = this.tail = void 0
|
||||
this._keymap = {}
|
||||
}
|
||||
}
|
||||
|
||||
Cache.prototype = {
|
||||
|
||||
put(key, value) {
|
||||
var entry = {
|
||||
key: key,
|
||||
value: value
|
||||
}
|
||||
this._keymap[key] = entry
|
||||
if (this.tail) {
|
||||
// 如果存在tail(缓存数组的长度不为0),将tail指向新的 entry
|
||||
this.tail.newer = entry
|
||||
entry.older = this.tail
|
||||
} else {
|
||||
// 如果缓存数组的长度为0,将head指向新的entry
|
||||
this.head = entry
|
||||
}
|
||||
this.tail = entry
|
||||
// 如果缓存数组达到上限,则先删除 head 指向的缓存对象
|
||||
/* istanbul ignore if */
|
||||
if (this.size === this.limit) {
|
||||
this.shift()
|
||||
} else {
|
||||
this.size++
|
||||
}
|
||||
return value
|
||||
},
|
||||
|
||||
shift() {
|
||||
/* istanbul ignore next */
|
||||
var entry = this.head
|
||||
/* istanbul ignore if */
|
||||
if (entry) {
|
||||
// 删除 head ,并改变指向
|
||||
this.head = this.head.newer
|
||||
// 同步更新 _keymap 里面的属性值
|
||||
this.head.older =
|
||||
entry.newer =
|
||||
entry.older =
|
||||
this._keymap[entry.key] =
|
||||
void 0
|
||||
delete this._keymap[entry.key] //#1029
|
||||
// 同步更新 缓存数组的长度
|
||||
this.size--
|
||||
}
|
||||
},
|
||||
|
||||
get(key) {
|
||||
var entry = this._keymap[key]
|
||||
// 如果查找不到含有`key`这个属性的缓存对象
|
||||
if (entry === void 0)
|
||||
return
|
||||
// 如果查找到的缓存对象已经是 tail (最近使用过的)
|
||||
/* istanbul ignore if */
|
||||
if (entry === this.tail) {
|
||||
return entry.value
|
||||
}
|
||||
// HEAD--------------TAIL
|
||||
// <.older .newer>
|
||||
// <--- add direction --
|
||||
// A B C <D> E
|
||||
if (entry.newer) {
|
||||
// 处理 newer 指向
|
||||
if (entry === this.head) {
|
||||
// 如果查找到的缓存对象是 head (最近最少使用过的)
|
||||
// 则将 head 指向原 head 的 newer 所指向的缓存对象
|
||||
this.head = entry.newer
|
||||
}
|
||||
// 将所查找的缓存对象的下一级的 older 指向所查找的缓存对象的older所指向的值
|
||||
// 例如:A B C D E
|
||||
// 如果查找到的是D,那么将E指向C,不再指向D
|
||||
entry.newer.older = entry.older // C <-- E.
|
||||
}
|
||||
if (entry.older) {
|
||||
// 处理 older 指向
|
||||
// 如果查找到的是D,那么C指向E,不再指向D
|
||||
entry.older.newer = entry.newer // C. --> E
|
||||
}
|
||||
// 处理所查找到的对象的 newer 以及 older 指向
|
||||
entry.newer = void 0 // D --x
|
||||
// older指向之前使用过的变量,即D指向E
|
||||
entry.older = this.tail // D. --> E
|
||||
if (this.tail) {
|
||||
// 将E的newer指向D
|
||||
this.tail.newer = entry // E. <-- D
|
||||
}
|
||||
// 改变 tail 为D
|
||||
this.tail = entry
|
||||
return entry.value
|
||||
put(key, value) {
|
||||
var entry = { key, value }
|
||||
this._keymap[key] = entry
|
||||
if (this.tail) {
|
||||
// 如果存在tail(缓存数组的长度不为0),将tail指向新的 entry
|
||||
this.tail.newer = entry
|
||||
entry.older = this.tail
|
||||
} else {
|
||||
// 如果缓存数组的长度为0,将head指向新的entry
|
||||
this.head = entry
|
||||
}
|
||||
this.tail = entry
|
||||
// 如果缓存数组达到上限,则先删除 head 指向的缓存对象
|
||||
/* istanbul ignore if */
|
||||
if (this.size === this.limit) {
|
||||
this.shift()
|
||||
} else {
|
||||
this.size++
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
shift() {
|
||||
/* istanbul ignore next */
|
||||
var entry = this.head
|
||||
/* istanbul ignore if */
|
||||
if (entry) {
|
||||
// 删除 head ,并改变指向
|
||||
this.head = this.head.newer
|
||||
// 同步更新 _keymap 里面的属性值
|
||||
this.head.older = entry.newer = entry.older = this._keymap[
|
||||
entry.key
|
||||
] = void 0
|
||||
delete this._keymap[entry.key] //#1029
|
||||
// 同步更新 缓存数组的长度
|
||||
this.size--
|
||||
}
|
||||
}
|
||||
|
||||
get(key) {
|
||||
var entry = this._keymap[key]
|
||||
// 如果查找不到含有`key`这个属性的缓存对象
|
||||
if (entry === void 0) return
|
||||
// 如果查找到的缓存对象已经是 tail (最近使用过的)
|
||||
/* istanbul ignore if */
|
||||
if (entry === this.tail) {
|
||||
return entry.value
|
||||
}
|
||||
// HEAD--------------TAIL
|
||||
// <.older .newer>
|
||||
// <--- add direction --
|
||||
// A B C <D> E
|
||||
if (entry.newer) {
|
||||
// 处理 newer 指向
|
||||
if (entry === this.head) {
|
||||
// 如果查找到的缓存对象是 head (最近最少使用过的)
|
||||
// 则将 head 指向原 head 的 newer 所指向的缓存对象
|
||||
this.head = entry.newer
|
||||
}
|
||||
// 将所查找的缓存对象的下一级的 older 指向所查找的缓存对象的older所指向的值
|
||||
// 例如:A B C D E
|
||||
// 如果查找到的是D,那么将E指向C,不再指向D
|
||||
entry.newer.older = entry.older // C <-- E.
|
||||
}
|
||||
if (entry.older) {
|
||||
// 处理 older 指向
|
||||
// 如果查找到的是D,那么C指向E,不再指向D
|
||||
entry.older.newer = entry.newer // C. --> E
|
||||
}
|
||||
// 处理所查找到的对象的 newer 以及 older 指向
|
||||
entry.newer = void 0 // D --x
|
||||
// older指向之前使用过的变量,即D指向E
|
||||
entry.older = this.tail // D. --> E
|
||||
if (this.tail) {
|
||||
// 将E的newer指向D
|
||||
this.tail.newer = entry // E. <-- D
|
||||
}
|
||||
// 改变 tail 为D
|
||||
this.tail = entry
|
||||
return entry.value
|
||||
}
|
||||
}
|
|
@ -24,8 +24,8 @@ export function oneObject(array, val) {
|
|||
if (typeof array === 'string') {
|
||||
array = array.match(rword) || []
|
||||
}
|
||||
var result = {},
|
||||
value = val !== void 0 ? val : 1
|
||||
var result = {}
|
||||
var value = val !== void 0 ? val : 1
|
||||
for (var i = 0, n = array.length; i < n; i++) {
|
||||
result[array[i]] = value
|
||||
}
|
||||
|
@ -114,9 +114,10 @@ export var validators = {}
|
|||
export var cssHooks = {}
|
||||
|
||||
window.Anot = Anot
|
||||
Anot.platform = platform
|
||||
|
||||
/* istanbul ignore next */
|
||||
export function createFragment() {
|
||||
/* istanbul ignore next */
|
||||
return document.createDocumentFragment()
|
||||
}
|
||||
|
||||
|
|
|
@ -6,22 +6,20 @@ var rarraylike = /(Array|List|Collection|Map|Arguments|Set)\]$/
|
|||
|
||||
// Anot.type
|
||||
var class2type = {}
|
||||
'Boolean Number String Function Array Date RegExp Object Error'.replace(
|
||||
Anot.rword,
|
||||
function(name) {
|
||||
'Boolean,Number,String,Function,Array,Date,RegExp,Object,Error,AsyncFunction,Promise,Generator,GeneratorFunction'
|
||||
.split(',')
|
||||
.forEach(function(name) {
|
||||
class2type['[object ' + name + ']'] = name.toLowerCase()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
Anot.type = function(obj) {
|
||||
//取得目标的类型
|
||||
if (obj == null) {
|
||||
return String(obj)
|
||||
if (obj) {
|
||||
// 早期的webkit内核浏览器实现了已废弃的ecma262v4标准,可以将正则字面量当作函数使用,因此typeof在判定正则时会返回function
|
||||
return typeof obj === 'object' || typeof obj === 'function'
|
||||
? class2type[inspect.call(obj)] || 'object'
|
||||
: typeof obj
|
||||
}
|
||||
// 早期的webkit内核浏览器实现了已废弃的ecma262v4标准,可以将正则字面量当作函数使用,因此typeof在判定正则时会返回function
|
||||
return typeof obj === 'object' || typeof obj === 'function'
|
||||
? class2type[inspect.call(obj)] || 'object'
|
||||
: typeof obj
|
||||
return String(obj)
|
||||
}
|
||||
|
||||
Anot.isFunction = function(fn) {
|
||||
|
@ -123,8 +121,8 @@ export function isArrayLike(obj) {
|
|||
}
|
||||
|
||||
Anot.each = function(obj, fn) {
|
||||
//排除null, undefined
|
||||
if (obj) {
|
||||
//排除null, undefined
|
||||
var i = 0
|
||||
if (isArrayLike(obj)) {
|
||||
for (var n = obj.length; i < n; i++) {
|
||||
|
|
|
@ -5,32 +5,34 @@ import {
|
|||
propagateChanged
|
||||
} from './transaction'
|
||||
import { Anot, platform } from '../seed/core'
|
||||
|
||||
/**
|
||||
*
|
||||
与Computed等共享UUID
|
||||
*/
|
||||
export let obid = 1
|
||||
export function Mutation(expr, value, vm) {
|
||||
//构造函数
|
||||
this.expr = expr
|
||||
if (value) {
|
||||
var childVm = platform.createProxy(value, this)
|
||||
if (childVm) {
|
||||
value = childVm
|
||||
}
|
||||
}
|
||||
this.value = value
|
||||
this.vm = vm
|
||||
try {
|
||||
vm.$mutations[expr] = this
|
||||
} catch (ignoreIE) {}
|
||||
this.uuid = ++obid
|
||||
this.updateVersion()
|
||||
this.mapIDs = {}
|
||||
this.observers = []
|
||||
}
|
||||
|
||||
Mutation.prototype = {
|
||||
export class Mutation {
|
||||
constructor(expr, value, vm) {
|
||||
//构造函数
|
||||
this.expr = expr
|
||||
if (value) {
|
||||
var childVm = platform.createProxy(value, this)
|
||||
if (childVm) {
|
||||
value = childVm
|
||||
}
|
||||
}
|
||||
this.value = value
|
||||
this.vm = vm
|
||||
try {
|
||||
vm.$mutations[expr] = this
|
||||
} catch (ignoreIE) {}
|
||||
this.uuid = ++obid
|
||||
this.updateVersion()
|
||||
this.mapIDs = {}
|
||||
this.observers = []
|
||||
}
|
||||
|
||||
get() {
|
||||
if (Anot.trackingAction) {
|
||||
this.collect() //被收集
|
||||
|
@ -52,22 +54,7 @@ Mutation.prototype = {
|
|||
}
|
||||
}
|
||||
return this.value
|
||||
},
|
||||
|
||||
collect() {
|
||||
// Anot.track(name, '被收集')
|
||||
reportObserved(this)
|
||||
},
|
||||
|
||||
updateVersion() {
|
||||
this.version = Math.random() + Math.random()
|
||||
},
|
||||
|
||||
notify() {
|
||||
transactionStart()
|
||||
propagateChanged(this)
|
||||
transactionEnd()
|
||||
},
|
||||
}
|
||||
|
||||
set(newValue) {
|
||||
var oldValue = this.value
|
||||
|
@ -87,4 +74,18 @@ Mutation.prototype = {
|
|||
this.notify()
|
||||
}
|
||||
}
|
||||
collect() {
|
||||
// Anot.track(name, '被收集')
|
||||
reportObserved(this)
|
||||
}
|
||||
|
||||
updateVersion() {
|
||||
this.version = Math.random() + Math.random()
|
||||
}
|
||||
|
||||
notify() {
|
||||
transactionStart()
|
||||
propagateChanged(this)
|
||||
transactionEnd()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,76 +3,76 @@ import { voidTag } from './voidTag'
|
|||
import { makeOrphan } from './makeOrphan'
|
||||
|
||||
export function fromDOM(dom) {
|
||||
return [from(dom)]
|
||||
return [_from(dom)]
|
||||
}
|
||||
|
||||
export function from(node) {
|
||||
var type = node.nodeName.toLowerCase()
|
||||
switch (type) {
|
||||
case '#text':
|
||||
case '#comment':
|
||||
return {
|
||||
nodeName: type,
|
||||
dom: node,
|
||||
nodeValue: node.nodeValue
|
||||
}
|
||||
default:
|
||||
var props = markProps(node, node.attributes || [])
|
||||
var vnode = {
|
||||
nodeName: type,
|
||||
dom: node,
|
||||
isVoidTag: !!voidTag[type],
|
||||
props: props
|
||||
}
|
||||
if(type === 'option'){
|
||||
//即便你设置了option.selected = true,
|
||||
//option.attributes也找不到selected属性
|
||||
props.selected = node.selected
|
||||
}
|
||||
if (orphanTag[type] || type === 'option') {
|
||||
makeOrphan(vnode, type, node.text || node.innerHTML)
|
||||
if (node.childNodes.length === 1) {
|
||||
vnode.children[0].dom = node.firstChild
|
||||
}
|
||||
} else if (!vnode.isVoidTag) {
|
||||
vnode.children = []
|
||||
for (var i = 0, el; el = node.childNodes[i++];) {
|
||||
var child = from(el)
|
||||
if (/\S/.test(child.nodeValue)) {
|
||||
vnode.children.push(child)
|
||||
}
|
||||
}
|
||||
}
|
||||
return vnode
|
||||
}
|
||||
export function _from(node) {
|
||||
var type = node.nodeName.toLowerCase()
|
||||
switch (type) {
|
||||
case '#text':
|
||||
case '#comment':
|
||||
return {
|
||||
nodeName: type,
|
||||
dom: node,
|
||||
nodeValue: node.nodeValue
|
||||
}
|
||||
default:
|
||||
var props = markProps(node, node.attributes || [])
|
||||
var vnode = {
|
||||
nodeName: type,
|
||||
dom: node,
|
||||
isVoidTag: !!voidTag[type],
|
||||
props: props
|
||||
}
|
||||
if (type === 'option') {
|
||||
//即便你设置了option.selected = true,
|
||||
//option.attributes也找不到selected属性
|
||||
props.selected = node.selected
|
||||
}
|
||||
if (orphanTag[type] || type === 'option') {
|
||||
makeOrphan(vnode, type, node.text || node.innerHTML)
|
||||
if (node.childNodes.length === 1) {
|
||||
vnode.children[0].dom = node.firstChild
|
||||
}
|
||||
} else if (!vnode.isVoidTag) {
|
||||
vnode.children = []
|
||||
for (var i = 0, el; (el = node.childNodes[i++]); ) {
|
||||
var child = _from(el)
|
||||
if (/\S/.test(child.nodeValue)) {
|
||||
vnode.children.push(child)
|
||||
}
|
||||
}
|
||||
}
|
||||
return vnode
|
||||
}
|
||||
}
|
||||
|
||||
var rformElement = /input|textarea|select/i
|
||||
|
||||
function markProps(node, attrs) {
|
||||
var ret = {}
|
||||
for (var i = 0, n = attrs.length; i < n; i++) {
|
||||
var attr = attrs[i]
|
||||
if (attr.specified) {
|
||||
//IE6-9不会将属性名变小写,比如它会将用户的contenteditable变成contentEditable
|
||||
ret[attr.name.toLowerCase()] = attr.value
|
||||
}
|
||||
var ret = {}
|
||||
for (var i = 0, n = attrs.length; i < n; i++) {
|
||||
var attr = attrs[i]
|
||||
if (attr.specified) {
|
||||
//IE6-9不会将属性名变小写,比如它会将用户的contenteditable变成contentEditable
|
||||
ret[attr.name.toLowerCase()] = attr.value
|
||||
}
|
||||
if (rformElement.test(node.nodeName)) {
|
||||
ret.type = node.type
|
||||
var a = node.getAttributeNode('value')
|
||||
if (a && /\S/.test(a.value)) { //IE6,7中无法取得checkbox,radio的value
|
||||
ret.value = a.value
|
||||
}
|
||||
|
||||
}
|
||||
if (rformElement.test(node.nodeName)) {
|
||||
ret.type = node.type
|
||||
var a = node.getAttributeNode('value')
|
||||
if (a && /\S/.test(a.value)) {
|
||||
//IE6,7中无法取得checkbox,radio的value
|
||||
ret.value = a.value
|
||||
}
|
||||
var style = node.style.cssText
|
||||
if (style) {
|
||||
ret.style = style
|
||||
}
|
||||
//类名 = 去重(静态类名+动态类名+ hover类名? + active类名)
|
||||
if (ret.type === 'select-one') {
|
||||
ret.selectedIndex = node.selectedIndex
|
||||
}
|
||||
return ret
|
||||
}
|
||||
var style = node.style.cssText
|
||||
if (style) {
|
||||
ret.style = style
|
||||
}
|
||||
//类名 = 去重(静态类名+动态类名+ hover类名? + active类名)
|
||||
if (ret.type === 'select-one') {
|
||||
ret.selectedIndex = node.selectedIndex
|
||||
}
|
||||
return ret
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
export var orphanTag = {
|
||||
script: 1,
|
||||
style: 1,
|
||||
textarea: 1,
|
||||
xmp: 1,
|
||||
noscript: 1,
|
||||
template: 1
|
||||
script: 1,
|
||||
style: 1,
|
||||
textarea: 1,
|
||||
xmp: 1,
|
||||
noscript: 1,
|
||||
template: 1
|
||||
}
|
|
@ -1,5 +1,29 @@
|
|||
import { Anot, oneObject } from '../seed/core'
|
||||
|
||||
var pNestChild = oneObject('div,ul,ol,dl,table,h1,h2,h3,h4,h5,h6,form,fieldset')
|
||||
var tNestChild = makeObject('tr,style,script')
|
||||
var nestObject = {
|
||||
p: pNestChild,
|
||||
select: makeObject('option,optgroup,#text'),
|
||||
optgroup: makeObject('option,#text'),
|
||||
option: makeObject('#text'),
|
||||
tr: makeObject('th,td,style,script'),
|
||||
|
||||
tbody: tNestChild,
|
||||
tfoot: tNestChild,
|
||||
thead: tNestChild,
|
||||
colgroup: makeObject('col'),
|
||||
// table: oneObject('caption,colgroup,tbody,thead,tfoot,style,script,template,#document-fragment'),
|
||||
head: makeObject(
|
||||
'base,basefont,bgsound,link,style,script,meta,title,noscript,noframes'
|
||||
),
|
||||
html: oneObject('head,body')
|
||||
}
|
||||
|
||||
function makeObject(str) {
|
||||
return oneObject(str + ',template,#document-fragment,#comment')
|
||||
}
|
||||
|
||||
export function validateDOMNesting(parent, child) {
|
||||
var parentTag = parent.nodeName
|
||||
var tag = child.nodeName
|
||||
|
@ -8,16 +32,16 @@ export function validateDOMNesting(parent, child) {
|
|||
if (parentTag === 'p') {
|
||||
if (pNestChild[tag]) {
|
||||
console.warn(
|
||||
'P element can not add these childlren:\n' + Object.keys(pNestChild)
|
||||
'P标签节点不允许以下类型的子节点:\n' + Object.keys(pNestChild)
|
||||
)
|
||||
return false
|
||||
}
|
||||
} else if (!parentChild[tag]) {
|
||||
console.warn(
|
||||
parentTag.toUpperCase() +
|
||||
'element only add these children:\n' +
|
||||
'标签节点只能增加以下子节点:\n' +
|
||||
Object.keys(parentChild) +
|
||||
'\nbut you add ' +
|
||||
'\n当前子节点为:' +
|
||||
tag.toUpperCase() +
|
||||
' !!'
|
||||
)
|
||||
|
@ -26,38 +50,3 @@ export function validateDOMNesting(parent, child) {
|
|||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function makeObject(str) {
|
||||
return oneObject(str + ',template,#document-fragment,#comment')
|
||||
}
|
||||
var pNestChild = oneObject('div,ul,ol,dl,table,h1,h2,h3,h4,h5,h6,form,fieldset')
|
||||
var tNestChild = makeObject('tr,style,script')
|
||||
var nestObject = {
|
||||
p: pNestChild,
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
|
||||
select: makeObject('option,optgroup,#text'),
|
||||
optgroup: makeObject('option,#text'),
|
||||
option: makeObject('#text'),
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
|
||||
// No special behavior since these rules fall back to "in body" mode for
|
||||
// all except special table nodes which cause bad parsing behavior anyway.
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
|
||||
tr: makeObject('th,td,style,script'),
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
|
||||
tbody: tNestChild,
|
||||
tfoot: tNestChild,
|
||||
thead: tNestChild,
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
|
||||
colgroup: makeObject('col'),
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
|
||||
// table: oneObject('caption,colgroup,tbody,thead,tfoot,style,script,template,#document-fragment'),
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
|
||||
head: makeObject(
|
||||
'base,basefont,bgsound,link,style,script,meta,title,noscript,noframes'
|
||||
),
|
||||
// https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
|
||||
html: oneObject('head,body')
|
||||
}
|
||||
|
|
Reference in New Issue