forma 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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