1
2
3    Polymer('core-input', {
4      publish: {
5        /**
6         * Placeholder text that hints to the user what can be entered in
7         * the input.
8         *
9         * @attribute placeholder
10         * @type string
11         * @default ''
12         */
13        placeholder: '',
14
15        /**
16         * If true, this input cannot be focused and the user cannot change
17         * its value.
18         *
19         * @attribute disabled
20         * @type boolean
21         * @default false
22         */
23        disabled: false,
24
25        /**
26         * If true, the user cannot modify the value of the input.
27         *
28         * @attribute readonly
29         * @type boolean
30         * @default false
31         */
32        readonly: false,
33
34        /**
35         * If true, this input will automatically gain focus on page load.
36         *
37         * @attribute autofocus
38         * @type boolean
39         * @default false
40         */
41        autofocus: false,
42
43        /**
44         * If true, this input accepts multi-line input like a `<textarea>`
45         *
46         * @attribute multiline
47         * @type boolean
48         * @default false
49         */
50        multiline: false,
51
52        /**
53         * (multiline only) The height of this text input in rows. The input
54         * will scroll internally if more input is entered beyond the size
55         * of the component. This property is meaningless if multiline is
56         * false. You can also set this property to "fit" and size the
57         * component with CSS to make the input fit the CSS size.
58         *
59         * @attribute rows
60         * @type number|'fit'
61         * @default 'fit'
62         */
63        rows: 'fit',
64
65        /**
66         * The current value of this input. Changing inputValue programmatically
67         * will cause value to be out of sync. Instead, change value directly
68         * or call commit() after changing inputValue.
69         *
70         * @attribute inputValue
71         * @type string
72         * @default ''
73         */
74        inputValue: '',
75
76        /**
77         * The value of the input committed by the user, either by changing the
78         * inputValue and blurring the input, or by hitting the `enter` key.
79         *
80         * @attribute value
81         * @type string
82         * @default ''
83         */
84        value: '',
85
86        /**
87         * Set the input type. Not supported for `multiline`.
88         *
89         * @attribute type
90         * @type string
91         * @default text
92         */
93        type: 'text',
94
95        /**
96         * If true, the input is invalid if its value is null.
97         *
98         * @attribute required
99         * @type boolean
100         * @default false
101         */
102        required: false,
103
104        /**
105         * A regular expression to validate the input value against. See
106         * https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation#Validation-related_attributes
107         * for more info. Not supported if `multiline` is true.
108         *
109         * @attribute pattern
110         * @type string
111         * @default '.*'
112         */
113        // FIXME(yvonne): The default is set to .* because we can't bind to pattern such
114        // that the attribute is unset if pattern is null.
115        pattern: '.*',
116
117        /**
118         * If set, the input is invalid if the value is less than this property. See
119         * https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation#Validation-related_attributes
120         * for more info. Not supported if `multiline` is true.
121         *
122         * @attribute min
123         */
124        min: null,
125
126        /**
127         * If set, the input is invalid if the value is greater than this property. See
128         * https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation#Validation-related_attributes
129         * for more info. Not supported if `multiline` is true.
130         *
131         * @attribute max
132         */
133        max: null,
134
135        /**
136         * If set, the input is invalid if the value is not `min` plus an integral multiple
137         * of this property. See
138         * https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation#Validation-related_attributes
139         * for more info. Not supported if `multiline` is true.
140         *
141         * @attribute step
142         */
143        step: null,
144
145        /**
146         * The maximum length of the input value.
147         *
148         * @attribute maxlength
149         * @type number
150         */
151        maxlength: null,
152
153        /**
154         * If this property is true, the text input's inputValue failed validation.
155         *
156         * @attribute invalid
157         * @type boolean
158         * @default false
159         */
160        invalid: false
161      },
162
163      ready: function() {
164        this.handleTabindex(this.getAttribute('tabindex'));
165      },
166
167      invalidChanged: function() {
168        this.classList.toggle('invalid', this.invalid);
169        this.fire('input-'+ (this.invalid ? 'invalid' : 'valid'), {value: this.inputValue});
170      },
171
172      inputValueChanged: function() {
173        this.updateValidity_();
174      },
175
176      valueChanged: function() {
177        this.inputValue = this.value;
178      },
179
180      requiredChanged: function() {
181        this.updateValidity_();
182      },
183
184      attributeChanged: function(attr, oldVal, curVal) {
185        if (attr === 'tabindex') {
186          this.handleTabindex(curVal);
187        }
188      },
189
190      handleTabindex: function(tabindex) {
191        if (tabindex > 0) {
192          this.$.input.setAttribute('tabindex', -1);
193        } else {
194          this.$.input.removeAttribute('tabindex');
195        }
196      },
197
198      /**
199       * Commits the inputValue to value.
200       *
201       * @method commit
202       */
203      commit: function() {
204         this.value = this.inputValue;
205      },
206
207      updateValidity_: function() {
208        if (this.$.input.willValidate) {
209          this.invalid = !this.$.input.validity.valid;
210        }
211      },
212
213      keydownAction: function() {
214        // for type = number, the value is the empty string unless the input is a valid number.
215        // FIXME(yvonne): check other types
216        if (this.type === 'number') {
217          this.async(function() {
218            this.updateValidity_();
219          });
220        }
221      },
222
223      inputChangeAction: function() {
224        this.commit();
225        if (!window.ShadowDOMPolyfill) {
226          // re-fire event that does not bubble across shadow roots
227          this.fire('change', null, this);
228        }
229      },
230
231      focusAction: function(e) {
232        if (this.getAttribute('tabindex') > 0) {
233          // Forward focus to the inner input if tabindex is set on the element
234          // This will not cause an infinite loop because focus will not fire on the <input>
235          // again if it's already focused.
236          this.$.input.focus();
237        }
238      },
239
240      inputFocusAction: function(e) {
241        if (window.ShadowDOMPolyfill) {
242          // re-fire non-bubbling event if polyfill
243          this.fire('focus', null, this, false);
244        }
245      },
246
247      inputBlurAction: function() {
248        if (window.ShadowDOMPolyfill) {
249          // re-fire non-bubbling event
250          this.fire('blur', null, this, false);
251        }
252      },
253
254      blur: function() {
255        // forward blur method to the internal input / textarea element
256        this.$.input.blur();
257      },
258
259      click: function() {
260        // forward click method to the internal input / textarea element
261        this.$.input.click();
262      },
263
264      focus: function() {
265        // forward focus method to the internal input / textarea element
266        this.$.input.focus();
267      },
268
269      select: function() {
270        // forward select method to the internal input / textarea element
271        this.$.input.focus();
272      },
273
274      setSelectionRange: function(selectionStart, selectionEnd, selectionDirection) {
275        // forward setSelectionRange method to the internal input / textarea element
276        this.$.input.setSelectionRange(selectionStart, selectionEnd, selectionDirection);
277      },
278
279      setRangeText: function(replacement, start, end, selectMode) {
280        // forward setRangeText method to the internal input element
281        if (!this.multiline) {
282          this.$.input.setRangeText(replacement, start, end, selectMode);
283        }
284      },
285
286      stepDown: function(n) {
287        // forward stepDown method to the internal input element
288        if (!this.multiline) {
289          this.$.input.stepDown(n);
290        }
291      },
292
293      stepUp: function(n) {
294        // forward stepUp method to the internal input element
295        if (!this.multiline) {
296          this.$.input.stepUp(n);
297        }
298      },
299
300      get willValidate() {
301        return this.$.input.willValidate;
302      },
303
304      get validity() {
305        return this.$.input.validity;
306      },
307
308      get validationMessage() {
309        return this.$.input.validationMessage;
310      },
311
312      checkValidity: function() {
313        var r = this.$.input.checkValidity();
314        this.updateValidity_();
315        return r;
316      },
317
318      setCustomValidity: function(message) {
319        this.$.input.setCustomValidity(message);
320        this.updateValidity_();
321      }
322
323    });
324