@@ -15,20 +15,16 @@ angular.module('ui.bootstrap.tabs', [])
1515 } ;
1616} )
1717
18- . controller ( 'TabsetController' , [ '$scope' , '$element' ,
18+ . controller ( 'TabsetController' , [ '$scope' , '$element' ,
1919function TabsetCtrl ( $scope , $element ) {
2020
21- //Expose the outer scope for tab content compiling, so it can compile
22- //on outer scope like it should
23- this . $outerScope = $scope . $parent ;
24-
2521 var ctrl = this ,
2622 tabs = ctrl . tabs = $scope . tabs = [ ] ;
2723
2824 ctrl . select = function ( tab ) {
2925 angular . forEach ( tabs , function ( tab ) {
3026 tab . active = false ;
31- } ) ;
27+ } ) ;
3228 tab . active = true ;
3329 } ;
3430
@@ -39,7 +35,7 @@ function TabsetCtrl($scope, $element) {
3935 }
4036 } ;
4137
42- ctrl . removeTab = function removeTab ( tab ) {
38+ ctrl . removeTab = function removeTab ( tab ) {
4339 var index = tabs . indexOf ( tab ) ;
4440 //Select a new tab if the tab to be removed is selected
4541 if ( tab . active && tabs . length > 1 ) {
@@ -101,7 +97,7 @@ function TabsetCtrl($scope, $element) {
10197 * @param {boolean= } active A binding, telling whether or not this tab is selected.
10298 * @param {boolean= } disabled A binding, telling whether or not this tab is disabled.
10399 *
104- * @description
100+ * @description
105101 * Creates a tab with a heading and content. Must be placed within a {@link ui.bootstrap.tabs.directive:tabset tabset}.
106102 *
107103 * @example
@@ -235,37 +231,11 @@ function($parse, $http, $templateCache, $compile) {
235231 //value won't overwrite what is initially set by the tabset
236232 if ( scope . active ) {
237233 setActive ( scope . $parent , true ) ;
238- }
234+ }
239235
240- //Transclude the collection of sibling elements. Use forEach to find
241- //the heading if it exists. We don't use a directive for tab-heading
242- //because it is problematic. Discussion @ http://git.io/MSNPwQ
243- transclude ( scope . $parent , function ( clone ) {
244- //Look at every element in the clone collection. If it's tab-heading,
245- //mark it as that. If it's not tab-heading, mark it as tab contents
246- var contents = [ ] , heading ;
247- angular . forEach ( clone , function ( el ) {
248- //See if it's a tab-heading attr or element directive
249- //First make sure it's a normal element, one that has a tagName
250- if ( el . tagName &&
251- ( el . hasAttribute ( "tab-heading" ) ||
252- el . hasAttribute ( "data-tab-heading" ) ||
253- el . tagName . toLowerCase ( ) == "tab-heading" ||
254- el . tagName . toLowerCase ( ) == "data-tab-heading"
255- ) ) {
256- heading = el ;
257- } else {
258- contents . push ( el ) ;
259- }
260- } ) ;
261- //Share what we found on the scope, so our tabHeadingTransclude and
262- //tabContentTransclude directives can find out what the heading and
263- //contents are.
264- if ( heading ) {
265- scope . headingElement = angular . element ( heading ) ;
266- }
267- scope . contentElement = angular . element ( contents ) ;
268- } ) ;
236+ //We need to transclude later, once the content container is ready.
237+ //when this link happens, we're inside a tab heading.
238+ scope . $transcludeFn = transclude ;
269239 } ;
270240 }
271241 } ;
@@ -274,7 +244,7 @@ function($parse, $http, $templateCache, $compile) {
274244. directive ( 'tabHeadingTransclude' , [ function ( ) {
275245 return {
276246 restrict : 'A' ,
277- require : '^tab' ,
247+ require : '^tab' ,
278248 link : function ( scope , elm , attrs , tabCtrl ) {
279249 scope . $watch ( 'headingElement' , function updateHeadingElement ( heading ) {
280250 if ( heading ) {
@@ -290,17 +260,31 @@ function($parse, $http, $templateCache, $compile) {
290260 return {
291261 restrict : 'A' ,
292262 require : '^tabset' ,
293- link : function ( scope , elm , attrs , tabsetCtrl ) {
294- var outerScope = tabsetCtrl . $outerScope ;
295- scope . $watch ( $parse ( attrs . tabContentTransclude ) , function ( tab ) {
296- elm . html ( '' ) ;
297- if ( tab ) {
298- elm . append ( tab . contentElement ) ;
299- $compile ( tab . contentElement ) ( outerScope ) ;
300- }
263+ link : function ( scope , elm , attrs ) {
264+ var tab = scope . $eval ( attrs . tabContentTransclude ) ;
265+
266+ //Now our tab is ready to be transcluded: both the tab heading area
267+ //and the tab content area are loaded. Transclude 'em both.
268+ tab . $transcludeFn ( tab . $parent , function ( contents ) {
269+ angular . forEach ( contents , function ( node ) {
270+ if ( isTabHeading ( node ) ) {
271+ //Let tabHeadingTransclude know.
272+ tab . headingElement = node ;
273+ } else {
274+ elm . append ( node ) ;
275+ }
276+ } ) ;
301277 } ) ;
302278 }
303279 } ;
280+ function isTabHeading ( node ) {
281+ return node . tagName && (
282+ node . hasAttribute ( 'tab-heading' ) ||
283+ node . hasAttribute ( 'data-tab-heading' ) ||
284+ node . tagName . toLowerCase ( ) === 'tab-heading' ||
285+ node . tagName . toLowerCase ( ) === 'data-tab-heading'
286+ ) ;
287+ }
304288} ] )
305289
306290;
0 commit comments