Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / polymer / v1_0 / components-chromium / iron-behaviors / iron-control-state-extracted.js
blobbdd4c2eeec5e5846c8304aaef3749b4c16f477f2
3   /**
4    * @demo demo/index.html
5    * @polymerBehavior
6    */
7   Polymer.IronControlState = {
9     properties: {
11       /**
12        * If true, the element currently has focus.
13        */
14       focused: {
15         type: Boolean,
16         value: false,
17         notify: true,
18         readOnly: true,
19         reflectToAttribute: true
20       },
22       /**
23        * If true, the user cannot interact with this element.
24        */
25       disabled: {
26         type: Boolean,
27         value: false,
28         notify: true,
29         observer: '_disabledChanged',
30         reflectToAttribute: true
31       },
33       _oldTabIndex: {
34         type: Number
35       },
37       _boundFocusBlurHandler: {
38         type: Function,
39         value: function() {
40           return this._focusBlurHandler.bind(this);
41         }
42       }
44     },
46     observers: [
47       '_changedControlState(focused, disabled)'
48     ],
50     ready: function() {
51       this.addEventListener('focus', this._boundFocusBlurHandler, true);
52       this.addEventListener('blur', this._boundFocusBlurHandler, true);
53     },
55     _focusBlurHandler: function(event) {
56       // NOTE(cdata):  if we are in ShadowDOM land, `event.target` will
57       // eventually become `this` due to retargeting; if we are not in
58       // ShadowDOM land, `event.target` will eventually become `this` due
59       // to the second conditional which fires a synthetic event (that is also
60       // handled). In either case, we can disregard `event.path`.
62       if (event.target === this) {
63         var focused = event.type === 'focus';
64         this._setFocused(focused);
65       } else if (!this.shadowRoot) {
66         this.fire(event.type, {sourceEvent: event}, {
67           node: this,
68           bubbles: event.bubbles,
69           cancelable: event.cancelable
70         });
71       }
72     },
74     _disabledChanged: function(disabled, old) {
75       this.setAttribute('aria-disabled', disabled ? 'true' : 'false');
76       this.style.pointerEvents = disabled ? 'none' : '';
77       if (disabled) {
78         this._oldTabIndex = this.tabIndex;
79         this.focused = false;
80         this.tabIndex = -1;
81       } else if (this._oldTabIndex !== undefined) {
82         this.tabIndex = this._oldTabIndex;
83       }
84     },
86     _changedControlState: function() {
87       // _controlStateChanged is abstract, follow-on behaviors may implement it
88       if (this._controlStateChanged) {
89         this._controlStateChanged();
90       }
91     }
93   };