forked from ionic-team/ionic-framework
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtab.js
204 lines (181 loc) · 7.34 KB
/
tab.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/**
* @ngdoc directive
* @name ionTab
* @module ionic
* @restrict E
* @parent ionic.directive:ionTabs
*
* @description
* Contains a tab's content. The content only exists while the given tab is selected.
*
* Each ionTab has its own view history.
*
* @usage
* ```html
* <ion-tab
* title="Tab!"
* icon="my-icon"
* href="#/tab/tab-link"
* on-select="onTabSelected()"
* on-deselect="onTabDeselected()">
* </ion-tab>
* ```
* For a complete, working tab bar example, see the {@link ionic.directive:ionTabs} documentation.
*
* @param {string} title The title of the tab.
* @param {string=} href The link that this tab will navigate to when tapped.
* @param {string=} icon The icon of the tab. If given, this will become the default for icon-on and icon-off.
* @param {string=} icon-on The icon of the tab while it is selected.
* @param {string=} icon-off The icon of the tab while it is not selected.
* @param {expression=} badge The badge to put on this tab (usually a number).
* @param {expression=} badge-style The style of badge to put on this tab (eg: badge-positive).
* @param {expression=} on-select Called when this tab is selected.
* @param {expression=} on-deselect Called when this tab is deselected.
* @param {expression=} ng-click By default, the tab will be selected on click. If ngClick is set, it will not. You can explicitly switch tabs using {@link ionic.service:$ionicTabsDelegate#select $ionicTabsDelegate.select()}.
* @param {expression=} hidden Whether the tab is to be hidden or not.
* @param {expression=} disabled Whether the tab is to be disabled or not.
*/
IonicModule
.directive('ionTab', [
'$compile',
'$ionicConfig',
'$ionicBind',
'$ionicViewSwitcher',
function($compile, $ionicConfig, $ionicBind, $ionicViewSwitcher) {
//Returns ' key="value"' if value exists
function attrStr(k, v) {
return isDefined(v) ? ' ' + k + '="' + v + '"' : '';
}
return {
restrict: 'E',
require: ['^ionTabs', 'ionTab'],
controller: '$ionicTab',
scope: true,
compile: function(element, attr) {
//We create the tabNavTemplate in the compile phase so that the
//attributes we pass down won't be interpolated yet - we want
//to pass down the 'raw' versions of the attributes
var tabNavTemplate = '<ion-tab-nav' +
attrStr('ng-click', attr.ngClick) +
attrStr('title', attr.title) +
attrStr('icon', attr.icon) +
attrStr('icon-on', attr.iconOn) +
attrStr('icon-off', attr.iconOff) +
attrStr('badge', attr.badge) +
attrStr('badge-style', attr.badgeStyle) +
attrStr('hidden', attr.hidden) +
attrStr('disabled', attr.disabled) +
attrStr('class', attr['class']) +
'></ion-tab-nav>';
//Remove the contents of the element so we can compile them later, if tab is selected
var tabContentEle = document.createElement('div');
for (var x = 0; x < element[0].children.length; x++) {
tabContentEle.appendChild(element[0].children[x].cloneNode(true));
}
var childElementCount = tabContentEle.childElementCount;
element.empty();
var navViewName, isNavView;
if (childElementCount) {
if (tabContentEle.children[0].tagName === 'ION-NAV-VIEW') {
// get the name if it's a nav-view
navViewName = tabContentEle.children[0].getAttribute('name');
tabContentEle.children[0].classList.add('view-container');
isNavView = true;
}
if (childElementCount === 1) {
// make the 1 child element the primary tab content container
tabContentEle = tabContentEle.children[0];
}
if (!isNavView) tabContentEle.classList.add('pane');
tabContentEle.classList.add('tab-content');
}
return function link($scope, $element, $attr, ctrls) {
var childScope;
var childElement;
var tabsCtrl = ctrls[0];
var tabCtrl = ctrls[1];
var isTabContentAttached = false;
$scope.$tabSelected = false;
$ionicBind($scope, $attr, {
onSelect: '&',
onDeselect: '&',
title: '@',
uiSref: '@',
href: '@'
});
tabsCtrl.add($scope);
$scope.$on('$destroy', function() {
if (!$scope.$tabsDestroy) {
// if the containing ionTabs directive is being destroyed
// then don't bother going through the controllers remove
// method, since remove will reset the active tab as each tab
// is being destroyed, causing unnecessary view loads and transitions
tabsCtrl.remove($scope);
}
tabNavElement.isolateScope().$destroy();
tabNavElement.remove();
tabNavElement = tabContentEle = childElement = null;
});
//Remove title attribute so browser-tooltip does not apear
$element[0].removeAttribute('title');
if (navViewName) {
tabCtrl.navViewName = $scope.navViewName = navViewName;
}
$scope.$on('$stateChangeSuccess', selectIfMatchesState);
selectIfMatchesState();
function selectIfMatchesState() {
if (tabCtrl.tabMatchesState()) {
tabsCtrl.select($scope, false);
}
}
var tabNavElement = jqLite(tabNavTemplate);
tabNavElement.data('$ionTabsController', tabsCtrl);
tabNavElement.data('$ionTabController', tabCtrl);
tabsCtrl.$tabsElement.append($compile(tabNavElement)($scope));
function tabSelected(isSelected) {
if (isSelected && childElementCount) {
// this tab is being selected
// check if the tab is already in the DOM
// only do this if the tab has child elements
if (!isTabContentAttached) {
// tab should be selected and is NOT in the DOM
// create a new scope and append it
childScope = $scope.$new();
childElement = jqLite(tabContentEle);
$ionicViewSwitcher.viewEleIsActive(childElement, true);
tabsCtrl.$element.append(childElement);
$compile(childElement)(childScope);
isTabContentAttached = true;
}
// remove the hide class so the tabs content shows up
$ionicViewSwitcher.viewEleIsActive(childElement, true);
} else if (isTabContentAttached && childElement) {
// this tab should NOT be selected, and it is already in the DOM
if ($ionicConfig.views.maxCache() > 0) {
// keep the tabs in the DOM, only css hide it
$ionicViewSwitcher.viewEleIsActive(childElement, false);
} else {
// do not keep tabs in the DOM
destroyTab();
}
}
}
function destroyTab() {
childScope && childScope.$destroy();
isTabContentAttached && childElement && childElement.remove();
tabContentEle.innerHTML = '';
isTabContentAttached = childScope = childElement = null;
}
$scope.$watch('$tabSelected', tabSelected);
$scope.$on('$ionicView.afterEnter', function() {
$ionicViewSwitcher.viewEleIsActive(childElement, $scope.$tabSelected);
});
$scope.$on('$ionicView.clearCache', function() {
if (!$scope.$tabSelected) {
destroyTab();
}
});
};
}
};
}]);