Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / third_party / polymer / v1_0 / components-chromium / paper-tabs / paper-tabs-extracted.js
blobaaf1b8f6cb191f217272f243cd50c86a115f46d9
3 Polymer({
5 is: 'paper-tabs',
7 behaviors: [
8 Polymer.IronResizableBehavior,
9 Polymer.IronMenubarBehavior
12 properties: {
14 /**
15 * If true, ink ripple effect is disabled.
17 noink: {
18 type: Boolean,
19 value: false
22 /**
23 * If true, the bottom bar to indicate the selected tab will not be shown.
25 noBar: {
26 type: Boolean,
27 value: false
30 /**
31 * If true, the slide effect for the bottom bar is disabled.
33 noSlide: {
34 type: Boolean,
35 value: false
38 /**
39 * If true, tabs are scrollable and the tab width is based on the label width.
41 scrollable: {
42 type: Boolean,
43 value: false
46 /**
47 * If true, dragging on the tabs to scroll is disabled.
49 disableDrag: {
50 type: Boolean,
51 value: false
54 /**
55 * If true, scroll buttons (left/right arrow) will be hidden for scrollable tabs.
57 hideScrollButtons: {
58 type: Boolean,
59 value: false
62 /**
63 * If true, the tabs are aligned to bottom (the selection bar appears at the top).
65 alignBottom: {
66 type: Boolean,
67 value: false
70 /**
71 * Gets or sets the selected element. The default is to use the index of the item.
73 selected: {
74 type: String,
75 notify: true
78 selectable: {
79 type: String,
80 value: 'paper-tab'
83 _step: {
84 type: Number,
85 value: 10
88 _holdDelay: {
89 type: Number,
90 value: 1
93 _leftHidden: {
94 type: Boolean,
95 value: false
98 _rightHidden: {
99 type: Boolean,
100 value: false
103 _previousTab: {
104 type: Object
108 hostAttributes: {
109 role: 'tablist'
112 listeners: {
113 'iron-resize': '_onResize',
114 'iron-select': '_onIronSelect',
115 'iron-deselect': '_onIronDeselect'
118 _computeScrollButtonClass: function(hideThisButton, scrollable, hideScrollButtons) {
119 if (!scrollable || hideScrollButtons) {
120 return 'hidden';
123 if (hideThisButton) {
124 return 'not-visible';
127 return '';
130 _computeTabsContentClass: function(scrollable) {
131 return scrollable ? 'scrollable' : 'horizontal layout';
134 _computeSelectionBarClass: function(noBar, alignBottom) {
135 if (noBar) {
136 return 'hidden';
137 } else if (alignBottom) {
138 return 'align-bottom';
142 // TODO(cdata): Add `track` response back in when gesture lands.
144 _onResize: function() {
145 this.debounce('_onResize', function() {
146 this._scroll();
147 this._tabChanged(this.selectedItem);
148 }, 10);
151 _onIronSelect: function(event) {
152 this._tabChanged(event.detail.item, this._previousTab);
153 this._previousTab = event.detail.item;
154 this.cancelDebouncer('tab-changed');
157 _onIronDeselect: function(event) {
158 this.debounce('tab-changed', function() {
159 this._tabChanged(null, this._previousTab);
160 // See polymer/polymer#1305
161 }, 1);
164 get _tabContainerScrollSize () {
165 return Math.max(
167 this.$.tabsContainer.scrollWidth -
168 this.$.tabsContainer.offsetWidth
172 _scroll: function() {
173 var scrollLeft;
175 if (!this.scrollable) {
176 return;
179 scrollLeft = this.$.tabsContainer.scrollLeft;
181 this._leftHidden = scrollLeft === 0;
182 this._rightHidden = scrollLeft === this._tabContainerScrollSize;
185 _onLeftScrollButtonDown: function() {
186 this._holdJob = setInterval(this._scrollToLeft.bind(this), this._holdDelay);
189 _onRightScrollButtonDown: function() {
190 this._holdJob = setInterval(this._scrollToRight.bind(this), this._holdDelay);
193 _onScrollButtonUp: function() {
194 clearInterval(this._holdJob);
195 this._holdJob = null;
198 _scrollToLeft: function() {
199 this.$.tabsContainer.scrollLeft -= this._step;
202 _scrollToRight: function() {
203 this.$.tabsContainer.scrollLeft += this._step;
206 _tabChanged: function(tab, old) {
207 if (!tab) {
208 this._positionBar(0, 0);
209 return;
212 var r = this.$.tabsContent.getBoundingClientRect();
213 var w = r.width;
214 var tabRect = tab.getBoundingClientRect();
215 var tabOffsetLeft = tabRect.left - r.left;
217 this._pos = {
218 width: this._calcPercent(tabRect.width, w),
219 left: this._calcPercent(tabOffsetLeft, w)
222 if (this.noSlide || old == null) {
223 // position bar directly without animation
224 this._positionBar(this._pos.width, this._pos.left);
225 return;
228 var oldRect = old.getBoundingClientRect();
229 var oldIndex = this.items.indexOf(old);
230 var index = this.items.indexOf(tab);
231 var m = 5;
233 // bar animation: expand
234 this.$.selectionBar.classList.add('expand');
236 if (oldIndex < index) {
237 this._positionBar(this._calcPercent(tabRect.left + tabRect.width - oldRect.left, w) - m,
238 this._left);
239 } else {
240 this._positionBar(this._calcPercent(oldRect.left + oldRect.width - tabRect.left, w) - m,
241 this._calcPercent(tabOffsetLeft, w) + m);
244 if (this.scrollable) {
245 this._scrollToSelectedIfNeeded(tabRect.width, tabOffsetLeft);
249 _scrollToSelectedIfNeeded: function(tabWidth, tabOffsetLeft) {
250 var l = tabOffsetLeft - this.$.tabsContainer.scrollLeft;
251 if (l < 0) {
252 this.$.tabsContainer.scrollLeft += l;
253 } else {
254 l += (tabWidth - this.$.tabsContainer.offsetWidth);
255 if (l > 0) {
256 this.$.tabsContainer.scrollLeft += l;
261 _calcPercent: function(w, w0) {
262 return 100 * w / w0;
265 _positionBar: function(width, left) {
266 width = width || 0;
267 left = left || 0;
269 this._width = width;
270 this._left = left;
271 this.transform(
272 'translate3d(' + left + '%, 0, 0) scaleX(' + (width / 100) + ')',
273 this.$.selectionBar);
276 _onBarTransitionEnd: function(e) {
277 var cl = this.$.selectionBar.classList;
278 // bar animation: expand -> contract
279 if (cl.contains('expand')) {
280 cl.remove('expand');
281 cl.add('contract');
282 this._positionBar(this._pos.width, this._pos.left);
283 // bar animation done
284 } else if (cl.contains('contract')) {
285 cl.remove('contract');