Home | History | Annotate | Download | only in iron-behaviors
      1 <!--
      2 @license
      3 Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
      4 This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
      5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
      6 The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
      7 Code distributed by Google as part of the polymer project is also
      8 subject 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