* Compile function matches each node in nodeList against the directives. Once all directives * for a particular node are collected their compile functions are executed. The compile * functions return values - the linking functions - are combined into a composite linking * function, wh
(nodeList, transcludeFn, $rootElement, maxPriority)
| 3951 | * @returns {?function} A composite linking function of all of the matched directives or null. |
| 3952 | */ |
| 3953 | function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority) { |
| 3954 | var linkFns = [], |
| 3955 | nodeLinkFn, childLinkFn, directives, attrs, linkFnFound; |
| 3956 | |
| 3957 | for(var i = 0; i < nodeList.length; i++) { |
| 3958 | attrs = new Attributes(); |
| 3959 | |
| 3960 | // we must always refer to nodeList[i] since the nodes can be replaced underneath us. |
| 3961 | directives = collectDirectives(nodeList[i], [], attrs, maxPriority); |
| 3962 | |
| 3963 | nodeLinkFn = (directives.length) |
| 3964 | ? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement) |
| 3965 | : null; |
| 3966 | |
| 3967 | childLinkFn = (nodeLinkFn && nodeLinkFn.terminal || !nodeList[i].childNodes || !nodeList[i].childNodes.length) |
| 3968 | ? null |
| 3969 | : compileNodes(nodeList[i].childNodes, |
| 3970 | nodeLinkFn ? nodeLinkFn.transclude : transcludeFn); |
| 3971 | |
| 3972 | linkFns.push(nodeLinkFn); |
| 3973 | linkFns.push(childLinkFn); |
| 3974 | linkFnFound = (linkFnFound || nodeLinkFn || childLinkFn); |
| 3975 | } |
| 3976 | |
| 3977 | // return a linking function if we have found anything, null otherwise |
| 3978 | return linkFnFound ? compositeLinkFn : null; |
| 3979 | |
| 3980 | function compositeLinkFn(scope, nodeList, $rootElement, boundTranscludeFn) { |
| 3981 | var nodeLinkFn, childLinkFn, node, childScope, childTranscludeFn, i, ii, n; |
| 3982 | |
| 3983 | // copy nodeList so that linking doesn't break due to live list updates. |
| 3984 | var stableNodeList = []; |
| 3985 | for (i = 0, ii = nodeList.length; i < ii; i++) { |
| 3986 | stableNodeList.push(nodeList[i]); |
| 3987 | } |
| 3988 | |
| 3989 | for(i = 0, n = 0, ii = linkFns.length; i < ii; n++) { |
| 3990 | node = stableNodeList[n]; |
| 3991 | nodeLinkFn = linkFns[i++]; |
| 3992 | childLinkFn = linkFns[i++]; |
| 3993 | |
| 3994 | if (nodeLinkFn) { |
| 3995 | if (nodeLinkFn.scope) { |
| 3996 | childScope = scope.$new(isObject(nodeLinkFn.scope)); |
| 3997 | jqLite(node).data('$scope', childScope); |
| 3998 | } else { |
| 3999 | childScope = scope; |
| 4000 | } |
| 4001 | childTranscludeFn = nodeLinkFn.transclude; |
| 4002 | if (childTranscludeFn || (!boundTranscludeFn && transcludeFn)) { |
| 4003 | nodeLinkFn(childLinkFn, childScope, node, $rootElement, |
| 4004 | (function(transcludeFn) { |
| 4005 | return function(cloneFn) { |
| 4006 | var transcludeScope = scope.$new(); |
| 4007 | transcludeScope.$$transcluded = true; |
| 4008 | |
| 4009 | return transcludeFn(transcludeScope, cloneFn). |
| 4010 | bind('$destroy', bind(transcludeScope, transcludeScope.$destroy)); |
no test coverage detected