Index: third_party/polymer/components/core-input/core-input.html |
diff --git a/third_party/polymer/components/core-input/core-input.html b/third_party/polymer/components/core-input/core-input.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..95edde0787e8e7dbd9c88e5d8223be645e89a476 |
--- /dev/null |
+++ b/third_party/polymer/components/core-input/core-input.html |
@@ -0,0 +1,432 @@ |
+<!-- |
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved. |
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE |
+The complete set of authors may be found at http://polymer.github.io/AUTHORS |
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS |
+Code distributed by Google as part of the polymer project is also |
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS |
+--> |
+ |
+<!-- |
+/** |
+ * core-input is an unstyled single- or multi-line text field where user can |
+ * enter input. |
+ * |
+ * Example: |
+ * |
+ * <core-input placeholder="Placeholder text here"></core-input> |
+ * |
+ * <core-input multiline placeholder="Enter multiple lines here"></core-input> |
+ * |
+ * The text input's value is considered "committed" if the user hits the "enter" |
+ * key or blurs the input after changing the value. The `change` event is fired |
+ * when the value becomes committed, and the committed value is stored in the |
+ * `value` property. The current value of the input is stored in the `inputValue` |
+ * property. |
+ * |
+ * Validation |
+ * ---------- |
+ * |
+ * core-input can optionally validate the value using the HTML5 constraints API, |
+ * similar to native inputs. There are two methods to enable input validation: |
+ * |
+ * 1. By setting the `type` attribute. For example, setting it to `email` will |
+ * check the value is a valid email, and setting it to `number` will check |
+ * the input is a number. |
+ * |
+ * 2. By setting attributes related to validation. The attributes are `pattern`, |
+ * `min`, `max`, `step` and `required`. |
+ * |
+ * Only `required` is supported for multiline inputs currently. |
+ * |
+ * Example: |
+ * |
+ * <core-input type="email" placeholder="enter your email"></core-input> |
+ * |
+ * <core-input type="number" min="5" placeholder="enter a number greater than or equal to 5"></core-input> |
+ * |
+ * <core-input pattern=".*abc.*" placeholder="enter something containing 'abc'"></core-input> |
+ * |
+ * See https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation |
+ * for more info on validation. |
+ * |
+ * @group Polymer Core Elements |
+ * @element core-input |
+ * @homepage github.io |
+ */ |
+--> |
+ |
+<!-- |
+Fired when the inputValue of is changed. This is the same event as the DOM |
+"input" event. |
+ |
+@event input |
+--> |
+ |
+<!-- |
+Fired when the user commits the value of the input, either by the hitting the |
+`enter` key or blurring the input after the changing the inputValue. Also see the |
+DOM "change" event. |
+ |
+@event change |
+--> |
+ |
+<!-- |
+Fired when the inputValue of this text input changes and fails validation. |
+ |
+@event input-invalid |
+@param {Object} detail |
+@param {string} value The text input's inputValue. |
+--> |
+ |
+<!-- |
+Fired when the inputValue of this text input changes and passes validation. |
+ |
+@event input-valid |
+@param {Object} detail |
+@param {string} value The text input's inputValue. |
+--> |
+<link href="../polymer/polymer.html" rel="import"> |
+ |
+<polymer-element name="core-input" on-focus="{{focusAction}}"> |
+ |
+ <template> |
+ |
+ <link href="core-input.css" rel="stylesheet"> |
+ |
+ <template if="{{multiline}}"> |
+ <textarea id="input" value="{{inputValue}}" rows="{{rows}}" fit?="{{rows === 'fit'}}" disabled?="{{disabled}}" placeholder="{{placeholder}}" autofocus?="{{autofocus}}" required?="{{required}}" readonly?="{{readonly}}" aria-label="{{label || placeholder}}" aria-invalid="{{invalid}}" on-change="{{inputChangeAction}}" on-focus="{{inputFocusAction}}" on-blur="{{inputBlurAction}}"></textarea> |
+ </template> |
+ |
+ <template if="{{!multiline}}"> |
+ <input id="input" value="{{inputValue}}" disabled?="{{disabled}}" type="{{type}}" placeholder="{{placeholder}}" autofocus?="{{autofocus}}" required?="{{required}}" readonly?="{{readonly}}" pattern="{{pattern}}" min="{{min}}" max="{{max}}" step="{{step}}" maxlength="{{maxlength}}" aria-label="{{label || placeholder}}" aria-invalid="{{invalid}}" on-keydown="{{keydownAction}}" on-change="{{inputChangeAction}}" on-focus="{{inputFocusAction}}" on-blur="{{inputBlurAction}}"> |
+ </template> |
+ |
+ </template> |
+ |
+ <script> |
+ |
+ Polymer('core-input', { |
+ publish: { |
+ /** |
+ * Placeholder text that hints to the user what can be entered in |
+ * the input. |
+ * |
+ * @attribute placeholder |
+ * @type string |
+ * @default '' |
+ */ |
+ placeholder: '', |
+ |
+ /** |
+ * If true, this input cannot be focused and the user cannot change |
+ * its value. |
+ * |
+ * @attribute disabled |
+ * @type boolean |
+ * @default false |
+ */ |
+ disabled: false, |
+ |
+ /** |
+ * If true, the user cannot modify the value of the input. |
+ * |
+ * @attribute readonly |
+ * @type boolean |
+ * @default false |
+ */ |
+ readonly: false, |
+ |
+ /** |
+ * If true, this input will automatically gain focus on page load. |
+ * |
+ * @attribute autofocus |
+ * @type boolean |
+ * @default false |
+ */ |
+ autofocus: false, |
+ |
+ /** |
+ * If true, this input accepts multi-line input like a `<textarea>` |
+ * |
+ * @attribute multiline |
+ * @type boolean |
+ * @default false |
+ */ |
+ multiline: false, |
+ |
+ /** |
+ * (multiline only) The height of this text input in rows. The input |
+ * will scroll internally if more input is entered beyond the size |
+ * of the component. This property is meaningless if multiline is |
+ * false. You can also set this property to "fit" and size the |
+ * component with CSS to make the input fit the CSS size. |
+ * |
+ * @attribute rows |
+ * @type number|'fit' |
+ * @default 'fit' |
+ */ |
+ rows: 'fit', |
+ |
+ /** |
+ * The current value of this input. Changing inputValue programmatically |
+ * will cause value to be out of sync. Instead, change value directly |
+ * or call commit() after changing inputValue. |
+ * |
+ * @attribute inputValue |
+ * @type string |
+ * @default '' |
+ */ |
+ inputValue: '', |
+ |
+ /** |
+ * The value of the input committed by the user, either by changing the |
+ * inputValue and blurring the input, or by hitting the `enter` key. |
+ * |
+ * @attribute value |
+ * @type string |
+ * @default '' |
+ */ |
+ value: '', |
+ |
+ /** |
+ * Set the input type. Not supported for `multiline`. |
+ * |
+ * @attribute type |
+ * @type string |
+ * @default text |
+ */ |
+ type: 'text', |
+ |
+ /** |
+ * If true, the input is invalid if its value is null. |
+ * |
+ * @attribute required |
+ * @type boolean |
+ * @default false |
+ */ |
+ required: false, |
+ |
+ /** |
+ * A regular expression to validate the input value against. See |
+ * https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation#Validation-related_attributes |
+ * for more info. Not supported if `multiline` is true. |
+ * |
+ * @attribute pattern |
+ * @type string |
+ * @default '.*' |
+ */ |
+ // FIXME(yvonne): The default is set to .* because we can't bind to pattern such |
+ // that the attribute is unset if pattern is null. |
+ pattern: '.*', |
+ |
+ /** |
+ * If set, the input is invalid if the value is less than this property. See |
+ * https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation#Validation-related_attributes |
+ * for more info. Not supported if `multiline` is true. |
+ * |
+ * @attribute min |
+ */ |
+ min: null, |
+ |
+ /** |
+ * If set, the input is invalid if the value is greater than this property. See |
+ * https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation#Validation-related_attributes |
+ * for more info. Not supported if `multiline` is true. |
+ * |
+ * @attribute max |
+ */ |
+ max: null, |
+ |
+ /** |
+ * If set, the input is invalid if the value is not `min` plus an integral multiple |
+ * of this property. See |
+ * https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation#Validation-related_attributes |
+ * for more info. Not supported if `multiline` is true. |
+ * |
+ * @attribute step |
+ */ |
+ step: null, |
+ |
+ /** |
+ * The maximum length of the input value. |
+ * |
+ * @attribute maxlength |
+ * @type number |
+ */ |
+ maxlength: null, |
+ |
+ /** |
+ * If this property is true, the text input's inputValue failed validation. |
+ * |
+ * @attribute invalid |
+ * @type boolean |
+ * @default false |
+ */ |
+ invalid: false |
+ }, |
+ |
+ ready: function() { |
+ this.handleTabindex(this.getAttribute('tabindex')); |
+ }, |
+ |
+ invalidChanged: function() { |
+ this.classList.toggle('invalid', this.invalid); |
+ this.fire('input-'+ (this.invalid ? 'invalid' : 'valid'), {value: this.inputValue}); |
+ }, |
+ |
+ inputValueChanged: function() { |
+ this.updateValidity_(); |
+ }, |
+ |
+ valueChanged: function() { |
+ this.inputValue = this.value; |
+ }, |
+ |
+ requiredChanged: function() { |
+ this.updateValidity_(); |
+ }, |
+ |
+ attributeChanged: function(attr, oldVal, curVal) { |
+ if (attr === 'tabindex') { |
+ this.handleTabindex(curVal); |
+ } |
+ }, |
+ |
+ handleTabindex: function(tabindex) { |
+ if (tabindex > 0) { |
+ this.$.input.setAttribute('tabindex', -1); |
+ } else { |
+ this.$.input.removeAttribute('tabindex'); |
+ } |
+ }, |
+ |
+ /** |
+ * Commits the inputValue to value. |
+ * |
+ * @method commit |
+ */ |
+ commit: function() { |
+ this.value = this.inputValue; |
+ }, |
+ |
+ updateValidity_: function() { |
+ if (this.$.input.willValidate) { |
+ this.invalid = !this.$.input.validity.valid; |
+ } |
+ }, |
+ |
+ keydownAction: function() { |
+ // for type = number, the value is the empty string unless the input is a valid number. |
+ // FIXME(yvonne): check other types |
+ if (this.type === 'number') { |
+ this.async(function() { |
+ this.updateValidity_(); |
+ }); |
+ } |
+ }, |
+ |
+ inputChangeAction: function() { |
+ this.commit(); |
+ if (!window.ShadowDOMPolyfill) { |
+ // re-fire event that does not bubble across shadow roots |
+ this.fire('change', null, this); |
+ } |
+ }, |
+ |
+ focusAction: function(e) { |
+ if (this.getAttribute('tabindex') > 0) { |
+ // Forward focus to the inner input if tabindex is set on the element |
+ // This will not cause an infinite loop because focus will not fire on the <input> |
+ // again if it's already focused. |
+ this.$.input.focus(); |
+ } |
+ }, |
+ |
+ inputFocusAction: function(e) { |
+ if (window.ShadowDOMPolyfill) { |
+ // re-fire non-bubbling event if polyfill |
+ this.fire('focus', null, this, false); |
+ } |
+ }, |
+ |
+ inputBlurAction: function() { |
+ if (window.ShadowDOMPolyfill) { |
+ // re-fire non-bubbling event |
+ this.fire('blur', null, this, false); |
+ } |
+ }, |
+ |
+ blur: function() { |
+ // forward blur method to the internal input / textarea element |
+ this.$.input.blur(); |
+ }, |
+ |
+ click: function() { |
+ // forward click method to the internal input / textarea element |
+ this.$.input.click(); |
+ }, |
+ |
+ focus: function() { |
+ // forward focus method to the internal input / textarea element |
+ this.$.input.focus(); |
+ }, |
+ |
+ select: function() { |
+ // forward select method to the internal input / textarea element |
+ this.$.input.focus(); |
+ }, |
+ |
+ setSelectionRange: function(selectionStart, selectionEnd, selectionDirection) { |
+ // forward setSelectionRange method to the internal input / textarea element |
+ this.$.input.setSelectionRange(selectionStart, selectionEnd, selectionDirection); |
+ }, |
+ |
+ setRangeText: function(replacement, start, end, selectMode) { |
+ // forward setRangeText method to the internal input element |
+ if (!this.multiline) { |
+ this.$.input.setRangeText(replacement, start, end, selectMode); |
+ } |
+ }, |
+ |
+ stepDown: function(n) { |
+ // forward stepDown method to the internal input element |
+ if (!this.multiline) { |
+ this.$.input.stepDown(n); |
+ } |
+ }, |
+ |
+ stepUp: function(n) { |
+ // forward stepUp method to the internal input element |
+ if (!this.multiline) { |
+ this.$.input.stepUp(n); |
+ } |
+ }, |
+ |
+ get willValidate() { |
+ return this.$.input.willValidate; |
+ }, |
+ |
+ get validity() { |
+ return this.$.input.validity; |
+ }, |
+ |
+ get validationMessage() { |
+ return this.$.input.validationMessage; |
+ }, |
+ |
+ checkValidity: function() { |
+ var r = this.$.input.checkValidity(); |
+ this.updateValidity_(); |
+ return r; |
+ }, |
+ |
+ setCustomValidity: function(message) { |
+ this.$.input.setCustomValidity(message); |
+ this.updateValidity_(); |
+ } |
+ |
+ }); |
+ </script> |
+ |
+</polymer-element> |