polymer-paper-rails 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +69 -0
  3. data/Rakefile +1 -0
  4. data/app/assets/components/core/animation/web-animations.html.erb +1 -0
  5. data/app/assets/components/core/animation/web-animations.js +5666 -0
  6. data/app/assets/components/core/icon/core-icon.css +25 -0
  7. data/app/assets/components/core/icon/core-icon.html.erb +126 -0
  8. data/app/assets/components/core/iconset/core-iconset.html.erb +236 -0
  9. data/app/assets/components/core/input/core-input.css +35 -0
  10. data/app/assets/components/core/input/core-input.html.erb +385 -0
  11. data/app/assets/components/core/list/core-list.css +20 -0
  12. data/app/assets/components/core/list/core-list.html.erb +403 -0
  13. data/app/assets/components/core/media-query/core-media-query.html +86 -0
  14. data/app/assets/components/core/menu/core-menu.css +18 -0
  15. data/app/assets/components/core/menu/core-menu.html.erb +62 -0
  16. data/app/assets/components/core/menu/core-submenu.css +29 -0
  17. data/app/assets/components/core/menu/core-submenu.html.erb +106 -0
  18. data/app/assets/components/core/meta/core-meta.html +143 -0
  19. data/app/assets/components/core/overlay/core-key-helper.html +17 -0
  20. data/app/assets/components/core/overlay/core-overlay-layer.html +112 -0
  21. data/app/assets/components/core/overlay/core-overlay.html.erb +661 -0
  22. data/app/assets/components/core/range/core-range.html +106 -0
  23. data/app/assets/components/core/selection/core-selection.html +148 -0
  24. data/app/assets/components/core/selector/core-selector.html.erb +423 -0
  25. data/app/assets/components/core/style/core-style.html +386 -0
  26. data/app/assets/components/core/transition/core-transition-css.html.erb +76 -0
  27. data/app/assets/components/core/transition/core-transition-overlay.css +46 -0
  28. data/app/assets/components/core/transition/core-transition.html.erb +44 -0
  29. data/app/assets/components/paper-button/paper-button.css +115 -0
  30. data/app/assets/components/paper-button/paper-button.html.erb +210 -0
  31. data/app/assets/components/paper-checkbox/paper-checkbox.css +262 -0
  32. data/app/assets/components/paper-checkbox/paper-checkbox.html.erb +104 -0
  33. data/app/assets/components/paper-dialog/paper-dialog-transition.css +59 -0
  34. data/app/assets/components/paper-dialog/paper-dialog-transition.html.erb +27 -0
  35. data/app/assets/components/paper-dialog/paper-dialog.css +0 -0
  36. data/app/assets/components/paper-dialog/paper-dialog.html.erb +176 -0
  37. data/app/assets/components/paper-fab/paper-fab.css +27 -0
  38. data/app/assets/components/paper-fab/paper-fab.html.erb +55 -0
  39. data/app/assets/components/paper-focusable/paper-focusable.html +144 -0
  40. data/app/assets/components/paper-icon-button/paper-icon-button.css +17 -0
  41. data/app/assets/components/paper-icon-button/paper-icon-button.html.erb +87 -0
  42. data/app/assets/components/paper-input/error-100.png +0 -0
  43. data/app/assets/components/paper-input/error-200.png +0 -0
  44. data/app/assets/components/paper-input/paper-input.html.erb +398 -0
  45. data/app/assets/components/paper-input/paper-input.scss +203 -0
  46. data/app/assets/components/paper-item/paper-item.css +30 -0
  47. data/app/assets/components/paper-item/paper-item.html.erb +103 -0
  48. data/app/assets/components/paper-menu-button/paper-menu-button-overlay.html.erb +86 -0
  49. data/app/assets/components/paper-menu-button/paper-menu-button-transition.css +19 -0
  50. data/app/assets/components/paper-menu-button/paper-menu-button-transition.html.erb +118 -0
  51. data/app/assets/components/paper-menu-button/paper-menu-button.css +86 -0
  52. data/app/assets/components/paper-menu-button/paper-menu-button.html.erb +128 -0
  53. data/app/assets/components/paper-progress/paper-progress.css +35 -0
  54. data/app/assets/components/paper-progress/paper-progress.html.erb +98 -0
  55. data/app/assets/components/paper-radio-button/paper-radio-button.css +98 -0
  56. data/app/assets/components/paper-radio-button/paper-radio-button.html.erb +148 -0
  57. data/app/assets/components/paper-radio-group/paper-radio-group.html.erb +68 -0
  58. data/app/assets/components/paper-ripple/paper-ripple.html +426 -0
  59. data/app/assets/components/paper-shadow/paper-shadow.css +81 -0
  60. data/app/assets/components/paper-shadow/paper-shadow.html.erb +212 -0
  61. data/app/assets/components/paper-slider/paper-slider.css +193 -0
  62. data/app/assets/components/paper-slider/paper-slider.html.erb +310 -0
  63. data/app/assets/components/paper-tabs/paper-tab.css +49 -0
  64. data/app/assets/components/paper-tabs/paper-tab.html.erb +66 -0
  65. data/app/assets/components/paper-tabs/paper-tabs.css +57 -0
  66. data/app/assets/components/paper-tabs/paper-tabs.html.erb +127 -0
  67. data/app/assets/components/paper-toast/paper-toast.css +0 -0
  68. data/app/assets/components/paper-toast/paper-toast.html.erb +258 -0
  69. data/app/assets/components/paper-toggle-button/paper-toggle-button.css +61 -0
  70. data/app/assets/components/paper-toggle-button/paper-toggle-button.html.erb +125 -0
  71. data/lib/polymer-paper-rails/engine.rb +4 -0
  72. data/lib/polymer-paper-rails/version.rb +3 -0
  73. data/lib/polymer-paper-rails.rb +2 -0
  74. metadata +158 -0
