Service workers: Allow HTTPS pages arrived at via HTTP redirect to use SW
[chromium-blink-merge.git] / third_party / polymer / v1_0 / components-chromium / iron-autogrow-textarea / iron-autogrow-textarea-extracted.js
blob13f0ebb04b7ef1ec409113628caf5a2fd26e3e99
1 Polymer({
3     is: 'iron-autogrow-textarea',
5     behaviors: [
6       Polymer.IronFormElementBehavior,
7       Polymer.IronValidatableBehavior,
8       Polymer.IronControlState
9     ],
11     properties: {
13       /**
14        * Use this property instead of `value` for two-way data binding.
15        */
16       bindValue: {
17         observer: '_bindValueChanged',
18         type: String
19       },
21       /**
22        * The initial number of rows.
23        *
24        * @attribute rows
25        * @type number
26        * @default 1
27        */
28       rows: {
29         type: Number,
30         value: 1,
31         observer: '_updateCached'
32       },
34       /**
35        * The maximum number of rows this element can grow to until it
36        * scrolls. 0 means no maximum.
37        *
38        * @attribute maxRows
39        * @type number
40        * @default 0
41        */
42       maxRows: {
43        type: Number,
44        value: 0,
45        observer: '_updateCached'
46       },
48       /**
49        * Bound to the textarea's `autocomplete` attribute.
50        */
51       autocomplete: {
52         type: String,
53         value: 'off'
54       },
56       /**
57        * Bound to the textarea's `autofocus` attribute.
58        */
59       autofocus: {
60         type: Boolean,
61         value: false
62       },
64       /**
65        * Bound to the textarea's `inputmode` attribute.
66        */
67       inputmode: {
68         type: String
69       },
71       /**
72        * Bound to the textarea's `name` attribute.
73        */
74       name: {
75         type: String
76       },
78       /**
79        * The value for this input, same as `bindValue`
80        */
81       value: {
82         notify: true,
83         type: String,
84         computed: '_computeValue(bindValue)'
85       },
87       /**
88        * Bound to the textarea's `placeholder` attribute.
89        */
90       placeholder: {
91         type: String
92       },
94       /**
95        * Bound to the textarea's `readonly` attribute.
96        */
97       readonly: {
98         type: String
99       },
101       /**
102        * Set to true to mark the textarea as required.
103        */
104       required: {
105         type: Boolean
106       },
108       /**
109        * The maximum length of the input value.
110        */
111       maxlength: {
112         type: Number
113       }
115     },
117     listeners: {
118       'input': '_onInput'
119     },
121     /**
122      * Returns the underlying textarea.
123      * @type HTMLTextAreaElement
124      */
125     get textarea() {
126       return this.$.textarea;
127     },
129     /**
130      * Returns true if `value` is valid. The validator provided in `validator`
131      * will be used first, if it exists; otherwise, the `textarea`'s validity
132      * is used.
133      * @return {boolean} True if the value is valid.
134      */
135     validate: function() {
136       // Empty, non-required input is valid.
137       if (!this.required && this.value == '') {
138         this.invalid = false;
139         return true;
140       }
142       var valid;
143       if (this.hasValidator()) {
144         valid = Polymer.IronValidatableBehavior.validate.call(this, this.value);
145       } else {
146         valid = this.$.textarea.validity.valid;
147         this.invalid = !valid;
148       }
149       this.fire('iron-input-validate');
150       return valid;
151     },
153     _update: function() {
154       this.$.mirror.innerHTML = this._valueForMirror();
156       var textarea = this.textarea;
157       // If the value of the textarea was updated imperatively, then we
158       // need to manually update bindValue as well.
159       if (textarea && this.bindValue != textarea.value) {
160         this.bindValue = textarea.value;
161       }
162     },
164     _bindValueChanged: function() {
165       var textarea = this.textarea;
166       if (!textarea) {
167         return;
168       }
170       textarea.value = this.bindValue;
171       this._update();
172       // manually notify because we don't want to notify until after setting value
173       this.fire('bind-value-changed', {value: this.bindValue});
174     },
176     _onInput: function(event) {
177       this.bindValue = event.path ? event.path[0].value : event.target.value;
178       this._update();
179     },
181     _constrain: function(tokens) {
182       var _tokens;
183       tokens = tokens || [''];
184       // Enforce the min and max heights for a multiline input to avoid measurement
185       if (this.maxRows > 0 && tokens.length > this.maxRows) {
186         _tokens = tokens.slice(0, this.maxRows);
187       } else {
188         _tokens = tokens.slice(0);
189       }
190       while (this.rows > 0 && _tokens.length < this.rows) {
191         _tokens.push('');
192       }
193       return _tokens.join('<br>') + '&nbsp;';
194     },
196     _valueForMirror: function() {
197       var input = this.textarea;
198       if (!input) {
199         return;
200       }
201       this.tokens = (input && input.value) ? input.value.replace(/&/gm, '&amp;').replace(/"/gm, '&quot;').replace(/'/gm, '&#39;').replace(/</gm, '&lt;').replace(/>/gm, '&gt;').split('\n') : [''];
202       return this._constrain(this.tokens);
203     },
205     _updateCached: function() {
206       this.$.mirror.innerHTML = this._constrain(this.tokens);
207     },
209     _computeValue: function() {
210       return this.bindValue;
211     }
212   });