avalon-rails 1.3.9.1 → 1.3.9.1.20150212184918
Sign up to get free protection for your applications and to get access to all the features.
- 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,9 +5,8 @@
|
|
5
5
|
http://weibo.com/jslouvre/
|
6
6
|
|
7
7
|
Released under the MIT license
|
8
|
-
avalon.modern.js 1.391
|
9
|
-
|
10
|
-
support IE6+ and other browsers
|
8
|
+
avalon.modern.js 1.391 built in 2015.2.12
|
9
|
+
support IE10+ and other browsers
|
11
10
|
==================================================*/
|
12
11
|
(function(global, factory) {
|
13
12
|
|
@@ -38,7 +37,7 @@ var expose = Date.now()
|
|
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.head //HEAD元素
|
41
|
-
head.insertAdjacentHTML("afterBegin", '<avalon ms-skip><style id="avalonStyle">.avalonHide{ display: none!important }</style></avalon>')
|
40
|
+
head.insertAdjacentHTML("afterBegin", '<avalon ms-skip class="avalonHide"><style id="avalonStyle">.avalonHide{ display: none!important }</style></avalon>')
|
42
41
|
var ifGroup = head.firstChild
|
43
42
|
|
44
43
|
function log() {
|
@@ -135,7 +134,7 @@ avalon.type = function(obj) { //取得目标的类型
|
|
135
134
|
}
|
136
135
|
|
137
136
|
var isFunction = function(fn) {
|
138
|
-
return serialize.call(fn)
|
137
|
+
return serialize.call(fn) === "[object Function]"
|
139
138
|
}
|
140
139
|
|
141
140
|
avalon.isFunction = isFunction
|
@@ -245,7 +244,7 @@ avalon.mix({
|
|
245
244
|
}
|
246
245
|
var index = -1,
|
247
246
|
length = Math.max(0, Math.ceil((end - start) / step)),
|
248
|
-
result = Array(length)
|
247
|
+
result = new Array(length)
|
249
248
|
while (++index < length) {
|
250
249
|
result[index] = start
|
251
250
|
start += step
|
@@ -285,10 +284,10 @@ avalon.mix({
|
|
285
284
|
if (node instanceof avalon) {
|
286
285
|
node = node[0]
|
287
286
|
}
|
288
|
-
var prop = /[_-]/.test(name) ? camelize(name) : name
|
287
|
+
var prop = /[_-]/.test(name) ? camelize(name) : name, fn
|
289
288
|
name = avalon.cssName(prop) || prop
|
290
289
|
if (value === void 0 || typeof value === "boolean") { //获取样式
|
291
|
-
|
290
|
+
fn = cssHooks[prop + ":get"] || cssHooks["@:get"]
|
292
291
|
if (name === "background") {
|
293
292
|
name = "backgroundColor"
|
294
293
|
}
|
@@ -318,7 +317,7 @@ avalon.mix({
|
|
318
317
|
}
|
319
318
|
} else {
|
320
319
|
for (i in obj) {
|
321
|
-
if (obj.hasOwnProperty(i) && fn(i, obj[i] === false)
|
320
|
+
if (obj.hasOwnProperty(i) && fn(i, obj[i]) === false) {
|
322
321
|
break
|
323
322
|
}
|
324
323
|
}
|
@@ -619,7 +618,7 @@ var EventBus = {
|
|
619
618
|
return this
|
620
619
|
},
|
621
620
|
$fire: function(type) {
|
622
|
-
var special
|
621
|
+
var special, i, v, callback
|
623
622
|
if (/^(\w+)!(\S+)$/.test(type)) {
|
624
623
|
special = RegExp.$1
|
625
624
|
type = RegExp.$2
|
@@ -628,8 +627,8 @@ var EventBus = {
|
|
628
627
|
var args = aslice.call(arguments, 1)
|
629
628
|
var detail = [type].concat(args)
|
630
629
|
if (special === "all") {
|
631
|
-
for (
|
632
|
-
|
630
|
+
for (i in avalon.vmodels) {
|
631
|
+
v = avalon.vmodels[i]
|
633
632
|
if (v !== this) {
|
634
633
|
v.$fire.apply(v, detail)
|
635
634
|
}
|
@@ -638,8 +637,8 @@ var EventBus = {
|
|
638
637
|
var elements = events.expr ? findNodes(events.expr) : []
|
639
638
|
if (elements.length === 0)
|
640
639
|
return
|
641
|
-
for (
|
642
|
-
|
640
|
+
for (i in avalon.vmodels) {
|
641
|
+
v = avalon.vmodels[i]
|
643
642
|
if (v !== this) {
|
644
643
|
if (v.$events.expr) {
|
645
644
|
var eventNodes = findNodes(v.$events.expr)
|
@@ -672,19 +671,19 @@ var EventBus = {
|
|
672
671
|
if (special === "up") {
|
673
672
|
alls.reverse()
|
674
673
|
}
|
675
|
-
for (
|
676
|
-
if (
|
674
|
+
for (i = 0; callback = alls[i++]; ) {
|
675
|
+
if (callback.$fire.apply(callback, detail) === false) {
|
677
676
|
break
|
678
677
|
}
|
679
678
|
}
|
680
679
|
} else {
|
681
680
|
var callbacks = events[type] || []
|
682
681
|
var all = events.$all || []
|
683
|
-
for (
|
682
|
+
for (i = 0; callback = callbacks[i++]; ) {
|
684
683
|
if (isFunction(callback))
|
685
684
|
callback.apply(this, args)
|
686
685
|
}
|
687
|
-
for (
|
686
|
+
for (i = 0; callback = all[i++]; ) {
|
688
687
|
if (isFunction(callback))
|
689
688
|
callback.apply(this, arguments)
|
690
689
|
}
|
@@ -852,7 +851,7 @@ function modelFactory(source, $special, $model) {
|
|
852
851
|
} else {
|
853
852
|
if (accessor.type === 0) { //type 0 计算属性 1 监控属性 2 对象属性
|
854
853
|
//计算属性不需要收集视图刷新函数,都是由其他监控属性代劳
|
855
|
-
|
854
|
+
newValue = accessor.get.call($vmodel)
|
856
855
|
if (oldValue !== newValue) {
|
857
856
|
$model[name] = newValue
|
858
857
|
//这里不用同步视图
|
@@ -884,12 +883,12 @@ function modelFactory(source, $special, $model) {
|
|
884
883
|
initCallbacks.push(function() {
|
885
884
|
var data = {
|
886
885
|
evaluator: function() {
|
887
|
-
data.type =
|
886
|
+
data.type = Math.random(),
|
888
887
|
data.element = null
|
889
888
|
$model[name] = accessor.get.call($vmodel)
|
890
889
|
},
|
891
890
|
element: head,
|
892
|
-
type:
|
891
|
+
type: Math.random(),
|
893
892
|
handler: noop,
|
894
893
|
args: []
|
895
894
|
}
|
@@ -930,7 +929,7 @@ function modelFactory(source, $special, $model) {
|
|
930
929
|
$vmodel.$id = generateID()
|
931
930
|
$vmodel.$model = $model
|
932
931
|
$vmodel.$events = $events
|
933
|
-
for (
|
932
|
+
for ( i in EventBus) {
|
934
933
|
var fn = EventBus[i]
|
935
934
|
if (!W3C) { //在IE6-8下,VB对象的方法里的this并不指向自身,需要用bind处理一下
|
936
935
|
fn = fn.bind($vmodel)
|
@@ -1372,7 +1371,7 @@ function removeSubscribers() {
|
|
1372
1371
|
if (diff) {
|
1373
1372
|
//avalon.log("有需要移除的元素")
|
1374
1373
|
while (obj = $$subscribers[--i]) {
|
1375
|
-
|
1374
|
+
data = obj.data
|
1376
1375
|
if (data.element === void 0)
|
1377
1376
|
continue
|
1378
1377
|
if (needTest[data.type] && isRemove(data.element)) { //如果它没有在DOM树
|
@@ -1576,50 +1575,6 @@ function bindingSorter(a, b) {
|
|
1576
1575
|
return a.priority - b.priority
|
1577
1576
|
}
|
1578
1577
|
|
1579
|
-
function scanTag(elem, vmodels, node) {
|
1580
|
-
//扫描顺序 ms-skip(0) --> ms-important(1) --> ms-controller(2) --> ms-if(10) --> ms-repeat(100)
|
1581
|
-
//--> ms-if-loop(110) --> ms-attr(970) ...--> ms-each(1400)-->ms-with(1500)--〉ms-duplex(2000)垫后
|
1582
|
-
var a = elem.getAttribute("ms-skip")
|
1583
|
-
var b = elem.getAttributeNode("ms-important")
|
1584
|
-
var c = elem.getAttributeNode("ms-controller")
|
1585
|
-
if (typeof a === "string") {
|
1586
|
-
return
|
1587
|
-
} else if (node = b || c) {
|
1588
|
-
var newVmodel = avalon.vmodels[node.value]
|
1589
|
-
if (!newVmodel) {
|
1590
|
-
return
|
1591
|
-
}
|
1592
|
-
//ms-important不包含父VM,ms-controller相反
|
1593
|
-
vmodels = node === b ? [newVmodel] : [newVmodel].concat(vmodels)
|
1594
|
-
elem.removeAttribute(node.name) //removeAttributeNode不会刷新[ms-controller]样式规则
|
1595
|
-
elem.classList.remove(node.name)
|
1596
|
-
createSignalTower(elem, newVmodel)
|
1597
|
-
}
|
1598
|
-
scanAttr(elem, vmodels) //扫描特性节点
|
1599
|
-
}
|
1600
|
-
function scanNodeList(parent, vmodels) {
|
1601
|
-
var node = parent.firstChild
|
1602
|
-
while (node) {
|
1603
|
-
var nextNode = node.nextSibling
|
1604
|
-
scanNode(node, node.nodeType, vmodels)
|
1605
|
-
node = nextNode
|
1606
|
-
}
|
1607
|
-
}
|
1608
|
-
|
1609
|
-
function scanNodeArray(nodes, vmodels) {
|
1610
|
-
for (var i = 0, node; node = nodes[i++]; ) {
|
1611
|
-
scanNode(node, node.nodeType, vmodels)
|
1612
|
-
}
|
1613
|
-
}
|
1614
|
-
function scanNode(node, nodeType, vmodels) {
|
1615
|
-
if (nodeType === 1) {
|
1616
|
-
scanTag(node, vmodels) //扫描元素节点
|
1617
|
-
} else if (nodeType === 3 && rexpr.test(node.data)){
|
1618
|
-
scanText(node, vmodels) //扫描文本节点
|
1619
|
-
} else if (kernel.commentInterpolate && nodeType === 8 && !rexpr.test(node.nodeValue)) {
|
1620
|
-
scanText(node, vmodels) //扫描注释节点
|
1621
|
-
}
|
1622
|
-
}
|
1623
1578
|
function scanAttr(elem, vmodels) {
|
1624
1579
|
//防止setAttribute, removeAttribute时 attributes自动被同步,导致for循环出错
|
1625
1580
|
var attributes = elem.hasAttributes() ? avalon.slice(elem.attributes) : []
|
@@ -1688,8 +1643,8 @@ function scanAttr(elem, vmodels) {
|
|
1688
1643
|
}
|
1689
1644
|
bindings.sort(bindingSorter)
|
1690
1645
|
var scanNode = true
|
1691
|
-
for (
|
1692
|
-
|
1646
|
+
for (i = 0; binding = bindings[i]; i++) {
|
1647
|
+
type = binding.type
|
1693
1648
|
if (rnoscanAttrBinding.test(type)) {
|
1694
1649
|
return executeBindings(bindings.slice(0, i + 1), vmodels)
|
1695
1650
|
} else if (scanNode) {
|
@@ -1705,14 +1660,61 @@ function scanAttr(elem, vmodels) {
|
|
1705
1660
|
|
1706
1661
|
var rnoscanAttrBinding = /^if|widget|repeat$/
|
1707
1662
|
var rnoscanNodeBinding = /^each|with|html|include$/
|
1663
|
+
function scanNodeList(parent, vmodels) {
|
1664
|
+
var node = parent.firstChild
|
1665
|
+
while (node) {
|
1666
|
+
var nextNode = node.nextSibling
|
1667
|
+
scanNode(node, node.nodeType, vmodels)
|
1668
|
+
node = nextNode
|
1669
|
+
}
|
1670
|
+
}
|
1671
|
+
|
1672
|
+
function scanNodeArray(nodes, vmodels) {
|
1673
|
+
for (var i = 0, node; node = nodes[i++]; ) {
|
1674
|
+
scanNode(node, node.nodeType, vmodels)
|
1675
|
+
}
|
1676
|
+
}
|
1677
|
+
function scanNode(node, nodeType, vmodels) {
|
1678
|
+
if (nodeType === 1) {
|
1679
|
+
scanTag(node, vmodels) //扫描元素节点
|
1680
|
+
} else if (nodeType === 3 && rexpr.test(node.data)){
|
1681
|
+
scanText(node, vmodels) //扫描文本节点
|
1682
|
+
} else if (kernel.commentInterpolate && nodeType === 8 && !rexpr.test(node.nodeValue)) {
|
1683
|
+
scanText(node, vmodels) //扫描注释节点
|
1684
|
+
}
|
1685
|
+
}
|
1686
|
+
function scanTag(elem, vmodels, node) {
|
1687
|
+
//扫描顺序 ms-skip(0) --> ms-important(1) --> ms-controller(2) --> ms-if(10) --> ms-repeat(100)
|
1688
|
+
//--> ms-if-loop(110) --> ms-attr(970) ...--> ms-each(1400)-->ms-with(1500)--〉ms-duplex(2000)垫后
|
1689
|
+
var a = elem.getAttribute("ms-skip")
|
1690
|
+
var b = elem.getAttributeNode("ms-important")
|
1691
|
+
var c = elem.getAttributeNode("ms-controller")
|
1692
|
+
if (typeof a === "string") {
|
1693
|
+
return
|
1694
|
+
} else if (node = b || c) {
|
1695
|
+
var newVmodel = avalon.vmodels[node.value]
|
1696
|
+
if (!newVmodel) {
|
1697
|
+
return
|
1698
|
+
}
|
1699
|
+
//ms-important不包含父VM,ms-controller相反
|
1700
|
+
vmodels = node === b ? [newVmodel] : [newVmodel].concat(vmodels)
|
1701
|
+
elem.removeAttribute(node.name) //removeAttributeNode不会刷新[ms-controller]样式规则
|
1702
|
+
elem.classList.remove(node.name)
|
1703
|
+
createSignalTower(elem, newVmodel)
|
1704
|
+
}
|
1705
|
+
scanAttr(elem, vmodels) //扫描特性节点
|
1706
|
+
}
|
1708
1707
|
var rhasHtml = /\|\s*html\s*/,
|
1709
1708
|
r11a = /\|\|/g,
|
1710
1709
|
rlt = /</g,
|
1711
1710
|
rgt = />/g
|
1712
|
-
|
1711
|
+
rstringLiteral = /(['"])(\\\1|.)+?\1/g
|
1713
1712
|
function getToken(value) {
|
1714
1713
|
if (value.indexOf("|") > 0) {
|
1715
|
-
var
|
1714
|
+
var scapegoat = value.replace( rstringLiteral, function(_){
|
1715
|
+
return Math.pow(10,_.length)
|
1716
|
+
})
|
1717
|
+
var index = scapegoat.replace(r11a, "\u1122\u3344").indexOf("|") //干掉所有短路或
|
1716
1718
|
if (index > -1) {
|
1717
1719
|
return {
|
1718
1720
|
filters: value.slice(index),
|
@@ -1776,7 +1778,7 @@ function scanText(textNode, vmodels) {
|
|
1776
1778
|
tokens = scanExpr(textNode.data)
|
1777
1779
|
}
|
1778
1780
|
if (tokens.length) {
|
1779
|
-
for (var i = 0
|
1781
|
+
for (var i = 0; token = tokens[i++]; ) {
|
1780
1782
|
var node = DOC.createTextNode(token.value) //将文本转换为文本节点,并替换原来的文本节点
|
1781
1783
|
if (token.expr) {
|
1782
1784
|
token.type = "text"
|
@@ -2226,14 +2228,14 @@ var keywords =
|
|
2226
2228
|
// 关键字
|
2227
2229
|
"break,case,catch,continue,debugger,default,delete,do,else,false" +
|
2228
2230
|
",finally,for,function,if,in,instanceof,new,null,return,switch,this" +
|
2229
|
-
",throw,true,try,typeof,var,void,while,with"
|
2231
|
+
",throw,true,try,typeof,var,void,while,with" +
|
2230
2232
|
// 保留字
|
2231
|
-
|
2233
|
+
",abstract,boolean,byte,char,class,const,double,enum,export,extends" +
|
2232
2234
|
",final,float,goto,implements,import,int,interface,long,native" +
|
2233
2235
|
",package,private,protected,public,short,static,super,synchronized" +
|
2234
|
-
",throws,transient,volatile"
|
2236
|
+
",throws,transient,volatile" +
|
2235
2237
|
// ECMA 5 - use strict
|
2236
|
-
|
2238
|
+
",arguments,let,yield" + ",undefined"
|
2237
2239
|
var rrexpstr = /\/\*[\w\W]*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|"(?:[^"\\]|\\[\w\W])*"|'(?:[^'\\]|\\[\w\W])*'|[\s\t\n]*\.[\s\t\n]*[$\w\.]+/g
|
2238
2240
|
var rsplit = /[^\w$]+/g
|
2239
2241
|
var rkeywords = new RegExp(["\\b" + keywords.replace(/,/g, '\\b|\\b') + "\\b"].join('|'), 'g')
|
@@ -2373,7 +2375,7 @@ function parseExpr(code, scopes, data) {
|
|
2373
2375
|
data.evaluator = fn
|
2374
2376
|
return
|
2375
2377
|
}
|
2376
|
-
|
2378
|
+
prefix = assigns.join(", ")
|
2377
2379
|
if (prefix) {
|
2378
2380
|
prefix = "var " + prefix
|
2379
2381
|
}
|
@@ -2441,12 +2443,6 @@ function parseExprProxy(code, scopes, data, tokens, noregister) {
|
|
2441
2443
|
}
|
2442
2444
|
}
|
2443
2445
|
avalon.parseExprProxy = parseExprProxy
|
2444
|
-
/*********************************************************************
|
2445
|
-
* 各种指令 *
|
2446
|
-
**********************************************************************/
|
2447
|
-
//ms-skip绑定已经在scanTag 方法中实现
|
2448
|
-
//ms-controller绑定已经在scanTag 方法中实现
|
2449
|
-
//ms-important绑定已经在scanTag 方法中实现
|
2450
2446
|
var bools = "autofocus,autoplay,async,allowTransparency,checked,controls,declare,disabled,defer,defaultChecked,defaultSelected" +
|
2451
2447
|
"contentEditable,isMap,loop,multiple,noHref,noResize,noShade,open,readOnly,selected"
|
2452
2448
|
var boolMap = {}
|
@@ -2544,7 +2540,7 @@ bindingExecutors.attr = function(val, elem, data) {
|
|
2544
2540
|
var loaded = data.includeLoaded
|
2545
2541
|
var replace = data.includeReplaced
|
2546
2542
|
var target = replace ? elem.parentNode : elem
|
2547
|
-
|
2543
|
+
var scanTemplate = function(text) {
|
2548
2544
|
if (loaded) {
|
2549
2545
|
text = loaded.apply(target, [text].concat(vmodels))
|
2550
2546
|
}
|
@@ -2594,7 +2590,7 @@ bindingExecutors.attr = function(val, elem, data) {
|
|
2594
2590
|
var el = val && val.nodeType === 1 ? val : DOC.getElementById(val)
|
2595
2591
|
if (el) {
|
2596
2592
|
if (el.tagName === "NOSCRIPT" && !(el.innerHTML || el.fixIE78)) { //IE7-8 innerText,innerHTML都无法取得其内容,IE6能取得其innerHTML
|
2597
|
-
|
2593
|
+
xhr = getXHR() //IE9-11与chrome的innerHTML会得到转义的内容,它们的innerText可以
|
2598
2594
|
xhr.open("GET", location, false) //谢谢Nodejs 乱炖群 深圳-纯属虚构
|
2599
2595
|
xhr.send(null)
|
2600
2596
|
//http://bbs.csdn.net/topics/390349046?page=1#post-393492653
|
@@ -2632,8 +2628,6 @@ bindingExecutors.attr = function(val, elem, data) {
|
|
2632
2628
|
"title,alt,src,value,css,include,href".replace(rword, function(name) {
|
2633
2629
|
bindingHandlers[name] = bindingHandlers.attr
|
2634
2630
|
})
|
2635
|
-
//ms-include绑定已由ms-attr绑定实现
|
2636
|
-
|
2637
2631
|
//根据VM的属性值或表达式的值切换类名,ms-class="xxx yyy zzz:flag"
|
2638
2632
|
//http://www.cnblogs.com/rubylouvre/archive/2012/12/17/2818540.html
|
2639
2633
|
bindingHandlers["class"] = function(data, vmodels) {
|
@@ -2724,6 +2718,10 @@ bindingExecutors ["class"] = function(val, elem, data) {
|
|
2724
2718
|
"hover,active".replace(rword, function(method) {
|
2725
2719
|
bindingHandlers[method] = bindingHandlers["class"]
|
2726
2720
|
})
|
2721
|
+
//ms-controller绑定已经在scanTag 方法中实现
|
2722
|
+
//ms-css绑定已由ms-attr绑定实现
|
2723
|
+
|
2724
|
+
|
2727
2725
|
// bindingHandlers.data 定义在if.js
|
2728
2726
|
bindingExecutors.data = function(val, elem, data) {
|
2729
2727
|
var key = "data-" + data.param
|
@@ -2734,357 +2732,107 @@ bindingExecutors.data = function(val, elem, data) {
|
|
2734
2732
|
}
|
2735
2733
|
}
|
2736
2734
|
|
2737
|
-
|
2738
|
-
|
2739
|
-
|
2740
|
-
|
2741
|
-
|
2742
|
-
elem.data = val
|
2743
|
-
} catch (e) {
|
2744
|
-
}
|
2745
|
-
} else { //绑定在特性节点上
|
2746
|
-
elem.textContent = val
|
2747
|
-
}
|
2748
|
-
}
|
2735
|
+
//双工绑定
|
2736
|
+
var duplexBinding = bindingHandlers.duplex = function(data, vmodels) {
|
2737
|
+
var elem = data.element,
|
2738
|
+
hasCast
|
2739
|
+
parseExprProxy(data.value, vmodels, data, 0, 1)
|
2749
2740
|
|
2750
|
-
|
2751
|
-
|
2752
|
-
|
2753
|
-
|
2754
|
-
|
2755
|
-
|
2756
|
-
return
|
2757
|
-
if (val.nodeType === 11) { //将val转换为文档碎片
|
2758
|
-
var fragment = val
|
2759
|
-
} else if (val.nodeType === 1 || val.item) {
|
2760
|
-
var nodes = val.nodeType === 1 ? val.childNodes : val.item ? val : []
|
2761
|
-
fragment = hyperspace.cloneNode(true)
|
2762
|
-
while (nodes[0]) {
|
2763
|
-
fragment.appendChild(nodes[0])
|
2741
|
+
data.changed = getBindingCallback(elem, "data-duplex-changed", vmodels) || noop
|
2742
|
+
if (data.evaluator && data.args) {
|
2743
|
+
var params = []
|
2744
|
+
var casting = oneObject("string,number,boolean,checked")
|
2745
|
+
if (elem.type === "radio" && data.param === "") {
|
2746
|
+
data.param = "checked"
|
2764
2747
|
}
|
2765
|
-
|
2766
|
-
|
2767
|
-
|
2768
|
-
|
2769
|
-
|
2770
|
-
|
2771
|
-
|
2772
|
-
|
2773
|
-
|
2774
|
-
|
2775
|
-
if (
|
2776
|
-
|
2777
|
-
|
2748
|
+
if (elem.msData) {
|
2749
|
+
elem.msData["ms-duplex"] = data.value
|
2750
|
+
}
|
2751
|
+
data.param.replace(/\w+/g, function(name) {
|
2752
|
+
if (/^(checkbox|radio)$/.test(elem.type) && /^(radio|checked)$/.test(name)) {
|
2753
|
+
if (name === "radio")
|
2754
|
+
log("ms-duplex-radio已经更名为ms-duplex-checked")
|
2755
|
+
name = "checked"
|
2756
|
+
data.isChecked = true
|
2757
|
+
}
|
2758
|
+
if (name === "bool") {
|
2759
|
+
name = "boolean"
|
2760
|
+
log("ms-duplex-bool已经更名为ms-duplex-boolean")
|
2761
|
+
} else if (name === "text") {
|
2762
|
+
name = "string"
|
2763
|
+
log("ms-duplex-text已经更名为ms-duplex-string")
|
2778
2764
|
}
|
2765
|
+
if (casting[name]) {
|
2766
|
+
hasCast = true
|
2767
|
+
}
|
2768
|
+
avalon.Array.ensure(params, name)
|
2769
|
+
})
|
2770
|
+
if (!hasCast) {
|
2771
|
+
params.push("string")
|
2779
2772
|
}
|
2780
|
-
|
2781
|
-
data.
|
2782
|
-
|
2783
|
-
|
2784
|
-
|
2785
|
-
|
2786
|
-
|
2773
|
+
data.param = params.join("-")
|
2774
|
+
data.bound = function(type, callback) {
|
2775
|
+
if (elem.addEventListener) {
|
2776
|
+
elem.addEventListener(type, callback, false)
|
2777
|
+
} else {
|
2778
|
+
elem.attachEvent("on" + type, callback)
|
2779
|
+
}
|
2780
|
+
var old = data.rollback
|
2781
|
+
data.rollback = function() {
|
2782
|
+
elem.avalonSetter = null
|
2783
|
+
avalon.unbind(elem, type, callback)
|
2784
|
+
old && old()
|
2785
|
+
}
|
2786
|
+
}
|
2787
|
+
for (var i in avalon.vmodels) {
|
2788
|
+
var v = avalon.vmodels[i]
|
2789
|
+
v.$fire("avalon-ms-duplex-init", data)
|
2790
|
+
}
|
2791
|
+
var cpipe = data.pipe || (data.pipe = pipe)
|
2792
|
+
cpipe(null, data, "init")
|
2793
|
+
var tagName = elem.tagName
|
2794
|
+
duplexBinding[tagName] && duplexBinding[tagName](elem, data.evaluator.apply(null, data.args), data)
|
2787
2795
|
}
|
2788
|
-
|
2789
|
-
|
2790
|
-
|
2791
|
-
|
2792
|
-
|
2793
|
-
|
2796
|
+
}
|
2797
|
+
//不存在 bindingExecutors.duplex
|
2798
|
+
function fixNull(val) {
|
2799
|
+
return val == null ? "" : val
|
2800
|
+
}
|
2801
|
+
avalon.duplexHooks = {
|
2802
|
+
checked: {
|
2803
|
+
get: function(val, data) {
|
2804
|
+
return !data.element.oldValue
|
2794
2805
|
}
|
2806
|
+
},
|
2807
|
+
string: {
|
2808
|
+
get: function(val) { //同步到VM
|
2809
|
+
return val
|
2810
|
+
},
|
2811
|
+
set: fixNull
|
2812
|
+
},
|
2813
|
+
"boolean": {
|
2814
|
+
get: function(val) {
|
2815
|
+
return val === "true"
|
2816
|
+
},
|
2817
|
+
set: fixNull
|
2818
|
+
},
|
2819
|
+
number: {
|
2820
|
+
get: function(val) {
|
2821
|
+
return isFinite(val) ? parseFloat(val) || 0 : val
|
2822
|
+
},
|
2823
|
+
set: fixNull
|
2795
2824
|
}
|
2796
|
-
scanNodeArray(nodes, data.vmodels)
|
2797
2825
|
}
|
2798
2826
|
|
2799
|
-
|
2800
|
-
|
2801
|
-
|
2802
|
-
|
2803
|
-
|
2804
|
-
parseExprProxy(data.value, vmodels, data)
|
2827
|
+
function pipe(val, data, action, e) {
|
2828
|
+
data.param.replace(/\w+/g, function(name) {
|
2829
|
+
var hook = avalon.duplexHooks[name]
|
2830
|
+
if (hook && typeof hook[action] === "function") {
|
2831
|
+
val = hook[action](val, data)
|
2805
2832
|
}
|
2806
|
-
|
2807
|
-
|
2808
|
-
|
2809
|
-
if (elem.nodeType === 8) {
|
2810
|
-
elem.parentNode.replaceChild(data.template, elem)
|
2811
|
-
elem = data.element = data.template //这时可能为null
|
2812
|
-
}
|
2813
|
-
if (elem.getAttribute(data.name)) {
|
2814
|
-
elem.removeAttribute(data.name)
|
2815
|
-
scanAttr(elem, data.vmodels)
|
2816
|
-
}
|
2817
|
-
data.rollback = null
|
2818
|
-
} else { //移出DOM树,并用注释节点占据原位置
|
2819
|
-
if (elem.nodeType === 1) {
|
2820
|
-
var node = data.element = DOC.createComment("ms-if")
|
2821
|
-
elem.parentNode.replaceChild(node, elem)
|
2822
|
-
data.template = elem //元素节点
|
2823
|
-
ifGroup.appendChild(elem)
|
2824
|
-
data.rollback = function() {
|
2825
|
-
if (elem.parentNode === ifGroup) {
|
2826
|
-
ifGroup.removeChild(elem)
|
2827
|
-
}
|
2828
|
-
}
|
2829
|
-
}
|
2830
|
-
}
|
2831
|
-
}
|
2832
|
-
|
2833
|
-
|
2834
|
-
function parseDisplay(nodeName, val) {
|
2835
|
-
//用于取得此类标签的默认display值
|
2836
|
-
var key = "_" + nodeName
|
2837
|
-
if (!parseDisplay[key]) {
|
2838
|
-
var node = DOC.createElement(nodeName)
|
2839
|
-
root.appendChild(node)
|
2840
|
-
if (W3C) {
|
2841
|
-
val = getComputedStyle(node, null).display
|
2842
|
-
} else {
|
2843
|
-
val = node.currentStyle.display
|
2844
|
-
}
|
2845
|
-
root.removeChild(node)
|
2846
|
-
parseDisplay[key] = val
|
2847
|
-
}
|
2848
|
-
return parseDisplay[key]
|
2849
|
-
}
|
2850
|
-
|
2851
|
-
avalon.parseDisplay = parseDisplay
|
2852
|
-
|
2853
|
-
bindingHandlers.visible = function(data, vmodels) {
|
2854
|
-
var elem = avalon(data.element)
|
2855
|
-
var display = elem.css("display")
|
2856
|
-
if (display === "none") {
|
2857
|
-
var style = elem[0].style
|
2858
|
-
var has = /visibility/i.test(style.cssText)
|
2859
|
-
var visible = elem.css("visibility")
|
2860
|
-
style.display = ""
|
2861
|
-
style.visibility = "hidden"
|
2862
|
-
display = elem.css("display")
|
2863
|
-
if (display === "none") {
|
2864
|
-
display = parseDisplay(elem[0].nodeName)
|
2865
|
-
}
|
2866
|
-
style.visibility = has ? visible : ""
|
2867
|
-
}
|
2868
|
-
data.display = display
|
2869
|
-
parseExprProxy(data.value, vmodels, data)
|
2870
|
-
}
|
2871
|
-
|
2872
|
-
bindingExecutors.visible = function(val, elem, data) {
|
2873
|
-
elem.style.display = val ? data.display : "none"
|
2874
|
-
}
|
2875
|
-
|
2876
|
-
var rdash = /\(([^)]*)\)/
|
2877
|
-
bindingHandlers.on = function(data, vmodels) {
|
2878
|
-
var value = data.value
|
2879
|
-
data.type = "on"
|
2880
|
-
var eventType = data.param.replace(/-\d+$/, "") // ms-on-mousemove-10
|
2881
|
-
if (typeof bindingHandlers.on[eventType + "Hook"] === "function") {
|
2882
|
-
bindingHandlers.on[eventType + "Hook"](data)
|
2883
|
-
}
|
2884
|
-
if (value.indexOf("(") > 0 && value.indexOf(")") > -1) {
|
2885
|
-
var matched = (value.match(rdash) || ["", ""])[1].trim()
|
2886
|
-
if (matched === "" || matched === "$event") { // aaa() aaa($event)当成aaa处理
|
2887
|
-
value = value.replace(rdash, "")
|
2888
|
-
}
|
2889
|
-
}
|
2890
|
-
parseExprProxy(value, vmodels, data)
|
2891
|
-
}
|
2892
|
-
|
2893
|
-
bindingExecutors.on = function(callback, elem, data) {
|
2894
|
-
callback = function(e) {
|
2895
|
-
var fn = data.evaluator || noop
|
2896
|
-
return fn.apply(this, data.args.concat(e))
|
2897
|
-
}
|
2898
|
-
var eventType = data.param.replace(/-\d+$/, "") // ms-on-mousemove-10
|
2899
|
-
if (eventType === "scan") {
|
2900
|
-
callback.call(elem, {
|
2901
|
-
type: eventType
|
2902
|
-
})
|
2903
|
-
} else if (typeof data.specialBind === "function") {
|
2904
|
-
data.specialBind(elem, callback)
|
2905
|
-
} else {
|
2906
|
-
var removeFn = avalon.bind(elem, eventType, callback)
|
2907
|
-
}
|
2908
|
-
data.rollback = function() {
|
2909
|
-
if (typeof data.specialUnbind === "function") {
|
2910
|
-
data.specialUnbind()
|
2911
|
-
} else {
|
2912
|
-
avalon.unbind(elem, eventType, removeFn)
|
2913
|
-
}
|
2914
|
-
}
|
2915
|
-
}
|
2916
|
-
|
2917
|
-
|
2918
|
-
bindingHandlers.widget = function(data, vmodels) {
|
2919
|
-
var args = data.value.match(rword)
|
2920
|
-
var elem = data.element
|
2921
|
-
var widget = args[0]
|
2922
|
-
var id = args[1]
|
2923
|
-
if (!id || id === "$") {//没有定义或为$时,取组件名+随机数
|
2924
|
-
id = generateID(widget)
|
2925
|
-
}
|
2926
|
-
var optName = args[2] || widget//没有定义,取组件名
|
2927
|
-
var constructor = avalon.ui[widget]
|
2928
|
-
if (typeof constructor === "function") { //ms-widget="tabs,tabsAAA,optname"
|
2929
|
-
vmodels = elem.vmodels || vmodels
|
2930
|
-
for (var i = 0, v; v = vmodels[i++]; ) {
|
2931
|
-
if (v.hasOwnProperty(optName) && typeof v[optName] === "object") {
|
2932
|
-
var vmOptions = v[optName]
|
2933
|
-
vmOptions = vmOptions.$model || vmOptions
|
2934
|
-
break
|
2935
|
-
}
|
2936
|
-
}
|
2937
|
-
if (vmOptions) {
|
2938
|
-
var wid = vmOptions[widget + "Id"]
|
2939
|
-
if (typeof wid === "string") {
|
2940
|
-
id = wid
|
2941
|
-
}
|
2942
|
-
}
|
2943
|
-
//抽取data-tooltip-text、data-tooltip-attr属性,组成一个配置对象
|
2944
|
-
var widgetData = avalon.getWidgetData(elem, widget)
|
2945
|
-
data.value = [widget, id, optName].join(",")
|
2946
|
-
data[widget + "Id"] = id
|
2947
|
-
data.evaluator = noop
|
2948
|
-
elem.msData["ms-widget-id"] = id
|
2949
|
-
var options = data[widget + "Options"] = avalon.mix({}, constructor.defaults, vmOptions || {}, widgetData)
|
2950
|
-
elem.removeAttribute("ms-widget")
|
2951
|
-
var vmodel = constructor(elem, data, vmodels) || {} //防止组件不返回VM
|
2952
|
-
if (vmodel.$id) {
|
2953
|
-
avalon.vmodels[id] = vmodel
|
2954
|
-
createSignalTower(elem, vmodel)
|
2955
|
-
if (vmodel.hasOwnProperty("$init")) {
|
2956
|
-
vmodel.$init(function() {
|
2957
|
-
avalon.scan(elem, [vmodel].concat(vmodels))
|
2958
|
-
if (typeof options.onInit === "function") {
|
2959
|
-
options.onInit.call(elem, vmodel, options, vmodels)
|
2960
|
-
}
|
2961
|
-
})
|
2962
|
-
}
|
2963
|
-
data.rollback = function() {
|
2964
|
-
try {
|
2965
|
-
vmodel.widgetElement = null
|
2966
|
-
vmodel.$remove()
|
2967
|
-
} catch (e) {
|
2968
|
-
}
|
2969
|
-
elem.msData = {}
|
2970
|
-
delete avalon.vmodels[vmodel.$id]
|
2971
|
-
}
|
2972
|
-
addSubscribers(data, widgetList)
|
2973
|
-
if (window.chrome) {
|
2974
|
-
elem.addEventListener("DOMNodeRemovedFromDocument", function() {
|
2975
|
-
setTimeout(removeSubscribers)
|
2976
|
-
})
|
2977
|
-
}
|
2978
|
-
} else {
|
2979
|
-
avalon.scan(elem, vmodels)
|
2980
|
-
}
|
2981
|
-
} else if (vmodels.length) { //如果该组件还没有加载,那么保存当前的vmodels
|
2982
|
-
elem.vmodels = vmodels
|
2983
|
-
}
|
2984
|
-
}
|
2985
|
-
var widgetList = []
|
2986
|
-
//不存在 bindingExecutors.widget
|
2987
|
-
//双工绑定
|
2988
|
-
var duplexBinding = bindingHandlers.duplex = function(data, vmodels) {
|
2989
|
-
var elem = data.element,
|
2990
|
-
hasCast
|
2991
|
-
parseExprProxy(data.value, vmodels, data, 0, 1)
|
2992
|
-
|
2993
|
-
data.changed = getBindingCallback(elem, "data-duplex-changed", vmodels) || noop
|
2994
|
-
if (data.evaluator && data.args) {
|
2995
|
-
var params = []
|
2996
|
-
var casting = oneObject("string,number,boolean,checked")
|
2997
|
-
if (elem.type === "radio" && data.param === "") {
|
2998
|
-
data.param = "checked"
|
2999
|
-
}
|
3000
|
-
if (elem.msData) {
|
3001
|
-
elem.msData["ms-duplex"] = data.value
|
3002
|
-
}
|
3003
|
-
data.param.replace(/\w+/g, function(name) {
|
3004
|
-
if (/^(checkbox|radio)$/.test(elem.type) && /^(radio|checked)$/.test(name)) {
|
3005
|
-
if (name === "radio")
|
3006
|
-
log("ms-duplex-radio已经更名为ms-duplex-checked")
|
3007
|
-
name = "checked"
|
3008
|
-
data.isChecked = true
|
3009
|
-
}
|
3010
|
-
if (name === "bool") {
|
3011
|
-
name = "boolean"
|
3012
|
-
log("ms-duplex-bool已经更名为ms-duplex-boolean")
|
3013
|
-
} else if (name === "text") {
|
3014
|
-
name = "string"
|
3015
|
-
log("ms-duplex-text已经更名为ms-duplex-string")
|
3016
|
-
}
|
3017
|
-
if (casting[name]) {
|
3018
|
-
hasCast = true
|
3019
|
-
}
|
3020
|
-
avalon.Array.ensure(params, name)
|
3021
|
-
})
|
3022
|
-
if (!hasCast) {
|
3023
|
-
params.push("string")
|
3024
|
-
}
|
3025
|
-
data.param = params.join("-")
|
3026
|
-
data.bound = function(type, callback) {
|
3027
|
-
if (elem.addEventListener) {
|
3028
|
-
elem.addEventListener(type, callback, false)
|
3029
|
-
} else {
|
3030
|
-
elem.attachEvent("on" + type, callback)
|
3031
|
-
}
|
3032
|
-
var old = data.rollback
|
3033
|
-
data.rollback = function() {
|
3034
|
-
elem.avalonSetter = null
|
3035
|
-
avalon.unbind(elem, type, callback)
|
3036
|
-
old && old()
|
3037
|
-
}
|
3038
|
-
}
|
3039
|
-
for (var i in avalon.vmodels) {
|
3040
|
-
var v = avalon.vmodels[i]
|
3041
|
-
v.$fire("avalon-ms-duplex-init", data)
|
3042
|
-
}
|
3043
|
-
var cpipe = data.pipe || (data.pipe = pipe)
|
3044
|
-
cpipe(null, data, "init")
|
3045
|
-
var tagName = elem.tagName
|
3046
|
-
duplexBinding[tagName] && duplexBinding[tagName](elem, data.evaluator.apply(null, data.args), data)
|
3047
|
-
}
|
3048
|
-
}
|
3049
|
-
//不存在 bindingExecutors.duplex
|
3050
|
-
function fixNull(val) {
|
3051
|
-
return val == null ? "" : val
|
3052
|
-
}
|
3053
|
-
avalon.duplexHooks = {
|
3054
|
-
checked: {
|
3055
|
-
get: function(val, data) {
|
3056
|
-
return !data.element.oldValue
|
3057
|
-
}
|
3058
|
-
},
|
3059
|
-
string: {
|
3060
|
-
get: function(val) { //同步到VM
|
3061
|
-
return val
|
3062
|
-
},
|
3063
|
-
set: fixNull
|
3064
|
-
},
|
3065
|
-
"boolean": {
|
3066
|
-
get: function(val) {
|
3067
|
-
return val === "true"
|
3068
|
-
},
|
3069
|
-
set: fixNull
|
3070
|
-
},
|
3071
|
-
number: {
|
3072
|
-
get: function(val) {
|
3073
|
-
return isFinite(val) ? parseFloat(val) || 0 : val
|
3074
|
-
},
|
3075
|
-
set: fixNull
|
3076
|
-
}
|
3077
|
-
}
|
3078
|
-
|
3079
|
-
function pipe(val, data, action, e) {
|
3080
|
-
data.param.replace(/\w+/g, function(name) {
|
3081
|
-
var hook = avalon.duplexHooks[name]
|
3082
|
-
if (hook && typeof hook[action] === "function") {
|
3083
|
-
val = hook[action](val, data)
|
3084
|
-
}
|
3085
|
-
})
|
3086
|
-
return val
|
3087
|
-
}
|
2833
|
+
})
|
2834
|
+
return val
|
2835
|
+
}
|
3088
2836
|
|
3089
2837
|
var TimerID, ribbon = []
|
3090
2838
|
function W3CFire(el, name, detail) {
|
@@ -3244,60 +2992,189 @@ duplexBinding.INPUT = function(element, evaluator, data) {
|
|
3244
2992
|
if (element.value !== element.oldValue) {
|
3245
2993
|
updateVModel()
|
3246
2994
|
}
|
3247
|
-
} else if (!element.msRetain) {
|
3248
|
-
return false
|
2995
|
+
} else if (!element.msRetain) {
|
2996
|
+
return false
|
2997
|
+
}
|
2998
|
+
})
|
2999
|
+
}
|
3000
|
+
|
3001
|
+
element.avalonSetter = updateVModel
|
3002
|
+
element.oldValue = element.value
|
3003
|
+
registerSubscriber(data)
|
3004
|
+
callback.call(element, element.value)
|
3005
|
+
}
|
3006
|
+
duplexBinding.TEXTAREA = duplexBinding.INPUT
|
3007
|
+
duplexBinding.SELECT = function(element, evaluator, data) {
|
3008
|
+
var $elem = avalon(element)
|
3009
|
+
function updateVModel() {
|
3010
|
+
if ($elem.data("duplex-observe") !== false) {
|
3011
|
+
var val = $elem.val() //字符串或字符串数组
|
3012
|
+
if (Array.isArray(val)) {
|
3013
|
+
val = val.map(function(v) {
|
3014
|
+
return data.pipe(v, data, "get")
|
3015
|
+
})
|
3016
|
+
} else {
|
3017
|
+
val = data.pipe(val, data, "get")
|
3018
|
+
}
|
3019
|
+
if (val + "" !== element.oldValue) {
|
3020
|
+
evaluator(val)
|
3021
|
+
}
|
3022
|
+
data.changed.call(element, val, data)
|
3023
|
+
}
|
3024
|
+
}
|
3025
|
+
data.handler = function() {
|
3026
|
+
var val = evaluator()
|
3027
|
+
val = val && val.$model || val
|
3028
|
+
if (Array.isArray(val)) {
|
3029
|
+
if (!element.multiple) {
|
3030
|
+
log("ms-duplex在<select multiple=true>上要求对应一个数组")
|
3031
|
+
}
|
3032
|
+
} else {
|
3033
|
+
if (element.multiple) {
|
3034
|
+
log("ms-duplex在<select multiple=false>不能对应一个数组")
|
3035
|
+
}
|
3036
|
+
}
|
3037
|
+
//必须变成字符串后才能比较
|
3038
|
+
val = Array.isArray(val) ? val.map(String) : val + ""
|
3039
|
+
if (val + "" !== element.oldValue) {
|
3040
|
+
$elem.val(val)
|
3041
|
+
element.oldValue = val + ""
|
3042
|
+
}
|
3043
|
+
}
|
3044
|
+
data.bound("change", updateVModel)
|
3045
|
+
checkScan(element, function() {
|
3046
|
+
registerSubscriber(data)
|
3047
|
+
data.changed.call(element, evaluator(), data)
|
3048
|
+
}, NaN)
|
3049
|
+
}
|
3050
|
+
|
3051
|
+
|
3052
|
+
// bindingHandlers.html 定义在if.js
|
3053
|
+
bindingExecutors.html = function(val, elem, data) {
|
3054
|
+
val = val == null ? "" : val
|
3055
|
+
var isHtmlFilter = "group" in data
|
3056
|
+
var parent = isHtmlFilter ? elem.parentNode : elem
|
3057
|
+
if (!parent)
|
3058
|
+
return
|
3059
|
+
if (val.nodeType === 11) { //将val转换为文档碎片
|
3060
|
+
var fragment = val
|
3061
|
+
} else if (val.nodeType === 1 || val.item) {
|
3062
|
+
var nodes = val.nodeType === 1 ? val.childNodes : val.item ? val : []
|
3063
|
+
fragment = hyperspace.cloneNode(true)
|
3064
|
+
while (nodes[0]) {
|
3065
|
+
fragment.appendChild(nodes[0])
|
3066
|
+
}
|
3067
|
+
} else {
|
3068
|
+
fragment = avalon.parseHTML(val)
|
3069
|
+
}
|
3070
|
+
//插入占位符, 如果是过滤器,需要有节制地移除指定的数量,如果是html指令,直接清空
|
3071
|
+
var comment = DOC.createComment("ms-html")
|
3072
|
+
if (isHtmlFilter) {
|
3073
|
+
parent.insertBefore(comment, elem)
|
3074
|
+
var n = data.group, i = 1
|
3075
|
+
while (i < n) {
|
3076
|
+
var node = elem.nextSibling
|
3077
|
+
if (node) {
|
3078
|
+
parent.removeChild(node)
|
3079
|
+
i++
|
3080
|
+
}
|
3081
|
+
}
|
3082
|
+
parent.removeChild(elem)
|
3083
|
+
data.element = comment //防止被CG
|
3084
|
+
} else {
|
3085
|
+
avalon.clearHTML(parent).appendChild(comment)
|
3086
|
+
}
|
3087
|
+
if (isHtmlFilter) {
|
3088
|
+
data.group = fragment.childNodes.length || 1
|
3089
|
+
}
|
3090
|
+
nodes = avalon.slice(fragment.childNodes)
|
3091
|
+
if (nodes[0]) {
|
3092
|
+
if (comment.parentNode)
|
3093
|
+
comment.parentNode.replaceChild(fragment, comment)
|
3094
|
+
if (isHtmlFilter) {
|
3095
|
+
data.element = nodes[0]
|
3096
|
+
}
|
3097
|
+
}
|
3098
|
+
scanNodeArray(nodes, data.vmodels)
|
3099
|
+
}
|
3100
|
+
|
3101
|
+
bindingHandlers["if"] =
|
3102
|
+
bindingHandlers.data =
|
3103
|
+
bindingHandlers.text =
|
3104
|
+
bindingHandlers.html =
|
3105
|
+
function(data, vmodels) {
|
3106
|
+
parseExprProxy(data.value, vmodels, data)
|
3107
|
+
}
|
3108
|
+
|
3109
|
+
bindingExecutors["if"] = function(val, elem, data) {
|
3110
|
+
if (val) { //插回DOM树
|
3111
|
+
if (elem.nodeType === 8) {
|
3112
|
+
elem.parentNode.replaceChild(data.template, elem)
|
3113
|
+
elem = data.element = data.template //这时可能为null
|
3114
|
+
}
|
3115
|
+
if (elem.getAttribute(data.name)) {
|
3116
|
+
elem.removeAttribute(data.name)
|
3117
|
+
scanAttr(elem, data.vmodels)
|
3118
|
+
}
|
3119
|
+
data.rollback = null
|
3120
|
+
} else { //移出DOM树,并用注释节点占据原位置
|
3121
|
+
if (elem.nodeType === 1) {
|
3122
|
+
var node = data.element = DOC.createComment("ms-if")
|
3123
|
+
elem.parentNode.replaceChild(node, elem)
|
3124
|
+
data.template = elem //元素节点
|
3125
|
+
ifGroup.appendChild(elem)
|
3126
|
+
data.rollback = function() {
|
3127
|
+
if (elem.parentNode === ifGroup) {
|
3128
|
+
ifGroup.removeChild(elem)
|
3129
|
+
}
|
3249
3130
|
}
|
3250
|
-
}
|
3131
|
+
}
|
3251
3132
|
}
|
3252
|
-
|
3253
|
-
element.avalonSetter = updateVModel
|
3254
|
-
element.oldValue = element.value
|
3255
|
-
registerSubscriber(data)
|
3256
|
-
callback.call(element, element.value)
|
3257
3133
|
}
|
3258
|
-
|
3259
|
-
|
3260
|
-
|
3261
|
-
|
3262
|
-
|
3263
|
-
|
3264
|
-
|
3265
|
-
|
3266
|
-
|
3267
|
-
|
3268
|
-
|
3269
|
-
|
3270
|
-
|
3271
|
-
|
3272
|
-
|
3273
|
-
|
3274
|
-
|
3134
|
+
|
3135
|
+
|
3136
|
+
//ms-important绑定已经在scanTag 方法中实现
|
3137
|
+
//ms-include绑定已由ms-attr绑定实现
|
3138
|
+
|
3139
|
+
var rdash = /\(([^)]*)\)/
|
3140
|
+
bindingHandlers.on = function(data, vmodels) {
|
3141
|
+
var value = data.value
|
3142
|
+
data.type = "on"
|
3143
|
+
var eventType = data.param.replace(/-\d+$/, "") // ms-on-mousemove-10
|
3144
|
+
if (typeof bindingHandlers.on[eventType + "Hook"] === "function") {
|
3145
|
+
bindingHandlers.on[eventType + "Hook"](data)
|
3146
|
+
}
|
3147
|
+
if (value.indexOf("(") > 0 && value.indexOf(")") > -1) {
|
3148
|
+
var matched = (value.match(rdash) || ["", ""])[1].trim()
|
3149
|
+
if (matched === "" || matched === "$event") { // aaa() aaa($event)当成aaa处理
|
3150
|
+
value = value.replace(rdash, "")
|
3275
3151
|
}
|
3276
3152
|
}
|
3277
|
-
|
3278
|
-
|
3279
|
-
|
3280
|
-
|
3281
|
-
|
3282
|
-
|
3283
|
-
|
3153
|
+
parseExprProxy(value, vmodels, data)
|
3154
|
+
}
|
3155
|
+
|
3156
|
+
bindingExecutors.on = function(callback, elem, data) {
|
3157
|
+
callback = function(e) {
|
3158
|
+
var fn = data.evaluator || noop
|
3159
|
+
return fn.apply(this, data.args.concat(e))
|
3160
|
+
}
|
3161
|
+
var eventType = data.param.replace(/-\d+$/, "") // ms-on-mousemove-10
|
3162
|
+
if (eventType === "scan") {
|
3163
|
+
callback.call(elem, {
|
3164
|
+
type: eventType
|
3165
|
+
})
|
3166
|
+
} else if (typeof data.specialBind === "function") {
|
3167
|
+
data.specialBind(elem, callback)
|
3168
|
+
} else {
|
3169
|
+
var removeFn = avalon.bind(elem, eventType, callback)
|
3170
|
+
}
|
3171
|
+
data.rollback = function() {
|
3172
|
+
if (typeof data.specialUnbind === "function") {
|
3173
|
+
data.specialUnbind()
|
3284
3174
|
} else {
|
3285
|
-
|
3286
|
-
log("ms-duplex在<select multiple=false>不能对应一个数组")
|
3287
|
-
}
|
3288
|
-
}
|
3289
|
-
//必须变成字符串后才能比较
|
3290
|
-
val = Array.isArray(val) ? val.map(String) : val + ""
|
3291
|
-
if (val + "" !== element.oldValue) {
|
3292
|
-
$elem.val(val)
|
3293
|
-
element.oldValue = val + ""
|
3175
|
+
avalon.unbind(elem, eventType, removeFn)
|
3294
3176
|
}
|
3295
3177
|
}
|
3296
|
-
data.bound("change", updateVModel)
|
3297
|
-
checkScan(element, function() {
|
3298
|
-
registerSubscriber(data)
|
3299
|
-
data.changed.call(element, evaluator(), data)
|
3300
|
-
}, NaN)
|
3301
3178
|
}
|
3302
3179
|
|
3303
3180
|
|
@@ -3373,9 +3250,9 @@ bindingHandlers.repeat = function(data, vmodels) {
|
|
3373
3250
|
check0 = "$first"
|
3374
3251
|
check1 = "$last"
|
3375
3252
|
}
|
3376
|
-
for (
|
3377
|
-
if (
|
3378
|
-
data.$outer =
|
3253
|
+
for (i = 0; v = vmodels[i++]; ) {
|
3254
|
+
if (v.hasOwnProperty(check0) && v.hasOwnProperty(check1)) {
|
3255
|
+
data.$outer = v
|
3379
3256
|
break
|
3380
3257
|
}
|
3381
3258
|
}
|
@@ -3405,7 +3282,7 @@ bindingExecutors.repeat = function(method, pos, el) {
|
|
3405
3282
|
var n = pos + el
|
3406
3283
|
var array = data.$repeat
|
3407
3284
|
var last = array.length - 1
|
3408
|
-
var fragments = []
|
3285
|
+
var fragments = [], fragment
|
3409
3286
|
var start = locateNode(data, pos)
|
3410
3287
|
for (var i = pos; i < n; i++) {
|
3411
3288
|
var proxy = eachProxyAgent(i, data)
|
@@ -3413,7 +3290,7 @@ bindingExecutors.repeat = function(method, pos, el) {
|
|
3413
3290
|
shimController(data, transation, proxy, fragments)
|
3414
3291
|
}
|
3415
3292
|
parent.insertBefore(transation, start)
|
3416
|
-
for (
|
3293
|
+
for (i = 0; fragment = fragments[i++]; ) {
|
3417
3294
|
scanNodeArray(fragment.nodes, fragment.vmodels)
|
3418
3295
|
fragment.nodes = fragment.vmodels = null
|
3419
3296
|
}
|
@@ -3455,7 +3332,7 @@ bindingExecutors.repeat = function(method, pos, el) {
|
|
3455
3332
|
parent.insertBefore(transation, end)
|
3456
3333
|
break
|
3457
3334
|
case "index": //将proxies中的第pos个起的所有元素重新索引
|
3458
|
-
|
3335
|
+
last = proxies.length - 1
|
3459
3336
|
for (; el = proxies[pos]; pos++) {
|
3460
3337
|
el.$index = pos
|
3461
3338
|
el.$first = pos === 0
|
@@ -3463,7 +3340,7 @@ bindingExecutors.repeat = function(method, pos, el) {
|
|
3463
3340
|
}
|
3464
3341
|
return
|
3465
3342
|
case "set": //将proxies中的第pos个元素的VM设置为el(pos为数字,el任意)
|
3466
|
-
|
3343
|
+
proxy = proxies[pos]
|
3467
3344
|
if (proxy) {
|
3468
3345
|
notifySubscribers(proxy.$events.$index)
|
3469
3346
|
}
|
@@ -3471,7 +3348,7 @@ bindingExecutors.repeat = function(method, pos, el) {
|
|
3471
3348
|
case "append": //将pos的键值对从el中取出(pos为一个普通对象,el为预先生成好的代理VM对象池)
|
3472
3349
|
var pool = el
|
3473
3350
|
var keys = []
|
3474
|
-
|
3351
|
+
fragments = []
|
3475
3352
|
for (var key in pos) { //得到所有键名
|
3476
3353
|
if (pos.hasOwnProperty(key) && key !== "hasOwnProperty") {
|
3477
3354
|
keys.push(key)
|
@@ -3483,7 +3360,7 @@ bindingExecutors.repeat = function(method, pos, el) {
|
|
3483
3360
|
keys = keys2
|
3484
3361
|
}
|
3485
3362
|
}
|
3486
|
-
for (
|
3363
|
+
for (i = 0; key = keys[i++]; ) {
|
3487
3364
|
if (key !== "hasOwnProperty") {
|
3488
3365
|
if (!pool[key]) {
|
3489
3366
|
pool[key] = withProxyAgent(key, data)
|
@@ -3494,7 +3371,7 @@ bindingExecutors.repeat = function(method, pos, el) {
|
|
3494
3371
|
var comment = data.$stamp = data.clone
|
3495
3372
|
parent.insertBefore(comment, end)
|
3496
3373
|
parent.insertBefore(transation, end)
|
3497
|
-
for (
|
3374
|
+
for (i = 0; fragment = fragments[i++]; ) {
|
3498
3375
|
scanNodeArray(fragment.nodes, fragment.vmodels)
|
3499
3376
|
fragment.nodes = fragment.vmodels = null
|
3500
3377
|
}
|
@@ -3623,57 +3500,185 @@ function withProxyFactory() {
|
|
3623
3500
|
set: function(val) {
|
3624
3501
|
this.$host[this.$key] = val
|
3625
3502
|
}
|
3626
|
-
}
|
3627
|
-
}, {
|
3628
|
-
$val: 1
|
3629
|
-
})
|
3630
|
-
proxy.$id = generateID("$proxy$with")
|
3631
|
-
return proxy
|
3632
|
-
}
|
3633
|
-
|
3634
|
-
function withProxyAgent(key, data) {
|
3635
|
-
var proxy = withProxyPool.pop()
|
3636
|
-
if (!proxy) {
|
3637
|
-
proxy = withProxyFactory()
|
3638
|
-
}
|
3639
|
-
var host = data.$repeat
|
3640
|
-
proxy.$key = key
|
3641
|
-
proxy.$host = host
|
3642
|
-
proxy.$outer = data.$outer
|
3643
|
-
if (host.$events) {
|
3644
|
-
proxy.$events.$val = host.$events[key]
|
3645
|
-
} else {
|
3646
|
-
proxy.$events = {}
|
3647
|
-
}
|
3648
|
-
return proxy
|
3649
|
-
}
|
3650
|
-
|
3651
|
-
function recycleProxies(proxies, type) {
|
3652
|
-
var proxyPool = type === "each" ? eachProxyPool : withProxyPool
|
3653
|
-
avalon.each(proxies, function(key, proxy) {
|
3654
|
-
if (proxy.$events) {
|
3655
|
-
for (var i in proxy.$events) {
|
3656
|
-
if (Array.isArray(proxy.$events[i])) {
|
3657
|
-
proxy.$events[i].forEach(function(data) {
|
3658
|
-
if (typeof data === "object")
|
3659
|
-
disposeData(data)
|
3660
|
-
})
|
3661
|
-
proxy.$events[i].length = 0
|
3503
|
+
}
|
3504
|
+
}, {
|
3505
|
+
$val: 1
|
3506
|
+
})
|
3507
|
+
proxy.$id = generateID("$proxy$with")
|
3508
|
+
return proxy
|
3509
|
+
}
|
3510
|
+
|
3511
|
+
function withProxyAgent(key, data) {
|
3512
|
+
var proxy = withProxyPool.pop()
|
3513
|
+
if (!proxy) {
|
3514
|
+
proxy = withProxyFactory()
|
3515
|
+
}
|
3516
|
+
var host = data.$repeat
|
3517
|
+
proxy.$key = key
|
3518
|
+
proxy.$host = host
|
3519
|
+
proxy.$outer = data.$outer
|
3520
|
+
if (host.$events) {
|
3521
|
+
proxy.$events.$val = host.$events[key]
|
3522
|
+
} else {
|
3523
|
+
proxy.$events = {}
|
3524
|
+
}
|
3525
|
+
return proxy
|
3526
|
+
}
|
3527
|
+
|
3528
|
+
function recycleProxies(proxies, type) {
|
3529
|
+
var proxyPool = type === "each" ? eachProxyPool : withProxyPool
|
3530
|
+
avalon.each(proxies, function(key, proxy) {
|
3531
|
+
if (proxy.$events) {
|
3532
|
+
for (var i in proxy.$events) {
|
3533
|
+
if (Array.isArray(proxy.$events[i])) {
|
3534
|
+
proxy.$events[i].forEach(function(data) {
|
3535
|
+
if (typeof data === "object")
|
3536
|
+
disposeData(data)
|
3537
|
+
})
|
3538
|
+
proxy.$events[i].length = 0
|
3539
|
+
}
|
3540
|
+
}
|
3541
|
+
proxy.$host = proxy.$outer = {}
|
3542
|
+
if (proxyPool.unshift(proxy) > kernel.maxRepeatSize) {
|
3543
|
+
proxyPool.pop()
|
3544
|
+
}
|
3545
|
+
}
|
3546
|
+
})
|
3547
|
+
if (type === "each")
|
3548
|
+
proxies.length = 0
|
3549
|
+
}
|
3550
|
+
|
3551
|
+
|
3552
|
+
|
3553
|
+
|
3554
|
+
/*********************************************************************
|
3555
|
+
* 各种指令 *
|
3556
|
+
**********************************************************************/
|
3557
|
+
//ms-skip绑定已经在scanTag 方法中实现
|
3558
|
+
// bindingHandlers.text 定义在if.js
|
3559
|
+
bindingExecutors.text = function(val, elem) {
|
3560
|
+
val = val == null ? "" : val //不在页面上显示undefined null
|
3561
|
+
if (elem.nodeType === 3) { //绑定在文本节点上
|
3562
|
+
try { //IE对游离于DOM树外的节点赋值会报错
|
3563
|
+
elem.data = val
|
3564
|
+
} catch (e) {
|
3565
|
+
}
|
3566
|
+
} else { //绑定在特性节点上
|
3567
|
+
elem.textContent = val
|
3568
|
+
}
|
3569
|
+
}
|
3570
|
+
|
3571
|
+
function parseDisplay(nodeName, val) {
|
3572
|
+
//用于取得此类标签的默认display值
|
3573
|
+
var key = "_" + nodeName
|
3574
|
+
if (!parseDisplay[key]) {
|
3575
|
+
var node = DOC.createElement(nodeName)
|
3576
|
+
root.appendChild(node)
|
3577
|
+
if (W3C) {
|
3578
|
+
val = getComputedStyle(node, null).display
|
3579
|
+
} else {
|
3580
|
+
val = node.currentStyle.display
|
3581
|
+
}
|
3582
|
+
root.removeChild(node)
|
3583
|
+
parseDisplay[key] = val
|
3584
|
+
}
|
3585
|
+
return parseDisplay[key]
|
3586
|
+
}
|
3587
|
+
|
3588
|
+
avalon.parseDisplay = parseDisplay
|
3589
|
+
|
3590
|
+
bindingHandlers.visible = function(data, vmodels) {
|
3591
|
+
var elem = avalon(data.element)
|
3592
|
+
var display = elem.css("display")
|
3593
|
+
if (display === "none") {
|
3594
|
+
var style = elem[0].style
|
3595
|
+
var has = /visibility/i.test(style.cssText)
|
3596
|
+
var visible = elem.css("visibility")
|
3597
|
+
style.display = ""
|
3598
|
+
style.visibility = "hidden"
|
3599
|
+
display = elem.css("display")
|
3600
|
+
if (display === "none") {
|
3601
|
+
display = parseDisplay(elem[0].nodeName)
|
3602
|
+
}
|
3603
|
+
style.visibility = has ? visible : ""
|
3604
|
+
}
|
3605
|
+
data.display = display
|
3606
|
+
parseExprProxy(data.value, vmodels, data)
|
3607
|
+
}
|
3608
|
+
|
3609
|
+
bindingExecutors.visible = function(val, elem, data) {
|
3610
|
+
elem.style.display = val ? data.display : "none"
|
3611
|
+
}
|
3612
|
+
|
3613
|
+
bindingHandlers.widget = function(data, vmodels) {
|
3614
|
+
var args = data.value.match(rword)
|
3615
|
+
var elem = data.element
|
3616
|
+
var widget = args[0]
|
3617
|
+
var id = args[1]
|
3618
|
+
if (!id || id === "$") {//没有定义或为$时,取组件名+随机数
|
3619
|
+
id = generateID(widget)
|
3620
|
+
}
|
3621
|
+
var optName = args[2] || widget//没有定义,取组件名
|
3622
|
+
var constructor = avalon.ui[widget]
|
3623
|
+
if (typeof constructor === "function") { //ms-widget="tabs,tabsAAA,optname"
|
3624
|
+
vmodels = elem.vmodels || vmodels
|
3625
|
+
for (var i = 0, v; v = vmodels[i++]; ) {
|
3626
|
+
if (v.hasOwnProperty(optName) && typeof v[optName] === "object") {
|
3627
|
+
var vmOptions = v[optName]
|
3628
|
+
vmOptions = vmOptions.$model || vmOptions
|
3629
|
+
break
|
3630
|
+
}
|
3631
|
+
}
|
3632
|
+
if (vmOptions) {
|
3633
|
+
var wid = vmOptions[widget + "Id"]
|
3634
|
+
if (typeof wid === "string") {
|
3635
|
+
id = wid
|
3636
|
+
}
|
3637
|
+
}
|
3638
|
+
//抽取data-tooltip-text、data-tooltip-attr属性,组成一个配置对象
|
3639
|
+
var widgetData = avalon.getWidgetData(elem, widget)
|
3640
|
+
data.value = [widget, id, optName].join(",")
|
3641
|
+
data[widget + "Id"] = id
|
3642
|
+
data.evaluator = noop
|
3643
|
+
elem.msData["ms-widget-id"] = id
|
3644
|
+
var options = data[widget + "Options"] = avalon.mix({}, constructor.defaults, vmOptions || {}, widgetData)
|
3645
|
+
elem.removeAttribute("ms-widget")
|
3646
|
+
var vmodel = constructor(elem, data, vmodels) || {} //防止组件不返回VM
|
3647
|
+
if (vmodel.$id) {
|
3648
|
+
avalon.vmodels[id] = vmodel
|
3649
|
+
createSignalTower(elem, vmodel)
|
3650
|
+
if (vmodel.hasOwnProperty("$init")) {
|
3651
|
+
vmodel.$init(function() {
|
3652
|
+
avalon.scan(elem, [vmodel].concat(vmodels))
|
3653
|
+
if (typeof options.onInit === "function") {
|
3654
|
+
options.onInit.call(elem, vmodel, options, vmodels)
|
3655
|
+
}
|
3656
|
+
})
|
3657
|
+
}
|
3658
|
+
data.rollback = function() {
|
3659
|
+
try {
|
3660
|
+
vmodel.widgetElement = null
|
3661
|
+
vmodel.$remove()
|
3662
|
+
} catch (e) {
|
3662
3663
|
}
|
3664
|
+
elem.msData = {}
|
3665
|
+
delete avalon.vmodels[vmodel.$id]
|
3663
3666
|
}
|
3664
|
-
|
3665
|
-
if (
|
3666
|
-
|
3667
|
+
addSubscribers(data, widgetList)
|
3668
|
+
if (window.chrome) {
|
3669
|
+
elem.addEventListener("DOMNodeRemovedFromDocument", function() {
|
3670
|
+
setTimeout(removeSubscribers)
|
3671
|
+
})
|
3667
3672
|
}
|
3673
|
+
} else {
|
3674
|
+
avalon.scan(elem, vmodels)
|
3668
3675
|
}
|
3669
|
-
})
|
3670
|
-
|
3671
|
-
|
3676
|
+
} else if (vmodels.length) { //如果该组件还没有加载,那么保存当前的vmodels
|
3677
|
+
elem.vmodels = vmodels
|
3678
|
+
}
|
3672
3679
|
}
|
3673
|
-
|
3674
|
-
|
3675
|
-
|
3676
|
-
|
3680
|
+
var widgetList = []
|
3681
|
+
//不存在 bindingExecutors.widget
|
3677
3682
|
/*********************************************************************
|
3678
3683
|
* 自带过滤器 *
|
3679
3684
|
**********************************************************************/
|
@@ -3898,6 +3903,7 @@ new function() {
|
|
3898
3903
|
Z: timeZoneGetter
|
3899
3904
|
}
|
3900
3905
|
var rdateFormat = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/
|
3906
|
+
var raspnetjson = /^\/Date\((\d+)\)\/$/
|
3901
3907
|
filters.date = function(date, format) {
|
3902
3908
|
var locate = filters.date.locate,
|
3903
3909
|
text = "",
|
@@ -3908,6 +3914,8 @@ new function() {
|
|
3908
3914
|
if (typeof date === "string") {
|
3909
3915
|
if (/^\d+$/.test(date)) {
|
3910
3916
|
date = toInt(date)
|
3917
|
+
} else if (raspnetjson.test(date)) {
|
3918
|
+
date = +RegExp.$1
|
3911
3919
|
} else {
|
3912
3920
|
var trimDate = date.trim()
|
3913
3921
|
var dateArray = [0, 0, 0, 0, 0, 0, 0]
|
@@ -3915,9 +3923,9 @@ new function() {
|
|
3915
3923
|
//取得年月日
|
3916
3924
|
trimDate = trimDate.replace(/^(\d+)\D(\d+)\D(\d+)/, function(_, a, b, c) {
|
3917
3925
|
var array = c.length === 4 ? [c, a, b] : [a, b, c]
|
3918
|
-
dateArray[0] = toInt(array[0])
|
3926
|
+
dateArray[0] = toInt(array[0]) //年
|
3919
3927
|
dateArray[1] = toInt(array[1]) - 1 //月
|
3920
|
-
dateArray[2] = toInt(array[2])//日
|
3928
|
+
dateArray[2] = toInt(array[2]) //日
|
3921
3929
|
return ""
|
3922
3930
|
})
|
3923
3931
|
var dateSetter = oDate.setFullYear
|
@@ -3926,10 +3934,9 @@ new function() {
|
|
3926
3934
|
dateArray[3] = toInt(a) //小时
|
3927
3935
|
dateArray[4] = toInt(b) //分钟
|
3928
3936
|
dateArray[5] = toInt(c) //秒
|
3929
|
-
if (d) {
|
3930
|
-
dateArray[6] = Math.round(parseFloat("0." + d) * 1000)
|
3937
|
+
if (d) { //毫秒
|
3938
|
+
dateArray[6] = Math.round(parseFloat("0." + d) * 1000)
|
3931
3939
|
}
|
3932
|
-
dateArray[6] = d || ""
|
3933
3940
|
return ""
|
3934
3941
|
})
|
3935
3942
|
var tzHour = 0
|
@@ -4025,45 +4032,164 @@ new function() {
|
|
4025
4032
|
/*********************************************************************
|
4026
4033
|
* AMD加载器 *
|
4027
4034
|
**********************************************************************/
|
4028
|
-
|
4035
|
+
//去掉getFullUrl 精简loadJS text!插件 baseUrl插件
|
4029
4036
|
var modules = avalon.modules = {
|
4030
|
-
"
|
4031
|
-
exports: avalon
|
4037
|
+
"domReady!": {
|
4038
|
+
exports: avalon,
|
4039
|
+
state: 3
|
4032
4040
|
},
|
4033
4041
|
"avalon": {
|
4034
4042
|
exports: avalon,
|
4035
|
-
state:
|
4043
|
+
state: 4
|
4036
4044
|
}
|
4037
4045
|
}
|
4046
|
+
//Object(modules[id]).state拥有如下值
|
4047
|
+
// undefined 没有定义
|
4048
|
+
// 1(send) 已经发出请求
|
4049
|
+
// 2(loading) 已经被执行但还没有执行完成,在这个阶段define方法会被执行
|
4050
|
+
// 3(loaded) 执行完毕,通过onload/onreadystatechange回调判定,在这个阶段checkDeps方法会执行
|
4051
|
+
// 4(execute) 其依赖也执行完毕, 值放到exports对象上,在这个阶段fireFactory方法会执行
|
4038
4052
|
modules.exports = modules.avalon
|
4039
|
-
|
4040
|
-
//http://maxogden.com/nested-dependencies.html
|
4053
|
+
|
4041
4054
|
new function() {
|
4042
4055
|
var loadings = [] //正在加载中的模块列表
|
4043
|
-
var factorys = []
|
4044
|
-
|
4045
|
-
|
4056
|
+
var factorys = [] //放置define方法的factory函数
|
4057
|
+
var rjsext = /\.js$/i
|
4058
|
+
var name2url = {}
|
4059
|
+
function makeRequest(name, config) {
|
4060
|
+
//1. 去掉资源前缀
|
4061
|
+
var res = "js"
|
4062
|
+
name = name.replace(/^(\w+)\!/, function(a, b) {
|
4063
|
+
res = b
|
4064
|
+
return ""
|
4065
|
+
})
|
4066
|
+
if (res === "ready") {
|
4067
|
+
log("debug: ready!已经被废弃,请使用domReady!")
|
4068
|
+
res = "domReady"
|
4069
|
+
}
|
4070
|
+
//2. 去掉querystring, hash
|
4071
|
+
var query = ""
|
4072
|
+
name = name.replace(rquery, function(a) {
|
4073
|
+
query = a
|
4074
|
+
return ""
|
4075
|
+
})
|
4076
|
+
//3. 去掉扩展名
|
4077
|
+
var suffix = "." + res
|
4078
|
+
var ext = /js|css/.test(suffix) ? suffix : ""
|
4079
|
+
name = name.replace(/\.[a-z0-9]+$/g, function(a) {
|
4080
|
+
if (a === suffix) {
|
4081
|
+
ext = a
|
4082
|
+
return ""
|
4083
|
+
} else {
|
4084
|
+
return a
|
4085
|
+
}
|
4086
|
+
})
|
4087
|
+
var req = avalon.mix({
|
4088
|
+
query: query,
|
4089
|
+
ext: ext,
|
4090
|
+
res: res,
|
4091
|
+
name: name,
|
4092
|
+
toUrl: toUrl
|
4093
|
+
}, config)
|
4094
|
+
req.toUrl(name)
|
4095
|
+
return req
|
4096
|
+
}
|
4097
|
+
|
4098
|
+
function fireRequest(req) {
|
4099
|
+
var name = req.name
|
4100
|
+
var res = req.res
|
4101
|
+
//1. 如果该模块已经发出请求,直接返回
|
4102
|
+
var module = modules[name]
|
4103
|
+
var urlNoQuery = name && req.urlNoQuery
|
4104
|
+
|
4105
|
+
if (module && module.state >= 3) {
|
4106
|
+
return name
|
4107
|
+
}
|
4108
|
+
module = modules[urlNoQuery]
|
4109
|
+
if (module && module.state >= 3) {
|
4110
|
+
innerRequire(module.deps || [], module.factory, urlNoQuery)
|
4111
|
+
return urlNoQuery
|
4112
|
+
}
|
4113
|
+
if (name && !module) {
|
4114
|
+
module = modules[urlNoQuery] = {
|
4115
|
+
id: urlNoQuery,
|
4116
|
+
state: 1 //send
|
4117
|
+
}
|
4118
|
+
var wrap = function(obj) {
|
4119
|
+
resources[res] = obj
|
4120
|
+
obj.load(name, req, function(a) {
|
4121
|
+
if (arguments.length && a !== void 0) {
|
4122
|
+
module.exports = a
|
4123
|
+
}
|
4124
|
+
module.state = 4
|
4125
|
+
checkDeps()
|
4126
|
+
})
|
4127
|
+
}
|
4128
|
+
|
4129
|
+
if (!resources[res]) {
|
4130
|
+
innerRequire([res], wrap)
|
4131
|
+
} else {
|
4132
|
+
wrap(resources[res])
|
4133
|
+
}
|
4134
|
+
}
|
4135
|
+
return name ? urlNoQuery : res + "!"
|
4136
|
+
}
|
4137
|
+
|
4138
|
+
|
4139
|
+
//核心API之一 require
|
4140
|
+
|
4141
|
+
var requireQueue = []
|
4142
|
+
var isUserFirstRequire = false
|
4143
|
+
innerRequire = avalon.require = function(array, factory, parentUrl, defineConfig) {
|
4144
|
+
if (!isUserFirstRequire) {
|
4145
|
+
requireQueue.push(avalon.slice(arguments))
|
4146
|
+
if (arguments.length <= 2) {
|
4147
|
+
isUserFirstRequire = true
|
4148
|
+
var queue = requireQueue.splice(0, requireQueue.length), args
|
4149
|
+
while (args = queue.shift()) {
|
4150
|
+
innerRequire.apply(null, args)
|
4151
|
+
}
|
4152
|
+
}
|
4153
|
+
return
|
4154
|
+
}
|
4155
|
+
|
4046
4156
|
if (!Array.isArray(array)) {
|
4047
|
-
avalon.error("require
|
4157
|
+
avalon.error("require方法的第一个参数应为数组 " + array)
|
4048
4158
|
}
|
4049
|
-
var
|
4050
|
-
var
|
4159
|
+
var deps = [] // 放置所有依赖项的完整路径
|
4160
|
+
var uniq = {}
|
4051
4161
|
var id = parentUrl || "callback" + setTimeout("1")
|
4052
|
-
|
4053
|
-
|
4054
|
-
|
4055
|
-
|
4056
|
-
|
4057
|
-
|
4058
|
-
|
4059
|
-
|
4060
|
-
|
4162
|
+
defineConfig = defineConfig || {}
|
4163
|
+
defineConfig.baseUrl = kernel.baseUrl
|
4164
|
+
var isBuilt = !!defineConfig.built
|
4165
|
+
if (parentUrl) {
|
4166
|
+
defineConfig.parentUrl = parentUrl.substr(0, parentUrl.lastIndexOf("/"))
|
4167
|
+
defineConfig.mapUrl = parentUrl.replace(rjsext, "")
|
4168
|
+
}
|
4169
|
+
if (isBuilt) {
|
4170
|
+
var req = makeRequest(defineConfig.name, defineConfig)
|
4171
|
+
id = req.urlNoQuery
|
4172
|
+
} else {
|
4173
|
+
array.forEach(function(name) {
|
4174
|
+
var req = makeRequest(name, defineConfig)
|
4175
|
+
var url = fireRequest(req) //加载资源,并返回该资源的完整地址
|
4176
|
+
if (url) {
|
4177
|
+
if (!uniq[url]) {
|
4178
|
+
deps.push(url)
|
4179
|
+
uniq[url] = "司徒正美" //去重
|
4180
|
+
}
|
4061
4181
|
}
|
4062
|
-
}
|
4063
|
-
}
|
4182
|
+
})
|
4183
|
+
}
|
4184
|
+
|
4064
4185
|
var module = modules[id]
|
4065
|
-
if (!module || module.state !==
|
4066
|
-
modules[id] =
|
4186
|
+
if (!module || module.state !== 4) {
|
4187
|
+
modules[id] = {
|
4188
|
+
id: id,
|
4189
|
+
deps: isBuilt ? array.concat() : deps,
|
4190
|
+
factory: factory || noop,
|
4191
|
+
state: 3
|
4192
|
+
}
|
4067
4193
|
}
|
4068
4194
|
if (!module) {
|
4069
4195
|
//如果此模块是定义在另一个JS文件中, 那必须等该文件加载完毕, 才能放到检测列队中
|
@@ -4071,52 +4197,63 @@ new function() {
|
|
4071
4197
|
}
|
4072
4198
|
checkDeps()
|
4073
4199
|
}
|
4074
|
-
|
4075
|
-
|
4076
|
-
|
4077
|
-
if (typeof
|
4078
|
-
|
4200
|
+
|
4201
|
+
//核心API之二 require
|
4202
|
+
innerRequire.define = function(name, deps, factory) { //模块名,依赖列表,模块本身
|
4203
|
+
if (typeof name !== "string") {
|
4204
|
+
factory = deps
|
4205
|
+
deps = name
|
4206
|
+
name = "anonymous"
|
4079
4207
|
}
|
4080
|
-
if (
|
4081
|
-
|
4208
|
+
if (!Array.isArray(deps)) {
|
4209
|
+
factory = deps
|
4210
|
+
deps = []
|
4082
4211
|
}
|
4083
|
-
|
4084
|
-
|
4085
|
-
|
4086
|
-
var url = modules[id] && modules[id].state >= 1 ? id : trimQuery(getCurrentScript())
|
4087
|
-
factory = args[1]
|
4088
|
-
factory.id = id //用于调试
|
4089
|
-
|
4090
|
-
if (!modules[url] && id) {
|
4091
|
-
//必须先行定义,并且不存在deps,用于checkCycle方法
|
4092
|
-
modules[url] = makeModule(url, 1, factory)
|
4212
|
+
var config = {
|
4213
|
+
built: !isUserFirstRequire, //用r.js打包后,所有define会放到requirejs之前
|
4214
|
+
name: name
|
4093
4215
|
}
|
4094
|
-
|
4216
|
+
var args = [deps, factory, config]
|
4095
4217
|
factory.require = function(url) {
|
4096
|
-
args.
|
4097
|
-
|
4098
|
-
|
4099
|
-
isCycle =
|
4100
|
-
|
4101
|
-
|
4102
|
-
|
4103
|
-
|
4218
|
+
args.splice(2, 0, url)
|
4219
|
+
if (modules[url]) {
|
4220
|
+
modules[url].state = 3 //loaded
|
4221
|
+
var isCycle = false
|
4222
|
+
try {
|
4223
|
+
isCycle = checkCycle(modules[url].deps, url)
|
4224
|
+
} catch (e) {
|
4225
|
+
}
|
4226
|
+
if (isCycle) {
|
4227
|
+
avalon.error(url + "模块与之前的模块存在循环依赖,请不要直接用script标签引入" + url + "模块")
|
4228
|
+
}
|
4104
4229
|
}
|
4105
4230
|
delete factory.require //释放内存
|
4106
4231
|
innerRequire.apply(null, args) //0,1,2 --> 1,2,0
|
4107
4232
|
}
|
4233
|
+
//根据标准,所有遵循W3C标准的浏览器,script标签会按标签的出现顺序执行。
|
4234
|
+
//老的浏览器中,加载也是按顺序的:一个文件下载完成后,才开始下载下一个文件。
|
4235
|
+
//较新的浏览器中(IE8+ 、FireFox3.5+ 、Chrome4+ 、Safari4+),为了减小请求时间以优化体验,
|
4236
|
+
//下载可以是并行的,但是执行顺序还是按照标签出现的顺序。
|
4237
|
+
//但如果script标签是动态插入的, 就未必按照先请求先执行的原则了,目测只有firefox遵守
|
4238
|
+
//唯一比较一致的是,IE10+及其他标准浏览器,一旦开始解析脚本, 就会一直堵在那里,直接脚本解析完毕
|
4239
|
+
//亦即,先进入loading阶段的script标签(模块)必然会先进入loaded阶段
|
4240
|
+
var url = config.built ? "unknown" : getCurrentScript()
|
4108
4241
|
if (url) {
|
4242
|
+
var module = modules[url]
|
4243
|
+
if (module) {
|
4244
|
+
module.state = 2
|
4245
|
+
}
|
4109
4246
|
factory.require(url)
|
4110
|
-
} else {
|
4247
|
+
} else {//合并前后的safari,合并后的IE6-9走此分支
|
4111
4248
|
factorys.push(factory)
|
4112
4249
|
}
|
4113
4250
|
}
|
4114
|
-
|
4251
|
+
//核心API之三 require.config(settings)
|
4115
4252
|
innerRequire.config = kernel
|
4116
|
-
|
4253
|
+
//核心API之四 define.amd 标识其符合AMD规范
|
4117
4254
|
innerRequire.define.amd = modules
|
4118
4255
|
|
4119
|
-
|
4256
|
+
//==========================对用户配置项进行再加工==========================
|
4120
4257
|
var allpaths = kernel["orig.paths"] = {}
|
4121
4258
|
var allmaps = kernel["orig.map"] = {}
|
4122
4259
|
var allpackages = kernel["packages"] = []
|
@@ -4139,11 +4276,11 @@ new function() {
|
|
4139
4276
|
var uniq = {}
|
4140
4277
|
var ret = []
|
4141
4278
|
for (var i = 0, pkg; pkg = array[i++]; ) {
|
4142
|
-
|
4279
|
+
pkg = typeof pkg === "string" ? {name: pkg} : pkg
|
4143
4280
|
var name = pkg.name
|
4144
4281
|
if (!uniq[name]) {
|
4145
4282
|
var url = pkg.location ? pkg.location : joinPath(name, pkg.main || "main")
|
4146
|
-
url = url.replace(
|
4283
|
+
url = url.replace(rjsext, "")
|
4147
4284
|
ret.push(pkg)
|
4148
4285
|
uniq[name] = pkg.location = url
|
4149
4286
|
pkg.reg = makeMatcher(name)
|
@@ -4160,18 +4297,19 @@ new function() {
|
|
4160
4297
|
},
|
4161
4298
|
baseUrl: function(url) {
|
4162
4299
|
if (!isAbsUrl(url)) {
|
4163
|
-
var baseElement = head.
|
4300
|
+
var baseElement = head.querySelector("base")
|
4164
4301
|
if (baseElement) {
|
4165
4302
|
head.removeChild(baseElement)
|
4166
4303
|
}
|
4167
4304
|
var node = DOC.createElement("a")
|
4168
4305
|
node.href = url
|
4169
|
-
url =
|
4306
|
+
url = node.href
|
4170
4307
|
if (baseElement) {
|
4171
4308
|
head.insertBefore(baseElement, head.firstChild)
|
4172
4309
|
}
|
4173
4310
|
}
|
4174
|
-
|
4311
|
+
if (url.length > 3)
|
4312
|
+
kernel.baseUrl = url
|
4175
4313
|
},
|
4176
4314
|
shim: function(obj) {
|
4177
4315
|
for (var i in obj) {
|
@@ -4182,85 +4320,30 @@ new function() {
|
|
4182
4320
|
}
|
4183
4321
|
}
|
4184
4322
|
if (!value.exportsFn && (value.exports || value.init)) {
|
4185
|
-
value.exportsFn =
|
4323
|
+
value.exportsFn = makeExports(value)
|
4186
4324
|
}
|
4187
4325
|
}
|
4188
4326
|
kernel.shim = obj
|
4189
|
-
},
|
4190
|
-
//三大常用资源插件 js!, css!, text!
|
4191
|
-
js: function(url, shim) {
|
4192
|
-
var id = trimQuery(url)
|
4193
|
-
if (!modules[id]) { //如果之前没有加载过
|
4194
|
-
var module = modules[id] = makeModule(id)
|
4195
|
-
if (shim) { //shim机制
|
4196
|
-
innerRequire(shim.deps || [], function() {
|
4197
|
-
var args = avalon.slice(arguments)
|
4198
|
-
loadJS(url, id, function() {
|
4199
|
-
module.state = 2
|
4200
|
-
if (shim.exportsFn) {
|
4201
|
-
module.exports = shim.exportsFn.apply(0, args)
|
4202
|
-
}
|
4203
|
-
innerRequire.checkDeps()
|
4204
|
-
})
|
4205
|
-
})
|
4206
|
-
} else {
|
4207
|
-
loadJS(url, id)
|
4208
|
-
}
|
4209
|
-
}
|
4210
|
-
return id
|
4211
|
-
},
|
4212
|
-
css: function(url) {
|
4213
|
-
var id = trimQuery(url)
|
4214
|
-
if (!DOC.getElementById(id)) {
|
4215
|
-
var node = DOC.createElement("link")
|
4216
|
-
node.rel = "stylesheet"
|
4217
|
-
node.href = url
|
4218
|
-
node.id = id
|
4219
|
-
head.insertBefore(node, head.firstChild)
|
4220
|
-
}
|
4221
|
-
},
|
4222
|
-
text: function(url) {
|
4223
|
-
var id = trimQuery(url)
|
4224
|
-
modules[id] = {}
|
4225
|
-
var xhr = getXHR()
|
4226
|
-
xhr.onreadystatechange = function() {
|
4227
|
-
if (xhr.readyState === 4) {
|
4228
|
-
var status = xhr.status;
|
4229
|
-
if (status > 399 && status < 600) {
|
4230
|
-
avalon.error(url + " 对应资源不存在或没有开启 CORS")
|
4231
|
-
} else {
|
4232
|
-
modules[id].state = 2
|
4233
|
-
modules[id].exports = xhr.responseText
|
4234
|
-
innerRequire.checkDeps()
|
4235
|
-
}
|
4236
|
-
}
|
4237
|
-
}
|
4238
|
-
xhr.open("GET", url, true)
|
4239
|
-
if ("withCredentials" in xhr) {
|
4240
|
-
xhr.withCredentials = true
|
4241
|
-
}
|
4242
|
-
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest")
|
4243
|
-
xhr.send()
|
4244
|
-
return id
|
4245
4327
|
}
|
4328
|
+
|
4246
4329
|
})
|
4247
4330
|
|
4248
|
-
|
4249
|
-
|
4250
|
-
//==============================内部方法=================================
|
4331
|
+
|
4332
|
+
//==============================内部方法=================================
|
4251
4333
|
function checkCycle(deps, nick) {
|
4252
4334
|
//检测是否存在循环依赖
|
4253
|
-
for (var id
|
4254
|
-
if (
|
4335
|
+
for (var i = 0, id; id = deps[i++]; ) {
|
4336
|
+
if (modules[id].state !== 4 &&
|
4337
|
+
(id === nick || checkCycle(modules[id].deps, nick))) {
|
4255
4338
|
return true
|
4256
4339
|
}
|
4257
4340
|
}
|
4258
4341
|
}
|
4259
4342
|
|
4260
|
-
function checkFail(node, onError
|
4343
|
+
function checkFail(node, onError) {
|
4261
4344
|
var id = trimQuery(node.src) //检测是否死链
|
4262
|
-
node.onload = node.
|
4263
|
-
if (onError
|
4345
|
+
node.onload = node.onerror = null
|
4346
|
+
if (onError) {
|
4264
4347
|
setTimeout(function() {
|
4265
4348
|
head.removeChild(node)
|
4266
4349
|
node = null // 处理旧式IE下的循环引用问题
|
@@ -4276,19 +4359,103 @@ new function() {
|
|
4276
4359
|
loop: for (var i = loadings.length, id; id = loadings[--i]; ) {
|
4277
4360
|
var obj = modules[id],
|
4278
4361
|
deps = obj.deps
|
4279
|
-
|
4280
|
-
|
4362
|
+
if (!deps)
|
4363
|
+
continue
|
4364
|
+
for (var j = 0, key; key = deps[j]; j++) {
|
4365
|
+
var k = name2url[key]
|
4366
|
+
if (k) {
|
4367
|
+
key = deps[j] = k
|
4368
|
+
}
|
4369
|
+
if (Object(modules[key]).state !== 4) {
|
4281
4370
|
continue loop
|
4282
4371
|
}
|
4283
4372
|
}
|
4284
4373
|
//如果deps是空对象或者其依赖的模块的状态都是2
|
4285
|
-
if (obj.state !==
|
4374
|
+
if (obj.state !== 4) {
|
4286
4375
|
loadings.splice(i, 1) //必须先移除再安装,防止在IE下DOM树建完后手动刷新页面,会多次执行它
|
4287
|
-
fireFactory(obj.id, obj.
|
4376
|
+
fireFactory(obj.id, obj.deps, obj.factory)
|
4288
4377
|
checkDeps() //如果成功,则再执行一次,以防有些模块就差本模块没有安装好
|
4289
4378
|
}
|
4290
4379
|
}
|
4291
4380
|
}
|
4381
|
+
function loadJS(url, id, callback) {
|
4382
|
+
//通过script节点加载目标模块
|
4383
|
+
var node = DOC.createElement("script")
|
4384
|
+
node.className = subscribers //让getCurrentScript只处理类名为subscribers的script节点
|
4385
|
+
node.onload = function() {
|
4386
|
+
var factory = factorys.pop()
|
4387
|
+
factory && factory.require(id)
|
4388
|
+
if (callback) {
|
4389
|
+
callback()
|
4390
|
+
}
|
4391
|
+
log("debug: 已成功加载 " + url)
|
4392
|
+
id && loadings.push(id)
|
4393
|
+
checkDeps()
|
4394
|
+
}
|
4395
|
+
node.onerror = function() {
|
4396
|
+
checkFail(node, true)
|
4397
|
+
}
|
4398
|
+
|
4399
|
+
head.appendChild(node) //chrome下第二个参数不能为null
|
4400
|
+
node.src = url //插入到head的第一个节点前,防止IE6下head标签没闭合前使用appendChild抛错
|
4401
|
+
log("debug: 正准备加载 " + url) //更重要的是IE6下可以收窄getCurrentScript的寻找范围
|
4402
|
+
}
|
4403
|
+
|
4404
|
+
var resources = innerRequire.plugins = {
|
4405
|
+
//三大常用资源插件 js!, css!, text!, ready!
|
4406
|
+
ready: {
|
4407
|
+
load: noop
|
4408
|
+
},
|
4409
|
+
js: {
|
4410
|
+
load: function(name, req, onLoad) {
|
4411
|
+
var url = req.url
|
4412
|
+
var id = req.urlNoQuery
|
4413
|
+
var shim = kernel.shim[name.replace(rjsext, "")]
|
4414
|
+
if (shim) { //shim机制
|
4415
|
+
innerRequire(shim.deps || [], function() {
|
4416
|
+
var args = avalon.slice(arguments)
|
4417
|
+
loadJS(url, id, function() {
|
4418
|
+
onLoad(shim.exportsFn ? shim.exportsFn.apply(0, args) : void 0)
|
4419
|
+
})
|
4420
|
+
})
|
4421
|
+
} else {
|
4422
|
+
loadJS(url, id)
|
4423
|
+
}
|
4424
|
+
}
|
4425
|
+
},
|
4426
|
+
css: {
|
4427
|
+
load: function(name, req, onLoad) {
|
4428
|
+
var url = req.url
|
4429
|
+
var node = DOC.createElement("link")
|
4430
|
+
node.rel = "stylesheet"
|
4431
|
+
node.href = url
|
4432
|
+
head.appendChild(node)
|
4433
|
+
log("debug: 已成功加载 " + url)
|
4434
|
+
onLoad()
|
4435
|
+
}
|
4436
|
+
},
|
4437
|
+
text: {
|
4438
|
+
load: function(name, req, onLoad) {
|
4439
|
+
var url = req.url
|
4440
|
+
var xhr = getXHR()
|
4441
|
+
xhr.onload = function() {
|
4442
|
+
var status = xhr.status;
|
4443
|
+
if (status > 399 && status < 600) {
|
4444
|
+
avalon.error(url + " 对应资源不存在或没有开启 CORS")
|
4445
|
+
} else {
|
4446
|
+
onLoad(xhr.responseText)
|
4447
|
+
}
|
4448
|
+
}
|
4449
|
+
xhr.open("GET", url, true)
|
4450
|
+
if ("withCredentials" in xhr) {//这是处理跨域
|
4451
|
+
xhr.withCredentials = true
|
4452
|
+
}
|
4453
|
+
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest")//告诉后端这是AJAX请求
|
4454
|
+
xhr.send()
|
4455
|
+
log("debug: 正准备加载 " + url)
|
4456
|
+
}
|
4457
|
+
}
|
4458
|
+
}
|
4292
4459
|
innerRequire.checkDeps = checkDeps
|
4293
4460
|
|
4294
4461
|
var rquery = /(\?[^#]*)$/
|
@@ -4301,24 +4468,13 @@ new function() {
|
|
4301
4468
|
return /^(?:[a-z]+:)?\/\//i.test(String(path))
|
4302
4469
|
}
|
4303
4470
|
|
4304
|
-
function
|
4305
|
-
return parentUrl ?
|
4306
|
-
parentUrl.substr(0, parentUrl.lastIndexOf("/")) :
|
4307
|
-
kernel.baseUrl ? kernel.baseUrl :
|
4308
|
-
kernel.loaderUrl
|
4309
|
-
}
|
4310
|
-
|
4311
|
-
function getCurrentScript(base) {
|
4471
|
+
function getCurrentScript() {
|
4312
4472
|
// inspireb by https://github.com/samyk/jiagra/blob/master/jiagra.js
|
4313
4473
|
var stack
|
4314
4474
|
try {
|
4315
4475
|
a.b.c() //强制报错,以便捕获e.stack
|
4316
|
-
} catch (e) { //
|
4476
|
+
} catch (e) { //safari5的sourceURL,firefox的fileName,它们的效果与e.stack不一样
|
4317
4477
|
stack = e.stack
|
4318
|
-
if (!stack && window.opera) {
|
4319
|
-
//opera 9没有e.stack,但有e.Backtrace,但不能直接取得,需要对e对象转字符串进行抽取
|
4320
|
-
stack = (String(e).match(/of linked script \S+/g) || []).join(" ")
|
4321
|
-
}
|
4322
4478
|
}
|
4323
4479
|
if (stack) {
|
4324
4480
|
/**e.stack最后一行在所有支持的浏览器大致如下:
|
@@ -4334,116 +4490,83 @@ new function() {
|
|
4334
4490
|
*/
|
4335
4491
|
stack = stack.split(/[@ ]/g).pop() //取得最后一行,最后一个空格或@之后的部分
|
4336
4492
|
stack = stack[0] === "(" ? stack.slice(1, -1) : stack.replace(/\s/, "") //去掉换行符
|
4337
|
-
return stack.replace(/(:\d+)?:\d+$/i, "") //去掉行号与或许存在的出错字符起始位置
|
4493
|
+
return trimQuery(stack.replace(/(:\d+)?:\d+$/i, "")) //去掉行号与或许存在的出错字符起始位置
|
4338
4494
|
}
|
4339
|
-
var nodes =
|
4495
|
+
var nodes = head.getElementsByTagName("script") //只在head标签中寻找
|
4340
4496
|
for (var i = nodes.length, node; node = nodes[--i]; ) {
|
4341
|
-
if (
|
4342
|
-
var url =
|
4343
|
-
return node.className = url
|
4497
|
+
if (node.className === subscribers && node.readyState === "interactive") {
|
4498
|
+
var url = node.src
|
4499
|
+
return node.className = trimQuery(url)
|
4344
4500
|
}
|
4345
4501
|
}
|
4346
4502
|
}
|
4347
4503
|
|
4348
|
-
|
4349
|
-
|
4350
|
-
|
4351
|
-
|
4504
|
+
|
4505
|
+
function fireFactory(id, deps, factory) {
|
4506
|
+
var module = Object(modules[id])
|
4507
|
+
module.state = 4
|
4508
|
+
for (var i = 0, array = [], d; d = deps[i++]; ) {
|
4509
|
+
d = name2url[d] || d
|
4510
|
+
if (d === "exports") {
|
4511
|
+
var obj = module.exports || (module.exports = {})
|
4512
|
+
array.push(obj)
|
4513
|
+
} else {
|
4514
|
+
array.push(modules[d].exports)
|
4515
|
+
}
|
4352
4516
|
}
|
4353
|
-
|
4354
|
-
|
4355
|
-
|
4356
|
-
|
4357
|
-
|
4358
|
-
|
4359
|
-
|
4360
|
-
|
4361
|
-
|
4362
|
-
|
4363
|
-
return ""
|
4364
|
-
})
|
4365
|
-
var ext = ""
|
4366
|
-
if (res === "js") {
|
4367
|
-
url = id = id.replace(/\.js$/i, "")
|
4368
|
-
ext = ".js"
|
4517
|
+
var ret = factory.apply(window, array)
|
4518
|
+
if (ret !== void 0) {
|
4519
|
+
module.exports = ret
|
4520
|
+
}
|
4521
|
+
delete module.factory
|
4522
|
+
return ret
|
4523
|
+
}
|
4524
|
+
function toUrl(id) {
|
4525
|
+
if (id.indexOf(this.res + "!") === 0) {
|
4526
|
+
id = id.slice(this.res.length + 1) //处理define("css!style",[], function(){})的情况
|
4369
4527
|
}
|
4370
|
-
|
4528
|
+
var url = id
|
4529
|
+
//1. 是否命中paths配置项
|
4371
4530
|
var usePath = 0
|
4531
|
+
var baseUrl = this.baseUrl
|
4532
|
+
var rootUrl = this.parentUrl || baseUrl
|
4372
4533
|
eachIndexArray(id, kernel.paths, function(value, key) {
|
4373
4534
|
url = url.replace(key, value)
|
4374
4535
|
usePath = 1
|
4375
4536
|
})
|
4376
|
-
//
|
4537
|
+
//2. 是否命中packages配置项
|
4377
4538
|
if (!usePath) {
|
4378
4539
|
eachIndexArray(id, kernel.packages, function(value, key, item) {
|
4379
4540
|
url = url.replace(item.name, item.location)
|
4380
4541
|
})
|
4381
4542
|
}
|
4382
|
-
//
|
4383
|
-
if (mapUrl) {
|
4384
|
-
eachIndexArray(mapUrl, kernel.map, function(array) {
|
4543
|
+
//3. 是否命中map配置项
|
4544
|
+
if (this.mapUrl) {
|
4545
|
+
eachIndexArray(this.mapUrl, kernel.map, function(array) {
|
4385
4546
|
eachIndexArray(url, array, function(mdValue, mdKey) {
|
4386
4547
|
url = url.replace(mdKey, mdValue)
|
4548
|
+
rootUrl = baseUrl
|
4387
4549
|
})
|
4388
4550
|
})
|
4389
4551
|
}
|
4390
|
-
|
4552
|
+
var ext = this.ext
|
4553
|
+
if (ext && usePath && url.slice(-ext.length) === ext) {
|
4554
|
+
url = url.slice(0, -ext.length)
|
4555
|
+
}
|
4556
|
+
//4. 转换为绝对路径
|
4391
4557
|
if (!isAbsUrl(url)) {
|
4392
|
-
|
4558
|
+
rootUrl = this.built || /^\w/.test(url) ? baseUrl : rootUrl
|
4559
|
+
url = joinPath(rootUrl, url)
|
4393
4560
|
}
|
4394
|
-
//
|
4395
|
-
|
4396
|
-
|
4561
|
+
//5. 还原扩展名,query
|
4562
|
+
var urlNoQuery = url + ext
|
4563
|
+
url = urlNoQuery + this.query
|
4564
|
+
//6. 处理urlArgs
|
4397
4565
|
eachIndexArray(id, kernel.urlArgs, function(value) {
|
4398
4566
|
url += (url.indexOf("?") === -1 ? "?" : "&") + value;
|
4399
4567
|
})
|
4400
|
-
|
4401
|
-
|
4402
|
-
|
4403
|
-
function loadJS(url, id, callback) {
|
4404
|
-
//通过script节点加载目标模块
|
4405
|
-
var node = DOC.createElement("script")
|
4406
|
-
node.className = subscribers //让getCurrentScript只处理类名为subscribers的script节点
|
4407
|
-
node[W3C ? "onload" : "onreadystatechange"] = function() {
|
4408
|
-
if (W3C || /loaded|complete/i.test(node.readyState)) {
|
4409
|
-
//mass Framework会在_checkFail把它上面的回调清掉,尽可能释放回存,尽管DOM0事件写法在IE6下GC无望
|
4410
|
-
var factory = factorys.pop()
|
4411
|
-
|
4412
|
-
factory && factory.require(id)
|
4413
|
-
if (callback) {
|
4414
|
-
callback()
|
4415
|
-
}
|
4416
|
-
if (checkFail(node, false, !W3C)) {
|
4417
|
-
log("debug: 已成功加载 " + url)
|
4418
|
-
loadings.push(id)
|
4419
|
-
checkDeps()
|
4420
|
-
}
|
4421
|
-
}
|
4422
|
-
}
|
4423
|
-
node.onerror = function() {
|
4424
|
-
checkFail(node, true)
|
4425
|
-
}
|
4426
|
-
node.src = url //插入到head的第一个节点前,防止IE6下head标签没闭合前使用appendChild抛错
|
4427
|
-
head.insertBefore(node, head.firstChild) //chrome下第二个参数不能为null
|
4428
|
-
log("debug: 正准备加载 " + url) //更重要的是IE6下可以收窄getCurrentScript的寻找范围
|
4429
|
-
}
|
4430
|
-
|
4431
|
-
function fireFactory(id, deps, factory) {
|
4432
|
-
var module = Object(modules[id])
|
4433
|
-
module.state = 2
|
4434
|
-
for (var i = 0, array = [], d; d = deps[i++]; ) {
|
4435
|
-
if (d === "exports") {
|
4436
|
-
var obj = module.exports || (module.exports = {})
|
4437
|
-
array.push(obj)
|
4438
|
-
} else {
|
4439
|
-
array.push(modules[d].exports)
|
4440
|
-
}
|
4441
|
-
}
|
4442
|
-
var ret = factory.apply(window, array)
|
4443
|
-
if (ret !== void 0) {
|
4444
|
-
modules[id].exports = ret
|
4445
|
-
}
|
4446
|
-
return ret
|
4568
|
+
this.url = url
|
4569
|
+
return this.urlNoQuery = urlNoQuery
|
4447
4570
|
}
|
4448
4571
|
|
4449
4572
|
function makeIndexArray(hash, useStar, part) {
|
@@ -4457,7 +4580,7 @@ new function() {
|
|
4457
4580
|
return new RegExp('^' + prefix + '(/|$)')
|
4458
4581
|
}
|
4459
4582
|
|
4460
|
-
function
|
4583
|
+
function makeExports(value) {
|
4461
4584
|
return function() {
|
4462
4585
|
var ret
|
4463
4586
|
if (value.init) {
|
@@ -4467,15 +4590,6 @@ new function() {
|
|
4467
4590
|
}
|
4468
4591
|
}
|
4469
4592
|
|
4470
|
-
function makeModule(id, state, factory, deps, args) {
|
4471
|
-
return {
|
4472
|
-
id: id,
|
4473
|
-
state: state || 1,
|
4474
|
-
factory: factory || noop,
|
4475
|
-
deps: deps || {},
|
4476
|
-
args: args || []
|
4477
|
-
}
|
4478
|
-
}
|
4479
4593
|
|
4480
4594
|
function hash2array(hash, useStar, part) {
|
4481
4595
|
var array = [];
|
@@ -4486,9 +4600,7 @@ new function() {
|
|
4486
4600
|
val: hash[key]
|
4487
4601
|
}
|
4488
4602
|
array.push(item)
|
4489
|
-
item.reg = key === "*" && useStar
|
4490
|
-
? /^/
|
4491
|
-
: makeMatcher(key)
|
4603
|
+
item.reg = key === "*" && useStar ? /^/ : makeMatcher(key)
|
4492
4604
|
if (part && key !== "*") {
|
4493
4605
|
item.reg = new RegExp('\/' + key.replace(/^\//, "") + '(/|$)')
|
4494
4606
|
}
|
@@ -4506,7 +4618,7 @@ new function() {
|
|
4506
4618
|
}
|
4507
4619
|
}
|
4508
4620
|
}
|
4509
|
-
|
4621
|
+
// 根据元素的name项进行数组字符数逆序的排序函数
|
4510
4622
|
function descSorterByName(a, b) {
|
4511
4623
|
var aaa = a.name
|
4512
4624
|
var bbb = b.name
|
@@ -4551,14 +4663,17 @@ new function() {
|
|
4551
4663
|
return g
|
4552
4664
|
}
|
4553
4665
|
|
4554
|
-
|
4555
|
-
var
|
4556
|
-
if (
|
4557
|
-
|
4666
|
+
var mainNode = DOC.scripts[DOC.scripts.length - 1]
|
4667
|
+
var dataMain = mainNode.getAttribute("data-main")
|
4668
|
+
if (dataMain) {
|
4669
|
+
plugins.baseUrl(dataMain)
|
4670
|
+
var href = kernel.baseUrl
|
4671
|
+
kernel.baseUrl = href.slice(0, href.lastIndexOf("/") + 1)
|
4672
|
+
loadJS(href.replace(rjsext, "") + ".js")
|
4673
|
+
} else {
|
4674
|
+
var loaderUrl = trimQuery(mainNode.src)
|
4675
|
+
kernel.baseUrl = loaderUrl.slice(0, loaderUrl.lastIndexOf("/") + 1)
|
4558
4676
|
}
|
4559
|
-
var url = trimQuery(cur)
|
4560
|
-
kernel.loaderUrl = url.slice(0, url.lastIndexOf("/") + 1)
|
4561
|
-
|
4562
4677
|
}
|
4563
4678
|
|
4564
4679
|
/*********************************************************************
|
@@ -4567,13 +4682,12 @@ new function() {
|
|
4567
4682
|
var readyList = []
|
4568
4683
|
function fireReady() {
|
4569
4684
|
if (innerRequire) {
|
4570
|
-
modules["
|
4685
|
+
modules["domReady!"].state = 4
|
4571
4686
|
innerRequire.checkDeps()//隋性函数,防止IE9二次调用_checkDeps
|
4572
|
-
} else {
|
4573
|
-
readyList.forEach(function(a) {
|
4574
|
-
a(avalon)
|
4575
|
-
})
|
4576
4687
|
}
|
4688
|
+
readyList.forEach(function(a) {
|
4689
|
+
a(avalon)
|
4690
|
+
})
|
4577
4691
|
fireReady = noop //隋性函数,防止IE9二次调用_checkDeps
|
4578
4692
|
}
|
4579
4693
|
|
@@ -4584,9 +4698,7 @@ if (DOC.readyState === "complete") {
|
|
4584
4698
|
window.addEventListener("load", fireReady)
|
4585
4699
|
}
|
4586
4700
|
avalon.ready = function(fn) {
|
4587
|
-
if (
|
4588
|
-
innerRequire(["ready!"], fn)
|
4589
|
-
} else if (fireReady === noop) {
|
4701
|
+
if (fireReady === noop) {
|
4590
4702
|
fn(avalon)
|
4591
4703
|
} else {
|
4592
4704
|
readyList.push(fn)
|
@@ -4624,11 +4736,11 @@ avalon.ready(function() {
|
|
4624
4736
|
}
|
4625
4737
|
return avalon
|
4626
4738
|
}
|
4627
|
-
// Expose avalon
|
4739
|
+
// Expose avalon identifiers, even in AMD
|
4628
4740
|
// and CommonJS for browser emulators
|
4629
4741
|
if (noGlobal === void 0) {
|
4630
4742
|
window.avalon = avalon
|
4631
4743
|
}
|
4632
4744
|
return avalon
|
4633
4745
|
|
4634
|
-
}));
|
4746
|
+
}));
|