• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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