@@ -15,20 +15,16 @@ angular.module('ui.bootstrap.tabs', [])
15
15
} ;
16
16
} )
17
17
18
- . controller ( 'TabsetController' , [ '$scope' , '$element' ,
18
+ . controller ( 'TabsetController' , [ '$scope' , '$element' ,
19
19
function TabsetCtrl ( $scope , $element ) {
20
20
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
-
25
21
var ctrl = this ,
26
22
tabs = ctrl . tabs = $scope . tabs = [ ] ;
27
23
28
24
ctrl . select = function ( tab ) {
29
25
angular . forEach ( tabs , function ( tab ) {
30
26
tab . active = false ;
31
- } ) ;
27
+ } ) ;
32
28
tab . active = true ;
33
29
} ;
34
30
@@ -39,7 +35,7 @@ function TabsetCtrl($scope, $element) {
39
35
}
40
36
} ;
41
37
42
- ctrl . removeTab = function removeTab ( tab ) {
38
+ ctrl . removeTab = function removeTab ( tab ) {
43
39
var index = tabs . indexOf ( tab ) ;
44
40
//Select a new tab if the tab to be removed is selected
45
41
if ( tab . active && tabs . length > 1 ) {
@@ -101,7 +97,7 @@ function TabsetCtrl($scope, $element) {
101
97
* @param {boolean= } active A binding, telling whether or not this tab is selected.
102
98
* @param {boolean= } disabled A binding, telling whether or not this tab is disabled.
103
99
*
104
- * @description
100
+ * @description
105
101
* Creates a tab with a heading and content. Must be placed within a {@link ui.bootstrap.tabs.directive:tabset tabset}.
106
102
*
107
103
* @example
@@ -235,37 +231,11 @@ function($parse, $http, $templateCache, $compile) {
235
231
//value won't overwrite what is initially set by the tabset
236
232
if ( scope . active ) {
237
233
setActive ( scope . $parent , true ) ;
238
- }
234
+ }
239
235
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 ;
269
239
} ;
270
240
}
271
241
} ;
@@ -274,7 +244,7 @@ function($parse, $http, $templateCache, $compile) {
274
244
. directive ( 'tabHeadingTransclude' , [ function ( ) {
275
245
return {
276
246
restrict : 'A' ,
277
- require : '^tab' ,
247
+ require : '^tab' ,
278
248
link : function ( scope , elm , attrs , tabCtrl ) {
279
249
scope . $watch ( 'headingElement' , function updateHeadingElement ( heading ) {
280
250
if ( heading ) {
@@ -290,17 +260,31 @@ function($parse, $http, $templateCache, $compile) {
290
260
return {
291
261
restrict : 'A' ,
292
262
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
+ } ) ;
301
277
} ) ;
302
278
}
303
279
} ;
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
+ }
304
288
} ] )
305
289
306
290
;
0 commit comments