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,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
|
+
}));
|