@@ -1486,6 +1486,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
1486
1486
} ) ;
1487
1487
} ;
1488
1488
1489
+ // We need to attach the transclusion slots onto the `boundTranscludeFn`
1490
+ // so that they are available inside the `controllersBoundTransclude` function
1491
+ var boundSlots = boundTranscludeFn . $$slots = createMap ( ) ;
1492
+ for ( var slotName in transcludeFn . $$slots ) {
1493
+ boundSlots [ slotName ] = createBoundTranscludeFn ( scope , transcludeFn . $$slots [ slotName ] , previousBoundTranscludeFn ) ;
1494
+ }
1495
+
1489
1496
return boundTranscludeFn ;
1490
1497
}
1491
1498
@@ -1826,6 +1833,52 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
1826
1833
// on the same element more than once.
1827
1834
nonTlbTranscludeDirective : nonTlbTranscludeDirective
1828
1835
} ) ;
1836
+ } else if ( isObject ( directiveValue ) ) {
1837
+
1838
+ // We have multiple transclusion zones - match them and collect them up into slots
1839
+ $template = [ ] ;
1840
+ var slots = createMap ( ) ;
1841
+ var slotNames = createMap ( ) ;
1842
+ var filledSlots = createMap ( ) ;
1843
+
1844
+ // Parse the slot names: if they start with a ? then they are optional
1845
+ forEach ( directiveValue , function ( slotName , key ) {
1846
+ var optional = ( slotName . charAt ( 0 ) === '?' ) ;
1847
+ slotName = optional ? slotName . substring ( 1 ) : slotName ;
1848
+ slotNames [ key ] = slotName ;
1849
+ slots [ slotName ] = [ ] ;
1850
+ // filledSlots will contain true for all slots that are either
1851
+ // optional or have been filled
1852
+ filledSlots [ slotName ] = optional ;
1853
+ } ) ;
1854
+
1855
+
1856
+ forEach ( $compileNode . children ( ) , function ( node ) {
1857
+ var slotName = slotNames [ directiveNormalize ( nodeName_ ( node ) ) ] ;
1858
+ var slot = $template ;
1859
+ if ( slotName ) {
1860
+ filledSlots [ slotName ] = true ;
1861
+ slots [ slotName ] . push ( node ) ;
1862
+ } else {
1863
+ $template . push ( node ) ;
1864
+ }
1865
+ } ) ;
1866
+
1867
+ // Check for required slots that were not filled
1868
+ forEach ( filledSlots , function ( filled , slotName ) {
1869
+ if ( ! filled ) {
1870
+ throw $compileMinErr ( 'reqslot' , 'Required transclusion slot `{0}` was not filled.' , slotName ) ;
1871
+ }
1872
+ } ) ;
1873
+
1874
+ // Compile each slot into a transclusion function and attach them to the default transclusion function
1875
+ childTranscludeFn = compilationGenerator ( mightHaveMultipleTransclusionError , $template , transcludeFn ) ;
1876
+ forEach ( Object . keys ( slots ) , function ( slotName ) {
1877
+ slots [ slotName ] = compilationGenerator ( mightHaveMultipleTransclusionError , slots [ slotName ] , transcludeFn ) ;
1878
+ } ) ;
1879
+ childTranscludeFn . $$slots = slots ;
1880
+ $compileNode . empty ( ) ; // clear contents
1881
+
1829
1882
} else {
1830
1883
$template = jqLite ( jqLiteClone ( compileNode ) ) . contents ( ) ;
1831
1884
$compileNode . empty ( ) ; // clear contents
@@ -2134,11 +2187,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
2134
2187
2135
2188
// This is the function that is injected as `$transclude`.
2136
2189
// Note: all arguments are optional!
2137
- function controllersBoundTransclude ( scope , cloneAttachFn , futureParentElement ) {
2190
+ function controllersBoundTransclude ( scope , cloneAttachFn , futureParentElement , slotName ) {
2138
2191
var transcludeControllers ;
2139
-
2140
2192
// No scope passed in:
2141
2193
if ( ! isScope ( scope ) ) {
2194
+ slotName = futureParentElement ;
2142
2195
futureParentElement = cloneAttachFn ;
2143
2196
cloneAttachFn = scope ;
2144
2197
scope = undefined ;
@@ -2150,6 +2203,16 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
2150
2203
if ( ! futureParentElement ) {
2151
2204
futureParentElement = hasElementTranscludeDirective ? $element . parent ( ) : $element ;
2152
2205
}
2206
+ if ( slotName ) {
2207
+ var slotTranscludeFn = boundTranscludeFn . $$slots [ slotName ] ;
2208
+ if ( ! slotTranscludeFn ) {
2209
+ throw $compileMinErr ( 'noslot' ,
2210
+ 'No parent directive that requires a transclusion with slot name "{0}". ' +
2211
+ 'Element: {1}' ,
2212
+ slotName , startingTag ( $element ) ) ;
2213
+ }
2214
+ return slotTranscludeFn ( scope , cloneAttachFn , transcludeControllers , futureParentElement , scopeToChild ) ;
2215
+ }
2153
2216
return boundTranscludeFn ( scope , cloneAttachFn , transcludeControllers , futureParentElement , scopeToChild ) ;
2154
2217
}
2155
2218
}
0 commit comments