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

Compare commits

..

14 Commits

Author SHA1 Message Date
宇天 ce9c8542a9 fix 2021-07-30 11:57:49 +08:00
宇天 328a7ca6d5 fix 2021-07-30 11:52:50 +08:00
宇天 33429266f3 修复search() 2021-01-08 10:30:48 +08:00
宇天 542ebfc496 更新打包脚本 2021-01-08 10:20:18 +08:00
宇天 3f8361af05 更新依赖 2021-01-08 10:14:44 +08:00
宇天 1786724598 优化search方法 2021-01-08 10:09:42 +08:00
宇天 d1f3cd7a10 精简nextTick 2020-08-19 15:05:04 +08:00
宇天 02ccc30e23 更新打包脚本 2020-07-27 15:20:22 +08:00
宇天 275f6700a2 优化xlink 2020-07-06 14:46:15 +08:00
宇天 ccfd33529c 修复svg的支持 2020-07-06 14:38:22 +08:00
宇天 f795667b5b 因为不支持自定义协议的缘故,放弃fetch的使用,改回xhr 2019-09-09 20:18:17 +08:00
宇天 fe1fd505ed 剪切板的操作更新为调用navigator的API 2019-09-02 21:01:31 +08:00
宇天 9d790d087a 移除兼容代码 2019-08-30 17:49:55 +08:00
宇天 40ff56d26c 移除旧的兼容代码 2019-08-08 19:13:25 +08:00
11 changed files with 131 additions and 179 deletions

1
.gitignore vendored
View File

@ -3,6 +3,7 @@
.LSOverride
.idea
.vscode
package-lock.json
node_modules/
dist/

View File

