1<!-- 2@license 3Copyright (c) 2015 The Polymer Project Authors. All rights reserved. 4This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt 5The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt 6The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt 7Code distributed by Google as part of the polymer project is also 8subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt 9--> 10 11<link rel="import" href="../polymer/polymer.html"> 12 13<script> 14 15 /** 16 * @demo demo/index.html 17 * @polymerBehavior 18 */ 19 Polymer.IronControlState = { 20 21 properties: { 22 23 /** 24 * If true, the element currently has focus. 25 */ 26 focused: { 27 type: Boolean, 28 value: false, 29 notify: true, 30 readOnly: true, 31 reflectToAttribute: true 32 }, 33 34 /** 35 * If true, the user cannot interact with this element. 36 */ 37 disabled: { 38 type: Boolean, 39 value: false, 40 notify: true, 41 observer: '_disabledChanged', 42 reflectToAttribute: true 43 }, 44 45 _oldTabIndex: { 46 type: Number 47 }, 48 49 _boundFocusBlurHandler: { 50 type: Function, 51 value: function() { 52 return this._focusBlurHandler.bind(this); 53 } 54 } 55 56 }, 57 58 observers: [ 59 '_changedControlState(focused, disabled)' 60 ], 61 62 ready: function() { 63 this.addEventListener('focus', this._boundFocusBlurHandler, true); 64 this.addEventListener('blur', this._boundFocusBlurHandler, true); 65 }, 66 67 _focusBlurHandler: function(event) { 68 // NOTE(cdata): if we are in ShadowDOM land, `event.target` will 69 // eventually become `this` due to retargeting; if we are not in 70 // ShadowDOM land, `event.target` will eventually become `this` due 71 // to the second conditional which fires a synthetic event (that is also 72 // handled). In either case, we can disregard `event.path`. 73 74 if (event.target === this) { 75 this._setFocused(event.type === 'focus'); 76 } else if (!this.shadowRoot) { 77 var target = /** @type {Node} */(Polymer.dom(event).localTarget); 78 if (!this.isLightDescendant(target)) { 79 this.fire(event.type, {sourceEvent: event}, { 80 node: this, 81 bubbles: event.bubbles, 82 cancelable: event.cancelable 83 }); 84 } 85 } 86 }, 87 88 _disabledChanged: function(disabled, old) { 89 this.setAttribute('aria-disabled', disabled ? 'true' : 'false'); 90 this.style.pointerEvents = disabled ? 'none' : ''; 91 if (disabled) { 92 this._oldTabIndex = this.tabIndex; 93 this._setFocused(false); 94 this.tabIndex = -1; 95 this.blur(); 96 } else if (this._oldTabIndex !== undefined) { 97 this.tabIndex = this._oldTabIndex; 98 } 99 }, 100 101 _changedControlState: function() { 102 // _controlStateChanged is abstract, follow-on behaviors may implement it 103 if (this._controlStateChanged) { 104 this._controlStateChanged(); 105 } 106 } 107 108 }; 109 110</script> 111