| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @fileoverview Assertion support. | 6 * @fileoverview Assertion support. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 /** | 9 /** |
| 10 * Verify |condition| is truthy and return |condition| if so. | 10 * Verify |condition| is truthy and return |condition| if so. |
| (...skipping 5615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5626 | 5626 |
| 5627 }; | 5627 }; |
| 5628 | 5628 |
| 5629 /** @polymerBehavior Polymer.PaperInkyFocusBehavior */ | 5629 /** @polymerBehavior Polymer.PaperInkyFocusBehavior */ |
| 5630 Polymer.PaperInkyFocusBehavior = [ | 5630 Polymer.PaperInkyFocusBehavior = [ |
| 5631 Polymer.IronButtonState, | 5631 Polymer.IronButtonState, |
| 5632 Polymer.IronControlState, | 5632 Polymer.IronControlState, |
| 5633 Polymer.PaperRippleBehavior, | 5633 Polymer.PaperRippleBehavior, |
| 5634 Polymer.PaperInkyFocusBehaviorImpl | 5634 Polymer.PaperInkyFocusBehaviorImpl |
| 5635 ]; | 5635 ]; |
| 5636 Polymer({ | |
| 5637 is: 'paper-material', | |
| 5638 | |
| 5639 properties: { | |
| 5640 /** | |
| 5641 * The z-depth of this element, from 0-5. Setting to 0 will remove the | |
| 5642 * shadow, and each increasing number greater than 0 will be "deeper" | |
| 5643 * than the last. | |
| 5644 * | |
| 5645 * @attribute elevation | |
| 5646 * @type number | |
| 5647 * @default 1 | |
| 5648 */ | |
| 5649 elevation: { | |
| 5650 type: Number, | |
| 5651 reflectToAttribute: true, | |
| 5652 value: 1 | |
| 5653 }, | |
| 5654 | |
| 5655 /** | |
| 5656 * Set this to true to animate the shadow when setting a new | |
| 5657 * `elevation` value. | |
| 5658 * | |
| 5659 * @attribute animated | |
| 5660 * @type boolean | |
| 5661 * @default false | |
| 5662 */ | |
| 5663 animated: { | |
| 5664 type: Boolean, | |
| 5665 reflectToAttribute: true, | |
| 5666 value: false | |
| 5667 } | |
| 5668 } | |
| 5669 }); | |
| 5670 /** @polymerBehavior Polymer.PaperButtonBehavior */ | 5636 /** @polymerBehavior Polymer.PaperButtonBehavior */ |
| 5671 Polymer.PaperButtonBehaviorImpl = { | 5637 Polymer.PaperButtonBehaviorImpl = { |
| 5672 | 5638 |
| 5673 properties: { | 5639 properties: { |
| 5674 | 5640 |
| 5675 /** | 5641 /** |
| 5676 * The z-depth of this element, from 0-5. Setting to 0 will remove the | 5642 * The z-depth of this element, from 0-5. Setting to 0 will remove the |
| 5677 * shadow, and each increasing number greater than 0 will be "deeper" | 5643 * shadow, and each increasing number greater than 0 will be "deeper" |
| 5678 * than the last. | 5644 * than the last. |
| 5679 * | 5645 * |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5746 }; | 5712 }; |
| 5747 | 5713 |
| 5748 /** @polymerBehavior */ | 5714 /** @polymerBehavior */ |
| 5749 Polymer.PaperButtonBehavior = [ | 5715 Polymer.PaperButtonBehavior = [ |
| 5750 Polymer.IronButtonState, | 5716 Polymer.IronButtonState, |
| 5751 Polymer.IronControlState, | 5717 Polymer.IronControlState, |
| 5752 Polymer.PaperRippleBehavior, | 5718 Polymer.PaperRippleBehavior, |
| 5753 Polymer.PaperButtonBehaviorImpl | 5719 Polymer.PaperButtonBehaviorImpl |
| 5754 ]; | 5720 ]; |
| 5755 Polymer({ | 5721 Polymer({ |
| 5756 is: 'paper-button', | 5722 is: 'paper-material', |
| 5757 | |
| 5758 behaviors: [ | |
| 5759 Polymer.PaperButtonBehavior | |
| 5760 ], | |
| 5761 | 5723 |
| 5762 properties: { | 5724 properties: { |
| 5763 /** | 5725 /** |
| 5764 * If true, the button should be styled with a shadow. | 5726 * The z-depth of this element, from 0-5. Setting to 0 will remove the |
| 5727 * shadow, and each increasing number greater than 0 will be "deeper" |
| 5728 * than the last. |
| 5729 * |
| 5730 * @attribute elevation |
| 5731 * @type number |
| 5732 * @default 1 |
| 5765 */ | 5733 */ |
| 5766 raised: { | 5734 elevation: { |
| 5735 type: Number, |
| 5736 reflectToAttribute: true, |
| 5737 value: 1 |
| 5738 }, |
| 5739 |
| 5740 /** |
| 5741 * Set this to true to animate the shadow when setting a new |
| 5742 * `elevation` value. |
| 5743 * |
| 5744 * @attribute animated |
| 5745 * @type boolean |
| 5746 * @default false |
| 5747 */ |
| 5748 animated: { |
| 5767 type: Boolean, | 5749 type: Boolean, |
| 5768 reflectToAttribute: true, | 5750 reflectToAttribute: true, |
| 5769 value: false, | 5751 value: false |
| 5770 observer: '_calculateElevation' | |
| 5771 } | |
| 5772 }, | |
| 5773 | |
| 5774 _calculateElevation: function() { | |
| 5775 if (!this.raised) { | |
| 5776 this._setElevation(0); | |
| 5777 } else { | |
| 5778 Polymer.PaperButtonBehaviorImpl._calculateElevation.apply(this); | |
| 5779 } | 5752 } |
| 5780 } | 5753 } |
| 5781 /** | 5754 }); |
| 5755 Polymer({ |
| 5756 is: 'paper-button', |
| 5782 | 5757 |
| 5783 Fired when the animation finishes. | 5758 behaviors: [ |
| 5784 This is useful if you want to wait until | 5759 Polymer.PaperButtonBehavior |
| 5785 the ripple animation finishes to perform some action. | 5760 ], |
| 5786 | 5761 |
| 5787 @event transitionend | 5762 properties: { |
| 5788 @param {{node: Object}} detail Contains the animated node. | 5763 /** |
| 5789 */ | 5764 * If true, the button should be styled with a shadow. |
| 5790 }); | 5765 */ |
| 5766 raised: { |
| 5767 type: Boolean, |
| 5768 reflectToAttribute: true, |
| 5769 value: false, |
| 5770 observer: '_calculateElevation' |
| 5771 } |
| 5772 }, |
| 5773 |
| 5774 _calculateElevation: function() { |
| 5775 if (!this.raised) { |
| 5776 this._setElevation(0); |
| 5777 } else { |
| 5778 Polymer.PaperButtonBehaviorImpl._calculateElevation.apply(this); |
| 5779 } |
| 5780 } |
| 5781 |
| 5782 /** |
| 5783 Fired when the animation finishes. |
| 5784 This is useful if you want to wait until |
| 5785 the ripple animation finishes to perform some action. |
| 5786 |
| 5787 @event transitionend |
| 5788 Event param: {{node: Object}} detail Contains the animated node. |
| 5789 */ |
| 5790 }); |
| 5791 /** | 5791 /** |
| 5792 * `iron-range-behavior` provides the behavior for something with a minimum to m
aximum range. | 5792 * `iron-range-behavior` provides the behavior for something with a minimum to m
aximum range. |
| 5793 * | 5793 * |
| 5794 * @demo demo/index.html | 5794 * @demo demo/index.html |
| 5795 * @polymerBehavior | 5795 * @polymerBehavior |
| 5796 */ | 5796 */ |
| 5797 Polymer.IronRangeBehavior = { | 5797 Polymer.IronRangeBehavior = { |
| 5798 | 5798 |
| 5799 properties: { | 5799 properties: { |
| 5800 | 5800 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5852 | 5852 |
| 5853 _calcRatio: function(value) { | 5853 _calcRatio: function(value) { |
| 5854 return (this._clampValue(value) - this.min) / (this.max - this.min); | 5854 return (this._clampValue(value) - this.min) / (this.max - this.min); |
| 5855 }, | 5855 }, |
| 5856 | 5856 |
| 5857 _clampValue: function(value) { | 5857 _clampValue: function(value) { |
| 5858 return Math.min(this.max, Math.max(this.min, this._calcStep(value))); | 5858 return Math.min(this.max, Math.max(this.min, this._calcStep(value))); |
| 5859 }, | 5859 }, |
| 5860 | 5860 |
| 5861 _calcStep: function(value) { | 5861 _calcStep: function(value) { |
| 5862 /** | |
| 5863 * if we calculate the step using | |
| 5864 * `Math.round(value / step) * step` we may hit a precision point issue | |
| 5865 * eg. 0.1 * 0.2 = 0.020000000000000004 | |
| 5866 * http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html | |
| 5867 * | |
| 5868 * as a work around we can divide by the reciprocal of `step` | |
| 5869 */ | |
| 5870 // polymer/issues/2493 | 5862 // polymer/issues/2493 |
| 5871 value = parseFloat(value); | 5863 value = parseFloat(value); |
| 5872 return this.step ? (Math.round((value + this.min) / this.step) - | 5864 |
| 5873 (this.min / this.step)) / (1 / this.step) : value; | 5865 if (!this.step) { |
| 5866 return value; |
| 5867 } |
| 5868 |
| 5869 var numSteps = Math.round((value - this.min) / this.step); |
| 5870 if (this.step < 1) { |
| 5871 /** |
| 5872 * For small values of this.step, if we calculate the step using |
| 5873 * `Math.round(value / step) * step` we may hit a precision point issue |
| 5874 * eg. 0.1 * 0.2 = 0.020000000000000004 |
| 5875 * http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html |
| 5876 * |
| 5877 * as a work around we can divide by the reciprocal of `step` |
| 5878 */ |
| 5879 return numSteps / (1 / this.step) + this.min; |
| 5880 } else { |
| 5881 return numSteps * this.step + this.min; |
| 5882 } |
| 5874 }, | 5883 }, |
| 5875 | 5884 |
| 5876 _validateValue: function() { | 5885 _validateValue: function() { |
| 5877 var v = this._clampValue(this.value); | 5886 var v = this._clampValue(this.value); |
| 5878 this.value = this.oldValue = isNaN(v) ? this.oldValue : v; | 5887 this.value = this.oldValue = isNaN(v) ? this.oldValue : v; |
| 5879 return this.value !== v; | 5888 return this.value !== v; |
| 5880 }, | 5889 }, |
| 5881 | 5890 |
| 5882 _update: function() { | 5891 _update: function() { |
| 5883 this._validateValue(); | 5892 this._validateValue(); |
| (...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6618 */ | 6627 */ |
| 6619 | 6628 |
| 6620 /** | 6629 /** |
| 6621 * Fired when an item is deselected | 6630 * Fired when an item is deselected |
| 6622 * | 6631 * |
| 6623 * @event iron-deselect | 6632 * @event iron-deselect |
| 6624 */ | 6633 */ |
| 6625 | 6634 |
| 6626 /** | 6635 /** |
| 6627 * Fired when the list of selectable items changes (e.g., items are | 6636 * Fired when the list of selectable items changes (e.g., items are |
| 6628 * added or removed). The detail of the event is a list of mutation | 6637 * added or removed). The detail of the event is a mutation record that |
| 6629 * records that describe what changed. | 6638 * describes what changed. |
| 6630 * | 6639 * |
| 6631 * @event iron-items-changed | 6640 * @event iron-items-changed |
| 6632 */ | 6641 */ |
| 6633 | 6642 |
| 6634 properties: { | 6643 properties: { |
| 6635 | 6644 |
| 6636 /** | 6645 /** |
| 6637 * If you want to use an attribute value or property of an element for | 6646 * If you want to use an attribute value or property of an element for |
| 6638 * `selected` instead of the index, set this to the name of the attribute | 6647 * `selected` instead of the index, set this to the name of the attribute |
| 6639 * or property. Hyphenated values are converted to camel case when used to | 6648 * or property. Hyphenated values are converted to camel case when used to |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6926 this._selectionChange(); | 6935 this._selectionChange(); |
| 6927 this.fire('iron-' + (isSelected ? 'select' : 'deselect'), {item: item}); | 6936 this.fire('iron-' + (isSelected ? 'select' : 'deselect'), {item: item}); |
| 6928 }, | 6937 }, |
| 6929 | 6938 |
| 6930 _selectionChange: function() { | 6939 _selectionChange: function() { |
| 6931 this._setSelectedItem(this._selection.get()); | 6940 this._setSelectedItem(this._selection.get()); |
| 6932 }, | 6941 }, |
| 6933 | 6942 |
| 6934 // observe items change under the given node. | 6943 // observe items change under the given node. |
| 6935 _observeItems: function(node) { | 6944 _observeItems: function(node) { |
| 6936 return Polymer.dom(node).observeNodes(function(mutations) { | 6945 return Polymer.dom(node).observeNodes(function(mutation) { |
| 6937 this._updateItems(); | 6946 this._updateItems(); |
| 6938 | 6947 |
| 6939 if (this._shouldUpdateSelection) { | 6948 if (this._shouldUpdateSelection) { |
| 6940 this._updateSelected(); | 6949 this._updateSelected(); |
| 6941 } | 6950 } |
| 6942 | 6951 |
| 6943 // Let other interested parties know about the change so that | 6952 // Let other interested parties know about the change so that |
| 6944 // we don't have to recreate mutation observers everywhere. | 6953 // we don't have to recreate mutation observers everywhere. |
| 6945 this.fire('iron-items-changed', mutations, { | 6954 this.fire('iron-items-changed', mutation, { |
| 6946 bubbles: false, | 6955 bubbles: false, |
| 6947 cancelable: false | 6956 cancelable: false |
| 6948 }); | 6957 }); |
| 6949 }); | 6958 }); |
| 6950 }, | 6959 }, |
| 6951 | 6960 |
| 6952 _activateHandler: function(e) { | 6961 _activateHandler: function(e) { |
| 6953 var t = e.target; | 6962 var t = e.target; |
| 6954 var items = this.items; | 6963 var items = this.items; |
| 6955 while (t && t != this) { | 6964 while (t && t != this) { |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7216 * Given a KeyboardEvent, this method will focus the appropriate item in the | 7225 * Given a KeyboardEvent, this method will focus the appropriate item in the |
| 7217 * menu (if there is a relevant item, and it is possible to focus it). | 7226 * menu (if there is a relevant item, and it is possible to focus it). |
| 7218 * | 7227 * |
| 7219 * @param {KeyboardEvent} event A KeyboardEvent. | 7228 * @param {KeyboardEvent} event A KeyboardEvent. |
| 7220 */ | 7229 */ |
| 7221 _focusWithKeyboardEvent: function(event) { | 7230 _focusWithKeyboardEvent: function(event) { |
| 7222 for (var i = 0, item; item = this.items[i]; i++) { | 7231 for (var i = 0, item; item = this.items[i]; i++) { |
| 7223 var attr = this.attrForItemTitle || 'textContent'; | 7232 var attr = this.attrForItemTitle || 'textContent'; |
| 7224 var title = item[attr] || item.getAttribute(attr); | 7233 var title = item[attr] || item.getAttribute(attr); |
| 7225 | 7234 |
| 7226 if (!item.hasAttribute('disabled') && title && | 7235 if (!item.hasAttribute('disabled') && title && |
| 7227 title.trim().charAt(0).toLowerCase() === String.fromCharCode(event.k
eyCode).toLowerCase()) { | 7236 title.trim().charAt(0).toLowerCase() === String.fromCharCode(event.k
eyCode).toLowerCase()) { |
| 7228 this._setFocusedItem(item); | 7237 this._setFocusedItem(item); |
| 7229 break; | 7238 break; |
| 7230 } | 7239 } |
| 7231 } | 7240 } |
| 7232 }, | 7241 }, |
| 7233 | 7242 |
| 7234 /** | 7243 /** |
| 7235 * Focuses the previous item (relative to the currently focused item) in the | 7244 * Focuses the previous item (relative to the currently focused item) in the |
| 7236 * menu, disabled items will be skipped. | 7245 * menu, disabled items will be skipped. |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7297 }, | 7306 }, |
| 7298 | 7307 |
| 7299 /** | 7308 /** |
| 7300 * A handler that responds to mutation changes related to the list of items | 7309 * A handler that responds to mutation changes related to the list of items |
| 7301 * in the menu. | 7310 * in the menu. |
| 7302 * | 7311 * |
| 7303 * @param {CustomEvent} event An event containing mutation records as its | 7312 * @param {CustomEvent} event An event containing mutation records as its |
| 7304 * detail. | 7313 * detail. |
| 7305 */ | 7314 */ |
| 7306 _onIronItemsChanged: function(event) { | 7315 _onIronItemsChanged: function(event) { |
| 7307 var mutations = event.detail; | 7316 if (event.detail.addedNodes.length) { |
| 7308 var mutation; | 7317 this._resetTabindices(); |
| 7309 var index; | |
| 7310 | |
| 7311 for (index = 0; index < mutations.length; ++index) { | |
| 7312 mutation = mutations[index]; | |
| 7313 | |
| 7314 if (mutation.addedNodes.length) { | |
| 7315 this._resetTabindices(); | |
| 7316 break; | |
| 7317 } | |
| 7318 } | 7318 } |
| 7319 }, | 7319 }, |
| 7320 | 7320 |
| 7321 /** | 7321 /** |
| 7322 * Handler that is called when a shift+tab keypress is detected by the menu. | 7322 * Handler that is called when a shift+tab keypress is detected by the menu. |
| 7323 * | 7323 * |
| 7324 * @param {CustomEvent} event A key combination event. | 7324 * @param {CustomEvent} event A key combination event. |
| 7325 */ | 7325 */ |
| 7326 _onShiftTabDown: function(event) { | 7326 _onShiftTabDown: function(event) { |
| 7327 var oldTabIndex = this.getAttribute('tabindex'); | 7327 var oldTabIndex = this.getAttribute('tabindex'); |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7742 this.style[property] = info.inlineStyle[property]; | 7742 this.style[property] = info.inlineStyle[property]; |
| 7743 } | 7743 } |
| 7744 | 7744 |
| 7745 this._fitInfo = null; | 7745 this._fitInfo = null; |
| 7746 }, | 7746 }, |
| 7747 | 7747 |
| 7748 /** | 7748 /** |
| 7749 * Equivalent to calling `resetFit()` and `fit()`. Useful to call this after | 7749 * Equivalent to calling `resetFit()` and `fit()`. Useful to call this after |
| 7750 * the element or the `fitInto` element has been resized, or if any of the | 7750 * the element or the `fitInto` element has been resized, or if any of the |
| 7751 * positioning properties (e.g. `horizontalAlign, verticalAlign`) is updated
. | 7751 * positioning properties (e.g. `horizontalAlign, verticalAlign`) is updated
. |
| 7752 * It preserves the scroll position of the sizingTarget. |
| 7752 */ | 7753 */ |
| 7753 refit: function() { | 7754 refit: function() { |
| 7755 var scrollLeft = this.sizingTarget.scrollLeft; |
| 7756 var scrollTop = this.sizingTarget.scrollTop; |
| 7754 this.resetFit(); | 7757 this.resetFit(); |
| 7755 this.fit(); | 7758 this.fit(); |
| 7759 this.sizingTarget.scrollLeft = scrollLeft; |
| 7760 this.sizingTarget.scrollTop = scrollTop; |
| 7756 }, | 7761 }, |
| 7757 | 7762 |
| 7758 /** | 7763 /** |
| 7759 * Positions the element according to `horizontalAlign, verticalAlign`. | 7764 * Positions the element according to `horizontalAlign, verticalAlign`. |
| 7760 */ | 7765 */ |
| 7761 position: function() { | 7766 position: function() { |
| 7762 if (!this.horizontalAlign && !this.verticalAlign) { | 7767 if (!this.horizontalAlign && !this.verticalAlign) { |
| 7763 // needs to be centered, and it is done after constrain. | 7768 // needs to be centered, and it is done after constrain. |
| 7764 return; | 7769 return; |
| 7765 } | 7770 } |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7969 positions[5].left = positions[7].left -= positionRect.width; | 7974 positions[5].left = positions[7].left -= positionRect.width; |
| 7970 } | 7975 } |
| 7971 | 7976 |
| 7972 // Consider auto as null for coding convenience. | 7977 // Consider auto as null for coding convenience. |
| 7973 vAlign = vAlign === 'auto' ? null : vAlign; | 7978 vAlign = vAlign === 'auto' ? null : vAlign; |
| 7974 hAlign = hAlign === 'auto' ? null : hAlign; | 7979 hAlign = hAlign === 'auto' ? null : hAlign; |
| 7975 | 7980 |
| 7976 var position; | 7981 var position; |
| 7977 for (var i = 0; i < positions.length; i++) { | 7982 for (var i = 0; i < positions.length; i++) { |
| 7978 var pos = positions[i]; | 7983 var pos = positions[i]; |
| 7979 // Align is ok if: | |
| 7980 // - Horizontal AND vertical are required and match, or | |
| 7981 // - Only vertical is required and matches, or | |
| 7982 // - Only horizontal is required and matches. | |
| 7983 var alignOk = (pos.verticalAlign === vAlign && pos.horizontalAlign === h
Align) || | |
| 7984 (pos.verticalAlign === vAlign && !hAlign) || | |
| 7985 (pos.horizontalAlign === hAlign && !vAlign); | |
| 7986 | 7984 |
| 7987 // If both vAlign and hAlign are defined, return exact match. | 7985 // If both vAlign and hAlign are defined, return exact match. |
| 7988 // For dynamicAlign and noOverlap we'll have more than one candidate, so | 7986 // For dynamicAlign and noOverlap we'll have more than one candidate, so |
| 7989 // we'll have to check the croppedArea to make the best choice. | 7987 // we'll have to check the croppedArea to make the best choice. |
| 7990 if (!this.dynamicAlign && !this.noOverlap && vAlign && hAlign && alignOk
) { | 7988 if (!this.dynamicAlign && !this.noOverlap && |
| 7989 pos.verticalAlign === vAlign && pos.horizontalAlign === hAlign) { |
| 7991 position = pos; | 7990 position = pos; |
| 7992 break; | 7991 break; |
| 7993 } | 7992 } |
| 7994 | 7993 |
| 7994 // Align is ok if alignment preferences are respected. If no preferences
, |
| 7995 // it is considered ok. |
| 7996 var alignOk = (!vAlign || pos.verticalAlign === vAlign) && |
| 7997 (!hAlign || pos.horizontalAlign === hAlign); |
| 7998 |
| 7995 // Filter out elements that don't match the alignment (if defined). | 7999 // Filter out elements that don't match the alignment (if defined). |
| 7996 // With dynamicAlign, we need to consider all the positions to find the | 8000 // With dynamicAlign, we need to consider all the positions to find the |
| 7997 // one that minimizes the cropped area. | 8001 // one that minimizes the cropped area. |
| 7998 if (!this.dynamicAlign && (vAlign || hAlign) && !alignOk) { | 8002 if (!this.dynamicAlign && !alignOk) { |
| 7999 continue; | 8003 continue; |
| 8000 } | 8004 } |
| 8001 | 8005 |
| 8002 position = position || pos; | 8006 position = position || pos; |
| 8003 pos.croppedArea = this.__getCroppedArea(pos, size, fitRect); | 8007 pos.croppedArea = this.__getCroppedArea(pos, size, fitRect); |
| 8004 var diff = pos.croppedArea - position.croppedArea; | 8008 var diff = pos.croppedArea - position.croppedArea; |
| 8005 // Check which crops less. If it crops equally, | 8009 // Check which crops less. If it crops equally, check if align is ok. |
| 8006 // check for alignment preferences. | |
| 8007 if (diff < 0 || (diff === 0 && alignOk)) { | 8010 if (diff < 0 || (diff === 0 && alignOk)) { |
| 8008 position = pos; | 8011 position = pos; |
| 8009 } | 8012 } |
| 8013 // If not cropped and respects the align requirements, keep it. |
| 8014 // This allows to prefer positions overlapping horizontally over the |
| 8015 // ones overlapping vertically. |
| 8016 if (position.croppedArea === 0 && alignOk) { |
| 8017 break; |
| 8018 } |
| 8010 } | 8019 } |
| 8011 | 8020 |
| 8012 return position; | 8021 return position; |
| 8013 } | 8022 } |
| 8014 | 8023 |
| 8015 }; | 8024 }; |
| 8016 (function() { | 8025 (function() { |
| 8017 'use strict'; | 8026 'use strict'; |
| 8018 | 8027 |
| 8019 Polymer({ | 8028 Polymer({ |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8139 * @private {number} | 8148 * @private {number} |
| 8140 */ | 8149 */ |
| 8141 this._minimumZ = 101; | 8150 this._minimumZ = 101; |
| 8142 | 8151 |
| 8143 /** | 8152 /** |
| 8144 * Memoized backdrop element. | 8153 * Memoized backdrop element. |
| 8145 * @private {Element|null} | 8154 * @private {Element|null} |
| 8146 */ | 8155 */ |
| 8147 this._backdropElement = null; | 8156 this._backdropElement = null; |
| 8148 | 8157 |
| 8149 // Listen to mousedown or touchstart to be sure to be the first to capture | 8158 // Enable document-wide tap recognizer. |
| 8150 // clicks outside the overlay. | 8159 Polymer.Gestures.add(document, 'tap', null); |
| 8151 var clickEvent = ('ontouchstart' in window) ? 'touchstart' : 'mousedown'; | 8160 // Need to have useCapture=true, Polymer.Gestures doesn't offer that. |
| 8152 document.addEventListener(clickEvent, this._onCaptureClick.bind(this), true)
; | 8161 document.addEventListener('tap', this._onCaptureClick.bind(this), true); |
| 8153 document.addEventListener('focus', this._onCaptureFocus.bind(this), true); | 8162 document.addEventListener('focus', this._onCaptureFocus.bind(this), true); |
| 8154 document.addEventListener('keydown', this._onCaptureKeyDown.bind(this), true
); | 8163 document.addEventListener('keydown', this._onCaptureKeyDown.bind(this), true
); |
| 8155 }; | 8164 }; |
| 8156 | 8165 |
| 8157 Polymer.IronOverlayManagerClass.prototype = { | 8166 Polymer.IronOverlayManagerClass.prototype = { |
| 8158 | 8167 |
| 8159 constructor: Polymer.IronOverlayManagerClass, | 8168 constructor: Polymer.IronOverlayManagerClass, |
| 8160 | 8169 |
| 8161 /** | 8170 /** |
| 8162 * The shared backdrop element. | 8171 * The shared backdrop element. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8222 * Adds the overlay and updates its z-index if it's opened, or removes it if
it's closed. | 8231 * Adds the overlay and updates its z-index if it's opened, or removes it if
it's closed. |
| 8223 * Also updates the backdrop z-index. | 8232 * Also updates the backdrop z-index. |
| 8224 * @param {!Element} overlay | 8233 * @param {!Element} overlay |
| 8225 */ | 8234 */ |
| 8226 addOrRemoveOverlay: function(overlay) { | 8235 addOrRemoveOverlay: function(overlay) { |
| 8227 if (overlay.opened) { | 8236 if (overlay.opened) { |
| 8228 this.addOverlay(overlay); | 8237 this.addOverlay(overlay); |
| 8229 } else { | 8238 } else { |
| 8230 this.removeOverlay(overlay); | 8239 this.removeOverlay(overlay); |
| 8231 } | 8240 } |
| 8232 this.trackBackdrop(); | |
| 8233 }, | 8241 }, |
| 8234 | 8242 |
| 8235 /** | 8243 /** |
| 8236 * Tracks overlays for z-index and focus management. | 8244 * Tracks overlays for z-index and focus management. |
| 8237 * Ensures the last added overlay with always-on-top remains on top. | 8245 * Ensures the last added overlay with always-on-top remains on top. |
| 8238 * @param {!Element} overlay | 8246 * @param {!Element} overlay |
| 8239 */ | 8247 */ |
| 8240 addOverlay: function(overlay) { | 8248 addOverlay: function(overlay) { |
| 8241 var i = this._overlays.indexOf(overlay); | 8249 var i = this._overlays.indexOf(overlay); |
| 8242 if (i >= 0) { | 8250 if (i >= 0) { |
| 8243 this._bringOverlayAtIndexToFront(i); | 8251 this._bringOverlayAtIndexToFront(i); |
| 8252 this.trackBackdrop(); |
| 8244 return; | 8253 return; |
| 8245 } | 8254 } |
| 8246 var insertionIndex = this._overlays.length; | 8255 var insertionIndex = this._overlays.length; |
| 8247 var currentOverlay = this._overlays[insertionIndex - 1]; | 8256 var currentOverlay = this._overlays[insertionIndex - 1]; |
| 8248 var minimumZ = Math.max(this._getZ(currentOverlay), this._minimumZ); | 8257 var minimumZ = Math.max(this._getZ(currentOverlay), this._minimumZ); |
| 8249 var newZ = this._getZ(overlay); | 8258 var newZ = this._getZ(overlay); |
| 8250 | 8259 |
| 8251 // Ensure always-on-top overlay stays on top. | 8260 // Ensure always-on-top overlay stays on top. |
| 8252 if (currentOverlay && this._shouldBeBehindOverlay(overlay, currentOverlay)
) { | 8261 if (currentOverlay && this._shouldBeBehindOverlay(overlay, currentOverlay)
) { |
| 8253 // This bumps the z-index of +2. | 8262 // This bumps the z-index of +2. |
| 8254 this._applyOverlayZ(currentOverlay, minimumZ); | 8263 this._applyOverlayZ(currentOverlay, minimumZ); |
| 8255 insertionIndex--; | 8264 insertionIndex--; |
| 8256 // Update minimumZ to match previous overlay's z-index. | 8265 // Update minimumZ to match previous overlay's z-index. |
| 8257 var previousOverlay = this._overlays[insertionIndex - 1]; | 8266 var previousOverlay = this._overlays[insertionIndex - 1]; |
| 8258 minimumZ = Math.max(this._getZ(previousOverlay), this._minimumZ); | 8267 minimumZ = Math.max(this._getZ(previousOverlay), this._minimumZ); |
| 8259 } | 8268 } |
| 8260 | 8269 |
| 8261 // Update z-index and insert overlay. | 8270 // Update z-index and insert overlay. |
| 8262 if (newZ <= minimumZ) { | 8271 if (newZ <= minimumZ) { |
| 8263 this._applyOverlayZ(overlay, minimumZ); | 8272 this._applyOverlayZ(overlay, minimumZ); |
| 8264 } | 8273 } |
| 8265 this._overlays.splice(insertionIndex, 0, overlay); | 8274 this._overlays.splice(insertionIndex, 0, overlay); |
| 8266 | 8275 |
| 8267 // Get focused node. | 8276 // Get focused node. |
| 8268 var element = this.deepActiveElement; | 8277 var element = this.deepActiveElement; |
| 8269 overlay.restoreFocusNode = this._overlayParent(element) ? null : element; | 8278 overlay.restoreFocusNode = this._overlayParent(element) ? null : element; |
| 8279 this.trackBackdrop(); |
| 8270 }, | 8280 }, |
| 8271 | 8281 |
| 8272 /** | 8282 /** |
| 8273 * @param {!Element} overlay | 8283 * @param {!Element} overlay |
| 8274 */ | 8284 */ |
| 8275 removeOverlay: function(overlay) { | 8285 removeOverlay: function(overlay) { |
| 8276 var i = this._overlays.indexOf(overlay); | 8286 var i = this._overlays.indexOf(overlay); |
| 8277 if (i === -1) { | 8287 if (i === -1) { |
| 8278 return; | 8288 return; |
| 8279 } | 8289 } |
| 8280 this._overlays.splice(i, 1); | 8290 this._overlays.splice(i, 1); |
| 8281 | 8291 |
| 8282 var node = overlay.restoreFocusOnClose ? overlay.restoreFocusNode : null; | 8292 var node = overlay.restoreFocusOnClose ? overlay.restoreFocusNode : null; |
| 8283 overlay.restoreFocusNode = null; | 8293 overlay.restoreFocusNode = null; |
| 8284 // Focus back only if still contained in document.body | 8294 // Focus back only if still contained in document.body |
| 8285 if (node && Polymer.dom(document.body).deepContains(node)) { | 8295 if (node && Polymer.dom(document.body).deepContains(node)) { |
| 8286 node.focus(); | 8296 node.focus(); |
| 8287 } | 8297 } |
| 8298 this.trackBackdrop(); |
| 8288 }, | 8299 }, |
| 8289 | 8300 |
| 8290 /** | 8301 /** |
| 8291 * Returns the current overlay. | 8302 * Returns the current overlay. |
| 8292 * @return {Element|undefined} | 8303 * @return {Element|undefined} |
| 8293 */ | 8304 */ |
| 8294 currentOverlay: function() { | 8305 currentOverlay: function() { |
| 8295 var i = this._overlays.length - 1; | 8306 var i = this._overlays.length - 1; |
| 8296 return this._overlays[i]; | 8307 return this._overlays[i]; |
| 8297 }, | 8308 }, |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8446 | 8457 |
| 8447 /** | 8458 /** |
| 8448 * Ensures the click event is delegated to the right overlay. | 8459 * Ensures the click event is delegated to the right overlay. |
| 8449 * @param {!Event} event | 8460 * @param {!Event} event |
| 8450 * @private | 8461 * @private |
| 8451 */ | 8462 */ |
| 8452 _onCaptureClick: function(event) { | 8463 _onCaptureClick: function(event) { |
| 8453 var overlay = /** @type {?} */ (this.currentOverlay()); | 8464 var overlay = /** @type {?} */ (this.currentOverlay()); |
| 8454 // Check if clicked outside of top overlay. | 8465 // Check if clicked outside of top overlay. |
| 8455 if (overlay && this._overlayInPath(Polymer.dom(event).path) !== overlay) { | 8466 if (overlay && this._overlayInPath(Polymer.dom(event).path) !== overlay) { |
| 8456 if (overlay.withBackdrop) { | |
| 8457 // There's no need to stop the propagation as the backdrop element | |
| 8458 // already got this mousedown/touchstart event. Calling preventDefault | |
| 8459 // on this event ensures that click/tap won't be triggered at all. | |
| 8460 event.preventDefault(); | |
| 8461 } | |
| 8462 overlay._onCaptureClick(event); | 8467 overlay._onCaptureClick(event); |
| 8463 } | 8468 } |
| 8464 }, | 8469 }, |
| 8465 | 8470 |
| 8466 /** | 8471 /** |
| 8467 * Ensures the focus event is delegated to the right overlay. | 8472 * Ensures the focus event is delegated to the right overlay. |
| 8468 * @param {!Event} event | 8473 * @param {!Event} event |
| 8469 * @private | 8474 * @private |
| 8470 */ | 8475 */ |
| 8471 _onCaptureFocus: function(event) { | 8476 _onCaptureFocus: function(event) { |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8801 this.removeAttribute('aria-hidden'); | 8806 this.removeAttribute('aria-hidden'); |
| 8802 } else { | 8807 } else { |
| 8803 this.setAttribute('aria-hidden', 'true'); | 8808 this.setAttribute('aria-hidden', 'true'); |
| 8804 } | 8809 } |
| 8805 | 8810 |
| 8806 // wait to call after ready only if we're initially open | 8811 // wait to call after ready only if we're initially open |
| 8807 if (!this._overlaySetup) { | 8812 if (!this._overlaySetup) { |
| 8808 return; | 8813 return; |
| 8809 } | 8814 } |
| 8810 | 8815 |
| 8811 this._manager.addOrRemoveOverlay(this); | |
| 8812 | |
| 8813 if (this.__openChangedAsync) { | 8816 if (this.__openChangedAsync) { |
| 8814 window.cancelAnimationFrame(this.__openChangedAsync); | 8817 window.cancelAnimationFrame(this.__openChangedAsync); |
| 8815 } | 8818 } |
| 8816 | 8819 |
| 8820 // Synchronously remove the overlay. |
| 8821 // The adding is done asynchronously to go out of the scope of the event |
| 8822 // which might have generated the opening. |
| 8823 if (!this.opened) { |
| 8824 this._manager.removeOverlay(this); |
| 8825 } |
| 8826 |
| 8817 // Defer any animation-related code on attached | 8827 // Defer any animation-related code on attached |
| 8818 // (_openedChanged gets called again on attached). | 8828 // (_openedChanged gets called again on attached). |
| 8819 if (!this.isAttached) { | 8829 if (!this.isAttached) { |
| 8820 return; | 8830 return; |
| 8821 } | 8831 } |
| 8822 | 8832 |
| 8823 this.__isAnimating = true; | 8833 this.__isAnimating = true; |
| 8824 | 8834 |
| 8825 // requestAnimationFrame for non-blocking rendering | 8835 // requestAnimationFrame for non-blocking rendering |
| 8826 this.__openChangedAsync = window.requestAnimationFrame(function() { | 8836 this.__openChangedAsync = window.requestAnimationFrame(function() { |
| 8827 this.__openChangedAsync = null; | 8837 this.__openChangedAsync = null; |
| 8828 if (this.opened) { | 8838 if (this.opened) { |
| 8839 this._manager.addOverlay(this); |
| 8829 this._prepareRenderOpened(); | 8840 this._prepareRenderOpened(); |
| 8830 this._renderOpened(); | 8841 this._renderOpened(); |
| 8831 } else { | 8842 } else { |
| 8832 this._renderClosed(); | 8843 this._renderClosed(); |
| 8833 } | 8844 } |
| 8834 }.bind(this)); | 8845 }.bind(this)); |
| 8835 }, | 8846 }, |
| 8836 | 8847 |
| 8837 _canceledChanged: function() { | 8848 _canceledChanged: function() { |
| 8838 this.closingReason = this.closingReason || {}; | 8849 this.closingReason = this.closingReason || {}; |
| 8839 this.closingReason.canceled = this.canceled; | 8850 this.closingReason.canceled = this.canceled; |
| 8840 }, | 8851 }, |
| 8841 | 8852 |
| 8842 _withBackdropChanged: function() { | 8853 _withBackdropChanged: function() { |
| 8843 // If tabindex is already set, no need to override it. | 8854 // If tabindex is already set, no need to override it. |
| 8844 if (this.withBackdrop && !this.hasAttribute('tabindex')) { | 8855 if (this.withBackdrop && !this.hasAttribute('tabindex')) { |
| 8845 this.setAttribute('tabindex', '-1'); | 8856 this.setAttribute('tabindex', '-1'); |
| 8846 this.__shouldRemoveTabIndex = true; | 8857 this.__shouldRemoveTabIndex = true; |
| 8847 } else if (this.__shouldRemoveTabIndex) { | 8858 } else if (this.__shouldRemoveTabIndex) { |
| 8848 this.removeAttribute('tabindex'); | 8859 this.removeAttribute('tabindex'); |
| 8849 this.__shouldRemoveTabIndex = false; | 8860 this.__shouldRemoveTabIndex = false; |
| 8850 } | 8861 } |
| 8851 if (this.opened) { | 8862 if (this.opened && this.isAttached) { |
| 8852 this._manager.trackBackdrop(); | 8863 this._manager.trackBackdrop(); |
| 8853 } | 8864 } |
| 8854 }, | 8865 }, |
| 8855 | 8866 |
| 8856 /** | 8867 /** |
| 8857 * tasks which must occur before opening; e.g. making the element visible. | 8868 * tasks which must occur before opening; e.g. making the element visible. |
| 8858 * @protected | 8869 * @protected |
| 8859 */ | 8870 */ |
| 8860 _prepareRenderOpened: function() { | 8871 _prepareRenderOpened: function() { |
| 8861 | 8872 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 8891 /** | 8902 /** |
| 8892 * Tasks to be performed at the end of open action. Will fire `iron-overlay-
opened`. | 8903 * Tasks to be performed at the end of open action. Will fire `iron-overlay-
opened`. |
| 8893 * @protected | 8904 * @protected |
| 8894 */ | 8905 */ |
| 8895 _finishRenderOpened: function() { | 8906 _finishRenderOpened: function() { |
| 8896 // Focus the child node with [autofocus] | 8907 // Focus the child node with [autofocus] |
| 8897 this._applyFocus(); | 8908 this._applyFocus(); |
| 8898 | 8909 |
| 8899 this.notifyResize(); | 8910 this.notifyResize(); |
| 8900 this.__isAnimating = false; | 8911 this.__isAnimating = false; |
| 8912 |
| 8913 // Store it so we don't query too much. |
| 8914 var focusableNodes = this._focusableNodes; |
| 8915 this.__firstFocusableNode = focusableNodes[0]; |
| 8916 this.__lastFocusableNode = focusableNodes[focusableNodes.length - 1]; |
| 8917 |
| 8901 this.fire('iron-overlay-opened'); | 8918 this.fire('iron-overlay-opened'); |
| 8902 }, | 8919 }, |
| 8903 | 8920 |
| 8904 /** | 8921 /** |
| 8905 * Tasks to be performed at the end of close action. Will fire `iron-overlay
-closed`. | 8922 * Tasks to be performed at the end of close action. Will fire `iron-overlay
-closed`. |
| 8906 * @protected | 8923 * @protected |
| 8907 */ | 8924 */ |
| 8908 _finishRenderClosed: function() { | 8925 _finishRenderClosed: function() { |
| 8909 // Hide the overlay and remove the backdrop. | 8926 // Hide the overlay and remove the backdrop. |
| 8910 this.style.display = 'none'; | 8927 this.style.display = 'none'; |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8995 } | 9012 } |
| 8996 }, | 9013 }, |
| 8997 | 9014 |
| 8998 /** | 9015 /** |
| 8999 * Handles TAB key events to track focus changes. | 9016 * Handles TAB key events to track focus changes. |
| 9000 * Will wrap focus for overlays withBackdrop. | 9017 * Will wrap focus for overlays withBackdrop. |
| 9001 * @param {!Event} event | 9018 * @param {!Event} event |
| 9002 * @protected | 9019 * @protected |
| 9003 */ | 9020 */ |
| 9004 _onCaptureTab: function(event) { | 9021 _onCaptureTab: function(event) { |
| 9022 if (!this.withBackdrop) { |
| 9023 return; |
| 9024 } |
| 9005 // TAB wraps from last to first focusable. | 9025 // TAB wraps from last to first focusable. |
| 9006 // Shift + TAB wraps from first to last focusable. | 9026 // Shift + TAB wraps from first to last focusable. |
| 9007 var shift = event.shiftKey; | 9027 var shift = event.shiftKey; |
| 9008 var nodeToCheck = shift ? this.__firstFocusableNode : this.__lastFocusable
Node; | 9028 var nodeToCheck = shift ? this.__firstFocusableNode : this.__lastFocusable
Node; |
| 9009 var nodeToSet = shift ? this.__lastFocusableNode : this.__firstFocusableNo
de; | 9029 var nodeToSet = shift ? this.__lastFocusableNode : this.__firstFocusableNo
de; |
| 9010 if (this.withBackdrop && this._focusedChild === nodeToCheck) { | 9030 var shouldWrap = false; |
| 9031 if (nodeToCheck === nodeToSet) { |
| 9032 // If nodeToCheck is the same as nodeToSet, it means we have an overlay |
| 9033 // with 0 or 1 focusables; in either case we still need to trap the |
| 9034 // focus within the overlay. |
| 9035 shouldWrap = true; |
| 9036 } else { |
| 9037 // In dom=shadow, the manager will receive focus changes on the main |
| 9038 // root but not the ones within other shadow roots, so we can't rely on |
| 9039 // _focusedChild, but we should check the deepest active element. |
| 9040 var focusedNode = this._manager.deepActiveElement; |
| 9041 // If the active element is not the nodeToCheck but the overlay itself, |
| 9042 // it means the focus is about to go outside the overlay, hence we |
| 9043 // should prevent that (e.g. user opens the overlay and hit Shift+TAB). |
| 9044 shouldWrap = (focusedNode === nodeToCheck || focusedNode === this); |
| 9045 } |
| 9046 |
| 9047 if (shouldWrap) { |
| 9011 // When the overlay contains the last focusable element of the document | 9048 // When the overlay contains the last focusable element of the document |
| 9012 // and it's already focused, pressing TAB would move the focus outside | 9049 // and it's already focused, pressing TAB would move the focus outside |
| 9013 // the document (e.g. to the browser search bar). Similarly, when the | 9050 // the document (e.g. to the browser search bar). Similarly, when the |
| 9014 // overlay contains the first focusable element of the document and it's | 9051 // overlay contains the first focusable element of the document and it's |
| 9015 // already focused, pressing Shift+TAB would move the focus outside the | 9052 // already focused, pressing Shift+TAB would move the focus outside the |
| 9016 // document (e.g. to the browser search bar). | 9053 // document (e.g. to the browser search bar). |
| 9017 // In both cases, we would not receive a focus event, but only a blur. | 9054 // In both cases, we would not receive a focus event, but only a blur. |
| 9018 // In order to achieve focus wrapping, we prevent this TAB event and | 9055 // In order to achieve focus wrapping, we prevent this TAB event and |
| 9019 // force the focus. This will also prevent the focus to temporarily move | 9056 // force the focus. This will also prevent the focus to temporarily move |
| 9020 // outside the overlay, which might cause scrolling. | 9057 // outside the overlay, which might cause scrolling. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 9043 | 9080 |
| 9044 /** | 9081 /** |
| 9045 * Will call notifyResize if overlay is opened. | 9082 * Will call notifyResize if overlay is opened. |
| 9046 * Can be overridden in order to avoid multiple observers on the same node. | 9083 * Can be overridden in order to avoid multiple observers on the same node. |
| 9047 * @protected | 9084 * @protected |
| 9048 */ | 9085 */ |
| 9049 _onNodesChange: function() { | 9086 _onNodesChange: function() { |
| 9050 if (this.opened && !this.__isAnimating) { | 9087 if (this.opened && !this.__isAnimating) { |
| 9051 this.notifyResize(); | 9088 this.notifyResize(); |
| 9052 } | 9089 } |
| 9053 // Store it so we don't query too much. | |
| 9054 var focusableNodes = this._focusableNodes; | |
| 9055 this.__firstFocusableNode = focusableNodes[0]; | |
| 9056 this.__lastFocusableNode = focusableNodes[focusableNodes.length - 1]; | |
| 9057 } | 9090 } |
| 9058 }; | 9091 }; |
| 9059 | 9092 |
| 9060 /** @polymerBehavior */ | 9093 /** @polymerBehavior */ |
| 9061 Polymer.IronOverlayBehavior = [Polymer.IronFitBehavior, Polymer.IronResizableB
ehavior, Polymer.IronOverlayBehaviorImpl]; | 9094 Polymer.IronOverlayBehavior = [Polymer.IronFitBehavior, Polymer.IronResizableB
ehavior, Polymer.IronOverlayBehaviorImpl]; |
| 9062 | 9095 |
| 9063 /** | 9096 /** |
| 9064 * Fired after the overlay opens. | 9097 * Fired after the overlay opens. |
| 9065 * @event iron-overlay-opened | 9098 * @event iron-overlay-opened |
| 9066 */ | 9099 */ |
| (...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9722 }, | 9755 }, |
| 9723 | 9756 |
| 9724 /** | 9757 /** |
| 9725 * The element that should be focused when the dropdown opens. | 9758 * The element that should be focused when the dropdown opens. |
| 9726 * @deprecated | 9759 * @deprecated |
| 9727 */ | 9760 */ |
| 9728 get _focusTarget() { | 9761 get _focusTarget() { |
| 9729 return this.focusTarget || this.containedElement; | 9762 return this.focusTarget || this.containedElement; |
| 9730 }, | 9763 }, |
| 9731 | 9764 |
| 9765 detached: function() { |
| 9766 this.cancelAnimation(); |
| 9767 Polymer.IronDropdownScrollManager.removeScrollLock(this); |
| 9768 }, |
| 9769 |
| 9732 /** | 9770 /** |
| 9733 * Called when the value of `opened` changes. | 9771 * Called when the value of `opened` changes. |
| 9734 * Overridden from `IronOverlayBehavior` | 9772 * Overridden from `IronOverlayBehavior` |
| 9735 */ | 9773 */ |
| 9736 _openedChanged: function() { | 9774 _openedChanged: function() { |
| 9737 if (this.opened && this.disabled) { | 9775 if (this.opened && this.disabled) { |
| 9738 this.cancel(); | 9776 this.cancel(); |
| 9739 } else { | 9777 } else { |
| 9740 this.cancelAnimation(); | 9778 this.cancelAnimation(); |
| 9741 this.sizingTarget = this.containedElement || this.sizingTarget; | 9779 this.sizingTarget = this.containedElement || this.sizingTarget; |
| 9742 this._updateAnimationConfig(); | 9780 this._updateAnimationConfig(); |
| 9743 if (this.opened && !this.allowOutsideScroll) { | 9781 if (this.opened && !this.allowOutsideScroll) { |
| 9744 Polymer.IronDropdownScrollManager.pushScrollLock(this); | 9782 Polymer.IronDropdownScrollManager.pushScrollLock(this); |
| 9745 } else { | 9783 } else { |
| 9746 Polymer.IronDropdownScrollManager.removeScrollLock(this); | 9784 Polymer.IronDropdownScrollManager.removeScrollLock(this); |
| 9747 } | 9785 } |
| 9748 Polymer.IronOverlayBehaviorImpl._openedChanged.apply(this, arguments
); | 9786 Polymer.IronOverlayBehaviorImpl._openedChanged.apply(this, arguments
); |
| 9749 } | 9787 } |
| 9750 }, | 9788 }, |
| 9751 | 9789 |
| 9752 /** | 9790 /** |
| 9753 * Overridden from `IronOverlayBehavior`. | 9791 * Overridden from `IronOverlayBehavior`. |
| 9754 */ | 9792 */ |
| 9755 _renderOpened: function() { | 9793 _renderOpened: function() { |
| 9756 if (!this.noAnimations && this.animationConfig && this.animationConfig
.open) { | 9794 if (!this.noAnimations && this.animationConfig.open) { |
| 9757 if (this.withBackdrop) { | |
| 9758 this.backdropElement.open(); | |
| 9759 } | |
| 9760 this.$.contentWrapper.classList.add('animating'); | 9795 this.$.contentWrapper.classList.add('animating'); |
| 9761 this.playAnimation('open'); | 9796 this.playAnimation('open'); |
| 9762 } else { | 9797 } else { |
| 9763 Polymer.IronOverlayBehaviorImpl._renderOpened.apply(this, arguments)
; | 9798 Polymer.IronOverlayBehaviorImpl._renderOpened.apply(this, arguments)
; |
| 9764 } | 9799 } |
| 9765 }, | 9800 }, |
| 9766 | 9801 |
| 9767 /** | 9802 /** |
| 9768 * Overridden from `IronOverlayBehavior`. | 9803 * Overridden from `IronOverlayBehavior`. |
| 9769 */ | 9804 */ |
| 9770 _renderClosed: function() { | 9805 _renderClosed: function() { |
| 9771 if (!this.noAnimations && this.animationConfig && this.animationConfig
.close) { | 9806 if (!this.noAnimations && this.animationConfig.close) { |
| 9772 if (this.withBackdrop) { | |
| 9773 this.backdropElement.close(); | |
| 9774 } | |
| 9775 this.$.contentWrapper.classList.add('animating'); | 9807 this.$.contentWrapper.classList.add('animating'); |
| 9776 this.playAnimation('close'); | 9808 this.playAnimation('close'); |
| 9777 } else { | 9809 } else { |
| 9778 Polymer.IronOverlayBehaviorImpl._renderClosed.apply(this, arguments)
; | 9810 Polymer.IronOverlayBehaviorImpl._renderClosed.apply(this, arguments)
; |
| 9779 } | 9811 } |
| 9780 }, | 9812 }, |
| 9781 | 9813 |
| 9782 /** | 9814 /** |
| 9783 * Called when animation finishes on the dropdown (when opening or | 9815 * Called when animation finishes on the dropdown (when opening or |
| 9784 * closing). Responsible for "completing" the process of opening or | 9816 * closing). Responsible for "completing" the process of opening or |
| 9785 * closing the dropdown by positioning it or setting its display to | 9817 * closing the dropdown by positioning it or setting its display to |
| 9786 * none. | 9818 * none. |
| 9787 */ | 9819 */ |
| 9788 _onNeonAnimationFinish: function() { | 9820 _onNeonAnimationFinish: function() { |
| 9789 this.$.contentWrapper.classList.remove('animating'); | 9821 this.$.contentWrapper.classList.remove('animating'); |
| 9790 if (this.opened) { | 9822 if (this.opened) { |
| 9791 Polymer.IronOverlayBehaviorImpl._finishRenderOpened.apply(this); | 9823 this._finishRenderOpened(); |
| 9792 } else { | 9824 } else { |
| 9793 Polymer.IronOverlayBehaviorImpl._finishRenderClosed.apply(this); | 9825 this._finishRenderClosed(); |
| 9794 } | 9826 } |
| 9795 }, | 9827 }, |
| 9796 | 9828 |
| 9797 /** | 9829 /** |
| 9798 * Constructs the final animation config from different properties used | 9830 * Constructs the final animation config from different properties used |
| 9799 * to configure specific parts of the opening and closing animations. | 9831 * to configure specific parts of the opening and closing animations. |
| 9800 */ | 9832 */ |
| 9801 _updateAnimationConfig: function() { | 9833 _updateAnimationConfig: function() { |
| 9802 var animationConfig = {}; | 9834 var animations = (this.openAnimationConfig || []).concat(this.closeAni
mationConfig || []); |
| 9803 var animations = []; | 9835 for (var i = 0; i < animations.length; i++) { |
| 9804 | 9836 animations[i].node = this.containedElement; |
| 9805 if (this.openAnimationConfig) { | |
| 9806 // NOTE(cdata): When making `display:none` elements visible in Safar
i, | |
| 9807 // the element will paint once in a fully visible state, causing the | |
| 9808 // dropdown to flash before it fades in. We prepend an | |
| 9809 // `opaque-animation` to fix this problem: | |
| 9810 animationConfig.open = [{ | |
| 9811 name: 'opaque-animation', | |
| 9812 }].concat(this.openAnimationConfig); | |
| 9813 animations = animations.concat(animationConfig.open); | |
| 9814 } | 9837 } |
| 9815 | 9838 this.animationConfig = { |
| 9816 if (this.closeAnimationConfig) { | 9839 open: this.openAnimationConfig, |
| 9817 animationConfig.close = this.closeAnimationConfig; | 9840 close: this.closeAnimationConfig |
| 9818 animations = animations.concat(animationConfig.close); | 9841 }; |
| 9819 } | |
| 9820 | |
| 9821 animations.forEach(function(animation) { | |
| 9822 animation.node = this.containedElement; | |
| 9823 }, this); | |
| 9824 | |
| 9825 this.animationConfig = animationConfig; | |
| 9826 }, | 9842 }, |
| 9827 | 9843 |
| 9828 /** | 9844 /** |
| 9829 * Updates the overlay position based on configured horizontal | 9845 * Updates the overlay position based on configured horizontal |
| 9830 * and vertical alignment. | 9846 * and vertical alignment. |
| 9831 */ | 9847 */ |
| 9832 _updateOverlayPosition: function() { | 9848 _updateOverlayPosition: function() { |
| 9833 if (this.isAttached) { | 9849 if (this.isAttached) { |
| 9834 // This triggers iron-resize, and iron-overlay-behavior will call re
fit if needed. | 9850 // This triggers iron-resize, and iron-overlay-behavior will call re
fit if needed. |
| 9835 this.notifyResize(); | 9851 this.notifyResize(); |
| 9836 } | 9852 } |
| 9837 }, | 9853 }, |
| 9838 | 9854 |
| 9839 /** | 9855 /** |
| 9840 * Useful to call this after the element, the window, or the `fitInfo` | |
| 9841 * element has been resized. Will maintain the scroll position. | |
| 9842 */ | |
| 9843 refit: function () { | |
| 9844 if (!this.opened) { | |
| 9845 return | |
| 9846 } | |
| 9847 var containedElement = this.containedElement; | |
| 9848 var scrollTop; | |
| 9849 var scrollLeft; | |
| 9850 | |
| 9851 if (containedElement) { | |
| 9852 scrollTop = containedElement.scrollTop; | |
| 9853 scrollLeft = containedElement.scrollLeft; | |
| 9854 } | |
| 9855 Polymer.IronFitBehavior.refit.apply(this, arguments); | |
| 9856 | |
| 9857 if (containedElement) { | |
| 9858 containedElement.scrollTop = scrollTop; | |
| 9859 containedElement.scrollLeft = scrollLeft; | |
| 9860 } | |
| 9861 }, | |
| 9862 | |
| 9863 /** | |
| 9864 * Apply focus to focusTarget or containedElement | 9856 * Apply focus to focusTarget or containedElement |
| 9865 */ | 9857 */ |
| 9866 _applyFocus: function () { | 9858 _applyFocus: function () { |
| 9867 var focusTarget = this.focusTarget || this.containedElement; | 9859 var focusTarget = this.focusTarget || this.containedElement; |
| 9868 if (focusTarget && this.opened && !this.noAutoFocus) { | 9860 if (focusTarget && this.opened && !this.noAutoFocus) { |
| 9869 focusTarget.focus(); | 9861 focusTarget.focus(); |
| 9870 } else { | 9862 } else { |
| 9871 Polymer.IronOverlayBehaviorImpl._applyFocus.apply(this, arguments); | 9863 Polymer.IronOverlayBehaviorImpl._applyFocus.apply(this, arguments); |
| 9872 } | 9864 } |
| 9873 } | 9865 } |
| (...skipping 1613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11487 Manager.get().updateItem_(index, data); | 11479 Manager.get().updateItem_(index, data); |
| 11488 }; | 11480 }; |
| 11489 | 11481 |
| 11490 return {Manager: Manager}; | 11482 return {Manager: Manager}; |
| 11491 }); | 11483 }); |
| 11492 // Copyright 2015 The Chromium Authors. All rights reserved. | 11484 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 11493 // Use of this source code is governed by a BSD-style license that can be | 11485 // Use of this source code is governed by a BSD-style license that can be |
| 11494 // found in the LICENSE file. | 11486 // found in the LICENSE file. |
| 11495 | 11487 |
| 11496 window.addEventListener('load', downloads.Manager.onLoad); | 11488 window.addEventListener('load', downloads.Manager.onLoad); |
| OLD | NEW |