forma 0.0.0 → 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.
@@ -1,8 +1,328 @@
1
- /**
2
- * forma.less
3
- * ==========
4
- * (C) 2013 Dimitri Kurashvili
5
- */
6
- .ff {
1
+ .user-select-none {
2
+ user-select: none;
3
+ -webkit-user-select: none;
4
+ -moz-user-select: none;
5
+ -ms-user-select: none;
6
+ }
7
+ .ff-form,
8
+ .ff-table {
9
+ margin-bottom: 16px;
10
+ }
11
+ .ff-form .ff-action,
12
+ .ff-table .ff-action {
13
+ margin-left: 4px;
14
+ }
15
+ .ff-form .ff-action:first-child,
16
+ .ff-table .ff-action:first-child {
17
+ margin-left: 0;
18
+ }
19
+ .ff-form .ff-action img,
20
+ .ff-table .ff-action img {
21
+ padding-right: 4px;
22
+ height: 16px;
23
+ width: 16px;
24
+ }
25
+ .ff-form .ff-title,
26
+ .ff-table .ff-title {
27
+ position: relative;
28
+ }
29
+ .ff-form .ff-title .ff-active-title,
30
+ .ff-table .ff-title .ff-active-title {
31
+ user-select: none;
32
+ -webkit-user-select: none;
33
+ -moz-user-select: none;
34
+ -ms-user-select: none;
35
+ cursor: pointer;
36
+ display: inline-block;
37
+ padding: 4px 8px;
38
+ font-weight: bold;
7
39
  font-size: 14px;
8
40
  }
41
+ .ff-form .ff-title .ff-active-title .ff-collapse,
42
+ .ff-table .ff-title .ff-active-title .ff-collapse {
43
+ display: inline-block;
44
+ height: 14px;
45
+ width: 14px;
46
+ margin-right: 4px;
47
+ margin-top: 2px;
48
+ }
49
+ .ff-form .ff-title .ff-active-title img,
50
+ .ff-table .ff-title .ff-active-title img {
51
+ height: 16px;
52
+ width: 16px;
53
+ overflow: hidden;
54
+ margin-right: 4px;
55
+ }
56
+ .ff-form .ff-title .ff-title-actions,
57
+ .ff-table .ff-title .ff-title-actions {
58
+ position: absolute;
59
+ right: 0;
60
+ top: 4px;
61
+ padding: 0 8px;
62
+ }
63
+ .ff-form .ff-collapse,
64
+ .ff-table .ff-collapse {
65
+ background: url(/assets/glyphicons-halflings.png) -313px -119px;
66
+ }
67
+ .ff-form .ff-collapsed.ff-collapse,
68
+ .ff-table .ff-collapsed.ff-collapse {
69
+ background: url(/assets/glyphicons-halflings.png) -456px -72px;
70
+ }
71
+ .ff-form .ff-field-hint,
72
+ .ff-table .ff-field-hint {
73
+ background: url(/assets/glyphicons-halflings.png) -456px -72px;
74
+ }
75
+ .ff-form .ff-tabs,
76
+ .ff-table .ff-tabs {
77
+ padding: 4px 0;
78
+ }
79
+ .ff-form .ff-tabs ul.ff-tabs-header,
80
+ .ff-table .ff-tabs ul.ff-tabs-header {
81
+ list-style-type: none;
82
+ margin: 0;
83
+ position: relative;
84
+ border-bottom: 1px solid #b1b1b1;
85
+ }
86
+ .ff-form .ff-tabs ul.ff-tabs-header li,
87
+ .ff-table .ff-tabs ul.ff-tabs-header li {
88
+ user-select: none;
89
+ -webkit-user-select: none;
90
+ -moz-user-select: none;
91
+ -ms-user-select: none;
92
+ cursor: pointer;
93
+ display: inline-block;
94
+ padding: 4px 8px;
95
+ margin-left: 8px;
96
+ margin-bottom: -1px;
97
+ border: 1px solid transparent;
98
+ }
99
+ .ff-form .ff-tabs ul.ff-tabs-header li img,
100
+ .ff-table .ff-tabs ul.ff-tabs-header li img {
101
+ margin: 0 4px;
102
+ height: 16px;
103
+ width: 16px;
104
+ }
105
+ .ff-form .ff-tabs ul.ff-tabs-header li.ff-selected,
106
+ .ff-table .ff-tabs ul.ff-tabs-header li.ff-selected {
107
+ background: #ffffcc;
108
+ border: 1px solid #b1b1b1;
109
+ border-bottom: 1px solid #ffffcc;
110
+ }
111
+ .ff-form .ff-tabs .ff-tab-actions,
112
+ .ff-table .ff-tabs .ff-tab-actions {
113
+ padding: 4px 8px;
114
+ background: #ffffcc;
115
+ border: 1px solid #b1b1b1;
116
+ margin-top: -1px;
117
+ }
118
+ .ff-form .ff-tabs .ff-cols,
119
+ .ff-table .ff-tabs .ff-cols {
120
+ margin: 4px 0 0 0;
121
+ position: relative;
122
+ font-size: 13px;
123
+ }
124
+ .ff-form .ff-tabs .ff-cols .ff-col-100,
125
+ .ff-table .ff-tabs .ff-cols .ff-col-100 {
126
+ width: 100%;
127
+ }
128
+ .ff-form .ff-tabs .ff-cols .ff-col-50,
129
+ .ff-table .ff-tabs .ff-cols .ff-col-50 {
130
+ width: 50%;
131
+ float: left;
132
+ }
133
+ .ff-form .ff-tabs .ff-cols .ff-col:first-child .ff-col-inner,
134
+ .ff-table .ff-tabs .ff-cols .ff-col:first-child .ff-col-inner {
135
+ padding-right: 4px;
136
+ }
137
+ .ff-form .ff-tabs .ff-cols .ff-col:last-child .ff-col-inner,
138
+ .ff-table .ff-tabs .ff-cols .ff-col:last-child .ff-col-inner {
139
+ padding-left: 4px;
140
+ }
141
+ .ff-form .ff-tabs .ff-cols .ff-col-inner,
142
+ .ff-table .ff-tabs .ff-cols .ff-col-inner {
143
+ padding: 0;
144
+ position: relative;
145
+ }
146
+ .ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field,
147
+ .ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field {
148
+ position: relative;
149
+ border-bottom: 1px solid #b1b1b1;
150
+ }
151
+ .ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field:first-child,
152
+ .ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field:first-child {
153
+ border-top: 1px solid #b1b1b1;
154
+ }
155
+ .ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-label,
156
+ .ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-label {
157
+ display: table-cell;
158
+ vertical-align: top;
159
+ position: relative;
160
+ width: 150px;
161
+ padding: 4px 4px 4px 8px;
162
+ background-color: #c8ffb0;
163
+ border-right: 3px solid transparent;
164
+ }
165
+ .ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-label.ff-required,
166
+ .ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-label.ff-required {
167
+ border-right: 3px solid #cf0000;
168
+ }
169
+ .ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-label .ff-field-hint,
170
+ .ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-label .ff-field-hint {
171
+ display: block;
172
+ height: 16px;
173
+ width: 16px;
174
+ position: absolute;
175
+ right: 0;
176
+ top: 8px;
177
+ background-position: -96px -96px;
178
+ }
179
+ .ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-value,
180
+ .ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-value {
181
+ display: table-cell;
182
+ padding: 4px;
183
+ vertical-align: top;
184
+ }
185
+ .ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-value .ff-field-actions,
186
+ .ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-value .ff-field-actions {
187
+ display: inline-block;
188
+ border-left: 1px solid #b1b1b1;
189
+ padding-left: 8px;
190
+ margin-left: 8px;
191
+ }
192
+ .ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-field-before,
193
+ .ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-field-before {
194
+ padding-right: 8px;
195
+ }
196
+ .ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-field-after,
197
+ .ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-field-after {
198
+ padding-left: 8px;
199
+ }
200
+ .ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-complex-field .ff-complex-part,
201
+ .ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-complex-field .ff-complex-part {
202
+ display: inline-block;
203
+ padding-right: 8px;
204
+ }
205
+ .ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-complex-field .ff-field,
206
+ .ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-complex-field .ff-field {
207
+ display: inline-block;
208
+ border: none;
209
+ padding-right: 8px;
210
+ }
211
+ .ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-select-field .ff-select-link,
212
+ .ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-select-field .ff-select-link {
213
+ margin-left: 8px;
214
+ }
215
+ .ff-form .ff-tabs .ff-cols:after,
216
+ .ff-table .ff-tabs .ff-cols:after {
217
+ content: ".";
218
+ display: block;
219
+ clear: both;
220
+ width: 0;
221
+ height: 0;
222
+ overflow: hidden;
223
+ }
224
+ .ff-form .ff-tabs input,
225
+ .ff-table .ff-tabs input {
226
+ padding: 4px;
227
+ margin: 0;
228
+ font-size: 13px;
229
+ }
230
+ .ff-form .ff-tabs select,
231
+ .ff-table .ff-tabs select {
232
+ padding: 4px;
233
+ margin: 0;
234
+ font-size: 13px;
235
+ width: auto;
236
+ }
237
+ .ff-form .ff-tabs .ff-error input,
238
+ .ff-table .ff-tabs .ff-error input {
239
+ border: 1px solid red;
240
+ color: red;
241
+ background: #fff8f8;
242
+ }
243
+ .ff-form .ff-form-errors,
244
+ .ff-table .ff-form-errors {
245
+ margin: 8px;
246
+ padding: 8px;
247
+ border: 1px solid red;
248
+ background: #fee;
249
+ color: red;
250
+ }
251
+ .ff-form ul.ff-form-errors li,
252
+ .ff-table ul.ff-form-errors li {
253
+ margin-left: 16px;
254
+ }
255
+ .ff-form .ff-field-errors,
256
+ .ff-table .ff-field-errors {
257
+ color: red;
258
+ padding: 4px 0;
259
+ }
260
+ .ff-form .ff-bottom-actions,
261
+ .ff-table .ff-bottom-actions {
262
+ padding: 8px;
263
+ border-top: 1px solid #b1b1b1;
264
+ background: #e0e0e0;
265
+ }
266
+ .ff-form table.ff-common-table,
267
+ .ff-table table.ff-common-table {
268
+ margin-top: 8px;
269
+ width: 100%;
270
+ border-collapse: collapse;
271
+ }
272
+ .ff-form table.ff-common-table thead,
273
+ .ff-table table.ff-common-table thead {
274
+ text-align: left;
275
+ border-top: 1px solid #3316ff;
276
+ border-bottom: 1px solid #3316ff;
277
+ background: #c8ffb0;
278
+ }
279
+ .ff-form table.ff-common-table thead th,
280
+ .ff-table table.ff-common-table thead th {
281
+ font-weight: normal;
282
+ padding: 4px 8px;
283
+ }
284
+ .ff-form table.ff-common-table thead .ff-field-hint,
285
+ .ff-table table.ff-common-table thead .ff-field-hint {
286
+ display: inline-block;
287
+ height: 16px;
288
+ width: 16px;
289
+ background-position: -96px -96px;
290
+ }
291
+ .ff-form table.ff-common-table tbody td,
292
+ .ff-table table.ff-common-table tbody td {
293
+ padding: 4px 8px;
294
+ border-bottom: 1px solid #3316ff;
295
+ }
296
+ .ff-empty {
297
+ color: #a0a0a0;
298
+ }
299
+ .ff-table-empty {
300
+ padding: 32px;
301
+ text-align: center;
302
+ background-color: #f6f6f6;
303
+ border: 1px solid #a0a0a0;
304
+ border-top: none;
305
+ }
306
+ .ff-map {
307
+ width: 100%;
308
+ height: 100%;
309
+ overflow: hidden;
310
+ position: absolute;
311
+ top: 0;
312
+ left: 0;
313
+ right: 0;
314
+ bottom: 0;
315
+ }
316
+ .ff-map img {
317
+ max-width: none;
318
+ }
319
+ .ff-form .ff-title,
320
+ .ff-table .ff-title {
321
+ background-color: #cfc8ff;
322
+ border-bottom: 2px solid #3316ff;
323
+ border-top: 2px solid #3316ff;
324
+ }
325
+ .tooltip-inner {
326
+ white-space: pre;
327
+ max-width: none;
328
+ }
@@ -1,11 +1,141 @@
1
- /**
2
- * forma.less
3
- * ==========
4
- * (C) 2013 Dimitri Kurashvili
5
- */
1
+ .user-select-none { user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;}
2
+ .rounded-corners(@radius: 5px) { -webkit-border-radius: @radius; -moz-border-radius: @radius; -ms-border-radius: @radius; -o-border-radius: @radius; border-radius: @radius; }
6
3
 
7
- @font-size: 14px;
4
+ @halflings: url(/assets/glyphicons-halflings.png);
5
+ @halflings-white: url(/assets/glyphicons-halflings-white.png);
6
+ @border-color: #b1b1b1;
7
+ @selected-tab-color: #ffffcc;
8
+ @base-font-size: 13px;
9
+ @blue-theme: #cfc8ff;
10
+ @blue-theme-border: darken(@blue-theme, 35%);
11
+ @label-background: #c8ffb0;
12
+ // form
8
13
 
9
- .ff {
10
- font-size: @font-size;
14
+ .ff-form, .ff-table {
15
+ margin-bottom: 16px;
16
+ .ff-action {
17
+ margin-left: 4px;
18
+ &:first-child { margin-left: 0; };
19
+ img { padding-right: 4px; height: 16px; width: 16px; }
20
+ }
21
+ .ff-title {
22
+ position: relative;
23
+ .ff-active-title { .user-select-none; cursor: pointer; display: inline-block; padding: 4px 8px;
24
+ font-weight: bold; font-size: 14px;
25
+ .ff-collapse { display: inline-block; height: 14px; width: 14px; margin-right: 4px; margin-top: 2px; }
26
+ img { height: 16px; width: 16px; overflow: hidden; margin-right: 4px; }
27
+ }
28
+ .ff-title-actions { position: absolute; right: 0; top: 4px; padding: 0 8px; }
29
+ }
30
+ .ff-collapse { background: @halflings -313px -119px }
31
+ .ff-collapsed.ff-collapse { background: @halflings -456px -72px }
32
+ .ff-field-hint { background: @halflings -456px -72px }
33
+ .ff-tabs {
34
+ padding: 4px 0;
35
+ ul.ff-tabs-header {
36
+ list-style-type: none; margin: 0; position: relative;
37
+ border-bottom: 1px solid @border-color;
38
+ li { .user-select-none; cursor: pointer; display: inline-block;
39
+ padding: 4px 8px; margin-left: 8px; margin-bottom: -1px;
40
+ border: 1px solid transparent;
41
+ img { margin: 0 4px; height: 16px; width: 16px; }}
42
+ li.ff-selected {
43
+ background: @selected-tab-color;
44
+ border: 1px solid @border-color;
45
+ border-bottom: 1px solid @selected-tab-color;
46
+ }
47
+ }
48
+ .ff-tab-actions {
49
+ padding: 4px 8px; background: @selected-tab-color;
50
+ border: 1px solid @border-color;
51
+ margin-top: -1px;
52
+ }
53
+ .ff-cols {
54
+ margin: 4px 0 0 0;
55
+ position: relative;
56
+ font-size: @base-font-size;
57
+ .ff-col-100 { width: 100%; }
58
+ .ff-col-50 { width: 50%; float: left; }
59
+ .ff-col {
60
+ &:first-child { .ff-col-inner { padding-right: 4px; } }
61
+ &:last-child { .ff-col-inner { padding-left: 4px; } }
62
+ }
63
+ .ff-col-inner {
64
+ padding: 0; position: relative;
65
+ .ff-field {
66
+ position: relative;
67
+ border-bottom: 1px solid @border-color;
68
+ &:first-child { border-top: 1px solid @border-color; }
69
+ .ff-label { display: table-cell; vertical-align: top;
70
+ position: relative; width: 150px; padding: 4px 4px 4px 8px;
71
+ background-color: @label-background; border-right: 3px solid transparent;
72
+ &.ff-required { border-right: 3px solid #cf0000; }
73
+ .ff-field-hint { display: block; height: 16px; width: 16px; position: absolute; right: 0; top: 8px; background-position: -96px -96px; }}
74
+ .ff-value {
75
+ display: table-cell; padding: 4px; vertical-align: top;
76
+ .ff-field-actions { display: inline-block; border-left: 1px solid @border-color; padding-left: 8px; margin-left: 8px; }
77
+ }
78
+ .ff-field-before { padding-right: 8px; }
79
+ .ff-field-after { padding-left: 8px; }
80
+ .ff-complex-field {
81
+ .ff-complex-part { display: inline-block; padding-right: 8px; }
82
+ .ff-field { display: inline-block; border: none; padding-right: 8px; }
83
+ }
84
+ .ff-select-field {
85
+ .ff-select-link { margin-left: 8px; }
86
+ }
87
+ }
88
+ }
89
+ &:after { content: "."; display: block; clear: both; width: 0; height: 0; overflow: hidden; }
90
+ }
91
+ input { padding: 4px; margin: 0; font-size: @base-font-size; }
92
+ select { padding: 4px; margin: 0; font-size: @base-font-size; width: auto; }
93
+ .ff-error input { border: 1px solid red; color: red; background: #fff8f8; }
94
+ }
95
+ .ff-form-errors { margin: 8px; padding: 8px; border: 1px solid red; background: #fee; color: red;}
96
+ ul.ff-form-errors { li { margin-left: 16px; } }
97
+ .ff-field-errors { color: red; padding: 4px 0;}
98
+ .ff-bottom-actions { padding: 8px; border-top: 1px solid @border-color; background: #e0e0e0; }
99
+ table.ff-common-table {
100
+ margin-top: 8px; width: 100%; border-collapse: collapse;
101
+ thead { text-align: left;
102
+ border-top: 1px solid @blue-theme-border;
103
+ border-bottom: 1px solid @blue-theme-border;
104
+ background: @label-background;
105
+ th { font-weight: normal; padding: 4px 8px; }
106
+ .ff-field-hint { display: inline-block; height: 16px; width: 16px; background-position: -96px -96px; }
107
+ }
108
+ tbody {
109
+ td { padding: 4px 8px; border-bottom: 1px solid @blue-theme-border; }
110
+ }
111
+ }
11
112
  }
113
+ .ff-empty { color: #a0a0a0; }
114
+ .ff-table-empty { padding: 32px; text-align: center; background-color: #f6f6f6; border: 1px solid #a0a0a0; border-top: none; }
115
+
116
+ .ff-map {
117
+ width:100%; height:100%; overflow:hidden; position: absolute;
118
+ top: 0; left: 0; right: 0; bottom: 0;
119
+ img { max-width: none; }
120
+ }
121
+
122
+ // themes
123
+
124
+ // @red-theme: #ffc8c8;
125
+
126
+ // @yellow-theme: #efe300;
127
+ // @green-theme: #c8f0c3;
128
+
129
+ // .form-theme(@theme-color) { .ff-title { background-color: @theme-color; border-bottom: 3px solid darken(@theme-color, 35%); } }
130
+ // .ff-theme-red { .form-theme(@red-theme); }
131
+ // .ff-theme-blue { .form-theme(@blue-theme); }
132
+ // .ff-theme-yellow { .form-theme(@yellow-theme) }
133
+ // .ff-theme-green { .form-theme(@green-theme) }
134
+ .ff-form, .ff-table { .ff-title { background-color: @blue-theme;
135
+ border-bottom: 2px solid @blue-theme-border;
136
+ border-top: 2px solid @blue-theme-border;
137
+ } }
138
+
139
+ // bootstrap fixes
140
+
141
+ .tooltip-inner { white-space: pre; max-width: none; }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forma
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-21 00:00:00.000000000 Z
12
+ date: 2013-05-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -131,7 +131,6 @@ extensions: []
131
131
  extra_rdoc_files: []
132
132
  files:
133
133
  - .gitignore
134
- - .rspec
135
134
  - .travis.yml
136
135
  - Gemfile
137
136
  - LICENSE.txt
@@ -139,13 +138,27 @@ files:
139
138
  - Rakefile
140
139
  - forma.gemspec
141
140
  - lib/forma.rb
141
+ - lib/forma/action.rb
142
+ - lib/forma/config.rb
143
+ - lib/forma/field.rb
144
+ - lib/forma/form.rb
145
+ - lib/forma/helpers.rb
142
146
  - lib/forma/html.rb
143
- - lib/forma/html/attributes.rb
144
- - lib/forma/html/element.rb
147
+ - lib/forma/railtie.rb
148
+ - lib/forma/table.rb
149
+ - lib/forma/utils.rb
145
150
  - lib/forma/version.rb
146
- - spec/html/attributes_spec.rb
147
- - spec/html/element_spec.rb
151
+ - spec/config_spec.rb
152
+ - spec/field_spec.rb
153
+ - spec/form_spec.rb
154
+ - spec/helpers_spec.rb
155
+ - spec/html_spec.rb
148
156
  - spec/spec_helper.rb
157
+ - test/field_test.rb
158
+ - test/form_test.rb
159
+ - test/test_helper.rb
160
+ - vendor/assets/images/ff-icons.png
161
+ - vendor/assets/javascripts/forma.js
149
162
  - vendor/assets/stylesheets/forma-min.css
150
163
  - vendor/assets/stylesheets/forma.css
151
164
  - vendor/less/forma.less
@@ -175,6 +188,12 @@ signing_key:
175
188
  specification_version: 3
176
189
  summary: highly informative and flexible forms with ruby
177
190
  test_files:
178
- - spec/html/attributes_spec.rb
179
- - spec/html/element_spec.rb
191
+ - spec/config_spec.rb
192
+ - spec/field_spec.rb
193
+ - spec/form_spec.rb
194
+ - spec/helpers_spec.rb
195
+ - spec/html_spec.rb
180
196
  - spec/spec_helper.rb
197
+ - test/field_test.rb
198
+ - test/form_test.rb
199
+ - test/test_helper.rb
data/.rspec DELETED
@@ -1 +0,0 @@
1
- --color
@@ -1,104 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- module Forma::Html
3
-
4
- class Attributes
5
-
6
- def initialize(attrs = {})
7
- self.update_attributes(attrs) if attrs.present?
8
- end
9
-
10
- def update_attributes(attrs)
11
- attrs.each { |k, v| self[k] = v }
12
- end
13
-
14
- def [](k)
15
- k = k.to_s
16
- v = attributes[k.to_s]
17
- case k
18
- when 'class' then v = @klass ||= []
19
- when 'style' then v = @style ||= {}
20
- end
21
- v
22
- end
23
-
24
- def []=(k,v)
25
- k = k.to_s
26
- case k
27
- when 'class' then assign_class(v)
28
- when 'style' then assign_style(v)
29
- else attributes[k] = v
30
- end
31
- end
32
-
33
- def add_class(k)
34
- klass << k
35
- end
36
-
37
- def add_style(k,v)
38
- style[k] = v
39
- end
40
-
41
- def klass
42
- self[:class]
43
- end
44
-
45
- def style
46
- self[:style]
47
- end
48
-
49
- def empty?
50
- attributes.empty? and klass.empty? and style.empty?
51
- end
52
-
53
- def html
54
- generate_html unless empty?
55
- end
56
-
57
- private
58
-
59
- def attributes
60
- @attributes ||= {}
61
- end
62
-
63
- def assign_class(v)
64
- if v.is_a? Array
65
- @klass = v
66
- elsif v.nil?
67
- @klass = []
68
- else
69
- @klass = [ v ]
70
- end
71
- end
72
-
73
- def assign_style(v)
74
- raise 'style should be a hash' unless v.is_a? Hash
75
- @style = v
76
- end
77
-
78
- def generate_html
79
- h = ''
80
- h << ' ' << generate_class_html unless klass.empty?
81
- h << ' ' << generate_style_html unless style.empty?
82
- h << ' ' << generate_attributes_html unless attributes.empty?
83
- h.strip
84
- end
85
-
86
- def generate_class_html
87
- %Q{class="#{klass.join(' ')}"}
88
- end
89
-
90
- def generate_style_html
91
- st = []
92
- style.each { |k,v| st << "#{k}:#{v}" }
93
- %Q{style="#{st.join(';')}"}
94
- end
95
-
96
- def generate_attributes_html
97
- s = []
98
- attributes.each { |k,v| s << %Q{#{k}="#{v}"} }
99
- s.join(' ')
100
- end
101
-
102
- end
103
-
104
- end