avalon-rails 1.3.9.1 → 1.3.9.1.20150212184918
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/avalon-rails/version.rb +1 -1
- data/vendor/assets/javascripts/avalon.js +840 -707
- data/vendor/assets/javascripts/avalon.min.js +3 -135
- data/vendor/assets/javascripts/avalon.mobile.js +911 -738
- data/vendor/assets/javascripts/avalon.mobile.min.js +3 -122
- data/vendor/assets/javascripts/avalon.mobile.shim.js +146 -80
- data/vendor/assets/javascripts/avalon.modern.js +902 -790
- data/vendor/assets/javascripts/avalon.modern.min.js +2 -115
- data/vendor/assets/javascripts/avalon.modern.shim.js +453 -445
- data/vendor/assets/javascripts/avalon.shim.js +512 -504
- metadata +2 -2
@@ -5,8 +5,7 @@
|
|
5
5
|
http://weibo.com/jslouvre/
|
6
6
|
|
7
7
|
Released under the MIT license
|
8
|
-
avalon.shim.js(
|
9
|
-
___
|
8
|
+
avalon.shim.js(无加载器版本) 1.391 built in 2015.2.12
|
10
9
|
support IE6+ and other browsers
|
11
10
|
==================================================*/
|
12
11
|
(function(global, factory) {
|
@@ -34,13 +33,14 @@ ___
|
|
34
33
|
/*********************************************************************
|
35
34
|
* 全局变量及方法 *
|
36
35
|
**********************************************************************/
|
37
|
-
var expose = new Date - 0
|
36
|
+
var expose = new Date() - 0
|
38
37
|
//http://stackoverflow.com/questions/7290086/javascript-use-strict-and-nicks-find-global-function
|
39
38
|
var DOC = window.document
|
40
39
|
var head = DOC.getElementsByTagName("head")[0] //HEAD元素
|
41
40
|
var ifGroup = head.insertBefore(document.createElement("avalon"), head.firstChild) //避免IE6 base标签BUG
|
42
41
|
ifGroup.innerHTML = "X<style id='avalonStyle'>.avalonHide{ display: none!important }</style>"
|
43
42
|
ifGroup.setAttribute("ms-skip", "1")
|
43
|
+
ifGroup.className = "avalonHide"
|
44
44
|
var rnative = /\[native code\]/ //判定是否原生函数
|
45
45
|
function log() {
|
46
46
|
if (window.console && avalon.config.debug) {
|
@@ -143,7 +143,7 @@ var isFunction = typeof alert === "object" ? function(fn) {
|
|
143
143
|
return false
|
144
144
|
}
|
145
145
|
} : function(fn) {
|
146
|
-
return serialize.call(fn)
|
146
|
+
return serialize.call(fn) === "[object Function]"
|
147
147
|
}
|
148
148
|
avalon.isFunction = isFunction
|
149
149
|
|
@@ -305,7 +305,7 @@ avalon.mix({
|
|
305
305
|
}
|
306
306
|
var index = -1,
|
307
307
|
length = Math.max(0, Math.ceil((end - start) / step)),
|
308
|
-
result = Array(length)
|
308
|
+
result = new Array(length)
|
309
309
|
while (++index < length) {
|
310
310
|
result[index] = start
|
311
311
|
start += step
|
@@ -352,10 +352,10 @@ avalon.mix({
|
|
352
352
|
if (node instanceof avalon) {
|
353
353
|
node = node[0]
|
354
354
|
}
|
355
|
-
var prop = /[_-]/.test(name) ? camelize(name) : name
|
355
|
+
var prop = /[_-]/.test(name) ? camelize(name) : name, fn
|
356
356
|
name = avalon.cssName(prop) || prop
|
357
357
|
if (value === void 0 || typeof value === "boolean") { //获取样式
|
358
|
-
|
358
|
+
fn = cssHooks[prop + ":get"] || cssHooks["@:get"]
|
359
359
|
if (name === "background") {
|
360
360
|
name = "backgroundColor"
|
361
361
|
}
|
@@ -446,7 +446,7 @@ function isArrayLike(obj) {
|
|
446
446
|
}
|
447
447
|
return true
|
448
448
|
} catch (e) { //IE的NodeList直接抛错
|
449
|
-
return !obj.
|
449
|
+
return !obj.window //IE6-8 window
|
450
450
|
}
|
451
451
|
}
|
452
452
|
return false
|
@@ -691,7 +691,7 @@ function fixEvent(event) {
|
|
691
691
|
ret.wheelDeltaY = ret.wheelDelta
|
692
692
|
ret.wheelDeltaX = 0
|
693
693
|
}
|
694
|
-
ret.timeStamp = new Date - 0
|
694
|
+
ret.timeStamp = new Date() - 0
|
695
695
|
ret.originalEvent = event
|
696
696
|
ret.preventDefault = function() { //阻止默认行为
|
697
697
|
event.returnValue = false
|
@@ -873,7 +873,7 @@ var EventBus = {
|
|
873
873
|
return this
|
874
874
|
},
|
875
875
|
$fire: function(type) {
|
876
|
-
var special
|
876
|
+
var special, i, v, callback
|
877
877
|
if (/^(\w+)!(\S+)$/.test(type)) {
|
878
878
|
special = RegExp.$1
|
879
879
|
type = RegExp.$2
|
@@ -882,8 +882,8 @@ var EventBus = {
|
|
882
882
|
var args = aslice.call(arguments, 1)
|
883
883
|
var detail = [type].concat(args)
|
884
884
|
if (special === "all") {
|
885
|
-
for (
|
886
|
-
|
885
|
+
for (i in avalon.vmodels) {
|
886
|
+
v = avalon.vmodels[i]
|
887
887
|
if (v !== this) {
|
888
888
|
v.$fire.apply(v, detail)
|
889
889
|
}
|
@@ -892,8 +892,8 @@ var EventBus = {
|
|
892
892
|
var elements = events.expr ? findNodes(events.expr) : []
|
893
893
|
if (elements.length === 0)
|
894
894
|
return
|
895
|
-
for (
|
896
|
-
|
895
|
+
for (i in avalon.vmodels) {
|
896
|
+
v = avalon.vmodels[i]
|
897
897
|
if (v !== this) {
|
898
898
|
if (v.$events.expr) {
|
899
899
|
var eventNodes = findNodes(v.$events.expr)
|
@@ -926,19 +926,19 @@ var EventBus = {
|
|
926
926
|
if (special === "up") {
|
927
927
|
alls.reverse()
|
928
928
|
}
|
929
|
-
for (
|
930
|
-
if (
|
929
|
+
for (i = 0; callback = alls[i++]; ) {
|
930
|
+
if (callback.$fire.apply(callback, detail) === false) {
|
931
931
|
break
|
932
932
|
}
|
933
933
|
}
|
934
934
|
} else {
|
935
935
|
var callbacks = events[type] || []
|
936
936
|
var all = events.$all || []
|
937
|
-
for (
|
937
|
+
for (i = 0; callback = callbacks[i++]; ) {
|
938
938
|
if (isFunction(callback))
|
939
939
|
callback.apply(this, args)
|
940
940
|
}
|
941
|
-
for (
|
941
|
+
for (i = 0; callback = all[i++]; ) {
|
942
942
|
if (isFunction(callback))
|
943
943
|
callback.apply(this, arguments)
|
944
944
|
}
|
@@ -1116,7 +1116,7 @@ function modelFactory(source, $special, $model) {
|
|
1116
1116
|
} else {
|
1117
1117
|
if (accessor.type === 0) { //type 0 计算属性 1 监控属性 2 对象属性
|
1118
1118
|
//计算属性不需要收集视图刷新函数,都是由其他监控属性代劳
|
1119
|
-
|
1119
|
+
newValue = accessor.get.call($vmodel)
|
1120
1120
|
if (oldValue !== newValue) {
|
1121
1121
|
$model[name] = newValue
|
1122
1122
|
//这里不用同步视图
|
@@ -1148,12 +1148,12 @@ function modelFactory(source, $special, $model) {
|
|
1148
1148
|
initCallbacks.push(function() {
|
1149
1149
|
var data = {
|
1150
1150
|
evaluator: function() {
|
1151
|
-
data.type =
|
1151
|
+
data.type = Math.random(),
|
1152
1152
|
data.element = null
|
1153
1153
|
$model[name] = accessor.get.call($vmodel)
|
1154
1154
|
},
|
1155
1155
|
element: head,
|
1156
|
-
type:
|
1156
|
+
type: Math.random(),
|
1157
1157
|
handler: noop,
|
1158
1158
|
args: []
|
1159
1159
|
}
|
@@ -1194,7 +1194,7 @@ function modelFactory(source, $special, $model) {
|
|
1194
1194
|
$vmodel.$id = generateID()
|
1195
1195
|
$vmodel.$model = $model
|
1196
1196
|
$vmodel.$events = $events
|
1197
|
-
for (
|
1197
|
+
for ( i in EventBus) {
|
1198
1198
|
var fn = EventBus[i]
|
1199
1199
|
if (!W3C) { //在IE6-8下,VB对象的方法里的this并不指向自身,需要用bind处理一下
|
1200
1200
|
fn = fn.bind($vmodel)
|
@@ -1754,7 +1754,7 @@ function removeSubscribers() {
|
|
1754
1754
|
if (diff) {
|
1755
1755
|
//avalon.log("有需要移除的元素")
|
1756
1756
|
while (obj = $$subscribers[--i]) {
|
1757
|
-
|
1757
|
+
data = obj.data
|
1758
1758
|
if (data.element === void 0)
|
1759
1759
|
continue
|
1760
1760
|
if (needTest[data.type] && isRemove(data.element)) { //如果它没有在DOM树
|
@@ -1861,7 +1861,7 @@ avalon.parseHTML = function(html) {
|
|
1861
1861
|
for (i = wrap[0]; i--; wrapper = wrapper.lastChild) {
|
1862
1862
|
}
|
1863
1863
|
if (!W3C) { //fix IE
|
1864
|
-
|
1864
|
+
els = wrapper.getElementsByTagName("br"), n = els.length
|
1865
1865
|
while (el = els[--n]) {
|
1866
1866
|
if (el.className === "msNoScope") {
|
1867
1867
|
el.parentNode.removeChild(el)
|
@@ -2003,55 +2003,6 @@ function bindingSorter(a, b) {
|
|
2003
2003
|
return a.priority - b.priority
|
2004
2004
|
}
|
2005
2005
|
|
2006
|
-
function scanTag(elem, vmodels, node) {
|
2007
|
-
//扫描顺序 ms-skip(0) --> ms-important(1) --> ms-controller(2) --> ms-if(10) --> ms-repeat(100)
|
2008
|
-
//--> ms-if-loop(110) --> ms-attr(970) ...--> ms-each(1400)-->ms-with(1500)--〉ms-duplex(2000)垫后
|
2009
|
-
var a = elem.getAttribute("ms-skip")
|
2010
|
-
//#360 在旧式IE中 Object标签在引入Flash等资源时,可能出现没有getAttributeNode,innerHTML的情形
|
2011
|
-
if (!elem.getAttributeNode) {
|
2012
|
-
return log("warning " + elem.tagName + " no getAttributeNode method")
|
2013
|
-
}
|
2014
|
-
var b = elem.getAttributeNode("ms-important")
|
2015
|
-
var c = elem.getAttributeNode("ms-controller")
|
2016
|
-
if (typeof a === "string") {
|
2017
|
-
return
|
2018
|
-
} else if (node = b || c) {
|
2019
|
-
var newVmodel = avalon.vmodels[node.value]
|
2020
|
-
if (!newVmodel) {
|
2021
|
-
return
|
2022
|
-
}
|
2023
|
-
//ms-important不包含父VM,ms-controller相反
|
2024
|
-
vmodels = node === b ? [newVmodel] : [newVmodel].concat(vmodels)
|
2025
|
-
var name = node.name
|
2026
|
-
elem.removeAttribute(name) //removeAttributeNode不会刷新[ms-controller]样式规则
|
2027
|
-
avalon(elem).removeClass(name)
|
2028
|
-
createSignalTower(elem, newVmodel)
|
2029
|
-
}
|
2030
|
-
scanAttr(elem, vmodels) //扫描特性节点
|
2031
|
-
}
|
2032
|
-
function scanNodeList(parent, vmodels) {
|
2033
|
-
var node = parent.firstChild
|
2034
|
-
while (node) {
|
2035
|
-
var nextNode = node.nextSibling
|
2036
|
-
scanNode(node, node.nodeType, vmodels)
|
2037
|
-
node = nextNode
|
2038
|
-
}
|
2039
|
-
}
|
2040
|
-
|
2041
|
-
function scanNodeArray(nodes, vmodels) {
|
2042
|
-
for (var i = 0, node; node = nodes[i++]; ) {
|
2043
|
-
scanNode(node, node.nodeType, vmodels)
|
2044
|
-
}
|
2045
|
-
}
|
2046
|
-
function scanNode(node, nodeType, vmodels) {
|
2047
|
-
if (nodeType === 1) {
|
2048
|
-
scanTag(node, vmodels) //扫描元素节点
|
2049
|
-
} else if (nodeType === 3 && rexpr.test(node.data)){
|
2050
|
-
scanText(node, vmodels) //扫描文本节点
|
2051
|
-
} else if (kernel.commentInterpolate && nodeType === 8 && !rexpr.test(node.nodeValue)) {
|
2052
|
-
scanText(node, vmodels) //扫描注释节点
|
2053
|
-
}
|
2054
|
-
}
|
2055
2006
|
function scanAttr(elem, vmodels) {
|
2056
2007
|
//防止setAttribute, removeAttribute时 attributes自动被同步,导致for循环出错
|
2057
2008
|
var attributes = getAttributes ? getAttributes(elem) : avalon.slice(elem.attributes)
|
@@ -2120,8 +2071,8 @@ function scanAttr(elem, vmodels) {
|
|
2120
2071
|
log("warning!一个元素上不能同时定义ms-attr-checked与ms-duplex")
|
2121
2072
|
}
|
2122
2073
|
var scanNode = true
|
2123
|
-
for (
|
2124
|
-
|
2074
|
+
for (i = 0; binding = bindings[i]; i++) {
|
2075
|
+
type = binding.type
|
2125
2076
|
if (rnoscanAttrBinding.test(type)) {
|
2126
2077
|
return executeBindings(bindings.slice(0, i + 1), vmodels)
|
2127
2078
|
} else if (scanNode) {
|
@@ -2185,14 +2136,66 @@ if (!"1" [0]) {
|
|
2185
2136
|
}
|
2186
2137
|
}
|
2187
2138
|
|
2139
|
+
function scanNodeList(parent, vmodels) {
|
2140
|
+
var node = parent.firstChild
|
2141
|
+
while (node) {
|
2142
|
+
var nextNode = node.nextSibling
|
2143
|
+
scanNode(node, node.nodeType, vmodels)
|
2144
|
+
node = nextNode
|
2145
|
+
}
|
2146
|
+
}
|
2147
|
+
|
2148
|
+
function scanNodeArray(nodes, vmodels) {
|
2149
|
+
for (var i = 0, node; node = nodes[i++]; ) {
|
2150
|
+
scanNode(node, node.nodeType, vmodels)
|
2151
|
+
}
|
2152
|
+
}
|
2153
|
+
function scanNode(node, nodeType, vmodels) {
|
2154
|
+
if (nodeType === 1) {
|
2155
|
+
scanTag(node, vmodels) //扫描元素节点
|
2156
|
+
} else if (nodeType === 3 && rexpr.test(node.data)){
|
2157
|
+
scanText(node, vmodels) //扫描文本节点
|
2158
|
+
} else if (kernel.commentInterpolate && nodeType === 8 && !rexpr.test(node.nodeValue)) {
|
2159
|
+
scanText(node, vmodels) //扫描注释节点
|
2160
|
+
}
|
2161
|
+
}
|
2162
|
+
function scanTag(elem, vmodels, node) {
|
2163
|
+
//扫描顺序 ms-skip(0) --> ms-important(1) --> ms-controller(2) --> ms-if(10) --> ms-repeat(100)
|
2164
|
+
//--> ms-if-loop(110) --> ms-attr(970) ...--> ms-each(1400)-->ms-with(1500)--〉ms-duplex(2000)垫后
|
2165
|
+
var a = elem.getAttribute("ms-skip")
|
2166
|
+
//#360 在旧式IE中 Object标签在引入Flash等资源时,可能出现没有getAttributeNode,innerHTML的情形
|
2167
|
+
if (!elem.getAttributeNode) {
|
2168
|
+
return log("warning " + elem.tagName + " no getAttributeNode method")
|
2169
|
+
}
|
2170
|
+
var b = elem.getAttributeNode("ms-important")
|
2171
|
+
var c = elem.getAttributeNode("ms-controller")
|
2172
|
+
if (typeof a === "string") {
|
2173
|
+
return
|
2174
|
+
} else if (node = b || c) {
|
2175
|
+
var newVmodel = avalon.vmodels[node.value]
|
2176
|
+
if (!newVmodel) {
|
2177
|
+
return
|
2178
|
+
}
|
2179
|
+
//ms-important不包含父VM,ms-controller相反
|
2180
|
+
vmodels = node === b ? [newVmodel] : [newVmodel].concat(vmodels)
|
2181
|
+
var name = node.name
|
2182
|
+
elem.removeAttribute(name) //removeAttributeNode不会刷新[ms-controller]样式规则
|
2183
|
+
avalon(elem).removeClass(name)
|
2184
|
+
createSignalTower(elem, newVmodel)
|
2185
|
+
}
|
2186
|
+
scanAttr(elem, vmodels) //扫描特性节点
|
2187
|
+
}
|
2188
2188
|
var rhasHtml = /\|\s*html\s*/,
|
2189
2189
|
r11a = /\|\|/g,
|
2190
2190
|
rlt = /</g,
|
2191
2191
|
rgt = />/g
|
2192
|
-
|
2192
|
+
rstringLiteral = /(['"])(\\\1|.)+?\1/g
|
2193
2193
|
function getToken(value) {
|
2194
2194
|
if (value.indexOf("|") > 0) {
|
2195
|
-
var
|
2195
|
+
var scapegoat = value.replace( rstringLiteral, function(_){
|
2196
|
+
return Math.pow(10,_.length)
|
2197
|
+
})
|
2198
|
+
var index = scapegoat.replace(r11a, "\u1122\u3344").indexOf("|") //干掉所有短路或
|
2196
2199
|
if (index > -1) {
|
2197
2200
|
return {
|
2198
2201
|
filters: value.slice(index),
|
@@ -2256,7 +2259,7 @@ function scanText(textNode, vmodels) {
|
|
2256
2259
|
tokens = scanExpr(textNode.data)
|
2257
2260
|
}
|
2258
2261
|
if (tokens.length) {
|
2259
|
-
for (var i = 0
|
2262
|
+
for (var i = 0; token = tokens[i++]; ) {
|
2260
2263
|
var node = DOC.createTextNode(token.value) //将文本转换为文本节点,并替换原来的文本节点
|
2261
2264
|
if (token.expr) {
|
2262
2265
|
token.type = "text"
|
@@ -2295,7 +2298,7 @@ function camelize(target) {
|
|
2295
2298
|
})
|
2296
2299
|
}
|
2297
2300
|
|
2298
|
-
var
|
2301
|
+
var fakeClassListMethods = {
|
2299
2302
|
_toString: function() {
|
2300
2303
|
var node = this.node
|
2301
2304
|
var cls = node.className
|
@@ -2325,13 +2328,13 @@ var ClassListMethods = {
|
|
2325
2328
|
} //toggle存在版本差异,因此不使用它
|
2326
2329
|
}
|
2327
2330
|
|
2328
|
-
function
|
2331
|
+
function fakeClassList(node) {
|
2329
2332
|
if (!("classList" in node)) {
|
2330
2333
|
node.classList = {
|
2331
2334
|
node: node
|
2332
2335
|
}
|
2333
|
-
for (var k in
|
2334
|
-
node.classList[k.slice(1)] =
|
2336
|
+
for (var k in fakeClassListMethods) {
|
2337
|
+
node.classList[k.slice(1)] = fakeClassListMethods[k]
|
2335
2338
|
}
|
2336
2339
|
}
|
2337
2340
|
return node.classList
|
@@ -2344,7 +2347,7 @@ function ClassList(node) {
|
|
2344
2347
|
//https://developer.mozilla.org/zh-CN/docs/Mozilla/Firefox/Releases/26
|
2345
2348
|
if (cls && typeof cls === "string" && el && el.nodeType === 1) {
|
2346
2349
|
cls.replace(/\S+/g, function(c) {
|
2347
|
-
|
2350
|
+
fakeClassList(el)[method](c)
|
2348
2351
|
})
|
2349
2352
|
}
|
2350
2353
|
return this
|
@@ -2353,7 +2356,7 @@ function ClassList(node) {
|
|
2353
2356
|
avalon.fn.mix({
|
2354
2357
|
hasClass: function(cls) {
|
2355
2358
|
var el = this[0] || {}
|
2356
|
-
return el.nodeType === 1 &&
|
2359
|
+
return el.nodeType === 1 && fakeClassList(el).contains(cls)
|
2357
2360
|
},
|
2358
2361
|
toggleClass: function(value, stateVal) {
|
2359
2362
|
var className, i = 0
|
@@ -2845,14 +2848,14 @@ var keywords =
|
|
2845
2848
|
// 关键字
|
2846
2849
|
"break,case,catch,continue,debugger,default,delete,do,else,false" +
|
2847
2850
|
",finally,for,function,if,in,instanceof,new,null,return,switch,this" +
|
2848
|
-
",throw,true,try,typeof,var,void,while,with"
|
2851
|
+
",throw,true,try,typeof,var,void,while,with" +
|
2849
2852
|
// 保留字
|
2850
|
-
|
2853
|
+
",abstract,boolean,byte,char,class,const,double,enum,export,extends" +
|
2851
2854
|
",final,float,goto,implements,import,int,interface,long,native" +
|
2852
2855
|
",package,private,protected,public,short,static,super,synchronized" +
|
2853
|
-
",throws,transient,volatile"
|
2856
|
+
",throws,transient,volatile" +
|
2854
2857
|
// ECMA 5 - use strict
|
2855
|
-
|
2858
|
+
",arguments,let,yield" + ",undefined"
|
2856
2859
|
var rrexpstr = /\/\*[\w\W]*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|"(?:[^"\\]|\\[\w\W])*"|'(?:[^'\\]|\\[\w\W])*'|[\s\t\n]*\.[\s\t\n]*[$\w\.]+/g
|
2857
2860
|
var rsplit = /[^\w$]+/g
|
2858
2861
|
var rkeywords = new RegExp(["\\b" + keywords.replace(/,/g, '\\b|\\b') + "\\b"].join('|'), 'g')
|
@@ -2992,7 +2995,7 @@ function parseExpr(code, scopes, data) {
|
|
2992
2995
|
data.evaluator = fn
|
2993
2996
|
return
|
2994
2997
|
}
|
2995
|
-
|
2998
|
+
prefix = assigns.join(", ")
|
2996
2999
|
if (prefix) {
|
2997
3000
|
prefix = "var " + prefix
|
2998
3001
|
}
|
@@ -3060,12 +3063,6 @@ function parseExprProxy(code, scopes, data, tokens, noregister) {
|
|
3060
3063
|
}
|
3061
3064
|
}
|
3062
3065
|
avalon.parseExprProxy = parseExprProxy
|
3063
|
-
/*********************************************************************
|
3064
|
-
* 各种指令 *
|
3065
|
-
**********************************************************************/
|
3066
|
-
//ms-skip绑定已经在scanTag 方法中实现
|
3067
|
-
//ms-controller绑定已经在scanTag 方法中实现
|
3068
|
-
//ms-important绑定已经在scanTag 方法中实现
|
3069
3066
|
var bools = "autofocus,autoplay,async,allowTransparency,checked,controls,declare,disabled,defer,defaultChecked,defaultSelected" +
|
3070
3067
|
"contentEditable,isMap,loop,multiple,noHref,noResize,noShade,open,readOnly,selected"
|
3071
3068
|
var boolMap = {}
|
@@ -3163,7 +3160,7 @@ bindingExecutors.attr = function(val, elem, data) {
|
|
3163
3160
|
var loaded = data.includeLoaded
|
3164
3161
|
var replace = data.includeReplaced
|
3165
3162
|
var target = replace ? elem.parentNode : elem
|
3166
|
-
|
3163
|
+
var scanTemplate = function(text) {
|
3167
3164
|
if (loaded) {
|
3168
3165
|
text = loaded.apply(target, [text].concat(vmodels))
|
3169
3166
|
}
|
@@ -3213,7 +3210,7 @@ bindingExecutors.attr = function(val, elem, data) {
|
|
3213
3210
|
var el = val && val.nodeType === 1 ? val : DOC.getElementById(val)
|
3214
3211
|
if (el) {
|
3215
3212
|
if (el.tagName === "NOSCRIPT" && !(el.innerHTML || el.fixIE78)) { //IE7-8 innerText,innerHTML都无法取得其内容,IE6能取得其innerHTML
|
3216
|
-
|
3213
|
+
xhr = getXHR() //IE9-11与chrome的innerHTML会得到转义的内容,它们的innerText可以
|
3217
3214
|
xhr.open("GET", location, false) //谢谢Nodejs 乱炖群 深圳-纯属虚构
|
3218
3215
|
xhr.send(null)
|
3219
3216
|
//http://bbs.csdn.net/topics/390349046?page=1#post-393492653
|
@@ -3251,8 +3248,6 @@ bindingExecutors.attr = function(val, elem, data) {
|
|
3251
3248
|
"title,alt,src,value,css,include,href".replace(rword, function(name) {
|
3252
3249
|
bindingHandlers[name] = bindingHandlers.attr
|
3253
3250
|
})
|
3254
|
-
//ms-include绑定已由ms-attr绑定实现
|
3255
|
-
|
3256
3251
|
//根据VM的属性值或表达式的值切换类名,ms-class="xxx yyy zzz:flag"
|
3257
3252
|
//http://www.cnblogs.com/rubylouvre/archive/2012/12/17/2818540.html
|
3258
3253
|
bindingHandlers["class"] = function(data, vmodels) {
|
@@ -3343,6 +3338,10 @@ bindingExecutors ["class"] = function(val, elem, data) {
|
|
3343
3338
|
"hover,active".replace(rword, function(method) {
|
3344
3339
|
bindingHandlers[method] = bindingHandlers["class"]
|
3345
3340
|
})
|
3341
|
+
//ms-controller绑定已经在scanTag 方法中实现
|
3342
|
+
//ms-css绑定已由ms-attr绑定实现
|
3343
|
+
|
3344
|
+
|
3346
3345
|
// bindingHandlers.data 定义在if.js
|
3347
3346
|
bindingExecutors.data = function(val, elem, data) {
|
3348
3347
|
var key = "data-" + data.param
|
@@ -3353,350 +3352,95 @@ bindingExecutors.data = function(val, elem, data) {
|
|
3353
3352
|
}
|
3354
3353
|
}
|
3355
3354
|
|
3356
|
-
|
3357
|
-
|
3358
|
-
|
3359
|
-
|
3360
|
-
|
3361
|
-
|
3362
|
-
|
3355
|
+
//双工绑定
|
3356
|
+
var duplexBinding = bindingHandlers.duplex = function(data, vmodels) {
|
3357
|
+
var elem = data.element,
|
3358
|
+
hasCast
|
3359
|
+
parseExprProxy(data.value, vmodels, data, 0, 1)
|
3360
|
+
|
3361
|
+
data.changed = getBindingCallback(elem, "data-duplex-changed", vmodels) || noop
|
3362
|
+
if (data.evaluator && data.args) {
|
3363
|
+
var params = []
|
3364
|
+
var casting = oneObject("string,number,boolean,checked")
|
3365
|
+
if (elem.type === "radio" && data.param === "") {
|
3366
|
+
data.param = "checked"
|
3363
3367
|
}
|
3364
|
-
|
3365
|
-
|
3366
|
-
elem.textContent = val
|
3367
|
-
} else {
|
3368
|
-
elem.innerText = val
|
3368
|
+
if (elem.msData) {
|
3369
|
+
elem.msData["ms-duplex"] = data.value
|
3369
3370
|
}
|
3370
|
-
|
3371
|
-
|
3372
|
-
|
3373
|
-
|
3374
|
-
|
3375
|
-
|
3376
|
-
|
3377
|
-
|
3378
|
-
|
3379
|
-
|
3380
|
-
|
3381
|
-
|
3382
|
-
|
3383
|
-
|
3384
|
-
|
3385
|
-
|
3386
|
-
|
3387
|
-
|
3371
|
+
data.param.replace(/\w+/g, function(name) {
|
3372
|
+
if (/^(checkbox|radio)$/.test(elem.type) && /^(radio|checked)$/.test(name)) {
|
3373
|
+
if (name === "radio")
|
3374
|
+
log("ms-duplex-radio已经更名为ms-duplex-checked")
|
3375
|
+
name = "checked"
|
3376
|
+
data.isChecked = true
|
3377
|
+
}
|
3378
|
+
if (name === "bool") {
|
3379
|
+
name = "boolean"
|
3380
|
+
log("ms-duplex-bool已经更名为ms-duplex-boolean")
|
3381
|
+
} else if (name === "text") {
|
3382
|
+
name = "string"
|
3383
|
+
log("ms-duplex-text已经更名为ms-duplex-string")
|
3384
|
+
}
|
3385
|
+
if (casting[name]) {
|
3386
|
+
hasCast = true
|
3387
|
+
}
|
3388
|
+
avalon.Array.ensure(params, name)
|
3389
|
+
})
|
3390
|
+
if (!hasCast) {
|
3391
|
+
params.push("string")
|
3388
3392
|
}
|
3389
|
-
|
3390
|
-
|
3391
|
-
|
3392
|
-
|
3393
|
-
|
3394
|
-
|
3395
|
-
|
3396
|
-
|
3397
|
-
|
3398
|
-
|
3399
|
-
|
3400
|
-
|
3401
|
-
i++
|
3393
|
+
data.param = params.join("-")
|
3394
|
+
data.bound = function(type, callback) {
|
3395
|
+
if (elem.addEventListener) {
|
3396
|
+
elem.addEventListener(type, callback, false)
|
3397
|
+
} else {
|
3398
|
+
elem.attachEvent("on" + type, callback)
|
3399
|
+
}
|
3400
|
+
var old = data.rollback
|
3401
|
+
data.rollback = function() {
|
3402
|
+
elem.avalonSetter = null
|
3403
|
+
avalon.unbind(elem, type, callback)
|
3404
|
+
old && old()
|
3402
3405
|
}
|
3403
3406
|
}
|
3404
|
-
|
3405
|
-
|
3406
|
-
|
3407
|
-
|
3408
|
-
|
3409
|
-
|
3410
|
-
|
3407
|
+
for (var i in avalon.vmodels) {
|
3408
|
+
var v = avalon.vmodels[i]
|
3409
|
+
v.$fire("avalon-ms-duplex-init", data)
|
3410
|
+
}
|
3411
|
+
var cpipe = data.pipe || (data.pipe = pipe)
|
3412
|
+
cpipe(null, data, "init")
|
3413
|
+
var tagName = elem.tagName
|
3414
|
+
duplexBinding[tagName] && duplexBinding[tagName](elem, data.evaluator.apply(null, data.args), data)
|
3411
3415
|
}
|
3412
|
-
|
3413
|
-
|
3414
|
-
|
3415
|
-
|
3416
|
-
|
3417
|
-
|
3416
|
+
}
|
3417
|
+
//不存在 bindingExecutors.duplex
|
3418
|
+
function fixNull(val) {
|
3419
|
+
return val == null ? "" : val
|
3420
|
+
}
|
3421
|
+
avalon.duplexHooks = {
|
3422
|
+
checked: {
|
3423
|
+
get: function(val, data) {
|
3424
|
+
return !data.element.oldValue
|
3418
3425
|
}
|
3419
|
-
}
|
3420
|
-
|
3421
|
-
|
3422
|
-
|
3423
|
-
|
3424
|
-
|
3425
|
-
|
3426
|
-
|
3427
|
-
function(
|
3428
|
-
|
3429
|
-
}
|
3430
|
-
|
3431
|
-
|
3432
|
-
|
3433
|
-
|
3434
|
-
|
3435
|
-
|
3436
|
-
|
3437
|
-
if (elem.getAttribute(data.name)) {
|
3438
|
-
elem.removeAttribute(data.name)
|
3439
|
-
scanAttr(elem, data.vmodels)
|
3440
|
-
}
|
3441
|
-
data.rollback = null
|
3442
|
-
} else { //移出DOM树,并用注释节点占据原位置
|
3443
|
-
if (elem.nodeType === 1) {
|
3444
|
-
var node = data.element = DOC.createComment("ms-if")
|
3445
|
-
elem.parentNode.replaceChild(node, elem)
|
3446
|
-
data.template = elem //元素节点
|
3447
|
-
ifGroup.appendChild(elem)
|
3448
|
-
data.rollback = function() {
|
3449
|
-
if (elem.parentNode === ifGroup) {
|
3450
|
-
ifGroup.removeChild(elem)
|
3451
|
-
}
|
3452
|
-
}
|
3453
|
-
}
|
3454
|
-
}
|
3455
|
-
}
|
3456
|
-
|
3457
|
-
|
3458
|
-
function parseDisplay(nodeName, val) {
|
3459
|
-
//用于取得此类标签的默认display值
|
3460
|
-
var key = "_" + nodeName
|
3461
|
-
if (!parseDisplay[key]) {
|
3462
|
-
var node = DOC.createElement(nodeName)
|
3463
|
-
root.appendChild(node)
|
3464
|
-
if (W3C) {
|
3465
|
-
val = getComputedStyle(node, null).display
|
3466
|
-
} else {
|
3467
|
-
val = node.currentStyle.display
|
3468
|
-
}
|
3469
|
-
root.removeChild(node)
|
3470
|
-
parseDisplay[key] = val
|
3471
|
-
}
|
3472
|
-
return parseDisplay[key]
|
3473
|
-
}
|
3474
|
-
|
3475
|
-
avalon.parseDisplay = parseDisplay
|
3476
|
-
|
3477
|
-
bindingHandlers.visible = function(data, vmodels) {
|
3478
|
-
var elem = avalon(data.element)
|
3479
|
-
var display = elem.css("display")
|
3480
|
-
if (display === "none") {
|
3481
|
-
var style = elem[0].style
|
3482
|
-
var has = /visibility/i.test(style.cssText)
|
3483
|
-
var visible = elem.css("visibility")
|
3484
|
-
style.display = ""
|
3485
|
-
style.visibility = "hidden"
|
3486
|
-
display = elem.css("display")
|
3487
|
-
if (display === "none") {
|
3488
|
-
display = parseDisplay(elem[0].nodeName)
|
3489
|
-
}
|
3490
|
-
style.visibility = has ? visible : ""
|
3491
|
-
}
|
3492
|
-
data.display = display
|
3493
|
-
parseExprProxy(data.value, vmodels, data)
|
3494
|
-
}
|
3495
|
-
|
3496
|
-
bindingExecutors.visible = function(val, elem, data) {
|
3497
|
-
elem.style.display = val ? data.display : "none"
|
3498
|
-
}
|
3499
|
-
|
3500
|
-
var rdash = /\(([^)]*)\)/
|
3501
|
-
bindingHandlers.on = function(data, vmodels) {
|
3502
|
-
var value = data.value
|
3503
|
-
data.type = "on"
|
3504
|
-
var eventType = data.param.replace(/-\d+$/, "") // ms-on-mousemove-10
|
3505
|
-
if (typeof bindingHandlers.on[eventType + "Hook"] === "function") {
|
3506
|
-
bindingHandlers.on[eventType + "Hook"](data)
|
3507
|
-
}
|
3508
|
-
if (value.indexOf("(") > 0 && value.indexOf(")") > -1) {
|
3509
|
-
var matched = (value.match(rdash) || ["", ""])[1].trim()
|
3510
|
-
if (matched === "" || matched === "$event") { // aaa() aaa($event)当成aaa处理
|
3511
|
-
value = value.replace(rdash, "")
|
3512
|
-
}
|
3513
|
-
}
|
3514
|
-
parseExprProxy(value, vmodels, data)
|
3515
|
-
}
|
3516
|
-
|
3517
|
-
bindingExecutors.on = function(callback, elem, data) {
|
3518
|
-
callback = function(e) {
|
3519
|
-
var fn = data.evaluator || noop
|
3520
|
-
return fn.apply(this, data.args.concat(e))
|
3521
|
-
}
|
3522
|
-
var eventType = data.param.replace(/-\d+$/, "") // ms-on-mousemove-10
|
3523
|
-
if (eventType === "scan") {
|
3524
|
-
callback.call(elem, {
|
3525
|
-
type: eventType
|
3526
|
-
})
|
3527
|
-
} else if (typeof data.specialBind === "function") {
|
3528
|
-
data.specialBind(elem, callback)
|
3529
|
-
} else {
|
3530
|
-
var removeFn = avalon.bind(elem, eventType, callback)
|
3531
|
-
}
|
3532
|
-
data.rollback = function() {
|
3533
|
-
if (typeof data.specialUnbind === "function") {
|
3534
|
-
data.specialUnbind()
|
3535
|
-
} else {
|
3536
|
-
avalon.unbind(elem, eventType, removeFn)
|
3537
|
-
}
|
3538
|
-
}
|
3539
|
-
}
|
3540
|
-
|
3541
|
-
|
3542
|
-
bindingHandlers.widget = function(data, vmodels) {
|
3543
|
-
var args = data.value.match(rword)
|
3544
|
-
var elem = data.element
|
3545
|
-
var widget = args[0]
|
3546
|
-
var id = args[1]
|
3547
|
-
if (!id || id === "$") {//没有定义或为$时,取组件名+随机数
|
3548
|
-
id = generateID(widget)
|
3549
|
-
}
|
3550
|
-
var optName = args[2] || widget//没有定义,取组件名
|
3551
|
-
var constructor = avalon.ui[widget]
|
3552
|
-
if (typeof constructor === "function") { //ms-widget="tabs,tabsAAA,optname"
|
3553
|
-
vmodels = elem.vmodels || vmodels
|
3554
|
-
for (var i = 0, v; v = vmodels[i++]; ) {
|
3555
|
-
if (v.hasOwnProperty(optName) && typeof v[optName] === "object") {
|
3556
|
-
var vmOptions = v[optName]
|
3557
|
-
vmOptions = vmOptions.$model || vmOptions
|
3558
|
-
break
|
3559
|
-
}
|
3560
|
-
}
|
3561
|
-
if (vmOptions) {
|
3562
|
-
var wid = vmOptions[widget + "Id"]
|
3563
|
-
if (typeof wid === "string") {
|
3564
|
-
id = wid
|
3565
|
-
}
|
3566
|
-
}
|
3567
|
-
//抽取data-tooltip-text、data-tooltip-attr属性,组成一个配置对象
|
3568
|
-
var widgetData = avalon.getWidgetData(elem, widget)
|
3569
|
-
data.value = [widget, id, optName].join(",")
|
3570
|
-
data[widget + "Id"] = id
|
3571
|
-
data.evaluator = noop
|
3572
|
-
elem.msData["ms-widget-id"] = id
|
3573
|
-
var options = data[widget + "Options"] = avalon.mix({}, constructor.defaults, vmOptions || {}, widgetData)
|
3574
|
-
elem.removeAttribute("ms-widget")
|
3575
|
-
var vmodel = constructor(elem, data, vmodels) || {} //防止组件不返回VM
|
3576
|
-
if (vmodel.$id) {
|
3577
|
-
avalon.vmodels[id] = vmodel
|
3578
|
-
createSignalTower(elem, vmodel)
|
3579
|
-
if (vmodel.hasOwnProperty("$init")) {
|
3580
|
-
vmodel.$init(function() {
|
3581
|
-
avalon.scan(elem, [vmodel].concat(vmodels))
|
3582
|
-
if (typeof options.onInit === "function") {
|
3583
|
-
options.onInit.call(elem, vmodel, options, vmodels)
|
3584
|
-
}
|
3585
|
-
})
|
3586
|
-
}
|
3587
|
-
data.rollback = function() {
|
3588
|
-
try {
|
3589
|
-
vmodel.widgetElement = null
|
3590
|
-
vmodel.$remove()
|
3591
|
-
} catch (e) {
|
3592
|
-
}
|
3593
|
-
elem.msData = {}
|
3594
|
-
delete avalon.vmodels[vmodel.$id]
|
3595
|
-
}
|
3596
|
-
addSubscribers(data, widgetList)
|
3597
|
-
if (window.chrome) {
|
3598
|
-
elem.addEventListener("DOMNodeRemovedFromDocument", function() {
|
3599
|
-
setTimeout(removeSubscribers)
|
3600
|
-
})
|
3601
|
-
}
|
3602
|
-
} else {
|
3603
|
-
avalon.scan(elem, vmodels)
|
3604
|
-
}
|
3605
|
-
} else if (vmodels.length) { //如果该组件还没有加载,那么保存当前的vmodels
|
3606
|
-
elem.vmodels = vmodels
|
3607
|
-
}
|
3608
|
-
}
|
3609
|
-
var widgetList = []
|
3610
|
-
//不存在 bindingExecutors.widget
|
3611
|
-
//双工绑定
|
3612
|
-
var duplexBinding = bindingHandlers.duplex = function(data, vmodels) {
|
3613
|
-
var elem = data.element,
|
3614
|
-
hasCast
|
3615
|
-
parseExprProxy(data.value, vmodels, data, 0, 1)
|
3616
|
-
|
3617
|
-
data.changed = getBindingCallback(elem, "data-duplex-changed", vmodels) || noop
|
3618
|
-
if (data.evaluator && data.args) {
|
3619
|
-
var params = []
|
3620
|
-
var casting = oneObject("string,number,boolean,checked")
|
3621
|
-
if (elem.type === "radio" && data.param === "") {
|
3622
|
-
data.param = "checked"
|
3623
|
-
}
|
3624
|
-
if (elem.msData) {
|
3625
|
-
elem.msData["ms-duplex"] = data.value
|
3626
|
-
}
|
3627
|
-
data.param.replace(/\w+/g, function(name) {
|
3628
|
-
if (/^(checkbox|radio)$/.test(elem.type) && /^(radio|checked)$/.test(name)) {
|
3629
|
-
if (name === "radio")
|
3630
|
-
log("ms-duplex-radio已经更名为ms-duplex-checked")
|
3631
|
-
name = "checked"
|
3632
|
-
data.isChecked = true
|
3633
|
-
}
|
3634
|
-
if (name === "bool") {
|
3635
|
-
name = "boolean"
|
3636
|
-
log("ms-duplex-bool已经更名为ms-duplex-boolean")
|
3637
|
-
} else if (name === "text") {
|
3638
|
-
name = "string"
|
3639
|
-
log("ms-duplex-text已经更名为ms-duplex-string")
|
3640
|
-
}
|
3641
|
-
if (casting[name]) {
|
3642
|
-
hasCast = true
|
3643
|
-
}
|
3644
|
-
avalon.Array.ensure(params, name)
|
3645
|
-
})
|
3646
|
-
if (!hasCast) {
|
3647
|
-
params.push("string")
|
3648
|
-
}
|
3649
|
-
data.param = params.join("-")
|
3650
|
-
data.bound = function(type, callback) {
|
3651
|
-
if (elem.addEventListener) {
|
3652
|
-
elem.addEventListener(type, callback, false)
|
3653
|
-
} else {
|
3654
|
-
elem.attachEvent("on" + type, callback)
|
3655
|
-
}
|
3656
|
-
var old = data.rollback
|
3657
|
-
data.rollback = function() {
|
3658
|
-
elem.avalonSetter = null
|
3659
|
-
avalon.unbind(elem, type, callback)
|
3660
|
-
old && old()
|
3661
|
-
}
|
3662
|
-
}
|
3663
|
-
for (var i in avalon.vmodels) {
|
3664
|
-
var v = avalon.vmodels[i]
|
3665
|
-
v.$fire("avalon-ms-duplex-init", data)
|
3666
|
-
}
|
3667
|
-
var cpipe = data.pipe || (data.pipe = pipe)
|
3668
|
-
cpipe(null, data, "init")
|
3669
|
-
var tagName = elem.tagName
|
3670
|
-
duplexBinding[tagName] && duplexBinding[tagName](elem, data.evaluator.apply(null, data.args), data)
|
3671
|
-
}
|
3672
|
-
}
|
3673
|
-
//不存在 bindingExecutors.duplex
|
3674
|
-
function fixNull(val) {
|
3675
|
-
return val == null ? "" : val
|
3676
|
-
}
|
3677
|
-
avalon.duplexHooks = {
|
3678
|
-
checked: {
|
3679
|
-
get: function(val, data) {
|
3680
|
-
return !data.element.oldValue
|
3681
|
-
}
|
3682
|
-
},
|
3683
|
-
string: {
|
3684
|
-
get: function(val) { //同步到VM
|
3685
|
-
return val
|
3686
|
-
},
|
3687
|
-
set: fixNull
|
3688
|
-
},
|
3689
|
-
"boolean": {
|
3690
|
-
get: function(val) {
|
3691
|
-
return val === "true"
|
3692
|
-
},
|
3693
|
-
set: fixNull
|
3694
|
-
},
|
3695
|
-
number: {
|
3696
|
-
get: function(val) {
|
3697
|
-
return isFinite(val) ? parseFloat(val) || 0 : val
|
3698
|
-
},
|
3699
|
-
set: fixNull
|
3426
|
+
},
|
3427
|
+
string: {
|
3428
|
+
get: function(val) { //同步到VM
|
3429
|
+
return val
|
3430
|
+
},
|
3431
|
+
set: fixNull
|
3432
|
+
},
|
3433
|
+
"boolean": {
|
3434
|
+
get: function(val) {
|
3435
|
+
return val === "true"
|
3436
|
+
},
|
3437
|
+
set: fixNull
|
3438
|
+
},
|
3439
|
+
number: {
|
3440
|
+
get: function(val) {
|
3441
|
+
return isFinite(val) ? parseFloat(val) || 0 : val
|
3442
|
+
},
|
3443
|
+
set: fixNull
|
3700
3444
|
}
|
3701
3445
|
}
|
3702
3446
|
|
@@ -3906,67 +3650,196 @@ duplexBinding.INPUT = function(element, evaluator, data) {
|
|
3906
3650
|
}
|
3907
3651
|
})
|
3908
3652
|
}
|
3909
|
-
if (/text|password/.test(element.type)) {
|
3910
|
-
watchValueInTimer(function() {
|
3911
|
-
if (root.contains(element)) {
|
3912
|
-
if (element.value !== element.oldValue) {
|
3913
|
-
updateVModel()
|
3653
|
+
if (/text|password/.test(element.type)) {
|
3654
|
+
watchValueInTimer(function() {
|
3655
|
+
if (root.contains(element)) {
|
3656
|
+
if (element.value !== element.oldValue) {
|
3657
|
+
updateVModel()
|
3658
|
+
}
|
3659
|
+
} else if (!element.msRetain) {
|
3660
|
+
return false
|
3661
|
+
}
|
3662
|
+
})
|
3663
|
+
}
|
3664
|
+
element.avalonSetter = updateVModel
|
3665
|
+
element.oldValue = element.value
|
3666
|
+
registerSubscriber(data)
|
3667
|
+
callback.call(element, element.value)
|
3668
|
+
}
|
3669
|
+
duplexBinding.TEXTAREA = duplexBinding.INPUT
|
3670
|
+
|
3671
|
+
|
3672
|
+
duplexBinding.SELECT = function(element, evaluator, data) {
|
3673
|
+
var $elem = avalon(element)
|
3674
|
+
function updateVModel() {
|
3675
|
+
if ($elem.data("duplex-observe") !== false) {
|
3676
|
+
var val = $elem.val() //字符串或字符串数组
|
3677
|
+
if (Array.isArray(val)) {
|
3678
|
+
val = val.map(function(v) {
|
3679
|
+
return data.pipe(v, data, "get")
|
3680
|
+
})
|
3681
|
+
} else {
|
3682
|
+
val = data.pipe(val, data, "get")
|
3683
|
+
}
|
3684
|
+
if (val + "" !== element.oldValue) {
|
3685
|
+
evaluator(val)
|
3686
|
+
}
|
3687
|
+
data.changed.call(element, val, data)
|
3688
|
+
}
|
3689
|
+
}
|
3690
|
+
data.handler = function() {
|
3691
|
+
var val = evaluator()
|
3692
|
+
val = val && val.$model || val
|
3693
|
+
if (Array.isArray(val)) {
|
3694
|
+
if (!element.multiple) {
|
3695
|
+
log("ms-duplex在<select multiple=true>上要求对应一个数组")
|
3696
|
+
}
|
3697
|
+
} else {
|
3698
|
+
if (element.multiple) {
|
3699
|
+
log("ms-duplex在<select multiple=false>不能对应一个数组")
|
3700
|
+
}
|
3701
|
+
}
|
3702
|
+
//必须变成字符串后才能比较
|
3703
|
+
val = Array.isArray(val) ? val.map(String) : val + ""
|
3704
|
+
if (val + "" !== element.oldValue) {
|
3705
|
+
$elem.val(val)
|
3706
|
+
element.oldValue = val + ""
|
3707
|
+
}
|
3708
|
+
}
|
3709
|
+
data.bound("change", updateVModel)
|
3710
|
+
checkScan(element, function() {
|
3711
|
+
registerSubscriber(data)
|
3712
|
+
data.changed.call(element, evaluator(), data)
|
3713
|
+
}, NaN)
|
3714
|
+
}
|
3715
|
+
|
3716
|
+
|
3717
|
+
// bindingHandlers.html 定义在if.js
|
3718
|
+
bindingExecutors.html = function(val, elem, data) {
|
3719
|
+
val = val == null ? "" : val
|
3720
|
+
var isHtmlFilter = "group" in data
|
3721
|
+
var parent = isHtmlFilter ? elem.parentNode : elem
|
3722
|
+
if (!parent)
|
3723
|
+
return
|
3724
|
+
if (val.nodeType === 11) { //将val转换为文档碎片
|
3725
|
+
var fragment = val
|
3726
|
+
} else if (val.nodeType === 1 || val.item) {
|
3727
|
+
var nodes = val.nodeType === 1 ? val.childNodes : val.item ? val : []
|
3728
|
+
fragment = hyperspace.cloneNode(true)
|
3729
|
+
while (nodes[0]) {
|
3730
|
+
fragment.appendChild(nodes[0])
|
3731
|
+
}
|
3732
|
+
} else {
|
3733
|
+
fragment = avalon.parseHTML(val)
|
3734
|
+
}
|
3735
|
+
//插入占位符, 如果是过滤器,需要有节制地移除指定的数量,如果是html指令,直接清空
|
3736
|
+
var comment = DOC.createComment("ms-html")
|
3737
|
+
if (isHtmlFilter) {
|
3738
|
+
parent.insertBefore(comment, elem)
|
3739
|
+
var n = data.group, i = 1
|
3740
|
+
while (i < n) {
|
3741
|
+
var node = elem.nextSibling
|
3742
|
+
if (node) {
|
3743
|
+
parent.removeChild(node)
|
3744
|
+
i++
|
3745
|
+
}
|
3746
|
+
}
|
3747
|
+
parent.removeChild(elem)
|
3748
|
+
data.element = comment //防止被CG
|
3749
|
+
} else {
|
3750
|
+
avalon.clearHTML(parent).appendChild(comment)
|
3751
|
+
}
|
3752
|
+
if (isHtmlFilter) {
|
3753
|
+
data.group = fragment.childNodes.length || 1
|
3754
|
+
}
|
3755
|
+
nodes = avalon.slice(fragment.childNodes)
|
3756
|
+
if (nodes[0]) {
|
3757
|
+
if (comment.parentNode)
|
3758
|
+
comment.parentNode.replaceChild(fragment, comment)
|
3759
|
+
if (isHtmlFilter) {
|
3760
|
+
data.element = nodes[0]
|
3761
|
+
}
|
3762
|
+
}
|
3763
|
+
scanNodeArray(nodes, data.vmodels)
|
3764
|
+
}
|
3765
|
+
|
3766
|
+
bindingHandlers["if"] =
|
3767
|
+
bindingHandlers.data =
|
3768
|
+
bindingHandlers.text =
|
3769
|
+
bindingHandlers.html =
|
3770
|
+
function(data, vmodels) {
|
3771
|
+
parseExprProxy(data.value, vmodels, data)
|
3772
|
+
}
|
3773
|
+
|
3774
|
+
bindingExecutors["if"] = function(val, elem, data) {
|
3775
|
+
if (val) { //插回DOM树
|
3776
|
+
if (elem.nodeType === 8) {
|
3777
|
+
elem.parentNode.replaceChild(data.template, elem)
|
3778
|
+
elem = data.element = data.template //这时可能为null
|
3779
|
+
}
|
3780
|
+
if (elem.getAttribute(data.name)) {
|
3781
|
+
elem.removeAttribute(data.name)
|
3782
|
+
scanAttr(elem, data.vmodels)
|
3783
|
+
}
|
3784
|
+
data.rollback = null
|
3785
|
+
} else { //移出DOM树,并用注释节点占据原位置
|
3786
|
+
if (elem.nodeType === 1) {
|
3787
|
+
var node = data.element = DOC.createComment("ms-if")
|
3788
|
+
elem.parentNode.replaceChild(node, elem)
|
3789
|
+
data.template = elem //元素节点
|
3790
|
+
ifGroup.appendChild(elem)
|
3791
|
+
data.rollback = function() {
|
3792
|
+
if (elem.parentNode === ifGroup) {
|
3793
|
+
ifGroup.removeChild(elem)
|
3914
3794
|
}
|
3915
|
-
} else if (!element.msRetain) {
|
3916
|
-
return false
|
3917
3795
|
}
|
3918
|
-
}
|
3796
|
+
}
|
3919
3797
|
}
|
3920
|
-
element.avalonSetter = updateVModel
|
3921
|
-
element.oldValue = element.value
|
3922
|
-
registerSubscriber(data)
|
3923
|
-
callback.call(element, element.value)
|
3924
3798
|
}
|
3925
|
-
duplexBinding.TEXTAREA = duplexBinding.INPUT
|
3926
3799
|
|
3927
3800
|
|
3928
|
-
|
3929
|
-
|
3930
|
-
|
3931
|
-
|
3932
|
-
|
3933
|
-
|
3934
|
-
|
3935
|
-
|
3936
|
-
|
3937
|
-
|
3938
|
-
|
3939
|
-
|
3940
|
-
|
3941
|
-
|
3942
|
-
|
3943
|
-
data.changed.call(element, val, data)
|
3801
|
+
//ms-important绑定已经在scanTag 方法中实现
|
3802
|
+
//ms-include绑定已由ms-attr绑定实现
|
3803
|
+
|
3804
|
+
var rdash = /\(([^)]*)\)/
|
3805
|
+
bindingHandlers.on = function(data, vmodels) {
|
3806
|
+
var value = data.value
|
3807
|
+
data.type = "on"
|
3808
|
+
var eventType = data.param.replace(/-\d+$/, "") // ms-on-mousemove-10
|
3809
|
+
if (typeof bindingHandlers.on[eventType + "Hook"] === "function") {
|
3810
|
+
bindingHandlers.on[eventType + "Hook"](data)
|
3811
|
+
}
|
3812
|
+
if (value.indexOf("(") > 0 && value.indexOf(")") > -1) {
|
3813
|
+
var matched = (value.match(rdash) || ["", ""])[1].trim()
|
3814
|
+
if (matched === "" || matched === "$event") { // aaa() aaa($event)当成aaa处理
|
3815
|
+
value = value.replace(rdash, "")
|
3944
3816
|
}
|
3945
3817
|
}
|
3946
|
-
|
3947
|
-
|
3948
|
-
|
3949
|
-
|
3950
|
-
|
3951
|
-
|
3952
|
-
|
3818
|
+
parseExprProxy(value, vmodels, data)
|
3819
|
+
}
|
3820
|
+
|
3821
|
+
bindingExecutors.on = function(callback, elem, data) {
|
3822
|
+
callback = function(e) {
|
3823
|
+
var fn = data.evaluator || noop
|
3824
|
+
return fn.apply(this, data.args.concat(e))
|
3825
|
+
}
|
3826
|
+
var eventType = data.param.replace(/-\d+$/, "") // ms-on-mousemove-10
|
3827
|
+
if (eventType === "scan") {
|
3828
|
+
callback.call(elem, {
|
3829
|
+
type: eventType
|
3830
|
+
})
|
3831
|
+
} else if (typeof data.specialBind === "function") {
|
3832
|
+
data.specialBind(elem, callback)
|
3833
|
+
} else {
|
3834
|
+
var removeFn = avalon.bind(elem, eventType, callback)
|
3835
|
+
}
|
3836
|
+
data.rollback = function() {
|
3837
|
+
if (typeof data.specialUnbind === "function") {
|
3838
|
+
data.specialUnbind()
|
3953
3839
|
} else {
|
3954
|
-
|
3955
|
-
log("ms-duplex在<select multiple=false>不能对应一个数组")
|
3956
|
-
}
|
3957
|
-
}
|
3958
|
-
//必须变成字符串后才能比较
|
3959
|
-
val = Array.isArray(val) ? val.map(String) : val + ""
|
3960
|
-
if (val + "" !== element.oldValue) {
|
3961
|
-
$elem.val(val)
|
3962
|
-
element.oldValue = val + ""
|
3840
|
+
avalon.unbind(elem, eventType, removeFn)
|
3963
3841
|
}
|
3964
3842
|
}
|
3965
|
-
data.bound("change", updateVModel)
|
3966
|
-
checkScan(element, function() {
|
3967
|
-
registerSubscriber(data)
|
3968
|
-
data.changed.call(element, evaluator(), data)
|
3969
|
-
}, NaN)
|
3970
3843
|
}
|
3971
3844
|
|
3972
3845
|
|
@@ -4042,9 +3915,9 @@ bindingHandlers.repeat = function(data, vmodels) {
|
|
4042
3915
|
check0 = "$first"
|
4043
3916
|
check1 = "$last"
|
4044
3917
|
}
|
4045
|
-
for (
|
4046
|
-
if (
|
4047
|
-
data.$outer =
|
3918
|
+
for (i = 0; v = vmodels[i++]; ) {
|
3919
|
+
if (v.hasOwnProperty(check0) && v.hasOwnProperty(check1)) {
|
3920
|
+
data.$outer = v
|
4048
3921
|
break
|
4049
3922
|
}
|
4050
3923
|
}
|
@@ -4074,7 +3947,7 @@ bindingExecutors.repeat = function(method, pos, el) {
|
|
4074
3947
|
var n = pos + el
|
4075
3948
|
var array = data.$repeat
|
4076
3949
|
var last = array.length - 1
|
4077
|
-
var fragments = []
|
3950
|
+
var fragments = [], fragment
|
4078
3951
|
var start = locateNode(data, pos)
|
4079
3952
|
for (var i = pos; i < n; i++) {
|
4080
3953
|
var proxy = eachProxyAgent(i, data)
|
@@ -4082,7 +3955,7 @@ bindingExecutors.repeat = function(method, pos, el) {
|
|
4082
3955
|
shimController(data, transation, proxy, fragments)
|
4083
3956
|
}
|
4084
3957
|
parent.insertBefore(transation, start)
|
4085
|
-
for (
|
3958
|
+
for (i = 0; fragment = fragments[i++]; ) {
|
4086
3959
|
scanNodeArray(fragment.nodes, fragment.vmodels)
|
4087
3960
|
fragment.nodes = fragment.vmodels = null
|
4088
3961
|
}
|
@@ -4124,7 +3997,7 @@ bindingExecutors.repeat = function(method, pos, el) {
|
|
4124
3997
|
parent.insertBefore(transation, end)
|
4125
3998
|
break
|
4126
3999
|
case "index": //将proxies中的第pos个起的所有元素重新索引
|
4127
|
-
|
4000
|
+
last = proxies.length - 1
|
4128
4001
|
for (; el = proxies[pos]; pos++) {
|
4129
4002
|
el.$index = pos
|
4130
4003
|
el.$first = pos === 0
|
@@ -4132,7 +4005,7 @@ bindingExecutors.repeat = function(method, pos, el) {
|
|
4132
4005
|
}
|
4133
4006
|
return
|
4134
4007
|
case "set": //将proxies中的第pos个元素的VM设置为el(pos为数字,el任意)
|
4135
|
-
|
4008
|
+
proxy = proxies[pos]
|
4136
4009
|
if (proxy) {
|
4137
4010
|
notifySubscribers(proxy.$events.$index)
|
4138
4011
|
}
|
@@ -4140,7 +4013,7 @@ bindingExecutors.repeat = function(method, pos, el) {
|
|
4140
4013
|
case "append": //将pos的键值对从el中取出(pos为一个普通对象,el为预先生成好的代理VM对象池)
|
4141
4014
|
var pool = el
|
4142
4015
|
var keys = []
|
4143
|
-
|
4016
|
+
fragments = []
|
4144
4017
|
for (var key in pos) { //得到所有键名
|
4145
4018
|
if (pos.hasOwnProperty(key) && key !== "hasOwnProperty") {
|
4146
4019
|
keys.push(key)
|
@@ -4152,7 +4025,7 @@ bindingExecutors.repeat = function(method, pos, el) {
|
|
4152
4025
|
keys = keys2
|
4153
4026
|
}
|
4154
4027
|
}
|
4155
|
-
for (
|
4028
|
+
for (i = 0; key = keys[i++]; ) {
|
4156
4029
|
if (key !== "hasOwnProperty") {
|
4157
4030
|
if (!pool[key]) {
|
4158
4031
|
pool[key] = withProxyAgent(key, data)
|
@@ -4163,7 +4036,7 @@ bindingExecutors.repeat = function(method, pos, el) {
|
|
4163
4036
|
var comment = data.$stamp = data.clone
|
4164
4037
|
parent.insertBefore(comment, end)
|
4165
4038
|
parent.insertBefore(transation, end)
|
4166
|
-
for (
|
4039
|
+
for (i = 0; fragment = fragments[i++]; ) {
|
4167
4040
|
scanNodeArray(fragment.nodes, fragment.vmodels)
|
4168
4041
|
fragment.nodes = fragment.vmodels = null
|
4169
4042
|
}
|
@@ -4343,6 +4216,139 @@ function recycleProxies(proxies, type) {
|
|
4343
4216
|
|
4344
4217
|
|
4345
4218
|
|
4219
|
+
/*********************************************************************
|
4220
|
+
* 各种指令 *
|
4221
|
+
**********************************************************************/
|
4222
|
+
//ms-skip绑定已经在scanTag 方法中实现
|
4223
|
+
// bindingHandlers.text 定义在if.js
|
4224
|
+
bindingExecutors.text = function(val, elem) {
|
4225
|
+
val = val == null ? "" : val //不在页面上显示undefined null
|
4226
|
+
if (elem.nodeType === 3) { //绑定在文本节点上
|
4227
|
+
try { //IE对游离于DOM树外的节点赋值会报错
|
4228
|
+
elem.data = val
|
4229
|
+
} catch (e) {
|
4230
|
+
}
|
4231
|
+
} else { //绑定在特性节点上
|
4232
|
+
if ("textContent" in elem) {
|
4233
|
+
elem.textContent = val
|
4234
|
+
} else {
|
4235
|
+
elem.innerText = val
|
4236
|
+
}
|
4237
|
+
}
|
4238
|
+
}
|
4239
|
+
|
4240
|
+
|
4241
|
+
function parseDisplay(nodeName, val) {
|
4242
|
+
//用于取得此类标签的默认display值
|
4243
|
+
var key = "_" + nodeName
|
4244
|
+
if (!parseDisplay[key]) {
|
4245
|
+
var node = DOC.createElement(nodeName)
|
4246
|
+
root.appendChild(node)
|
4247
|
+
if (W3C) {
|
4248
|
+
val = getComputedStyle(node, null).display
|
4249
|
+
} else {
|
4250
|
+
val = node.currentStyle.display
|
4251
|
+
}
|
4252
|
+
root.removeChild(node)
|
4253
|
+
parseDisplay[key] = val
|
4254
|
+
}
|
4255
|
+
return parseDisplay[key]
|
4256
|
+
}
|
4257
|
+
|
4258
|
+
avalon.parseDisplay = parseDisplay
|
4259
|
+
|
4260
|
+
bindingHandlers.visible = function(data, vmodels) {
|
4261
|
+
var elem = avalon(data.element)
|
4262
|
+
var display = elem.css("display")
|
4263
|
+
if (display === "none") {
|
4264
|
+
var style = elem[0].style
|
4265
|
+
var has = /visibility/i.test(style.cssText)
|
4266
|
+
var visible = elem.css("visibility")
|
4267
|
+
style.display = ""
|
4268
|
+
style.visibility = "hidden"
|
4269
|
+
display = elem.css("display")
|
4270
|
+
if (display === "none") {
|
4271
|
+
display = parseDisplay(elem[0].nodeName)
|
4272
|
+
}
|
4273
|
+
style.visibility = has ? visible : ""
|
4274
|
+
}
|
4275
|
+
data.display = display
|
4276
|
+
parseExprProxy(data.value, vmodels, data)
|
4277
|
+
}
|
4278
|
+
|
4279
|
+
bindingExecutors.visible = function(val, elem, data) {
|
4280
|
+
elem.style.display = val ? data.display : "none"
|
4281
|
+
}
|
4282
|
+
|
4283
|
+
bindingHandlers.widget = function(data, vmodels) {
|
4284
|
+
var args = data.value.match(rword)
|
4285
|
+
var elem = data.element
|
4286
|
+
var widget = args[0]
|
4287
|
+
var id = args[1]
|
4288
|
+
if (!id || id === "$") {//没有定义或为$时,取组件名+随机数
|
4289
|
+
id = generateID(widget)
|
4290
|
+
}
|
4291
|
+
var optName = args[2] || widget//没有定义,取组件名
|
4292
|
+
var constructor = avalon.ui[widget]
|
4293
|
+
if (typeof constructor === "function") { //ms-widget="tabs,tabsAAA,optname"
|
4294
|
+
vmodels = elem.vmodels || vmodels
|
4295
|
+
for (var i = 0, v; v = vmodels[i++]; ) {
|
4296
|
+
if (v.hasOwnProperty(optName) && typeof v[optName] === "object") {
|
4297
|
+
var vmOptions = v[optName]
|
4298
|
+
vmOptions = vmOptions.$model || vmOptions
|
4299
|
+
break
|
4300
|
+
}
|
4301
|
+
}
|
4302
|
+
if (vmOptions) {
|
4303
|
+
var wid = vmOptions[widget + "Id"]
|
4304
|
+
if (typeof wid === "string") {
|
4305
|
+
id = wid
|
4306
|
+
}
|
4307
|
+
}
|
4308
|
+
//抽取data-tooltip-text、data-tooltip-attr属性,组成一个配置对象
|
4309
|
+
var widgetData = avalon.getWidgetData(elem, widget)
|
4310
|
+
data.value = [widget, id, optName].join(",")
|
4311
|
+
data[widget + "Id"] = id
|
4312
|
+
data.evaluator = noop
|
4313
|
+
elem.msData["ms-widget-id"] = id
|
4314
|
+
var options = data[widget + "Options"] = avalon.mix({}, constructor.defaults, vmOptions || {}, widgetData)
|
4315
|
+
elem.removeAttribute("ms-widget")
|
4316
|
+
var vmodel = constructor(elem, data, vmodels) || {} //防止组件不返回VM
|
4317
|
+
if (vmodel.$id) {
|
4318
|
+
avalon.vmodels[id] = vmodel
|
4319
|
+
createSignalTower(elem, vmodel)
|
4320
|
+
if (vmodel.hasOwnProperty("$init")) {
|
4321
|
+
vmodel.$init(function() {
|
4322
|
+
avalon.scan(elem, [vmodel].concat(vmodels))
|
4323
|
+
if (typeof options.onInit === "function") {
|
4324
|
+
options.onInit.call(elem, vmodel, options, vmodels)
|
4325
|
+
}
|
4326
|
+
})
|
4327
|
+
}
|
4328
|
+
data.rollback = function() {
|
4329
|
+
try {
|
4330
|
+
vmodel.widgetElement = null
|
4331
|
+
vmodel.$remove()
|
4332
|
+
} catch (e) {
|
4333
|
+
}
|
4334
|
+
elem.msData = {}
|
4335
|
+
delete avalon.vmodels[vmodel.$id]
|
4336
|
+
}
|
4337
|
+
addSubscribers(data, widgetList)
|
4338
|
+
if (window.chrome) {
|
4339
|
+
elem.addEventListener("DOMNodeRemovedFromDocument", function() {
|
4340
|
+
setTimeout(removeSubscribers)
|
4341
|
+
})
|
4342
|
+
}
|
4343
|
+
} else {
|
4344
|
+
avalon.scan(elem, vmodels)
|
4345
|
+
}
|
4346
|
+
} else if (vmodels.length) { //如果该组件还没有加载,那么保存当前的vmodels
|
4347
|
+
elem.vmodels = vmodels
|
4348
|
+
}
|
4349
|
+
}
|
4350
|
+
var widgetList = []
|
4351
|
+
//不存在 bindingExecutors.widget
|
4346
4352
|
/*********************************************************************
|
4347
4353
|
* 自带过滤器 *
|
4348
4354
|
**********************************************************************/
|
@@ -4567,6 +4573,7 @@ new function() {
|
|
4567
4573
|
Z: timeZoneGetter
|
4568
4574
|
}
|
4569
4575
|
var rdateFormat = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/
|
4576
|
+
var raspnetjson = /^\/Date\((\d+)\)\/$/
|
4570
4577
|
filters.date = function(date, format) {
|
4571
4578
|
var locate = filters.date.locate,
|
4572
4579
|
text = "",
|
@@ -4577,6 +4584,8 @@ new function() {
|
|
4577
4584
|
if (typeof date === "string") {
|
4578
4585
|
if (/^\d+$/.test(date)) {
|
4579
4586
|
date = toInt(date)
|
4587
|
+
} else if (raspnetjson.test(date)) {
|
4588
|
+
date = +RegExp.$1
|
4580
4589
|
} else {
|
4581
4590
|
var trimDate = date.trim()
|
4582
4591
|
var dateArray = [0, 0, 0, 0, 0, 0, 0]
|
@@ -4584,9 +4593,9 @@ new function() {
|
|
4584
4593
|
//取得年月日
|
4585
4594
|
trimDate = trimDate.replace(/^(\d+)\D(\d+)\D(\d+)/, function(_, a, b, c) {
|
4586
4595
|
var array = c.length === 4 ? [c, a, b] : [a, b, c]
|
4587
|
-
dateArray[0] = toInt(array[0])
|
4596
|
+
dateArray[0] = toInt(array[0]) //年
|
4588
4597
|
dateArray[1] = toInt(array[1]) - 1 //月
|
4589
|
-
dateArray[2] = toInt(array[2])//日
|
4598
|
+
dateArray[2] = toInt(array[2]) //日
|
4590
4599
|
return ""
|
4591
4600
|
})
|
4592
4601
|
var dateSetter = oDate.setFullYear
|
@@ -4595,10 +4604,9 @@ new function() {
|
|
4595
4604
|
dateArray[3] = toInt(a) //小时
|
4596
4605
|
dateArray[4] = toInt(b) //分钟
|
4597
4606
|
dateArray[5] = toInt(c) //秒
|
4598
|
-
if (d) {
|
4599
|
-
dateArray[6] = Math.round(parseFloat("0." + d) * 1000)
|
4607
|
+
if (d) { //毫秒
|
4608
|
+
dateArray[6] = Math.round(parseFloat("0." + d) * 1000)
|
4600
4609
|
}
|
4601
|
-
dateArray[6] = d || ""
|
4602
4610
|
return ""
|
4603
4611
|
})
|
4604
4612
|
var tzHour = 0
|
@@ -4718,7 +4726,7 @@ new function() {
|
|
4718
4726
|
}, 50)
|
4719
4727
|
}
|
4720
4728
|
avalon.ready = function(fn) {
|
4721
|
-
loaded ? fn() : fns.push(fn)
|
4729
|
+
loaded ? fn(avalon) : fns.push(fn)
|
4722
4730
|
}
|
4723
4731
|
avalon.ready(function() {
|
4724
4732
|
avalon.scan(DOC.body)
|
@@ -4751,11 +4759,11 @@ new function() {
|
|
4751
4759
|
}
|
4752
4760
|
return avalon
|
4753
4761
|
}
|
4754
|
-
// Expose avalon
|
4762
|
+
// Expose avalon identifiers, even in AMD
|
4755
4763
|
// and CommonJS for browser emulators
|
4756
4764
|
if (noGlobal === void 0) {
|
4757
4765
|
window.avalon = avalon
|
4758
4766
|
}
|
4759
4767
|
return avalon
|
4760
4768
|
|
4761
|
-
}));
|
4769
|
+
}));
|