Service workers: Allow HTTPS pages arrived at via HTTP redirect to use SW
[chromium-blink-merge.git] / third_party / polymer / v1_0 / components-chromium / paper-tabs / paper-tabs-extracted.js
blobbc09ae6365be0d0781ab74b982e4ba23bf5617bb
1 Polymer({
3     is: 'paper-tabs',
5     behaviors: [
6       Polymer.IronResizableBehavior,
7       Polymer.IronMenubarBehavior
8     ],
10     properties: {
12       /**
13        * If true, ink ripple effect is disabled.
14        */
15       noink: {
16         type: Boolean,
17         value: false
18       },
20       /**
21        * If true, the bottom bar to indicate the selected tab will not be shown.
22        */
23       noBar: {
24         type: Boolean,
25         value: false
26       },
28       /**
29        * If true, the slide effect for the bottom bar is disabled.
30        */
31       noSlide: {
32         type: Boolean,
33         value: false
34       },
36       /**
37        * If true, tabs are scrollable and the tab width is based on the label width.
38        */
39       scrollable: {
40         type: Boolean,
41         value: false
42       },
44       /**
45        * If true, dragging on the tabs to scroll is disabled.
46        */
47       disableDrag: {
48         type: Boolean,
49         value: false
50       },
52       /**
53        * If true, scroll buttons (left/right arrow) will be hidden for scrollable tabs.
54        */
55       hideScrollButtons: {
56         type: Boolean,
57         value: false
58       },
60       /**
61        * If true, the tabs are aligned to bottom (the selection bar appears at the top).
62        */
63       alignBottom: {
64         type: Boolean,
65         value: false
66       },
68       /**
69        * Gets or sets the selected element. The default is to use the index of the item.
70        */
71       selected: {
72         type: String,
73         notify: true
74       },
76       selectable: {
77         type: String,
78         value: 'paper-tab'
79       },
81       _step: {
82         type: Number,
83         value: 10
84       },
86       _holdDelay: {
87         type: Number,
88         value: 1
89       },
91       _leftHidden: {
92         type: Boolean,
93         value: false
94       },
96       _rightHidden: {
97         type: Boolean,
98         value: false
99       },
101       _previousTab: {
102         type: Object
103       }
104     },
106     hostAttributes: {
107       role: 'tablist'
108     },
110     listeners: {
111       'iron-resize': '_onResize',
112       'iron-select': '_onIronSelect',
113       'iron-deselect': '_onIronDeselect'
114     },
116     _computeScrollButtonClass: function(hideThisButton, scrollable, hideScrollButtons) {
117       if (!scrollable || hideScrollButtons) {
118         return 'hidden';
119       }
121       if (hideThisButton) {
122         return 'not-visible';
123       }
125       return '';
126     },
128     _computeTabsContentClass: function(scrollable) {
129       return scrollable ? 'scrollable' : 'horizontal layout';
130     },
132     _computeSelectionBarClass: function(noBar, alignBottom) {
133       if (noBar) {
134         return 'hidden';
135       } else if (alignBottom) {
136         return 'align-bottom';
137       }
138     },
140     // TODO(cdata): Add `track` response back in when gesture lands.
142     _onResize: function() {
143       this.debounce('_onResize', function() {
144         this._scroll();
145         this._tabChanged(this.selectedItem);
146       }, 10);
147     },
149     _onIronSelect: function(event) {
150       this._tabChanged(event.detail.item, this._previousTab);
151       this._previousTab = event.detail.item;
152       this.cancelDebouncer('tab-changed');
153     },
155     _onIronDeselect: function(event) {
156       this.debounce('tab-changed', function() {
157         this._tabChanged(null, this._previousTab);
158       // See polymer/polymer#1305
159       }, 1);
160     },
162     get _tabContainerScrollSize () {
163       return Math.max(
164         0,
165         this.$.tabsContainer.scrollWidth -
166           this.$.tabsContainer.offsetWidth
167       );
168     },
170     _scroll: function() {
171       var scrollLeft;
173       if (!this.scrollable) {
174         return;
175       }
177       scrollLeft = this.$.tabsContainer.scrollLeft;
179       this._leftHidden = scrollLeft === 0;
180       this._rightHidden = scrollLeft === this._tabContainerScrollSize;
181     },
183     _onLeftScrollButtonDown: function() {
184       this._holdJob = setInterval(this._scrollToLeft.bind(this), this._holdDelay);
185     },
187     _onRightScrollButtonDown: function() {
188       this._holdJob = setInterval(this._scrollToRight.bind(this), this._holdDelay);
189     },
191     _onScrollButtonUp: function() {
192       clearInterval(this._holdJob);
193       this._holdJob = null;
194     },
196     _scrollToLeft: function() {
197       this.$.tabsContainer.scrollLeft -= this._step;
198     },
200     _scrollToRight: function() {
201       this.$.tabsContainer.scrollLeft += this._step;
202     },
204     _tabChanged: function(tab, old) {
205       if (!tab) {
206         this._positionBar(0, 0);
207         return;
208       }
210       var r = this.$.tabsContent.getBoundingClientRect();
211       var w = r.width;
212       var tabRect = tab.getBoundingClientRect();
213       var tabOffsetLeft = tabRect.left - r.left;
215       this._pos = {
216         width: this._calcPercent(tabRect.width, w),
217         left: this._calcPercent(tabOffsetLeft, w)
218       };
220       if (this.noSlide || old == null) {
221         // position bar directly without animation
222         this._positionBar(this._pos.width, this._pos.left);
223         return;
224       }
226       var oldRect = old.getBoundingClientRect();
227       var oldIndex = this.items.indexOf(old);
228       var index = this.items.indexOf(tab);
229       var m = 5;
231       // bar animation: expand
232       this.$.selectionBar.classList.add('expand');
234       if (oldIndex < index) {
235         this._positionBar(this._calcPercent(tabRect.left + tabRect.width - oldRect.left, w) - m,
236             this._left);
237       } else {
238         this._positionBar(this._calcPercent(oldRect.left + oldRect.width - tabRect.left, w) - m,
239             this._calcPercent(tabOffsetLeft, w) + m);
240       }
242       if (this.scrollable) {
243         this._scrollToSelectedIfNeeded(tabRect.width, tabOffsetLeft);
244       }
245     },
247     _scrollToSelectedIfNeeded: function(tabWidth, tabOffsetLeft) {
248       var l = tabOffsetLeft - this.$.tabsContainer.scrollLeft;
249       if (l < 0) {
250         this.$.tabsContainer.scrollLeft += l;
251       } else {
252         l += (tabWidth - this.$.tabsContainer.offsetWidth);
253         if (l > 0) {
254           this.$.tabsContainer.scrollLeft += l;
255         }
256       }
257     },
259     _calcPercent: function(w, w0) {
260       return 100 * w / w0;
261     },
263     _positionBar: function(width, left) {
264       width = width || 0;
265       left = left || 0;
267       this._width = width;
268       this._left = left;
269       this.transform(
270           'translate3d(' + left + '%, 0, 0) scaleX(' + (width / 100) + ')',
271           this.$.selectionBar);
272     },
274     _onBarTransitionEnd: function(e) {
275       var cl = this.$.selectionBar.classList;
276       // bar animation: expand -> contract
277       if (cl.contains('expand')) {
278         cl.remove('expand');
279         cl.add('contract');
280         this._positionBar(this._pos.width, this._pos.left);
281       // bar animation done
282       } else if (cl.contains('contract')) {
283         cl.remove('contract');
284       }
285     }
287   });