增加next配置;重构表单验证模块,去除UI
parent
112e3c2316
commit
adc8d73365
|
@ -15,5 +15,8 @@
|
||||||
npm start
|
npm start
|
||||||
|
|
||||||
# 生产环境
|
# 生产环境
|
||||||
npm run build
|
npm run prod
|
||||||
|
|
||||||
|
# 不编译,只压缩
|
||||||
|
npm run next
|
||||||
```
|
```
|
||||||
|
|
|
@ -40,7 +40,8 @@ const compileJs = (entry, output) => {
|
||||||
fs.cp(entry, output)
|
fs.cp(entry, output)
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
const { code } = babel.transformFileSync(entry, jsOpt)
|
let { code } = babel.transformFileSync(entry, jsOpt)
|
||||||
|
code = code.replace(/\.scss/g, '.css')
|
||||||
fs.echo(code, output)
|
fs.echo(code, output)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return log(err)
|
return log(err)
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
#! /usr/bin/env node
|
||||||
|
|
||||||
|
const log = console.log
|
||||||
|
const fs = require('iofs')
|
||||||
|
const path = require('path')
|
||||||
|
const scss = require('node-sass')
|
||||||
|
const postcss = require('postcss')
|
||||||
|
const autoprefixer = require('autoprefixer')
|
||||||
|
const chalk = require('chalk')
|
||||||
|
const uglify = require('uglify-es')
|
||||||
|
|
||||||
|
const sourceDir = path.resolve(__dirname, 'src')
|
||||||
|
const buildDir = path.resolve(__dirname, 'dist')
|
||||||
|
const prefixer = postcss().use(
|
||||||
|
autoprefixer({
|
||||||
|
browsers: ['ie > 9', 'iOS > 8', 'Android >= 4.4', 'ff > 38', 'Chrome > 38']
|
||||||
|
})
|
||||||
|
)
|
||||||
|
const cssOpt = {
|
||||||
|
includePaths: ['src/css/'],
|
||||||
|
outputStyle: 'compressed'
|
||||||
|
}
|
||||||
|
|
||||||
|
const compileJs = (entry, output) => {
|
||||||
|
if (/touch\.patch/.test(entry)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let t1 = Date.now()
|
||||||
|
let buf = fs.cat(entry).toString()
|
||||||
|
let { code } = uglify.minify(buf)
|
||||||
|
code = code.replace(/\.scss/g, '.css')
|
||||||
|
log(
|
||||||
|
'编译JS: %s, 耗时 %s ms',
|
||||||
|
chalk.green(entry),
|
||||||
|
chalk.yellow(Date.now() - t1)
|
||||||
|
)
|
||||||
|
fs.echo(code, output)
|
||||||
|
}
|
||||||
|
|
||||||
|
const compileCss = (entry, output) => {
|
||||||
|
let t1 = Date.now()
|
||||||
|
const { css } = scss.renderSync({ ...cssOpt, file: entry })
|
||||||
|
prefixer.process(css, { from: '', to: '' }).then(result => {
|
||||||
|
log(
|
||||||
|
'编译scss: %s, 耗时 %s ms',
|
||||||
|
chalk.green(entry),
|
||||||
|
chalk.yellow(Date.now() - t1)
|
||||||
|
)
|
||||||
|
fs.echo(result.css, output)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const compileHtm = (entry, output) => {
|
||||||
|
let t1 = Date.now()
|
||||||
|
let htm = fs.cat(entry).toString('utf8')
|
||||||
|
htm = htm.replace(/[\r\n\t]+/g, ' ').replace(/\s{2,}/g, ' ')
|
||||||
|
log(
|
||||||
|
'压缩HTML: %s, 耗时 %s ms',
|
||||||
|
chalk.green(entry),
|
||||||
|
chalk.yellow(Date.now() - t1)
|
||||||
|
)
|
||||||
|
fs.echo(htm, output)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=======================================================*/
|
||||||
|
/*===== ===*/
|
||||||
|
/*=======================================================*/
|
||||||
|
|
||||||
|
const fontFiles = fs.ls('./src/font/', true)
|
||||||
|
const jsFiles = fs.ls('./src/js/', true)
|
||||||
|
const cssFiles = fs.ls('./src/css/', true)
|
||||||
|
|
||||||
|
if (fs.isdir(buildDir)) {
|
||||||
|
fs.rm(buildDir, true)
|
||||||
|
log(chalk.cyan('清除旧目录 dist/'))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 字体文件直接复制
|
||||||
|
fontFiles.forEach(file => {
|
||||||
|
fs.cp('./src/font/' + file, './dist/font/' + file)
|
||||||
|
})
|
||||||
|
|
||||||
|
// css目录
|
||||||
|
cssFiles.forEach(file => {
|
||||||
|
if (/\.scss$/.test(file)) {
|
||||||
|
let entry = path.resolve(sourceDir, 'css/', file)
|
||||||
|
let output = path.resolve(buildDir, 'css/', file.replace(/scss$/, 'css'))
|
||||||
|
|
||||||
|
compileCss(entry, output)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// js目录的处理要复杂一点
|
||||||
|
jsFiles.forEach(file => {
|
||||||
|
let entry = path.resolve(sourceDir, 'js', file)
|
||||||
|
let output = path.resolve(buildDir, 'js', file)
|
||||||
|
let ext = file.slice(file.lastIndexOf('.') + 1)
|
||||||
|
|
||||||
|
switch (ext) {
|
||||||
|
case 'js':
|
||||||
|
compileJs(entry, output)
|
||||||
|
break
|
||||||
|
case 'scss':
|
||||||
|
output = output.replace(/scss$/, 'css')
|
||||||
|
compileCss(entry, output)
|
||||||
|
break
|
||||||
|
case 'htm':
|
||||||
|
compileHtm(entry, output)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
if (!fs.isdir(entry)) {
|
||||||
|
fs.cp(entry, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
|
@ -8,7 +8,7 @@ const scss = require('node-sass')
|
||||||
const postcss = require('postcss')
|
const postcss = require('postcss')
|
||||||
const autoprefixer = require('autoprefixer')
|
const autoprefixer = require('autoprefixer')
|
||||||
const chalk = require('chalk')
|
const chalk = require('chalk')
|
||||||
const uglify = require('uglify-js')
|
const uglify = require('uglify-es')
|
||||||
|
|
||||||
const sourceDir = path.resolve(__dirname, 'src')
|
const sourceDir = path.resolve(__dirname, 'src')
|
||||||
const buildDir = path.resolve(__dirname, 'dist')
|
const buildDir = path.resolve(__dirname, 'dist')
|
||||||
|
@ -41,7 +41,7 @@ const compileJs = (entry, output) => {
|
||||||
tmpOpt = Object.assign({}, jsOpt, { plugins: [] })
|
tmpOpt = Object.assign({}, jsOpt, { plugins: [] })
|
||||||
}
|
}
|
||||||
let { code } = babel.transformFileSync(entry, tmpOpt)
|
let { code } = babel.transformFileSync(entry, tmpOpt)
|
||||||
code = uglify.minify(code).code
|
code = uglify.minify(code).code.replace(/\.scss/g, '.css')
|
||||||
log(
|
log(
|
||||||
'编译JS: %s, 耗时 %s ms',
|
'编译JS: %s, 耗时 %s ms',
|
||||||
chalk.green(entry),
|
chalk.green(entry),
|
||||||
|
@ -84,7 +84,7 @@ const jsFiles = fs.ls('./src/js/', true)
|
||||||
const cssFiles = fs.ls('./src/css/', true)
|
const cssFiles = fs.ls('./src/css/', true)
|
||||||
|
|
||||||
if (fs.isdir(buildDir)) {
|
if (fs.isdir(buildDir)) {
|
||||||
// fs.rm(buildDir, true)
|
fs.rm(buildDir, true)
|
||||||
log(chalk.cyan('清除旧目录 dist/'))
|
log(chalk.cyan('清除旧目录 dist/'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3672,16 +3672,22 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"uglify-js": {
|
"uglify-es": {
|
||||||
"version": "3.3.15",
|
"version": "3.3.9",
|
||||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.15.tgz",
|
"resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz",
|
||||||
"integrity": "sha512-bqtBCAINYXX/OkdnqMGpbXr+OPWc00hsozRpk+dAtfnbdk2jjKiLmyOkQ7zamg648lVMnzATL8JrSN6LmaVpYA==",
|
"integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"commander": "2.15.0",
|
"commander": "2.13.0",
|
||||||
"source-map": "0.6.1"
|
"source-map": "0.6.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"commander": {
|
||||||
|
"version": "2.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz",
|
||||||
|
"integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"source-map": {
|
"source-map": {
|
||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
|
|
10
package.json
10
package.json
|
@ -5,16 +5,14 @@
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node ./build.dev.js",
|
"start": "node ./build.dev.js",
|
||||||
"build": "node ./build.prod.js"
|
"prod": "node ./build.prod.js",
|
||||||
|
"next": "node ./build.next.js"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/yutent/doui.git"
|
"url": "git+https://github.com/yutent/doui.git"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": ["doui", "Anot"],
|
||||||
"doui",
|
|
||||||
"Anot"
|
|
||||||
],
|
|
||||||
"author": "yutent",
|
"author": "yutent",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -29,7 +27,7 @@
|
||||||
"iofs": "^1.0.3",
|
"iofs": "^1.0.3",
|
||||||
"node-sass": "^4.8.2",
|
"node-sass": "^4.8.2",
|
||||||
"postcss": "^6.0.19",
|
"postcss": "^6.0.19",
|
||||||
"uglify-js": "^3.3.15"
|
"uglify-es": "^3.3.9"
|
||||||
},
|
},
|
||||||
"dependencies": {}
|
"dependencies": {}
|
||||||
}
|
}
|
||||||
|
|
494
src/js/anot.js
494
src/js/anot.js
|
@ -5,22 +5,7 @@
|
||||||
* support IE10+ and other browsers
|
* support IE10+ and other browsers
|
||||||
*
|
*
|
||||||
==================================================*/
|
==================================================*/
|
||||||
;(function(global, factory) {
|
const _Anot = (function() {
|
||||||
if (typeof module === 'object' && typeof module.exports === 'object') {
|
|
||||||
module.exports = global.document
|
|
||||||
? factory(global, true)
|
|
||||||
: function(w) {
|
|
||||||
if (!w.document) {
|
|
||||||
throw new Error('Anot.js只能运行在浏览器环境')
|
|
||||||
}
|
|
||||||
return factory(w)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
factory(global)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pass this if window is not defined yet
|
|
||||||
})(typeof window !== 'undefined' ? window : this, function(window, noGlobal) {
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* 全局变量及方法 *
|
* 全局变量及方法 *
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
@ -35,7 +20,7 @@
|
||||||
var head = DOC.head //HEAD元素
|
var head = DOC.head //HEAD元素
|
||||||
head.insertAdjacentHTML(
|
head.insertAdjacentHTML(
|
||||||
'afterBegin',
|
'afterBegin',
|
||||||
'<anot :skip class="anot-hide"><style id="anot-style">.anot-hide{ display: none!important } .do-rule-tips {position:absolute;z-index:65535;min-width:75px;height:30px;padding:7px 8px;line-height:16px;color:#333;background:#f9ca05;white-space:pre;} .do-rule-tips::before {position:absolute;left:5px;bottom:-8px;width:0;height:0;border:8px solid transparent;border-left:8px solid #f9ca05;content: " "}</style></anot>'
|
'<anot skip class="anot-hide"><style id="anot-style">.anot-hide{ display: none!important }</style></anot>'
|
||||||
)
|
)
|
||||||
var ifGroup = head.firstChild
|
var ifGroup = head.firstChild
|
||||||
|
|
||||||
|
@ -141,7 +126,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tickObserver) {
|
if (tickObserver) {
|
||||||
var node = document.createTextNode('any')
|
var node = document.createTextNode('anot')
|
||||||
new tickObserver(callback).observe(node, { characterData: true }) // jshint ignore:line
|
new tickObserver(callback).observe(node, { characterData: true }) // jshint ignore:line
|
||||||
var bool = false
|
var bool = false
|
||||||
return function(fn) {
|
return function(fn) {
|
||||||
|
@ -181,7 +166,11 @@
|
||||||
return ''
|
return ''
|
||||||
},
|
},
|
||||||
check: function(val) {
|
check: function(val) {
|
||||||
return Anot.type(val) === this.checkType
|
this.result = Anot.type(val)
|
||||||
|
return this.result === this.checkType
|
||||||
|
},
|
||||||
|
call: function() {
|
||||||
|
return this.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,13 +224,13 @@
|
||||||
if ($elem === DOC.body) {
|
if ($elem === DOC.body) {
|
||||||
scanTag($elem, [])
|
scanTag($elem, [])
|
||||||
} else {
|
} else {
|
||||||
var $parent = null
|
var $parent = $elem
|
||||||
while (($parent = $elem.parentNode)) {
|
while (($parent = $parent.parentNode)) {
|
||||||
if ($parent.anotctrl) {
|
if ($parent.anotctrl) {
|
||||||
scanTag($elem.parentNode, [VMODELS[$parent.anotctrl]])
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
scanTag($elem.parentNode, $parent ? [VMODELS[$parent.anotctrl]] : [])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return vm
|
return vm
|
||||||
|
@ -460,7 +449,7 @@
|
||||||
value: function() {
|
value: function() {
|
||||||
var thisYear = this.getFullYear(),
|
var thisYear = this.getFullYear(),
|
||||||
that = new Date(thisYear, 0, 1),
|
that = new Date(thisYear, 0, 1),
|
||||||
firstDay = that.getDay(),
|
firstDay = that.getDay() || 1,
|
||||||
numsOfToday = (this - that) / 86400000
|
numsOfToday = (this - that) / 86400000
|
||||||
return Math.ceil((numsOfToday + firstDay) / 7)
|
return Math.ceil((numsOfToday + firstDay) / 7)
|
||||||
},
|
},
|
||||||
|
@ -1373,6 +1362,7 @@
|
||||||
var methods = source.methods
|
var methods = source.methods
|
||||||
var props = source.props
|
var props = source.props
|
||||||
var watches = source.watch
|
var watches = source.watch
|
||||||
|
var mounted = source.mounted
|
||||||
|
|
||||||
delete source.state
|
delete source.state
|
||||||
delete source.computed
|
delete source.computed
|
||||||
|
@ -1488,6 +1478,8 @@
|
||||||
hideProperty($vmodel, '$active', false)
|
hideProperty($vmodel, '$active', false)
|
||||||
hideProperty($vmodel, '$pathname', old ? old.$pathname : '')
|
hideProperty($vmodel, '$pathname', old ? old.$pathname : '')
|
||||||
hideProperty($vmodel, '$accessors', accessors)
|
hideProperty($vmodel, '$accessors', accessors)
|
||||||
|
hideProperty($vmodel, '$refs', {})
|
||||||
|
hideProperty($vmodel, '$children', [])
|
||||||
hideProperty($vmodel, 'hasOwnProperty', trackBy)
|
hideProperty($vmodel, 'hasOwnProperty', trackBy)
|
||||||
if (options.watch) {
|
if (options.watch) {
|
||||||
hideProperty($vmodel, '$watch', function() {
|
hideProperty($vmodel, '$watch', function() {
|
||||||
|
@ -1500,6 +1492,12 @@
|
||||||
var v = Anot.vmodels[i]
|
var v = Anot.vmodels[i]
|
||||||
v.$fire && v.$fire.apply(v, [ee, a])
|
v.$fire && v.$fire.apply(v, [ee, a])
|
||||||
}
|
}
|
||||||
|
} else if (path.indexOf('child!') === 0) {
|
||||||
|
var ee = 'props.' + path.slice(6)
|
||||||
|
for (var i in $vmodel.$children) {
|
||||||
|
var v = $vmodel.$children[i]
|
||||||
|
v.$fire && v.$fire.apply(v, [ee, a])
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$emit.call($vmodel, path, [a])
|
$emit.call($vmodel, path, [a])
|
||||||
}
|
}
|
||||||
|
@ -1527,6 +1525,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
$vmodel.$active = true
|
$vmodel.$active = true
|
||||||
|
$vmodel.mounted = mounted
|
||||||
|
|
||||||
|
if (old && old.$up) {
|
||||||
|
old.$up.$children.push($vmodel)
|
||||||
|
}
|
||||||
|
|
||||||
return $vmodel
|
return $vmodel
|
||||||
}
|
}
|
||||||
|
@ -2912,7 +2915,7 @@
|
||||||
binding.observers.forEach(function(it) {
|
binding.observers.forEach(function(it) {
|
||||||
if (it.type === 'function') {
|
if (it.type === 'function') {
|
||||||
// log(it, expr)
|
// log(it, expr)
|
||||||
let reg = new RegExp(it.p + '\\(([^)]*)\\)', 'g')
|
var reg = new RegExp(it.p + '\\(([^)]*)\\)', 'g')
|
||||||
expr = expr.replace(reg, function(s, m) {
|
expr = expr.replace(reg, function(s, m) {
|
||||||
m = m.trim()
|
m = m.trim()
|
||||||
return (
|
return (
|
||||||
|
@ -2933,7 +2936,7 @@
|
||||||
"'use strict';\ntry{\nvar " +
|
"'use strict';\ntry{\nvar " +
|
||||||
assigns.join(',\n') +
|
assigns.join(',\n') +
|
||||||
expr +
|
expr +
|
||||||
'\n}catch(e){log(e)}'
|
'\n}catch(e){console.log(e)}'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
/* jshint ignore:end */
|
/* jshint ignore:end */
|
||||||
|
@ -3082,17 +3085,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
var rnoCollect = /^(:\S+|data-\S+|on[a-z]+|id|style|class)$/
|
var rnoCollect = /^(:\S+|data-\S+|on[a-z]+|id|style|class)$/
|
||||||
var ronattr = /^on\-[\w-]+$/
|
var ronattr = '__fn__'
|
||||||
function getOptionsFromTag(elem, vmodels) {
|
function getOptionsFromTag(elem, vmodels) {
|
||||||
var attributes = elem.attributes
|
var attributes = elem.attributes
|
||||||
var ret = {}
|
var ret = {}
|
||||||
for (var i = 0, attr; (attr = attributes[i++]); ) {
|
for (var i = 0, attr; (attr = attributes[i++]); ) {
|
||||||
var name = attr.name
|
var name = attr.name
|
||||||
if (attr.specified && !rnoCollect.test(name)) {
|
if (attr.specified && !rnoCollect.test(name)) {
|
||||||
var camelizeName = camelize(attr.name)
|
if (name.indexOf(ronattr) === 0) {
|
||||||
if (/^on\-[\w-]+$/.test(name)) {
|
name = attr.value.slice(6)
|
||||||
ret[camelizeName] = getBindingCallback(elem, name, vmodels)
|
ret[name] = elem[attr.value]
|
||||||
|
delete elem[attr.value]
|
||||||
} else {
|
} else {
|
||||||
|
var camelizeName = camelize(name)
|
||||||
ret[camelizeName] = parseData(attr.value)
|
ret[camelizeName] = parseData(attr.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3224,6 +3229,12 @@
|
||||||
//确保所有:attr-name扫描完再处理
|
//确保所有:attr-name扫描完再处理
|
||||||
_delay_component(widget)
|
_delay_component(widget)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// 非组件才检查 ref属性
|
||||||
|
var ref = isRef(elem)
|
||||||
|
if (ref) {
|
||||||
|
vmodels[0].$refs[ref] = elem
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3267,34 +3278,19 @@
|
||||||
createSignalTower(elem, newVmodel)
|
createSignalTower(elem, newVmodel)
|
||||||
hideProperty(newVmodel, '$elem', elem)
|
hideProperty(newVmodel, '$elem', elem)
|
||||||
if (vmodels.length) {
|
if (vmodels.length) {
|
||||||
attrs.forEach(function(attr, i) {
|
var props = {}
|
||||||
|
attrs.forEach(function(attr) {
|
||||||
if (/^:/.test(attr.name)) {
|
if (/^:/.test(attr.name)) {
|
||||||
var name = attr.name.match(rmsAttr)[1]
|
var name = attr.name.match(rmsAttr)[1]
|
||||||
var value = null
|
var value = null
|
||||||
if (!name || Anot.directives[name]) {
|
if (!name || Anot.directives[name] || events[name]) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
value = parseExpr(attr.value, vmodels, {}).apply(0, vmodels)
|
value = parseExpr(attr.value, vmodels, {}).apply(0, vmodels)
|
||||||
|
value = toJson(value)
|
||||||
elem.removeAttribute(attr.name)
|
elem.removeAttribute(attr.name)
|
||||||
if (!value) {
|
props[name] = value
|
||||||
return
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
newVmodel.props[name] &&
|
|
||||||
newVmodel.props[name].type === 'PropsTypes'
|
|
||||||
) {
|
|
||||||
if (newVmodel.props[name].check(value)) {
|
|
||||||
newVmodel.props[name] = value
|
|
||||||
} else {
|
|
||||||
Anot.error(
|
|
||||||
'props「' + name + '」类型错误!' + value,
|
|
||||||
TypeError
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
newVmodel.props[name] = value
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log(
|
log(
|
||||||
'Props parse faild on (%s[class=%s]),',
|
'Props parse faild on (%s[class=%s]),',
|
||||||
|
@ -3306,13 +3302,38 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
// 一旦设定了 props的类型, 就必须传入正确的值
|
||||||
|
for (var k in newVmodel.props) {
|
||||||
|
if (newVmodel.props[k] && newVmodel.props[k].type === 'PropsTypes') {
|
||||||
|
if (newVmodel.props[k].check(props[k])) {
|
||||||
|
newVmodel.props[k] = props[k]
|
||||||
|
delete props[k]
|
||||||
|
} else {
|
||||||
|
Anot.error(
|
||||||
|
'props.' +
|
||||||
|
k +
|
||||||
|
' needs [' +
|
||||||
|
newVmodel.props[k].checkType +
|
||||||
|
'], but [' +
|
||||||
|
newVmodel.props[k].result +
|
||||||
|
'] given.',
|
||||||
|
TypeError
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Object.assign(newVmodel.props, props)
|
||||||
|
props = undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scanAttr(elem, vm) //扫描特性节点
|
scanAttr(elem, vm) //扫描特性节点
|
||||||
|
|
||||||
if (newVmodel) {
|
if (newVmodel) {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
newVmodel.$fire(':scan-end', elem)
|
if (typeof newVmodel.mounted === 'function') {
|
||||||
|
newVmodel.mounted()
|
||||||
|
}
|
||||||
|
delete newVmodel.mounted
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3436,15 +3457,13 @@
|
||||||
var componentQueue = []
|
var componentQueue = []
|
||||||
var widgetList = []
|
var widgetList = []
|
||||||
var componentHooks = {
|
var componentHooks = {
|
||||||
construct: function(props, next) {
|
construct: noop,
|
||||||
next(props)
|
|
||||||
},
|
|
||||||
componentWillMount: noop,
|
componentWillMount: noop,
|
||||||
componentDidMount: noop,
|
componentDidMount: noop,
|
||||||
childComponentDidMount: noop,
|
childComponentDidMount: noop,
|
||||||
componentWillUnmount: noop,
|
componentWillUnmount: noop,
|
||||||
render: function(str) {
|
render: function() {
|
||||||
return str
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3474,21 +3493,19 @@
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var props = getOptionsFromTag(elem, host.vmodels)
|
var props = getOptionsFromTag(elem, host.vmodels)
|
||||||
var vmOpts = getOptionsFromVM(host.vmodels, props.config)
|
|
||||||
var $id = props.uuid || generateID(widget)
|
var $id = props.uuid || generateID(widget)
|
||||||
var componentDefinition = {}
|
|
||||||
|
|
||||||
props = Object.assign({}, vmOpts, props)
|
|
||||||
vmOpts = void 0
|
|
||||||
delete props.config
|
|
||||||
delete props.uuid
|
delete props.uuid
|
||||||
hooks.construct.call(elem, props, function next(val) {
|
delete props.name
|
||||||
Object.assign(hooks.props, val)
|
|
||||||
Object.assign(componentDefinition, hooks)
|
|
||||||
})
|
|
||||||
|
|
||||||
componentDefinition.$refs = {}
|
hooks.props = hooks.props || {}
|
||||||
componentDefinition.$id = $id
|
hooks.state = hooks.state || {}
|
||||||
|
|
||||||
|
Object.assign(hooks.props, props)
|
||||||
|
|
||||||
|
hooks.construct.call(elem, hooks.props, hooks.state)
|
||||||
|
|
||||||
|
hooks.$id = $id
|
||||||
|
|
||||||
//==========构建VM=========
|
//==========构建VM=========
|
||||||
var {
|
var {
|
||||||
|
@ -3497,15 +3514,17 @@
|
||||||
childComponentDidMount,
|
childComponentDidMount,
|
||||||
componentWillUnmount,
|
componentWillUnmount,
|
||||||
render
|
render
|
||||||
} = componentDefinition
|
} = hooks
|
||||||
|
|
||||||
delete componentDefinition.construct
|
delete hooks.construct
|
||||||
delete componentDefinition.componentWillMount
|
delete hooks.componentWillMount
|
||||||
delete componentDefinition.componentDidMount
|
delete hooks.componentDidMount
|
||||||
delete componentDefinition.childComponentDidMount
|
delete hooks.childComponentDidMount
|
||||||
delete componentDefinition.componentWillUnmount
|
delete hooks.componentWillUnmount
|
||||||
|
|
||||||
var vmodel = Anot(componentDefinition)
|
var vmodel = Anot(hooks)
|
||||||
|
delete vmodel.mounted
|
||||||
|
host.vmodels[0].$children.push(vmodel)
|
||||||
|
|
||||||
elem.msResolved = 1 //防止二进扫描此元素
|
elem.msResolved = 1 //防止二进扫描此元素
|
||||||
|
|
||||||
|
@ -3514,18 +3533,30 @@
|
||||||
|
|
||||||
if (!elem.content.firstElementChild) {
|
if (!elem.content.firstElementChild) {
|
||||||
Anot.clearHTML(elem)
|
Anot.clearHTML(elem)
|
||||||
elem.innerHTML = render()
|
var html = render.call(vmodel) || ''
|
||||||
|
|
||||||
|
html = html.replace(/<\w+[^>]*>/g, function(m, s) {
|
||||||
|
return m.replace(/[\n\t\s]{1,}/g, ' ')
|
||||||
|
})
|
||||||
|
|
||||||
|
elem.innerHTML = html
|
||||||
}
|
}
|
||||||
|
|
||||||
// 组件所使用的标签是temlate,所以必须要要用子元素替换掉
|
// 组件所使用的标签是temlate,所以必须要要用子元素替换掉
|
||||||
var child = elem.content.firstElementChild
|
var child = elem.content.firstElementChild
|
||||||
elem.parentNode.replaceChild(child, elem)
|
var nullComponent = DOC.createComment('empty component')
|
||||||
|
elem.parentNode.replaceChild(child || nullComponent, elem)
|
||||||
|
|
||||||
|
// 空组件直接跳出
|
||||||
|
if (!child) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
child.msResolved = 1
|
child.msResolved = 1
|
||||||
var cssText = elem.style.cssText
|
var cssText = elem.style.cssText
|
||||||
var className = elem.className
|
var className = elem.className
|
||||||
elem = host.element = child
|
elem = host.element = child
|
||||||
elem.style.cssText += ';' + cssText
|
elem.style && (elem.style.cssText += ';' + cssText)
|
||||||
|
|
||||||
if (className) {
|
if (className) {
|
||||||
Anot(elem).addClass(className)
|
Anot(elem).addClass(className)
|
||||||
|
@ -3542,10 +3573,11 @@
|
||||||
if (ev.childReady) {
|
if (ev.childReady) {
|
||||||
dependencies += ev.childReady
|
dependencies += ev.childReady
|
||||||
if (vmodel !== ev.vm) {
|
if (vmodel !== ev.vm) {
|
||||||
vmodel.$refs[ev.vm.$id] = ev.vm
|
vmodel.$children.push(ev.vm)
|
||||||
|
ev.vm.$up = vmodel
|
||||||
if (ev.childReady === -1) {
|
if (ev.childReady === -1) {
|
||||||
children++
|
children++
|
||||||
childComponentDidMount.call(vmodel, elem, ev)
|
childComponentDidMount.call(vmodel, ev.vm)
|
||||||
}
|
}
|
||||||
ev.stopPropagation()
|
ev.stopPropagation()
|
||||||
}
|
}
|
||||||
|
@ -3590,24 +3622,11 @@
|
||||||
})
|
})
|
||||||
}, 17)
|
}, 17)
|
||||||
}
|
}
|
||||||
})(obj, Anot.components[name], obj.element, obj.name) // jshint ignore:line
|
})(obj, toJson(Anot.components[name]), obj.element, obj.name) // jshint ignore:line
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOptionsFromVM(vmodels, pre) {
|
|
||||||
if (pre) {
|
|
||||||
for (var i = 0, v; (v = vmodels[i++]); ) {
|
|
||||||
if (v.hasOwnProperty(pre) && typeof v[pre] === 'object') {
|
|
||||||
var vmOptions = v[pre]
|
|
||||||
return vmOptions.$model || vmOptions
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
|
|
||||||
function isWidget(el) {
|
function isWidget(el) {
|
||||||
//如果是组件,则返回组件的名字
|
//如果是组件,则返回组件的名字
|
||||||
var name = el.nodeName.toLowerCase()
|
var name = el.nodeName.toLowerCase()
|
||||||
|
@ -3617,6 +3636,10 @@
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isRef(el) {
|
||||||
|
return el.hasAttribute('ref') ? el.getAttribute('ref') : null
|
||||||
|
}
|
||||||
|
|
||||||
var bools = [
|
var bools = [
|
||||||
'autofocus,autoplay,async,allowTransparency,checked,controls',
|
'autofocus,autoplay,async,allowTransparency,checked,controls',
|
||||||
'declare,disabled,defer,defaultChecked,defaultSelected',
|
'declare,disabled,defer,defaultChecked,defaultSelected',
|
||||||
|
@ -3687,11 +3710,16 @@
|
||||||
update: function(val) {
|
update: function(val) {
|
||||||
var elem = this.element
|
var elem = this.element
|
||||||
var obj = val
|
var obj = val
|
||||||
|
var vm = this.vmodels[0]
|
||||||
|
|
||||||
if (typeof obj === 'object' && obj !== null) {
|
if (typeof obj === 'object' && obj !== null) {
|
||||||
if (!Anot.isPlainObject(obj)) obj = obj.$model
|
if (!Anot.isPlainObject(obj)) {
|
||||||
|
obj = obj.$model
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!this.param) return
|
if (!this.param) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
obj = {}
|
obj = {}
|
||||||
obj[this.param] = val
|
obj[this.param] = val
|
||||||
|
@ -3711,24 +3739,32 @@
|
||||||
//chrome v37- 下embed标签动态设置的src,无法发起请求
|
//chrome v37- 下embed标签动态设置的src,无法发起请求
|
||||||
if (window.chrome && elem.tagName === 'EMBED') {
|
if (window.chrome && elem.tagName === 'EMBED') {
|
||||||
var parent = elem.parentNode
|
var parent = elem.parentNode
|
||||||
var com = document.createComment(':src')
|
var com = DOC.createComment(':src')
|
||||||
parent.replaceChild(com, elem)
|
parent.replaceChild(com, elem)
|
||||||
parent.replaceChild(elem, com)
|
parent.replaceChild(elem, com)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var k = i
|
var k = i
|
||||||
//古董IE下,部分属性名字要进行映射
|
//古董IE下,部分属性名字要进行映射
|
||||||
if (!W3C && propMap[k]) k = propMap[k]
|
if (!W3C && propMap[k]) {
|
||||||
|
k = propMap[k]
|
||||||
|
}
|
||||||
|
if (obj[i] === false || obj[i] === null || obj[i] === undefined) {
|
||||||
|
obj[i] = ''
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof elem[boolMap[k]] === 'boolean') {
|
if (typeof elem[boolMap[k]] === 'boolean') {
|
||||||
//布尔属性必须使用el.xxx = true|false方式设值
|
//布尔属性必须使用el.xxx = true|false方式设值
|
||||||
elem[boolMap[k]] = !!obj[i]
|
elem[boolMap[k]] = !!obj[i]
|
||||||
|
|
||||||
//如果为false, IE全系列下相当于setAttribute(xxx, ''),会影响到样式,需要进一步处理
|
//如果为false, IE全系列下相当于setAttribute(xxx, ''),会影响到样式,需要进一步处理
|
||||||
if (!obj[i]) obj[i] = !!obj[i]
|
if (!obj[i]) {
|
||||||
|
obj[i] = !!obj[i]
|
||||||
|
}
|
||||||
|
if (obj[i] === false) {
|
||||||
|
return elem.removeAttribute(k)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (obj[i] === false || obj[i] === null || obj[i] === undefined)
|
|
||||||
return elem.removeAttribute(k)
|
|
||||||
|
|
||||||
//SVG只能使用setAttribute(xxx, yyy), VML只能使用elem.xxx = yyy ,HTML的固有属性必须elem.xxx = yyy
|
//SVG只能使用setAttribute(xxx, yyy), VML只能使用elem.xxx = yyy ,HTML的固有属性必须elem.xxx = yyy
|
||||||
var isInnate = rsvg.test(elem)
|
var isInnate = rsvg.test(elem)
|
||||||
|
@ -3737,6 +3773,13 @@
|
||||||
if (isInnate) {
|
if (isInnate) {
|
||||||
elem[k] = obj[i]
|
elem[k] = obj[i]
|
||||||
} else {
|
} else {
|
||||||
|
if (typeof obj[i] === 'object') {
|
||||||
|
obj[i] = JSON.stringify(obj[i])
|
||||||
|
} else if (typeof obj[i] === 'function') {
|
||||||
|
k = '__fn__' + camelize(k)
|
||||||
|
elem[k] = obj[i].bind(vm)
|
||||||
|
obj[i] = k
|
||||||
|
}
|
||||||
elem.setAttribute(k, obj[i])
|
elem.setAttribute(k, obj[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3881,115 +3924,121 @@
|
||||||
|
|
||||||
/*------ 表单验证 -------*/
|
/*------ 表单验证 -------*/
|
||||||
var __rules = {}
|
var __rules = {}
|
||||||
Anot.validate = function(key) {
|
Anot.validate = function(key, cb) {
|
||||||
return (
|
if (!__rules[key]) {
|
||||||
!__rules[key] ||
|
throw new Error('validate [' + key + '] not exists.')
|
||||||
__rules[key].every(function(it) {
|
}
|
||||||
return it.checked
|
if (typeof cb === 'function') {
|
||||||
})
|
__rules[key].event = cb
|
||||||
)
|
}
|
||||||
|
var result = __rules[key].result
|
||||||
|
for (var k in result) {
|
||||||
|
if (!result[k].passed) {
|
||||||
|
return result[k]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
Anot.directive('rule', {
|
Anot.directive('rule', {
|
||||||
priority: 2010,
|
priority: 2010,
|
||||||
init: function(binding) {
|
init: function(binding) {
|
||||||
if (binding.param && !__rules[binding.param]) {
|
if (binding.param && !__rules[binding.param]) {
|
||||||
__rules[binding.param] = []
|
__rules[binding.param] = {
|
||||||
|
event: noop,
|
||||||
|
result: {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
binding.target = __rules[binding.param]
|
binding.target = __rules[binding.param]
|
||||||
},
|
},
|
||||||
update: function(obj) {
|
update: function(opt) {
|
||||||
var _this = this,
|
var _this = this
|
||||||
elem = this.element,
|
var elem = this.element
|
||||||
ruleID = -1
|
if (!['INPUT', 'TEXTAREA'].includes(elem.nodeName)) {
|
||||||
|
return
|
||||||
if (!['INPUT', 'TEXTAREA'].includes(elem.nodeName)) return
|
}
|
||||||
|
|
||||||
if (this.target) {
|
if (this.target) {
|
||||||
ruleID = this.target.length
|
this.target.result[elem.expr] = { key: elem.expr }
|
||||||
this.target.push({ checked: true })
|
|
||||||
}
|
}
|
||||||
|
var target = this.target
|
||||||
|
|
||||||
//如果父级元素没有定位属性,则加上相对定位
|
// 0: 验证通过
|
||||||
if (getComputedStyle(elem.parentNode).position === 'static') {
|
// 10001: 不能为空
|
||||||
elem.parentNode.style.position = 'relative'
|
// 10002: 必须为合法数字
|
||||||
}
|
// 10003: Email格式错误
|
||||||
|
// 10004: 手机格式错误
|
||||||
var $elem = Anot(elem),
|
// 10005: 必须为纯中文
|
||||||
ol = elem.offsetLeft + elem.offsetWidth - 50,
|
// 10006: 格式匹配错误(正则)
|
||||||
ot = elem.offsetTop + elem.offsetHeight + 8,
|
// 10011: 输入值超过指定最大长度
|
||||||
tips = document.createElement('div')
|
// 10012: 输入值短于指定最小长度
|
||||||
|
// 10021: 输入值大于指定最大数值
|
||||||
tips.className = 'do-rule-tips'
|
// 10022: 输入值小于指定最小数值
|
||||||
tips.style.left = ol + 'px'
|
// 10031: 与指定的表单的值不一致
|
||||||
tips.style.bottom = ot + 'px'
|
|
||||||
|
|
||||||
function checked(ev) {
|
function checked(ev) {
|
||||||
var txt = '',
|
var val = elem.value
|
||||||
val = elem.value
|
var code = 0
|
||||||
|
|
||||||
if (obj.require && (val === '' || val === null)) txt = '必填项'
|
if (opt.require && (val === '' || val === null)) {
|
||||||
|
code = 10001
|
||||||
if (!txt && obj.isNumeric) txt = !isFinite(val) ? '必须为合法数字' : ''
|
|
||||||
|
|
||||||
if (!txt && obj.isEmail)
|
|
||||||
txt = !/^[\w\.\-]+@\w+([\.\-]\w+)*\.\w+$/.test(val)
|
|
||||||
? 'Email格式错误'
|
|
||||||
: ''
|
|
||||||
|
|
||||||
if (!txt && obj.isPhone)
|
|
||||||
txt = !/^1[34578]\d{9}$/.test(val) ? '手机格式错误' : ''
|
|
||||||
|
|
||||||
if (!txt && obj.isCN)
|
|
||||||
txt = !/^[\u4e00-\u9fa5]+$/.test(val) ? '必须为纯中文' : ''
|
|
||||||
|
|
||||||
if (!txt && obj.exp)
|
|
||||||
txt = !obj.exp.test(val) ? obj.msg || '格式错误' : ''
|
|
||||||
|
|
||||||
if (!txt && obj.maxLen)
|
|
||||||
txt =
|
|
||||||
val.length > obj.maxLen ? '长度不得超过' + obj.maxLen + '位' : ''
|
|
||||||
|
|
||||||
if (!txt && obj.minLen)
|
|
||||||
txt =
|
|
||||||
val.length < obj.minLen ? '长度不得小于' + obj.minLen + '位' : ''
|
|
||||||
|
|
||||||
if (!txt && obj.hasOwnProperty('max'))
|
|
||||||
txt = val > obj.max ? '输入值不能大于' + obj.max : ''
|
|
||||||
|
|
||||||
if (!txt && obj.hasOwnProperty('min'))
|
|
||||||
txt = val < obj.min ? '输入值不能小于' + obj.min : ''
|
|
||||||
|
|
||||||
if (!txt && obj.eq) {
|
|
||||||
var eqEl = document.querySelector('#' + obj.eq)
|
|
||||||
txt = val !== eqEl.value ? obj.msg || '2次值不一致' : ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (txt) {
|
if (code === 0 && opt.isNumeric) {
|
||||||
if (ev) {
|
code = !isFinite(val) ? 10002 : 0
|
||||||
tips.textContent = txt
|
}
|
||||||
elem.parentNode.appendChild(tips)
|
|
||||||
|
if (code === 0 && opt.isEmail)
|
||||||
|
code = !/^[\w\.\-]+@\w+([\.\-]\w+)*\.\w+$/.test(val) ? 10003 : 0
|
||||||
|
|
||||||
|
if (code === 0 && opt.isPhone) {
|
||||||
|
code = !/^1[34578]\d{9}$/.test(val) ? 10004 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code === 0 && opt.isCN) {
|
||||||
|
code = !/^[\u4e00-\u9fa5]+$/.test(val) ? 10005 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code === 0 && opt.exp) {
|
||||||
|
code = !opt.exp.test(val) ? 10006 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code === 0 && opt.maxLen) {
|
||||||
|
code = val.length > opt.maxLen ? 10011 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code === 0 && opt.minLen) {
|
||||||
|
code = val.length < opt.minLen ? 10012 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code === 0 && opt.hasOwnProperty('max')) {
|
||||||
|
code = val > opt.max ? 10021 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code === 0 && opt.hasOwnProperty('min')) {
|
||||||
|
code = val < opt.min ? 10022 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code === 0 && opt.eq) {
|
||||||
|
var eqEl = document.querySelector('#' + opt.eq)
|
||||||
|
txt = val !== eqEl.value ? 10031 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
target.result[elem.expr].code = code
|
||||||
|
target.result[elem.expr].passed = opt.require ? code === 0 : true
|
||||||
|
|
||||||
|
var done
|
||||||
|
for (var k in target.result) {
|
||||||
|
if (!target.result[k].passed) {
|
||||||
|
done = true
|
||||||
|
target.event(target.result[k])
|
||||||
|
break
|
||||||
}
|
}
|
||||||
//必须是"必填项"才会更新验证状态
|
}
|
||||||
if (_this.target && obj.require) {
|
if (!done) {
|
||||||
_this.target[ruleID].checked = false
|
target.event(true)
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (_this.target) {
|
|
||||||
_this.target[ruleID].checked = true
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
elem.parentNode.removeChild(tips)
|
|
||||||
} catch (err) {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$elem.bind('change,blur', checked)
|
Anot(elem).bind('blur', checked)
|
||||||
$elem.bind('focus', function(ev) {
|
|
||||||
try {
|
|
||||||
elem.parentNode.removeChild(tips)
|
|
||||||
} catch (err) {}
|
|
||||||
})
|
|
||||||
|
|
||||||
checked()
|
checked()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -4039,12 +4088,13 @@
|
||||||
? 'change'
|
? 'change'
|
||||||
: 'input'
|
: 'input'
|
||||||
}
|
}
|
||||||
|
elem.expr = binding.expr
|
||||||
//===================绑定事件======================
|
//===================绑定事件======================
|
||||||
var bound = (binding.bound = function(type, callback) {
|
var bound = (binding.bound = function(type, callback) {
|
||||||
elem.addEventListener(type, callback, false)
|
elem.addEventListener(type, callback, false)
|
||||||
var old = binding.rollback
|
var old = binding.rollback
|
||||||
binding.rollback = function() {
|
binding.rollback = function() {
|
||||||
elem.anotStter = null
|
elem.anotSetter = null
|
||||||
Anot.unbind(elem, type, callback)
|
Anot.unbind(elem, type, callback)
|
||||||
old && old()
|
old && old()
|
||||||
}
|
}
|
||||||
|
@ -4148,7 +4198,7 @@
|
||||||
elem.msFocus = false
|
elem.msFocus = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
elem.anotStter = updateVModel //#765
|
elem.anotSetter = updateVModel //#765
|
||||||
watchValueInTimer(function() {
|
watchValueInTimer(function() {
|
||||||
if (root.contains(elem)) {
|
if (root.contains(elem)) {
|
||||||
if (!elem.msFocus) {
|
if (!elem.msFocus) {
|
||||||
|
@ -4167,7 +4217,7 @@
|
||||||
if (!this.init) {
|
if (!this.init) {
|
||||||
for (var i in Anot.vmodels) {
|
for (var i in Anot.vmodels) {
|
||||||
var v = Anot.vmodels[i]
|
var v = Anot.vmodels[i]
|
||||||
v.$fire('any-duplex-init', binding)
|
v.$fire('anot-duplex-init', binding)
|
||||||
}
|
}
|
||||||
var cpipe = binding.pipe || (binding.pipe = pipe)
|
var cpipe = binding.pipe || (binding.pipe = pipe)
|
||||||
cpipe(null, binding, 'init')
|
cpipe(null, binding, 'init')
|
||||||
|
@ -4250,17 +4300,7 @@
|
||||||
if (-val === -number) {
|
if (-val === -number) {
|
||||||
return number
|
return number
|
||||||
}
|
}
|
||||||
var arr = /strong|medium|weak/.exec(
|
return 0
|
||||||
binding.element.getAttribute('data-duplex-number')
|
|
||||||
) || ['medium']
|
|
||||||
switch (arr[0]) {
|
|
||||||
case 'strong':
|
|
||||||
return 0
|
|
||||||
case 'medium':
|
|
||||||
return val === '' ? '' : 0
|
|
||||||
case 'weak':
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
set: fixNull
|
set: fixNull
|
||||||
}
|
}
|
||||||
|
@ -4308,8 +4348,8 @@
|
||||||
function newSetter(value) {
|
function newSetter(value) {
|
||||||
// jshint ignore:line
|
// jshint ignore:line
|
||||||
setters[this.tagName].call(this, value)
|
setters[this.tagName].call(this, value)
|
||||||
if (!this.msFocus && this.anotStter) {
|
if (!this.msFocus && this.anotSetter) {
|
||||||
this.anotStter()
|
this.anotSetter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var inputProto = HTMLInputElement.prototype
|
var inputProto = HTMLInputElement.prototype
|
||||||
|
@ -5676,7 +5716,9 @@
|
||||||
time: function(str) {
|
time: function(str) {
|
||||||
str = str >> 0
|
str = str >> 0
|
||||||
var s = str % 60
|
var s = str % 60
|
||||||
;(m = Math.floor(str / 60)), (h = Math.floor(m / 60)), (m = m % 60)
|
var m = Math.floor(str / 60)
|
||||||
|
var h = Math.floor(m / 60)
|
||||||
|
m = m % 60
|
||||||
m = m < 10 ? '0' + m : m
|
m = m < 10 ? '0' + m : m
|
||||||
s = s < 10 ? '0' + s : s
|
s = s < 10 ? '0' + s : s
|
||||||
|
|
||||||
|
@ -5763,14 +5805,38 @@
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Map over Anot in case of overwrite
|
/*********************************************************************
|
||||||
var _Anot = window.Anot
|
* DOMReady *
|
||||||
Anot.noConflict = function(deep) {
|
**********************************************************************/
|
||||||
if (deep && window.Anot === Anot) {
|
|
||||||
window.Anot = _Anot
|
var readyList = [],
|
||||||
|
isReady
|
||||||
|
var fireReady = function(fn) {
|
||||||
|
isReady = true
|
||||||
|
var require = Anot.require
|
||||||
|
if (require && require.checkDeps) {
|
||||||
|
modules['domReady!'].state = 4
|
||||||
|
require.checkDeps()
|
||||||
|
}
|
||||||
|
while ((fn = readyList.shift())) {
|
||||||
|
fn(Anot)
|
||||||
}
|
}
|
||||||
return Anot
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.Anot = Anot
|
if (DOC.readyState === 'complete') {
|
||||||
})
|
setTimeout(fireReady) //如果在domReady之外加载
|
||||||
|
} else {
|
||||||
|
DOC.addEventListener('DOMContentLoaded', fireReady)
|
||||||
|
}
|
||||||
|
window.addEventListener('load', fireReady)
|
||||||
|
Anot.ready = function(fn) {
|
||||||
|
if (!isReady) {
|
||||||
|
readyList.push(fn)
|
||||||
|
} else {
|
||||||
|
fn(Anot)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Anot
|
||||||
|
})()
|
||||||
|
export default _Anot
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
var head = DOC.head //HEAD元素
|
var head = DOC.head //HEAD元素
|
||||||
head.insertAdjacentHTML(
|
head.insertAdjacentHTML(
|
||||||
'afterBegin',
|
'afterBegin',
|
||||||
'<anot :skip class="anot-hide"><style id="anot-style">.anot-hide{ display: none!important } .do-rule-tips {position:absolute;z-index:65535;min-width:75px;height:30px;padding:7px 8px;line-height:16px;color:#333;background:#f9ca05;white-space:pre;} .do-rule-tips::before {position:absolute;left:5px;bottom:-8px;width:0;height:0;border:8px solid transparent;border-left:8px solid #f9ca05;content: " "}</style></anot>'
|
'<anot skip class="anot-hide"><style id="anot-style">.anot-hide{ display: none!important }</style></anot>'
|
||||||
)
|
)
|
||||||
var ifGroup = head.firstChild
|
var ifGroup = head.firstChild
|
||||||
|
|
||||||
|
@ -3939,115 +3939,120 @@
|
||||||
|
|
||||||
/*------ 表单验证 -------*/
|
/*------ 表单验证 -------*/
|
||||||
var __rules = {}
|
var __rules = {}
|
||||||
Anot.validate = function(key) {
|
Anot.validate = function(key, cb) {
|
||||||
return (
|
if (!__rules[key]) {
|
||||||
!__rules[key] ||
|
throw new Error('validate [' + key + '] not exists.')
|
||||||
__rules[key].every(function(it) {
|
}
|
||||||
return it.checked
|
if (typeof cb === 'function') {
|
||||||
})
|
__rules[key].event = cb
|
||||||
)
|
}
|
||||||
|
var result = __rules[key].result
|
||||||
|
for (var k in result) {
|
||||||
|
if (!result[k].passed) {
|
||||||
|
return result[k]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
Anot.directive('rule', {
|
Anot.directive('rule', {
|
||||||
priority: 2010,
|
priority: 2010,
|
||||||
init: function(binding) {
|
init: function(binding) {
|
||||||
if (binding.param && !__rules[binding.param]) {
|
if (binding.param && !__rules[binding.param]) {
|
||||||
__rules[binding.param] = []
|
__rules[binding.param] = {
|
||||||
|
event: noop,
|
||||||
|
result: {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
binding.target = __rules[binding.param]
|
binding.target = __rules[binding.param]
|
||||||
},
|
},
|
||||||
update: function(obj) {
|
update: function(opt) {
|
||||||
var _this = this,
|
var _this = this
|
||||||
elem = this.element,
|
var elem = this.element
|
||||||
ruleID = -1
|
if (!['INPUT', 'TEXTAREA'].includes(elem.nodeName)) {
|
||||||
|
return
|
||||||
if (!['INPUT', 'TEXTAREA'].includes(elem.nodeName)) return
|
}
|
||||||
|
|
||||||
if (this.target) {
|
if (this.target) {
|
||||||
ruleID = this.target.length
|
this.target.result[elem.expr] = { key: elem.expr }
|
||||||
this.target.push({ checked: true })
|
|
||||||
}
|
}
|
||||||
|
var target = this.target
|
||||||
|
|
||||||
//如果父级元素没有定位属性,则加上相对定位
|
// 0: 验证通过
|
||||||
if (getComputedStyle(elem.parentNode).position === 'static') {
|
// 10001: 不能为空
|
||||||
elem.parentNode.style.position = 'relative'
|
// 10002: 必须为合法数字
|
||||||
}
|
// 10003: Email格式错误
|
||||||
|
// 10004: 手机格式错误
|
||||||
var $elem = Anot(elem),
|
// 10005: 必须为纯中文
|
||||||
ol = elem.offsetLeft + elem.offsetWidth - 50,
|
// 10006: 格式匹配错误(正则)
|
||||||
ot = elem.offsetTop + elem.offsetHeight + 8,
|
// 10011: 输入值超过指定最大长度
|
||||||
tips = document.createElement('div')
|
// 10012: 输入值短于指定最小长度
|
||||||
|
// 10021: 输入值大于指定最大数值
|
||||||
tips.className = 'do-rule-tips'
|
// 10022: 输入值小于指定最小数值
|
||||||
tips.style.left = ol + 'px'
|
// 10031: 与指定的表单的值不一致
|
||||||
tips.style.bottom = ot + 'px'
|
|
||||||
|
|
||||||
function checked(ev) {
|
function checked(ev) {
|
||||||
var txt = '',
|
var val = elem.value
|
||||||
val = elem.value
|
var code = 0
|
||||||
|
|
||||||
if (obj.require && (val === '' || val === null)) txt = '必填项'
|
if (opt.require && (val === '' || val === null)) {
|
||||||
|
code = 10001
|
||||||
if (!txt && obj.isNumeric) txt = !isFinite(val) ? '必须为合法数字' : ''
|
|
||||||
|
|
||||||
if (!txt && obj.isEmail)
|
|
||||||
txt = !/^[\w\.\-]+@\w+([\.\-]\w+)*\.\w+$/.test(val)
|
|
||||||
? 'Email格式错误'
|
|
||||||
: ''
|
|
||||||
|
|
||||||
if (!txt && obj.isPhone)
|
|
||||||
txt = !/^1[34578]\d{9}$/.test(val) ? '手机格式错误' : ''
|
|
||||||
|
|
||||||
if (!txt && obj.isCN)
|
|
||||||
txt = !/^[\u4e00-\u9fa5]+$/.test(val) ? '必须为纯中文' : ''
|
|
||||||
|
|
||||||
if (!txt && obj.exp)
|
|
||||||
txt = !obj.exp.test(val) ? obj.msg || '格式错误' : ''
|
|
||||||
|
|
||||||
if (!txt && obj.maxLen)
|
|
||||||
txt =
|
|
||||||
val.length > obj.maxLen ? '长度不得超过' + obj.maxLen + '位' : ''
|
|
||||||
|
|
||||||
if (!txt && obj.minLen)
|
|
||||||
txt =
|
|
||||||
val.length < obj.minLen ? '长度不得小于' + obj.minLen + '位' : ''
|
|
||||||
|
|
||||||
if (!txt && obj.hasOwnProperty('max'))
|
|
||||||
txt = val > obj.max ? '输入值不能大于' + obj.max : ''
|
|
||||||
|
|
||||||
if (!txt && obj.hasOwnProperty('min'))
|
|
||||||
txt = val < obj.min ? '输入值不能小于' + obj.min : ''
|
|
||||||
|
|
||||||
if (!txt && obj.eq) {
|
|
||||||
var eqEl = document.querySelector('#' + obj.eq)
|
|
||||||
txt = val !== eqEl.value ? obj.msg || '2次值不一致' : ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (txt) {
|
if (code === 0 && opt.isNumeric) {
|
||||||
if (ev) {
|
code = !isFinite(val) ? 10002 : 0
|
||||||
tips.textContent = txt
|
}
|
||||||
elem.parentNode.appendChild(tips)
|
|
||||||
|
if (code === 0 && opt.isEmail)
|
||||||
|
code = !/^[\w\.\-]+@\w+([\.\-]\w+)*\.\w+$/.test(val) ? 10003 : 0
|
||||||
|
|
||||||
|
if (code === 0 && opt.isPhone) {
|
||||||
|
code = !/^1[34578]\d{9}$/.test(val) ? 10004 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code === 0 && opt.isCN) {
|
||||||
|
code = !/^[\u4e00-\u9fa5]+$/.test(val) ? 10005 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code === 0 && opt.exp) {
|
||||||
|
code = !opt.exp.test(val) ? 10006 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code === 0 && opt.maxLen) {
|
||||||
|
code = val.length > opt.maxLen ? 10011 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code === 0 && opt.minLen) {
|
||||||
|
code = val.length < opt.minLen ? 10012 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code === 0 && opt.hasOwnProperty('max')) {
|
||||||
|
code = val > opt.max ? 10021 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code === 0 && opt.hasOwnProperty('min')) {
|
||||||
|
code = val < opt.min ? 10022 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code === 0 && opt.eq) {
|
||||||
|
var eqEl = document.querySelector('#' + opt.eq)
|
||||||
|
txt = val !== eqEl.value ? 10031 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
target.result[elem.expr].code = code
|
||||||
|
target.result[elem.expr].passed = opt.require ? code === 0 : true
|
||||||
|
|
||||||
|
var done
|
||||||
|
for (var k in target.result) {
|
||||||
|
if (!target.result[k].passed) {
|
||||||
|
done = true
|
||||||
|
target.event(target.result[k])
|
||||||
|
break
|
||||||
}
|
}
|
||||||
//必须是"必填项"才会更新验证状态
|
}
|
||||||
if (_this.target && obj.require) {
|
if (!done) {
|
||||||
_this.target[ruleID].checked = false
|
target.event(true)
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (_this.target) {
|
|
||||||
_this.target[ruleID].checked = true
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
elem.parentNode.removeChild(tips)
|
|
||||||
} catch (err) {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$elem.bind('change,blur', checked)
|
Anot(elem).bind('blur', checked)
|
||||||
$elem.bind('focus', function(ev) {
|
|
||||||
try {
|
|
||||||
elem.parentNode.removeChild(tips)
|
|
||||||
} catch (err) {}
|
|
||||||
})
|
|
||||||
|
|
||||||
checked()
|
checked()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -4097,6 +4102,7 @@
|
||||||
? 'change'
|
? 'change'
|
||||||
: 'input'
|
: 'input'
|
||||||
}
|
}
|
||||||
|
elem.expr = binding.expr
|
||||||
//===================绑定事件======================
|
//===================绑定事件======================
|
||||||
var bound = (binding.bound = function(type, callback) {
|
var bound = (binding.bound = function(type, callback) {
|
||||||
elem.addEventListener(type, callback, false)
|
elem.addEventListener(type, callback, false)
|
||||||
|
|
Reference in New Issue