ApplicationImpl cleanup, part 1:
[chromium-blink-merge.git] / third_party / polymer / v1_0 / components-chromium / paper-drawer-panel / paper-drawer-panel-extracted.js
blob6305886a5ffaf744a0e764134efb57343d9fa42d
3   (function() {
5     'use strict';
7    // this would be the only `paper-drawer-panel` in
8    // the whole app that can be in `dragging` state
9     var sharedPanel = null;
11     function classNames(obj) {
12       var classes = [];
13       for (var key in obj) {
14         if (obj.hasOwnProperty(key) && obj[key]) {
15           classes.push(key);
16         }
17       }
19       return classes.join(' ');
20     }
22     Polymer({
24       is: 'paper-drawer-panel',
26       /**
27        * Fired when the narrow layout changes.
28        *
29        * @event paper-responsive-change {{narrow: boolean}} detail -
30        *     narrow: true if the panel is in narrow layout.
31        */
33       /**
34        * Fired when the a panel is selected.
35        *
36        * Listening for this event is an alternative to observing changes in the `selected` attribute.
37        * This event is fired both when a panel is selected.
38        *
39        * @event iron-select {{item: Object}} detail -
40        *     item: The panel that the event refers to.
41        */
43       /**
44        * Fired when a panel is deselected.
45        *
46        * Listening for this event is an alternative to observing changes in the `selected` attribute.
47        * This event is fired both when a panel is deselected.
48        *
49        * @event iron-deselect {{item: Object}} detail -
50        *     item: The panel that the event refers to.
51        */
52       properties: {
54         /**
55          * The panel to be selected when `paper-drawer-panel` changes to narrow
56          * layout.
57          */
58         defaultSelected: {
59           type: String,
60           value: 'main'
61         },
63         /**
64          * If true, swipe from the edge is disable.
65          */
66         disableEdgeSwipe: {
67           type: Boolean,
68           value: false
69         },
71         /**
72          * If true, swipe to open/close the drawer is disabled.
73          */
74         disableSwipe: {
75           type: Boolean,
76           value: false
77         },
79         /**
80          * Whether the user is dragging the drawer interactively.
81          */
82         dragging: {
83           type: Boolean,
84           value: false,
85           readOnly: true,
86           notify: true
87         },
89         /**
90          * Width of the drawer panel.
91          */
92         drawerWidth: {
93           type: String,
94           value: '256px'
95         },
97         /**
98          * How many pixels on the side of the screen are sensitive to edge
99          * swipes and peek.
100          */
101         edgeSwipeSensitivity: {
102           type: Number,
103           value: 30
104         },
106         /**
107          * If true, ignore `responsiveWidth` setting and force the narrow layout.
108          */
109         forceNarrow: {
110           type: Boolean,
111           value: false
112         },
114         /**
115          * Whether the browser has support for the transform CSS property.
116          */
117         hasTransform: {
118           type: Boolean,
119           value: function() {
120             return 'transform' in this.style;
121           }
122         },
124         /**
125          * Whether the browser has support for the will-change CSS property.
126          */
127         hasWillChange: {
128           type: Boolean,
129           value: function() {
130             return 'willChange' in this.style;
131           }
132         },
134         /**
135          * Returns true if the panel is in narrow layout.  This is useful if you
136          * need to show/hide elements based on the layout.
137          */
138         narrow: {
139           reflectToAttribute: true,
140           type: Boolean,
141           value: false,
142           readOnly: true,
143           notify: true
144         },
146         /**
147          * Whether the drawer is peeking out from the edge.
148          */
149         peeking: {
150           type: Boolean,
151           value: false,
152           readOnly: true,
153           notify: true
154         },
156         /**
157          * Max-width when the panel changes to narrow layout.
158          */
159         responsiveWidth: {
160           type: String,
161           value: '640px'
162         },
164         /**
165          * If true, position the drawer to the right.
166          */
167         rightDrawer: {
168           type: Boolean,
169           value: false
170         },
172         /**
173          * The panel that is being selected. `drawer` for the drawer panel and
174          * `main` for the main panel.
175          */
176         selected: {
177           reflectToAttribute: true,
178           notify: true,
179           type: String,
180           value: null
181         },
183         /**
184          * The attribute on elements that should toggle the drawer on tap, also elements will
185          * automatically be hidden in wide layout.
186          */
187         drawerToggleAttribute: {
188           type: String,
189           value: 'paper-drawer-toggle'
190         },
192         /**
193          * Whether the transition is enabled.
194          */
195         transition: {
196           type: Boolean,
197           value: false
198         },
200       },
202       listeners: {
203         tap: '_onTap',
204         track: '_onTrack',
205         down: '_downHandler',
206         up: '_upHandler'
207       },
209       observers: [
210         '_forceNarrowChanged(forceNarrow, defaultSelected)'
211       ],
213       /**
214        * Toggles the panel open and closed.
215        *
216        * @method togglePanel
217        */
218       togglePanel: function() {
219         if (this._isMainSelected()) {
220           this.openDrawer();
221         } else {
222           this.closeDrawer();
223         }
224       },
226       /**
227        * Opens the drawer.
228        *
229        * @method openDrawer
230        */
231       openDrawer: function() {
232         this.selected = 'drawer';
233       },
235       /**
236        * Closes the drawer.
237        *
238        * @method closeDrawer
239        */
240       closeDrawer: function() {
241         this.selected = 'main';
242       },
244       ready: function() {
245         // Avoid transition at the beginning e.g. page loads and enable
246         // transitions only after the element is rendered and ready.
247         this.transition = true;
248       },
250       _computeIronSelectorClass: function(narrow, transition, dragging, rightDrawer, peeking) {
251         return classNames({
252           dragging: dragging,
253           'narrow-layout': narrow,
254           'right-drawer': rightDrawer,
255           'left-drawer': !rightDrawer,
256           transition: transition,
257           peeking: peeking
258         });
259       },
261       _computeDrawerStyle: function(drawerWidth) {
262         return 'width:' + drawerWidth + ';';
263       },
265       _computeMainStyle: function(narrow, rightDrawer, drawerWidth) {
266         var style = '';
268         style += 'left:' + ((narrow || rightDrawer) ? '0' : drawerWidth) + ';';
270         if (rightDrawer) {
271           style += 'right:' + (narrow ? '' : drawerWidth) + ';';
272         }
274         return style;
275       },
277       _computeMediaQuery: function(forceNarrow, responsiveWidth) {
278         return forceNarrow ? '' : '(max-width: ' + responsiveWidth + ')';
279       },
281       _computeSwipeOverlayHidden: function(narrow, disableEdgeSwipe) {
282         return !narrow || disableEdgeSwipe;
283       },
285       _onTrack: function(event) {
286         if (sharedPanel && this !== sharedPanel) {
287           return;
288         }
289         switch (event.detail.state) {
290           case 'start':
291             this._trackStart(event);
292             break;
293           case 'track':
294             this._trackX(event);
295             break;
296           case 'end':
297             this._trackEnd(event);
298             break;
299         }
301       },
303       _responsiveChange: function(narrow) {
304         this._setNarrow(narrow);
306         if (this.narrow) {
307           this.selected = this.defaultSelected;
308         }
310         this.setScrollDirection(this._swipeAllowed() ? 'y' : 'all');
311         this.fire('paper-responsive-change', {narrow: this.narrow});
312       },
314       _onQueryMatchesChanged: function(event) {
315         this._responsiveChange(event.detail.value);
316       },
318       _forceNarrowChanged: function() {
319         // set the narrow mode only if we reached the `responsiveWidth`
320         this._responsiveChange(this.forceNarrow || this.$.mq.queryMatches);
321       },
323       _swipeAllowed: function() {
324         return this.narrow && !this.disableSwipe;
325       },
327       _isMainSelected: function() {
328         return this.selected === 'main';
329       },
331       _startEdgePeek: function() {
332         this.width = this.$.drawer.offsetWidth;
333         this._moveDrawer(this._translateXForDeltaX(this.rightDrawer ?
334             -this.edgeSwipeSensitivity : this.edgeSwipeSensitivity));
335         this._setPeeking(true);
336       },
338       _stopEdgePeek: function() {
339         if (this.peeking) {
340           this._setPeeking(false);
341           this._moveDrawer(null);
342         }
343       },
345       _downHandler: function(event) {
346         if (!this.dragging && this._isMainSelected() && this._isEdgeTouch(event) && !sharedPanel) {
347           this._startEdgePeek();
348           // cancel selection
349           event.preventDefault();
350           // grab this panel
351           sharedPanel = this;
352         }
353       },
355       _upHandler: function() {
356         this._stopEdgePeek();
357         // release the panel
358         sharedPanel = null;
359       },
361       _onTap: function(event) {
362         var targetElement = Polymer.dom(event).localTarget;
363         var isTargetToggleElement = targetElement &&
364           this.drawerToggleAttribute &&
365           targetElement.hasAttribute(this.drawerToggleAttribute);
367         if (isTargetToggleElement) {
368           this.togglePanel();
369         }
370       },
372       _isEdgeTouch: function(event) {
373         var x = event.detail.x;
375         return !this.disableEdgeSwipe && this._swipeAllowed() &&
376           (this.rightDrawer ?
377             x >= this.offsetWidth - this.edgeSwipeSensitivity :
378             x <= this.edgeSwipeSensitivity);
379       },
381       _trackStart: function(event) {
382         if (this._swipeAllowed()) {
383           sharedPanel = this;
384           this._setDragging(true);
386           if (this._isMainSelected()) {
387             this._setDragging(this.peeking || this._isEdgeTouch(event));
388           }
390           if (this.dragging) {
391             this.width = this.$.drawer.offsetWidth;
392             this.transition = false;
393           }
394         }
395       },
397       _translateXForDeltaX: function(deltaX) {
398         var isMain = this._isMainSelected();
400         if (this.rightDrawer) {
401           return Math.max(0, isMain ? this.width + deltaX : deltaX);
402         } else {
403           return Math.min(0, isMain ? deltaX - this.width : deltaX);
404         }
405       },
407       _trackX: function(event) {
408         if (this.dragging) {
409           var dx = event.detail.dx;
411           if (this.peeking) {
412             if (Math.abs(dx) <= this.edgeSwipeSensitivity) {
413               // Ignore trackx until we move past the edge peek.
414               return;
415             }
416             this._setPeeking(false);
417           }
419           this._moveDrawer(this._translateXForDeltaX(dx));
420         }
421       },
423       _trackEnd: function(event) {
424         if (this.dragging) {
425           var xDirection = event.detail.dx > 0;
427           this._setDragging(false);
428           this.transition = true;
429           sharedPanel = null;
430           this._moveDrawer(null);
432           if (this.rightDrawer) {
433             this[xDirection ? 'closeDrawer' : 'openDrawer']();
434           } else {
435             this[xDirection ? 'openDrawer' : 'closeDrawer']();
436           }
437         }
438       },
440       _transformForTranslateX: function(translateX) {
441         if (translateX === null) {
442           return '';
443         }
445         return this.hasWillChange ? 'translateX(' + translateX + 'px)' :
446             'translate3d(' + translateX + 'px, 0, 0)';
447       },
449       _moveDrawer: function(translateX) {
450         this.transform(this._transformForTranslateX(translateX), this.$.drawer);
451       }
453     });
455   }());