ApplicationImpl cleanup, part 1:
[chromium-blink-merge.git] / third_party / polymer / v1_0 / components-chromium / paper-input / paper-input-container-extracted.js
blobd307fe68ba87cc6b0fc289b7e1588c38bd8ee1d6
2 (function() {
4   Polymer({
6     is: 'paper-input-container',
8     properties: {
10       /**
11        * Set to true to disable the floating label. The label disappears when the input value is
12        * not null.
13        */
14       noLabelFloat: {
15         type: Boolean,
16         value: false
17       },
19       /**
20        * Set to true to always float the floating label.
21        */
22       alwaysFloatLabel: {
23         type: Boolean,
24         value: false
25       },
27       /**
28        * The attribute to listen for value changes on.
29        */
30       attrForValue: {
31         type: String,
32         value: 'bind-value'
33       },
35       /**
36        * Set to true to auto-validate the input value when it changes.
37        */
38       autoValidate: {
39         type: Boolean,
40         value: false
41       },
43       /**
44        * True if the input is invalid. This property is set automatically when the input value
45        * changes if auto-validating, or when the `iron-input-valid` event is heard from a child.
46        */
47       invalid: {
48         observer: '_invalidChanged',
49         type: Boolean,
50         value: false
51       },
53       /**
54        * True if the input has focus.
55        */
56       focused: {
57         readOnly: true,
58         type: Boolean,
59         value: false
60       },
62       _addons: {
63         type: Array
64         // do not set a default value here intentionally - it will be initialized lazily when a
65         // distributed child is attached, which may occur before configuration for this element
66         // in polyfill.
67       },
69       _inputHasContent: {
70         type: Boolean,
71         value: false
72       },
74       _inputSelector: {
75         type: String,
76         value: 'input,textarea,.paper-input-input'
77       },
79       _boundOnFocus: {
80         type: Function,
81         value: function() {
82           return this._onFocus.bind(this);
83         }
84       },
86       _boundOnBlur: {
87         type: Function,
88         value: function() {
89           return this._onBlur.bind(this);
90         }
91       },
93       _boundOnInput: {
94         type: Function,
95         value: function() {
96           return this._onInput.bind(this);
97         }
98       },
100       _boundValueChanged: {
101         type: Function,
102         value: function() {
103           return this._onValueChanged.bind(this);
104         }
105       }
107     },
109     listeners: {
110       'addon-attached': '_onAddonAttached',
111       'iron-input-validate': '_onIronInputValidate'
112     },
114     get _valueChangedEvent() {
115       return this.attrForValue + '-changed';
116     },
118     get _propertyForValue() {
119       return Polymer.CaseMap.dashToCamelCase(this.attrForValue);
120     },
122     get _inputElement() {
123       return Polymer.dom(this).querySelector(this._inputSelector);
124     },
126     ready: function() {
127       if (!this._addons) {
128         this._addons = [];
129       }
130       this.addEventListener('focus', this._boundOnFocus, true);
131       this.addEventListener('blur', this._boundOnBlur, true);
132       if (this.attrForValue) {
133         this._inputElement.addEventListener(this._valueChangedEvent, this._boundValueChanged);
134       } else {
135         this.addEventListener('input', this._onInput);
136       }
137     },
139     attached: function() {
140       this._handleValue(this._inputElement);
141     },
143     _onAddonAttached: function(event) {
144       if (!this._addons) {
145         this._addons = [];
146       }
147       var target = event.target;
148       if (this._addons.indexOf(target) === -1) {
149         this._addons.push(target);
150         if (this.isAttached) {
151           this._handleValue(this._inputElement);
152         }
153       }
154     },
156     _onFocus: function() {
157       this._setFocused(true);
158     },
160     _onBlur: function() {
161       this._setFocused(false);
162     },
164     _onInput: function(event) {
165       this._handleValue(event.target);
166     },
168     _onValueChanged: function(event) {
169       this._handleValue(event.target);
170     },
172     _handleValue: function(inputElement) {
173       var value = inputElement[this._propertyForValue] || inputElement.value;
175       if (this.autoValidate) {
176         var valid;
177         if (inputElement.validate) {
178           valid = inputElement.validate(value);
179         } else {
180           valid = inputElement.checkValidity();
181         }
182         this.invalid = !valid;
183       }
185       // type="number" hack needed because this.value is empty until it's valid
186       if (value || (inputElement.type === 'number' && !inputElement.checkValidity())) {
187         this._inputHasContent = true;
188       } else {
189         this._inputHasContent = false;
190       }
192       this.updateAddons({
193         inputElement: inputElement,
194         value: value,
195         invalid: this.invalid
196       });
197     },
199     _onIronInputValidate: function(event) {
200       this.invalid = this._inputElement.invalid;
201     },
203     _invalidChanged: function() {
204       if (this._addons) {
205         this.updateAddons({invalid: this.invalid});
206       }
207     },
209     /**
210      * Call this to update the state of add-ons.
211      * @param {Object} state Add-on state.
212      */
213     updateAddons: function(state) {
214       for (var addon, index = 0; addon = this._addons[index]; index++) {
215         addon.update(state);
216       }
217     },
219     _computeInputContentClass: function(noLabelFloat, alwaysFloatLabel, focused, invalid, _inputHasContent) {
220       var cls = 'input-content';
221       if (!noLabelFloat) {
222         if (alwaysFloatLabel || _inputHasContent) {
223           cls += ' label-is-floating';
224           if (invalid) {
225             cls += ' is-invalid';
226           } else if (focused) {
227             cls += " label-is-highlighted";
228           }
229         }
230       } else {
231         if (_inputHasContent) {
232           cls += ' label-is-hidden';
233         }
234       }
235       return cls;
236     },
238     _computeUnderlineClass: function(focused, invalid) {
239       var cls = 'underline';
240       if (invalid) {
241         cls += ' is-invalid';
242       } else if (focused) {
243         cls += ' is-highlighted'
244       }
245       return cls;
246     },
248     _computeAddOnContentClass: function(focused, invalid) {
249       var cls = 'add-on-content';
250       if (invalid) {
251         cls += ' is-invalid';
252       } else if (focused) {
253         cls += ' is-highlighted'
254       }
255       return cls;
256     }
258   });
260 })();