@ -1,19 +1,18 @@
/**
*
* @authors yutent (yutent@doui.cc)
* @authors yutent (yutent.io@gmail.com)
* @date 2018-08-04 01:00:06
*/
'use strict'
require('es.shim')
const fs = require('iofs')
const path = require('path')
const chokidar = require('chokidar')
const uglify = require('uglify-es')
const { minify } = require('terser')
const chalk = require('chalk')
const config = require('./package.json')
const log = console.log
const VERSION = '2.0.0'
const VERSION = config.version
const PACK_DIR = path.resolve('./dist')
const SOURCE_DIR = path.resolve('./src/')
@ -59,9 +58,9 @@ export default _Anot
function comment({ touch } = {}) {
return `/*==================================================
* Anot ${touch ? 'touch' : 'normal'} version for future browsers
* @authors yutent (yutent@doui.cc)
* @date 2017-03-21 21:05:57
* V${VERSION}
* @authors yutent<yutent.io@gmail.com>
* @date ${new Date().format()}
* @version v${VERSION}
*
==================================================*/
`
@ -115,8 +114,8 @@ function packNoCompress(file) {
* 打包带触摸事件的未来版的 anot
* --------------------------------------------------------
*/
fs.echo(Buffer.concat([PAD_START, touchVer, PAD_END]), './dist/anot-touch.js')
log('%s 打包完成...', chalk.green('anot-touch.js'))
fs.echo(Buffer.concat([PAD_START, touchVer, PAD_END]), './dist/anot.touch.js')
log('%s 打包完成...', chalk.green('anot.touch.js'))
}
// 打包并压缩
@ -136,22 +135,24 @@ function packAndCompress() {
*/
log('正在打包 anot.js...')
let normalVerPack = Buffer.concat([PAD_START, normalVer, PAD_END]).toString()
fs.echo(comment() + uglify.minify(normalVerPack).code, './dist/anot.js')
minify(normalVerPack, { sourceMap: false }).then(res => {
fs.echo(comment() + res.code, './dist/anot.js')
log(chalk.green('anot.js 打包压缩完成!'))
})
/**
* --------------------------------------------------------
* 打包带触摸事件的未来版的 anot
* --------------------------------------------------------
*/
log('正在打包 anot-touch.js...')
log('正在打包 anot.touch.js...')
let touchVerPack = Buffer.concat([PAD_START, touchVer, PAD_END]).toString()
fs.echo(
comment({ touch: true }) + uglify.minify(touchVerPack).code,
'./dist/anot-touch.js'
)
log(chalk.green('anot-touch.js 打包压缩完成!'))
minify(touchVerPack, { sourceMap: false }).then(res => {
fs.echo(comment({ touch: true }) + res.code, './dist/anot.touch.js')
log(chalk.green('anot.touch.js 打包压缩完成!'))
})
}
let args = process.argv.slice(2)

View File

@ -1,6 +1,6 @@
{
"name": "anot",
"version": "2.1.0",
"version": "2.2.4",
"description": "Anot - 迷你mvvm框架",
"main": "dist/anot.js",
"files": ["dist"],
@ -14,9 +14,9 @@
"devDependencies": {
"chalk": "^2.4.1",
"chokidar": "^2.0.4",
"es.shim": "^1.1.2",
"iofs": "^1.1.0",
"uglify-es": "^3.3.9"
"es.shim": "^2.0.1",
"iofs": "^1.5.2",
"terser": "^5.0.0"
},
"repository": "https://github.com/yutent/anot.js.git",
"author": "yutent",

View File

@ -16,7 +16,7 @@ npm run prod
```
执行完, 会打包为2个版本, 分别是
- anot.js 普通版(需要支持es6 module的现代浏览器)
- anot-touch.js 带触摸的版本(需要支持es6 module的现代浏览器)
- anot.touch.js 带触摸事件的版本(需要支持es6 module的现代浏览器)
### 文档:

View File

@ -9,7 +9,7 @@ var DOC = window.document
var head = DOC.head //HEAD元素
head.insertAdjacentHTML(
'afterbegin',
'<anot skip class="anot-hide"><style id="anot-style">.anot-hide{ display: none!important } slot{visibility:hidden;}</style></anot>'
'<anot skip class="anot-hide"><style id="anot-style">.anot-hide{ display: none!important }</style></anot>'
)
var ifGroup = head.firstChild
@ -31,6 +31,8 @@ function createMap() {
return Object.create(null)
}
var encode = encodeURIComponent
var decode = decodeURIComponent
var subscribers = '$' + expose
var nullObject = {} //作用类似于noop只用于代码防御千万不要在它上面添加属性

View File

@ -4,14 +4,7 @@ let Anot = function(el) {
}
/*视浏览器情况采用最快的异步回调*/
Anot.nextTick = new function() {
// jshint ignore:line
let tickImmediate = window.setImmediate
let tickObserver = window.MutationObserver
if (tickImmediate) {
return tickImmediate.bind(window)
}
Anot.nextTick = (function() {
let queue = []
function callback() {
let n = queue.length
@ -21,21 +14,16 @@ Anot.nextTick = new function() {
queue = queue.slice(n)
}
if (tickObserver) {
let node = document.createTextNode('anot')
new tickObserver(callback).observe(node, { characterData: true }) // jshint ignore:line
let node = document.createTextNode('<!-- -->')
new MutationObserver(callback).observe(node, { characterData: true })
let bool = false
return function(fn) {
queue.push(fn)
bool = !bool
node.data = bool
}
}
return function(fn) {
setTimeout(fn, 4)
}
}() // jshint ignore:line
})()
/*********************************************************************
* Anot的静态方法定义区 *
@ -97,10 +85,7 @@ Anot.PropsTypes.isBoolean = function() {
/*判定是否是一个朴素的javascript对象Object不是DOM对象不是BOM对象不是自定义类的实例*/
Anot.isPlainObject = function(obj) {
// 简单的 typeof obj === "object"检测会致使用isPlainObject(window)在opera下通不过
return (
serialize.call(obj) === '[object Object]' &&
Object.getPrototypeOf(obj) === oproto
)
return serialize.call(obj) === '[object Object]' && Object.getPrototypeOf(obj) === oproto
}
let VMODELS = (Anot.vmodels = {}) //所有vmodel都储存在这里
@ -180,11 +165,7 @@ Anot.mix = Anot.fn.mix = function() {
if (target === copy) {
continue
}
if (
deep &&
copy &&
(Anot.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))
) {
if (deep && copy && (Anot.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) {
if (copyIsArray) {
copyIsArray = false
clone = src && Array.isArray(src) ? src : []
@ -290,11 +271,11 @@ Anot.mix({
t = t.trim()
let hook = hooks[t]
if (typeof hook === 'object') {
type = hook.type || type
phase = hook.phase || !!phase
t = hook.type || t
phase = hook.phase || phase
fn = hook.fix ? hook.fix(el, fn) : fn
}
el.addEventListener(t, fn, phase)
el.addEventListener(t, fn, !!phase)
})
return fn
},
@ -307,10 +288,10 @@ Anot.mix({
t = t.trim()
let hook = hooks[t]
if (typeof hook === 'object') {
type = hook.type || type
phase = hook.phase || !!phase
t = hook.type || t
phase = hook.phase || phase
}
el.removeEventListener(t, fn, phase)
el.removeEventListener(t, fn, !!phase)
})
},
/*读写删除元素节点的样式*/
@ -349,13 +330,12 @@ Anot.mix({
each: function(obj, fn) {
if (obj) {
//排除null, undefined
let i = 0
if (isArrayLike(obj)) {
for (let n = obj.length; i < n; i++) {
for (let i = 0, n = obj.length; i < n; i++) {
if (fn(i, obj[i]) === false) break
}
} else {
for (i in obj) {
for (let i in obj) {
if (obj.hasOwnProperty(i) && fn(i, obj[i]) === false) {
break
}
@ -424,7 +404,7 @@ Anot.mix({
if ((this.type(val) == 'string' && val.trim() === '') || val === null) {
document.cookie =
encodeURIComponent(key) +
encode(key) +
'=; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=' +
opt.domain +
'; path=' +
@ -448,9 +428,9 @@ Anot.mix({
}
}
document.cookie =
encodeURIComponent(key) +
encode(key) +
'=' +
encodeURIComponent(val) +
encode(val) +
opt.expires +
'; domain=' +
opt.domain +
@ -464,11 +444,11 @@ Anot.mix({
return document.cookie
}
return (
decodeURIComponent(
decode(
document.cookie.replace(
new RegExp(
'(?:(?:^|.*;)\\s*' +
encodeURIComponent(key).replace(/[\-\.\+\*]/g, '\\$&') +
encode(key).replace(/[\-\.\+\*]/g, '\\$&') +
'\\s*\\=\\s*([^;]*).*$)|^.*$'
),
'$1'
@ -479,13 +459,12 @@ Anot.mix({
},
//获取url的参数
search: function(key) {
key += ''
let uri = location.search
if (!key || !uri) {
if (!uri) {
return null
}
uri = decodeURIComponent(uri)
uri = decode(uri)
uri = uri.slice(1)
uri = uri.split('&')
@ -506,26 +485,19 @@ Anot.mix({
obj[tmp[0]] = tmp[1]
}
}
if (key) {
return obj.hasOwnProperty(key) ? obj[key] : null
} else {
return obj
}
},
//复制文本到粘贴板
copy: function(txt) {
if (!DOC.queryCommandSupported || !DOC.queryCommandSupported('copy')) {
return log('该浏览器不支持复制到粘贴板')
}
let ta = DOC.createElement('textarea')
ta.textContent = txt
ta.style.position = 'fixed'
ta.style.bottom = '-1000px'
DOC.body.appendChild(ta)
ta.select()
try {
DOC.execCommand('copy')
navigator.clipboard.writeText(txt)
} catch (err) {
log('复制到粘贴板失败', err)
}
DOC.body.removeChild(ta)
}
})

View File

@ -21,46 +21,6 @@ Anot.contains = function(root, el) {
let eventHooks = Anot.eventHooks
//针对firefox, chrome修正mouseenter, mouseleave(chrome30+)
if (!('onmouseenter' in root)) {
Anot.each(
{
mouseenter: 'mouseover',
mouseleave: 'mouseout'
},
function(origType, fixType) {
eventHooks[origType] = {
type: fixType,
fix: function(elem, fn) {
return function(e) {
let t = e.relatedTarget
if (!t || (t !== elem && !(elem.compareDocumentPosition(t) & 16))) {
delete e.type
e.type = origType
return fn.call(elem, e)
}
}
}
}
}
)
}
//针对IE9+, w3c修正animationend
Anot.each(
{
AnimationEvent: 'animationend',
WebKitAnimationEvent: 'webkitAnimationEnd'
},
function(construct, fixType) {
if (window[construct] && !eventHooks.animationend) {
eventHooks.animationend = {
type: fixType
}
}
}
)
if (DOC.onmousewheel === void 0) {
/* IE6-11 chrome mousewheel wheelDetla -120 120
firefox DOMMouseScroll detail 下3 -3

View File

@ -264,8 +264,8 @@ function observeObject(source, options) {
return (old = value.get.call(this))
},
set: function(x) {
var older = old,
newer
var older = old
var newer
value.set.call(this, x)
newer = this[key]
if (this.$fire && newer !== older) {

View File

@ -50,7 +50,7 @@ function executeBindings(bindings, vmodels) {
}
var roneTime = /^\s*::/
var rmsAttr = /:(\w+)-?(.*)|@(.*)/
var rmsAttr = /^:(\w+)-?(.*)|@(.*)/
var events = oneObject(
'animationend,blur,change,input,click,dblclick,focus,keydown,keypress,keyup,mousedown,mouseenter,mouseleave,mousemove,mouseout,mouseover,mouseup,scan,scroll,submit'
@ -372,6 +372,8 @@ function scanText(textNode, vmodels, index) {
anotFragment.appendChild(node)
}
textNode.parentNode.replaceChild(anotFragment, textNode)
if (bindings.length) executeBindings(bindings, vmodels)
if (bindings.length) {
executeBindings(bindings, vmodels)
}
}
}

View File

@ -47,7 +47,8 @@ var attrDir = Anot.directive('attr', {
},
update: function(val) {
var elem = this.element
var obj = {}
var obj = Object.create(null)
var isSVG = rsvg.test(elem)
val = toJson(val)
@ -83,9 +84,13 @@ var attrDir = Anot.directive('attr', {
elem.style.cssText = obj[i]
continue
}
if (i === 'href' || i === 'src') {
elem[i] = obj[i]
} else {
if (i.slice(0, 6) === 'xlink:') {
var k = i
i = i.slice(6)
obj[i] = obj[k]
delete obj[k]
}
// 修正这些值的显示
if (obj[i] === false || obj[i] === null || obj[i] === undefined) {
obj[i] = ''
@ -110,7 +115,7 @@ var attrDir = Anot.directive('attr', {
}
//SVG只能使用setAttribute(xxx, yyy), HTML的固有属性必须elem.xxx = yyy
var isInnate = rsvg.test(elem) ? false : i in elem.cloneNode(false)
var isInnate = isSVG ? false : i in elem.cloneNode(false)
if (isInnate) {
elem[i] = obj[i]
} else {
@ -123,5 +128,4 @@ var attrDir = Anot.directive('attr', {
}
}
}
}
})

View File

@ -20,6 +20,26 @@ function nodesToFrag(nodes) {
}
return frag
}
function _fetch(url) {
var xhr = new XMLHttpRequest()
var defer = Promise.defer()
xhr.open('GET', url, true)
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest')
xhr.responseType = 'text'
xhr.onreadystatechange = function() {
if (this.readyState === 4) {
if (this.status >= 200 && this.status < 400) {
defer.resolve(this.response)
} else {
defer.reject(this)
}
}
}
xhr.send(null)
return defer.promise
}
Anot.directive('include', {
init: directives.attr.init,
update: function(val) {
@ -141,27 +161,17 @@ Anot.directive('include', {
scanTemplate(templatePool[val])
})
} else {
fetch(val, {
method: 'get',
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(res => {
if (res.status >= 200 && res.status < 300) {
return res.text()
} else {
return Promise.reject(
`获取网络资源出错, ${res.status} (${res.statusText})`
)
}
})
_fetch(val)
.then(text => {
templatePool[val] = text
scanTemplate(text)
})
.catch(err => {
log(':include load [' + val + '] error\n%c%s', 'color:#f30', err)
log(
':include load [' + val + '] error\n%c%s',
'color:#f30',
`获取网络资源出错, ${err.status} (${err.statusText})`
)
})
}
}