@@ -1480,6 +1480,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
14801480        } ) ; 
14811481      } ; 
14821482
1483+       // We need  to attach the transclusion slots onto the `boundTranscludeFn` 
1484+       // so that they are available inside the `controllersBoundTransclude` function 
1485+       var  boundSlots  =  boundTranscludeFn . $$slots  =  createMap ( ) ; 
1486+       for  ( var  slotName  in  transcludeFn . $$slots )  { 
1487+         boundSlots [ slotName ]  =  createBoundTranscludeFn ( scope ,  transcludeFn . $$slots [ slotName ] ,  previousBoundTranscludeFn ) ; 
1488+       } 
1489+ 
14831490      return  boundTranscludeFn ; 
14841491    } 
14851492
@@ -1821,9 +1828,56 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
18211828                                          nonTlbTranscludeDirective : nonTlbTranscludeDirective 
18221829                                        } ) ; 
18231830          }  else  { 
1831+ 
1832+             var  slots  =  createMap ( ) ; 
18241833            $template  =  jqLite ( jqLiteClone ( compileNode ) ) . contents ( ) ; 
1834+ 
1835+             if  ( isObject ( directiveValue ) )  { 
1836+ 
1837+               // We have transclusion slots - collect them up and compile them and store their 
1838+               // transclusion functions 
1839+               $template  =  [ ] ; 
1840+               var  slotNames  =  createMap ( ) ; 
1841+               var  filledSlots  =  createMap ( ) ; 
1842+ 
1843+               // Parse the slot names: if they start with a ? then they are optional 
1844+               forEach ( directiveValue ,  function ( slotName ,  key )  { 
1845+                 var  optional  =  ( slotName . charAt ( 0 )  ===  '?' ) ; 
1846+                 slotName  =  optional  ? slotName . substring ( 1 )  : slotName ; 
1847+                 slotNames [ key ]  =  slotName ; 
1848+                 slots [ slotName ]  =  [ ] ; 
1849+                 // filledSlots contains `true` for all slots that are either optional or have been 
1850+                 // filled. This is used to check that we have not missed any required slots 
1851+                 filledSlots [ slotName ]  =  optional ; 
1852+               } ) ; 
1853+ 
1854+               // Add the matching elements into their slot 
1855+               forEach ( $compileNode . children ( ) ,  function ( node )  { 
1856+                 var  slotName  =  slotNames [ directiveNormalize ( nodeName_ ( node ) ) ] ; 
1857+                 var  slot  =  $template ; 
1858+                 if  ( slotName )  { 
1859+                   filledSlots [ slotName ]  =  true ; 
1860+                   slots [ slotName ] . push ( node ) ; 
1861+                 }  else  { 
1862+                   $template . push ( node ) ; 
1863+                 } 
1864+               } ) ; 
1865+ 
1866+               // Check for required slots that were not filled 
1867+               forEach ( filledSlots ,  function ( filled ,  slotName )  { 
1868+                 if  ( ! filled )  { 
1869+                   throw  $compileMinErr ( 'reqslot' ,  'Required transclusion slot `{0}` was not filled.' ,  slotName ) ; 
1870+                 } 
1871+               } ) ; 
1872+ 
1873+               forEach ( Object . keys ( slots ) ,  function ( slotName )  { 
1874+                 slots [ slotName ]  =  compilationGenerator ( mightHaveMultipleTransclusionError ,  slots [ slotName ] ,  transcludeFn ) ; 
1875+               } ) ; 
1876+             } 
1877+ 
18251878            $compileNode . empty ( ) ;  // clear contents 
18261879            childTranscludeFn  =  compilationGenerator ( mightHaveMultipleTransclusionError ,  $template ,  transcludeFn ) ; 
1880+             childTranscludeFn . $$slots  =  slots ; 
18271881          } 
18281882        } 
18291883
@@ -2130,11 +2184,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
21302184
21312185        // This is the function that is injected as `$transclude`. 
21322186        // Note: all arguments are optional! 
2133-         function  controllersBoundTransclude ( scope ,  cloneAttachFn ,  futureParentElement )  { 
2187+         function  controllersBoundTransclude ( scope ,  cloneAttachFn ,  futureParentElement ,   slotName )  { 
21342188          var  transcludeControllers ; 
2135- 
21362189          // No scope passed in: 
21372190          if  ( ! isScope ( scope ) )  { 
2191+             slotName  =  futureParentElement ; 
21382192            futureParentElement  =  cloneAttachFn ; 
21392193            cloneAttachFn  =  scope ; 
21402194            scope  =  undefined ; 
@@ -2146,6 +2200,16 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
21462200          if  ( ! futureParentElement )  { 
21472201            futureParentElement  =  hasElementTranscludeDirective  ? $element . parent ( )  : $element ; 
21482202          } 
2203+           if  ( slotName )  { 
2204+             var  slotTranscludeFn  =  boundTranscludeFn . $$slots [ slotName ] ; 
2205+             if  ( ! slotTranscludeFn )  { 
2206+               throw  $compileMinErr ( 'noslot' , 
2207+                'No parent directive that requires a transclusion with slot name "{0}". '  + 
2208+                'Element: {1}' , 
2209+                slotName ,  startingTag ( $element ) ) ; 
2210+             } 
2211+             return  slotTranscludeFn ( scope ,  cloneAttachFn ,  transcludeControllers ,  futureParentElement ,  scopeToChild ) ; 
2212+           } 
21492213          return  boundTranscludeFn ( scope ,  cloneAttachFn ,  transcludeControllers ,  futureParentElement ,  scopeToChild ) ; 
21502214        } 
21512215      } 
0 commit comments