@@ -0,0 +1,25 @@
1
+ /* Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
2
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
3
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
4
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
5
+ Code distributed by Google as part of the polymer project is also
6
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt */
7
+
8
+ html /deep/ core-icon {
9
+ display: inline-block;
10
+ vertical-align: middle;
11
+ background-repeat: no-repeat;
12
+ fill: currentcolor;
13
+ }
14
+
15
+ html /deep/ core-icon[size=""] {
16
+ position: relative;
17
+ }
18
+
19
+ html /deep/ core-icon[size=""] > svg {
20
+ position: absolute;
21
+ top: 0;
22
+ right: 0;
23
+ bottom: 0;
24
+ left: 0;
25
+ }
@@ -0,0 +1,126 @@
1
+ <!--
2
+ Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
3
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
4
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
5
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
6
+ Code distributed by Google as part of the polymer project is also
7
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
8
+ -->
9
+ <!--
10
+
11
+ The `core-icon` element displays an icon using CSS background image. By default an icon renders as 24px square.
12
+
13
+ Example using src:
14
+
15
+ <core-icon src="star.png"></core-icon>
16
+
17
+ Example setting size to 32px x 32px:
18
+
19
+ <core-icon src="big_star.png" size="32"></core-icon>
20
+
21
+ Example using icon from default iconset:
22
+
23
+ <core-icon icon="menu"></core-icon>
24
+
25
+ Example using icon `cherry` from custom iconset `fruit`:
26
+
27
+ <core-icon icon="fruit:cherry"></core-icon>
28
+
29
+ See [core-iconset](#core-iconset) and [core-iconset-svg](#core-iconset-svg) for more information about
30
+ how to use a custom iconset.
31
+
32
+ See [core-icons](http://www.polymer-project.org/components/core-icons/demo.html) for the default set of icons. To use the default set of icons you'll need to include an import for `core-icons.html`.
33
+
34
+ @group Polymer Core Elements
35
+ @element core-icon
36
+ @homepage polymer.github.io
37
+ -->
38
+ <%= html_import_tag "core/iconset/core-iconset" %>
39
+
40
+ <%= stylesheet_link_tag "core/icon/core-icon"%>
41
+
42
+
43
+ <polymer-element name="core-icon" attributes="src size icon">
44
+ <script>
45
+ (function() {
46
+
47
+ // mono-state
48
+ var meta;
49
+
50
+ Polymer('core-icon', {
51
+
52
+ /**
53
+ * The URL of an image for the icon. If the src property is specified,
54
+ * the icon property should not be.
55
+ *
56
+ * @attribute src
57
+ * @type string
58
+ * @default ''
59
+ */
60
+ src: '',
61
+
62
+ /**
63
+ * Specifies the size of the icon in pixel units.
64
+ *
65
+ * @attribute size
66
+ * @type string
67
+ * @default 24
68
+ */
69
+ size: 24,
70
+
71
+ /**
72
+ * Specifies the icon name or index in the set of icons available in
73
+ * the icon's icon set. If the icon property is specified,
74
+ * the src property should not be.
75
+ *
76
+ * @attribute icon
77
+ * @type string
78
+ * @default ''
79
+ */
80
+ icon: '',
81
+
82
+ observe: {
83
+ 'size icon': 'updateIcon'
84
+ },
85
+
86
+ defaultIconset: 'icons',
87
+
88
+ ready: function() {
89
+ if (!meta) {
90
+ meta = document.createElement('core-iconset');
91
+ }
92
+ this.updateIcon();
93
+ },
94
+
95
+ srcChanged: function() {
96
+ this.style.backgroundImage = 'url(' + this.src + ')';
97
+ this.style.backgroundPosition = 'center';
98
+ this.style.backgroundSize = this.size + 'px ' + this.size + 'px';
99
+ },
100
+
101
+ getIconset: function(name) {
102
+ return meta.byId(name || this.defaultIconset);
103
+ },
104
+
105
+ updateIcon: function() {
106
+ if (this.size) {
107
+ this.style.width = this.style.height = this.size + 'px';
108
+ }
109
+ if (this.icon) {
110
+ var parts = String(this.icon).split(':');
111
+ var icon = parts.pop();
112
+ if (icon) {
113
+ var set = this.getIconset(parts.pop());
114
+ if (set) {
115
+ set.applyIcon(this, icon, this.size / set.iconSize);
116
+ }
117
+ }
118
+ }
119
+ }
120
+
121
+ });
122
+
123
+ })();
124
+ </script>
125
+
126
+ </polymer-element>
@@ -0,0 +1,236 @@
1
+ <!--
2
+ Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
3
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
4
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
5
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
6
+ Code distributed by Google as part of the polymer project is also
7
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
8
+ -->
9
+
10
+ <!--
11
+ /**
12
+ * @group Polymer Core Elements
13
+ *
14
+ * The `core-iconset` element allows users to define their own icon sets.
15
+ * The `src` property specifies the url of the icon image. Multiple icons may
16
+ * be included in this image and they may be organized into rows.
17
+ * The `icons` property is a space separated list of names corresponding to the
18
+ * icons. The names must be ordered as the icons are ordered in the icon image.
19
+ * Icons are expected to be square and are the size specified by the `iconSize`
20
+ * property. The `width` property corresponds to the width of the icon image
21
+ * and must be specified if icons are arranged into multiple rows in the image.
22
+ *
23
+ * All `core-iconset` elements are available for use by other `core-iconset`
24
+ * elements via a database keyed by id. Typically, an element author that wants
25
+ * to support a set of custom icons uses a `core-iconset` to retrieve
26
+ * and use another, user-defined iconset.
27
+ *
28
+ * Example:
29
+ *
30
+ * <core-iconset id="my-icons" src="my-icons.png" width="96" iconSize="24"
31
+ * icons="location place starta stopb bus car train walk">
32
+ * </core-iconset>
33
+ *
34
+ * This will automatically register the icon set "my-icons" to the iconset
35
+ * database. To use these icons from within another element, make a
36
+ * `core-iconset` element and call the `byId` method to retrieve a
37
+ * given iconset. To apply a particular icon to an element, use the
38
+ * `applyIcon` method. For example:
39
+ *
40
+ * iconset.applyIcon(iconNode, 'car');
41
+ *
42
+ * Themed icon sets are also supported. The `core-iconset` can contain child
43
+ * `property` elements that specify a theme with an offsetX and offsetY of the
44
+ * theme within the icon resource. For example.
45
+ *
46
+ * <core-iconset id="my-icons" src="my-icons.png" width="96" iconSize="24"
47
+ * icons="location place starta stopb bus car train walk">
48
+ * <property theme="special" offsetX="256" offsetY="24"></property>
49
+ * </core-iconset>
50
+ *
51
+ * Then a themed icon can be applied like this:
52
+ *
53
+ * iconset.applyIcon(iconNode, 'car', 'special');
54
+ *
55
+ * @element core-iconset
56
+ * @extends core-meta
57
+ * @homepage github.io
58
+ */
59
+ -->
60
+
61
+ <%= html_import_tag "core/meta/core-meta" %>
62
+
63
+ <polymer-element name="core-iconset" extends="core-meta" attributes="src width icons iconSize">
64
+
65
+ <script>
66
+
67
+ Polymer('core-iconset', {
68
+
69
+ /**
70
+ * The URL of the iconset image.
71
+ *
72
+ * @attribute src
73
+ * @type string
74
+ * @default ''
75
+ */
76
+ src: '',
77
+
78
+ /**
79
+ * The width of the iconset image. This must only be specified if the
80
+ * icons are arranged into separate rows inside the image.
81
+ *
82
+ * @attribute width
83
+ * @type number
84
+ * @default 0
85
+ */
86
+ width: 0,
87
+
88
+ /**
89
+ * A space separated list of names corresponding to icons in the iconset
90
+ * image file. This list must be ordered the same as the icon images
91
+ * in the image file.
92
+ *
93
+ * @attribute icons
94
+ * @type string
95
+ * @default ''
96
+ */
97
+ icons: '',
98
+
99
+ /**
100
+ * The size of an individual icon. Note that icons must be square.
101
+ *
102
+ * @attribute iconSize
103
+ * @type number
104
+ * @default 24
105
+ */
106
+ iconSize: 24,
107
+
108
+ /**
109
+ * The horizontal offset of the icon images in the inconset src image.
110
+ * This is typically used if the image resource contains additional images
111
+ * beside those intended for the iconset.
112
+ *
113
+ * @attribute offsetX
114
+ * @type number
115
+ * @default 0
116
+ */
117
+ offsetX: 0,
118
+ /**
119
+ * The vertical offset of the icon images in the inconset src image.
120
+ * This is typically used if the image resource contains additional images
121
+ * beside those intended for the iconset.
122
+ *
123
+ * @attribute offsetY
124
+ * @type number
125
+ * @default 0
126
+ */
127
+ offsetY: 0,
128
+ type: 'iconset',
129
+
130
+ created: function() {
131
+ this.iconMap = {};
132
+ this.iconNames = [];
133
+ this.themes = {};
134
+ },
135
+
136
+ ready: function() {
137
+ // TODO(sorvell): ensure iconset's src is always relative to the main
138
+ // document
139
+ if (this.src && (this.ownerDocument !== document)) {
140
+ this.src = this.resolvePath(this.src, this.ownerDocument.baseURI);
141
+ }
142
+ this.super();
143
+ this.updateThemes();
144
+ },
145
+
146
+ iconsChanged: function() {
147
+ var ox = this.offsetX;
148
+ var oy = this.offsetY;
149
+ this.icons && this.icons.split(/\s+/g).forEach(function(name, i) {
150
+ this.iconNames.push(name);
151
+ this.iconMap[name] = {
152
+ offsetX: ox,
153
+ offsetY: oy
154
+ }
155
+ if (ox + this.iconSize < this.width) {
156
+ ox += this.iconSize;
157
+ } else {
158
+ ox = this.offsetX;
159
+ oy += this.iconSize;
160
+ }
161
+ }, this);
162
+ },
163
+
164
+ updateThemes: function() {
165
+ var ts = this.querySelectorAll('property[theme]');
166
+ ts && ts.array().forEach(function(t) {
167
+ this.themes[t.getAttribute('theme')] = {
168
+ offsetX: parseInt(t.getAttribute('offsetX')) || 0,
169
+ offsetY: parseInt(t.getAttribute('offsetY')) || 0
170
+ };
171
+ }, this);
172
+ },
173
+
174
+ // TODO(ffu): support retrived by index e.g. getOffset(10);
175
+ /**
176
+ * Returns an object containing `offsetX` and `offsetY` properties which
177
+ * specify the pixel locaion in the iconset's src file for the given
178
+ * `icon` and `theme`. It's uncommon to call this method. It is useful,
179
+ * for example, to manually position a css backgroundImage to the proper
180
+ * offset. It's more common to use the `applyIcon` method.
181
+ *
182
+ * @method getOffset
183
+ * @param {String|Number} icon The name of the icon or the index of the
184
+ * icon within in the icon image.
185
+ * @param {String} theme The name of the theme.
186
+ * @returns {Object} An object specifying the offset of the given icon
187
+ * within the icon resource file; `offsetX` is the horizontal offset and
188
+ * `offsetY` is the vertical offset. Both values are in pixel units.
189
+ */
190
+ getOffset: function(icon, theme) {
191
+ var i = this.iconMap[icon];
192
+ if (!i) {
193
+ var n = this.iconNames[Number(icon)];
194
+ i = this.iconMap[n];
195
+ }
196
+ var t = this.themes[theme];
197
+ if (i && t) {
198
+ return {
199
+ offsetX: i.offsetX + t.offsetX,
200
+ offsetY: i.offsetY + t.offsetY
201
+ }
202
+ }
203
+ return i;
204
+ },
205
+
206
+ /**
207
+ * Applies an icon to the given element as a css background image. This
208
+ * method does not size the element, and it's often necessary to set
209
+ * the element's height and width so that the background image is visible.
210
+ *
211
+ * @method applyIcon
212
+ * @param {Element} element The element to which the background is
213
+ * applied.
214
+ * @param {String|Number} icon The name or index of the icon to apply.
215
+ * @param {String} theme (optional) The name of the theme for the icon.
216
+ * @param {Number} scale (optional, defaults to 1) A scaling factor
217
+ * with which the icon can be magnified.
218
+ */
219
+ applyIcon: function(element, icon, scale) {
220
+ var offset = this.getOffset(icon);
221
+ scale = scale || 1;
222
+ if (element && offset) {
223
+ var style = element.style;
224
+ style.backgroundImage = 'url(' + this.src + ')';
225
+ style.backgroundPosition = (-offset.offsetX * scale + 'px') +
226
+ ' ' + (-offset.offsetY * scale + 'px');
227
+ style.backgroundSize = scale === 1 ? 'auto' :
228
+ this.width * scale + 'px';
229
+ }
230
+ }
231
+
232
+ });
233
+
234
+ </script>
235
+
236
+ </polymer-element>
@@ -0,0 +1,35 @@
1
+ :host {
2
+ display: inline-block;
3
+ text-align: inherit;
4
+ color: #ccc;
5
+ position: relative;
6
+ width: 20em;
7
+ }
8
+
9
+ :host:hover {
10
+ cursor: text;
11
+ }
12
+
13
+ input,
14
+ textarea {
15
+ font: inherit;
16
+ width: 100%;
17
+ margin: 0;
18
+ padding: 0;
19
+ background-color: transparent;
20
+ border: none;
21
+ outline: none;
22
+ width: 100%;
23
+ }
24
+
25
+ textarea {
26
+ resize: none;
27
+ }
28
+
29
+ textarea[fit] {
30
+ position: absolute;
31
+ top: 0;
32
+ left: 0;
33
+ right: 0;
34
+ bottom: 0;
35
+ }
@@ -0,0 +1,385 @@
1
+ <!--
2
+ Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
3
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
4
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS
5
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
6
+ Code distributed by Google as part of the polymer project is also
7
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
8
+ -->
9
+
10
+ <!--
11
+ /**
12
+ * core-input is an unstyled single- or multi-line text field where user can
13
+ * enter input.
14
+ *
15
+ * Example:
16
+ *
17
+ * <core-input placeholder="Placeholder text here"></core-input>
18
+ *
19
+ * <core-input multiline placeholder="Enter multiple lines here"></core-input>
20
+ *
21
+ * The text input's value is considered "committed" if the user hits the `enter`
22
+ * key or blurs the input after changing the value. The "change" event is fired
23
+ * when the value becomes committed, and the committed value is stored in the
24
+ * "value" property. The current value of the input is stored in the "inputValue"
25
+ * property.
26
+ *
27
+ * core-input also can optionally validate the value by providing it with a
28
+ * regular expression to match against, or a validation function. The
29
+ * "input-invalid" event is fired if the input value changes and is invalid.
30
+ * The "invalid" property is also available for observation.
31
+ *
32
+ * Example:
33
+ *
34
+ * // valid only if the value is a number
35
+ * <core-input validate="^[0-9]*$" on-input-invalid="{{inputInvalidAction}}"></core-input>
36
+ *
37
+ * this.$.input.validate = /^[0-9]*$/; // valid only if the value is a number
38
+ *
39
+ * this.$.input2.validate = function(value) {
40
+ * return value === 'foo'; // valid only if the value is 'foo'
41
+ * }
42
+ *
43
+ * @group Polymer Core Elements
44
+ * @element core-input
45
+ * @homepage github.io
46
+ */
47
+ -->
48
+
49
+ <!--
50
+ Fired when the inputValue of is changed. This is the same event as the DOM
51
+ "input" event.
52
+
53
+ @event input
54
+ -->
55
+
56
+ <!--
57
+ Fired when the user commits the value of the input, either by the hitting the
58
+ `enter` key or blurring the input after the changing the inputValue. Also see the
59
+ DOM "change" event.
60
+
61
+ @event change
62
+ -->
63
+
64
+ <!--
65
+ Fired when the inputValue of this text input changes and fails validation.
66
+
67
+ @event input-invalid
68
+ @param {Object} detail
69
+ @param {string} value The text input's inputValue.
70
+ -->
71
+
72
+ <!--
73
+ Fired when the inputValue of this text input changes and passes validation.
74
+
75
+ @event input-valid
76
+ @param {Object} detail
77
+ @param {string} value The text input's inputValue.
78
+ -->
79
+
80
+ <polymer-element name="core-input" on-focus="{{focusAction}}">
81
+
82
+ <template>
83
+
84
+ <%= stylesheet_link_tag "core/input/core-input" %>
85
+
86
+ <template if="{{multiline}}">
87
+ <textarea id="input" value="{{inputValue}}" rows="{{rows}}" fit?="{{rows === 'fit'}}" disabled?="{{disabled}}" placeholder="{{placeholder}}" required?="{{required}}" readonly?="{{readonly}}" aria-label="{{label || placeholder}}" aria-invalid="{{invalid}}" on-change="{{inputChangeAction}}" on-focus="{{inputFocusAction}}" on-blur="{{inputBlurAction}}"></textarea>
88
+ </template>
89
+
90
+ <template if="{{!multiline}}">
91
+ <input id="input" value="{{inputValue}}" disabled?="{{disabled}}" type="{{type}}" placeholder="{{placeholder}}" required?="{{required}}" readonly?="{{readonly}}" aria-label="{{label || placeholder}}" aria-invalid="{{invalid}}" on-change="{{inputChangeAction}}" on-focus="{{inputFocusAction}}" on-blur="{{inputBlurAction}}">
92
+ </template>
93
+
94
+ </template>
95
+
96
+ <script>
97
+
98
+ Polymer('core-input', {
99
+ publish: {
100
+ /**
101
+ * Placeholder text that hints to the user what can be entered in
102
+ * the input.
103
+ *
104
+ * @attribute placeholder
105
+ * @type string
106
+ * @default ''
107
+ */
108
+ placeholder: '',
109
+
110
+ /**
111
+ * If true, this input cannot be focused and the user cannot change
112
+ * its value.
113
+ *
114
+ * @attribute disabled
115
+ * @type boolean
116
+ * @default false
117
+ */
118
+ disabled: false,
119
+
120
+ /**
121
+ * Set the input type. Not supported for `multiline`.
122
+ *
123
+ * @attribute type
124
+ * @type string
125
+ * @default text
126
+ */
127
+ type: 'text',
128
+
129
+ /**
130
+ * If true, the user cannot modify the value of the input.
131
+ *
132
+ * @attribute readonly
133
+ * @type boolean
134
+ * @default false
135
+ */
136
+ readonly: false,
137
+
138
+ /**
139
+ * If true, the input is invalid until the value becomes non-null.
140
+ *
141
+ * @attribute required
142
+ * @type boolean
143
+ * @default false
144
+ */
145
+ required: false,
146
+
147
+ /**
148
+ * If true, this input accepts multi-line input like a `<textarea>`
149
+ *
150
+ * @attribute multiline
151
+ * @type boolean
152
+ * @default false
153
+ */
154
+ multiline: false,
155
+
156
+ /**
157
+ * (multiline only) The height of this text input in rows. The input
158
+ * will scroll internally if more input is entered beyond the size
159
+ * of the component. This property is meaningless if multiline is
160
+ * false. You can also set this property to "fit" and size the
161
+ * component with CSS to make the input fit the CSS size.
162
+ *
163
+ * @attribute rows
164
+ * @type number|'fit'
165
+ * @default 'fit'
166
+ */
167
+ rows: 'fit',
168
+
169
+ /**
170
+ * The current value of this input. Changing inputValue programmatically
171
+ * will cause value to be out of sync. Instead, change value directly
172
+ * or call commit() after changing inputValue.
173
+ *
174
+ * @attribute inputValue
175
+ * @type string
176
+ * @default ''
177
+ */
178
+ inputValue: '',
179
+
180
+ /**
181
+ * The value of the input committed by the user, either by changing the
182
+ * inputValue and blurring the input, or by hitting the `enter` key.
183
+ *
184
+ * @attribute value
185
+ * @type string
186
+ * @default ''
187
+ */
188
+ value: '',
189
+
190
+ /**
191
+ * If this property is not null, the text input's inputValue will be
192
+ * validated. You can validate the value with either a regular expression
193
+ * or a custom function.
194
+ *
195
+ * To use a regular expression, set this property to a RegExp object or
196
+ * a string containing the regular expression to match against. To use a
197
+ * custom validator, set this property to a function with the signature
198
+ * function(value) that returns a boolean. The input is valid if the
199
+ * function returns true.
200
+ *
201
+ * Example:
202
+ *
203
+ * // valid only if the value is a number
204
+ * <core-input validate="^[0-9]*$"></core-input>
205
+ *
206
+ * // valid only if the value is a number
207
+ * this.$.input.validate = /^[0-9]*$/;
208
+ *
209
+ * this.$.input2.validate = function(value) {
210
+ * // valid only if the value is 'foo'
211
+ * return value === 'foo';
212
+ * }
213
+ *
214
+ * @attribute validate
215
+ * @type string|RegExp|Function(value)
216
+ * @default null
217
+ */
218
+ validate: null,
219
+
220
+ /**
221
+ * If this property is true, the text input's inputValue failed validation.
222
+ *
223
+ * @attribute invalid
224
+ * @type boolean
225
+ * @default false
226
+ */
227
+ invalid: false,
228
+ },
229
+
230
+ ready: function() {
231
+ this.handleTabindex(this.getAttribute('tabindex'));
232
+ },
233
+
234
+ validateValue: function() {
235
+ var valid = true;
236
+
237
+ if (this.validate) {
238
+
239
+ if (!this.inputValue) {
240
+ valid = !this.required;
241
+ } else if (typeof this.validate === 'string') {
242
+ valid = new RegExp(this.validate).exec(this.inputValue);
243
+ } else if (this.validate.exec) {
244
+ valid = this.validate.exec(this.inputValue);
245
+ } else if (this.validate instanceof Function) {
246
+ valid = this.validate.call(this, this.inputValue);
247
+ }
248
+
249
+ } else if (this.required) {
250
+ valid = !!this.inputValue;
251
+ }
252
+
253
+ this.invalid = !valid;
254
+ },
255
+
256
+ invalidChanged: function() {
257
+ this.classList.toggle('invalid', this.invalid);
258
+ this.fire('input-'+ this.invalid ? 'invalid' : 'valid', {value: this.inputValue});
259
+ },
260
+
261
+ inputValueChanged: function() {
262
+ if (this.validate || this.required) {
263
+ this.validateValue();
264
+ }
265
+ },
266
+
267
+ valueChanged: function() {
268
+ this.inputValue = this.value;
269
+ },
270
+
271
+ requiredChanged: function() {
272
+ this.validateValue();
273
+ },
274
+
275
+ attributeChanged: function(attr, oldVal, curVal) {
276
+ if (attr === 'tabindex') {
277
+ this.handleTabindex(curVal);
278
+ }
279
+ },
280
+
281
+ handleTabindex: function(tabindex) {
282
+ if (tabindex > 0) {
283
+ this.$.input.setAttribute('tabindex', -1);
284
+ } else {
285
+ this.$.input.removeAttribute('tabindex');
286
+ }
287
+ },
288
+
289
+ /**
290
+ * Commits the inputValue to value.
291
+ *
292
+ * @method commit
293
+ */
294
+ commit: function() {
295
+ this.value = this.inputValue;
296
+ },
297
+
298
+ inputChangeAction: function() {
299
+ this.commit();
300
+ if (!window.ShadowDOMPolyfill) {
301
+ // re-fire event that does not bubble across shadow roots
302
+ this.fire('change', null, this);
303
+ }
304
+ },
305
+
306
+ focusAction: function(e) {
307
+ if (this.getAttribute('tabindex') > 0) {
308
+ // Forward focus to the inner input if tabindex is set on the element
309
+ // This will not cause an infinite loop because focus will not fire on the <input>
310
+ // again if it's already focused.
311
+ this.$.input.focus();
312
+ }
313
+ },
314
+
315
+ inputFocusAction: function(e) {
316
+ if (window.ShadowDOMPolyfill) {
317
+ // re-fire non-bubbling event if polyfill
318
+ this.fire('focus', null, this, false);
319
+ }
320
+ },
321
+
322
+ inputBlurAction: function() {
323
+ if (window.ShadowDOMPolyfill) {
324
+ // re-fire non-bubbling event
325
+ this.fire('blur', null, this, false);
326
+ }
327
+ },
328
+
329
+ blur: function() {
330
+ // forward blur method to the internal input / textarea element
331
+ this.$.input.blur();
332
+ },
333
+
334
+ click: function() {
335
+ // forward click method to the internal input / textarea element
336
+ this.$.input.click();
337
+ },
338
+
339
+ focus: function() {
340
+ // forward focus method to the internal input / textarea element
341
+ this.$.input.focus();
342
+ },
343
+
344
+ select: function() {
345
+ // forward select method to the internal input / textarea element
346
+ this.$.input.focus();
347
+ },
348
+
349
+ setSelectionRange: function( selectionStart, selectionEnd, selectionDirection ) {
350
+ // forward setSelectionRange method to the internal input / textarea element
351
+ this.$.input.setSelectionRange( selectionStart, selectionEnd, selectionDirection );
352
+ },
353
+
354
+ setRangeText: function( replacement, start, end, selectMode ) {
355
+ // forward setRangeText method to the internal input element
356
+ if ( !this.multiline ) {
357
+ this.$.input.setRangeText( replacement, start, end, selectMode );
358
+ }
359
+ },
360
+
361
+ stepDown: function( n ) {
362
+ // forward stepDown method to the internal input element
363
+ if ( !this.multiline ) {
364
+ this.$.input.stepDown( n );
365
+ }
366
+ },
367
+
368
+ stepUp: function( n ) {
369
+ // forward stepUp method to the internal input element
370
+ if ( !this.multiline ) {
371
+ this.$.input.stepUp( n );
372
+ }
373
+ }
374
+
375
+ });
376
+
377
+ CoreInput = function() {
378
+ return document.createElement('core-input');
379
+ };
380
+ CoreInput.validate = {
381
+ number: /^[0-9]*$/
382
+ };
383
+ </script>
384
+
385
+ </polymer-element>