blib/lib/Mojolicious/Plugin/BootstrapHelpers/Helpers.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 502 | 510 | 98.4 |
branch | 200 | 230 | 86.9 |
condition | 39 | 53 | 73.5 |
subroutine | 61 | 63 | 96.8 |
pod | 0 | 44 | 0.0 |
total | 802 | 900 | 89.1 |
line | stmt | bran | cond | sub | pod | time | code | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 14 | 14 | 149 | use 5.20.0; | |||||||||||||||||||
14 | 46 | ||||||||||||||||||||||
2 | 14 | 14 | 62 | use warnings; | |||||||||||||||||||
14 | 27 | ||||||||||||||||||||||
14 | 783 | ||||||||||||||||||||||
3 | |||||||||||||||||||||||
4 | package Mojolicious::Plugin::BootstrapHelpers::Helpers; | ||||||||||||||||||||||
5 | |||||||||||||||||||||||
6 | # ABSTRACT: Supporting module | ||||||||||||||||||||||
7 | our $AUTHORITY = 'cpan:CSSON'; # AUTHORITY | ||||||||||||||||||||||
8 | our $VERSION = '0.0206'; | ||||||||||||||||||||||
9 | |||||||||||||||||||||||
10 | 14 | 14 | 70 | use List::Util qw/uniq/; | |||||||||||||||||||
14 | 27 | ||||||||||||||||||||||
14 | 790 | ||||||||||||||||||||||
11 | 14 | 14 | 72 | use Mojo::ByteStream; | |||||||||||||||||||
14 | 26 | ||||||||||||||||||||||
14 | 458 | ||||||||||||||||||||||
12 | 14 | 14 | 72 | use Mojo::Util 'xml_escape'; | |||||||||||||||||||
14 | 27 | ||||||||||||||||||||||
14 | 601 | ||||||||||||||||||||||
13 | 14 | 14 | 74 | use Scalar::Util 'blessed'; | |||||||||||||||||||
14 | 40 | ||||||||||||||||||||||
14 | 602 | ||||||||||||||||||||||
14 | 14 | 14 | 5098 | use String::Trim; | |||||||||||||||||||
14 | 7179 | ||||||||||||||||||||||
14 | 801 | ||||||||||||||||||||||
15 | 14 | 14 | 5494 | use String::Random; | |||||||||||||||||||
14 | 37952 | ||||||||||||||||||||||
14 | 748 | ||||||||||||||||||||||
16 | 14 | 14 | 5243 | use experimental qw/postderef signatures/; | |||||||||||||||||||
14 | 40221 | ||||||||||||||||||||||
14 | 74 | ||||||||||||||||||||||
17 | |||||||||||||||||||||||
18 | sub bootstraps_bootstraps { | ||||||||||||||||||||||
19 | 6 | 6 | 0 | 69351 | my $c = shift; | ||||||||||||||||||
20 | 6 | 15 | my $arg = shift; | ||||||||||||||||||||
21 | |||||||||||||||||||||||
22 | 6 | 13 | my $bs_version = '3.4.1'; | ||||||||||||||||||||
23 | |||||||||||||||||||||||
24 | 6 | 18 | my $css = qq{}; | ||||||||||||||||||||
25 | 6 | 17 | my $theme = qq{}; | ||||||||||||||||||||
26 | 6 | 13 | my $js = qq{}; | ||||||||||||||||||||
27 | 6 | 12 | my $jq = q{}; | ||||||||||||||||||||
28 | |||||||||||||||||||||||
29 | 6 | 50 | 59 | return out( | |||||||||||||||||||
100 | |||||||||||||||||||||||
100 | |||||||||||||||||||||||
100 | |||||||||||||||||||||||
100 | |||||||||||||||||||||||
100 | |||||||||||||||||||||||
30 | !defined $arg ? $css | ||||||||||||||||||||||
31 | : $arg eq 'css' ? join "\n" => $css, $theme | ||||||||||||||||||||||
32 | : $arg eq 'js' ? join "\n" => $js | ||||||||||||||||||||||
33 | : $arg eq 'jsq' ? join "\n" => $jq, $js | ||||||||||||||||||||||
34 | : $arg eq 'all' ? join "\n" => $css, $theme, $js | ||||||||||||||||||||||
35 | : $arg eq 'allq' ? join "\n" => $css, $theme, $jq, $js | ||||||||||||||||||||||
36 | : '' | ||||||||||||||||||||||
37 | ); | ||||||||||||||||||||||
38 | } | ||||||||||||||||||||||
39 | |||||||||||||||||||||||
40 | sub bootstrap_panel { | ||||||||||||||||||||||
41 | 4 | 4 | 0 | 29537 | my($c, $title, $callback, $content, $attr) = parse_call(@_); | ||||||||||||||||||
42 | |||||||||||||||||||||||
43 | 4 | 26 | $attr = add_classes($attr, 'panel', { panel => 'panel-%s', panel_default => 'default'}); | ||||||||||||||||||||
44 | |||||||||||||||||||||||
45 | 4 | 20 | my $body = qq{ | ||||||||||||||||||||
46 | |
||||||||||||||||||||||
47 | } . contents($callback, $content) . qq{ | ||||||||||||||||||||||
48 | |||||||||||||||||||||||
49 | }; | ||||||||||||||||||||||
50 | |||||||||||||||||||||||
51 | 4 | 97 | return create_panel($c, $title, $body, $attr); | ||||||||||||||||||||
52 | |||||||||||||||||||||||
53 | } | ||||||||||||||||||||||
54 | #-header => [buttongroup => ['Scan', ['#'], data => { bind => 'click: scanDatabases'}]] | ||||||||||||||||||||||
55 | sub create_panel { | ||||||||||||||||||||||
56 | 6 | 6 | 0 | 15 | my $c = shift; | ||||||||||||||||||
57 | 6 | 12 | my $title = shift; | ||||||||||||||||||||
58 | 6 | 10 | my $body = shift; | ||||||||||||||||||||
59 | 6 | 16 | my $attr = shift; | ||||||||||||||||||||
60 | |||||||||||||||||||||||
61 | 6 | 100 | 18 | my $header_attr = exists $attr->{'-header'} ? delete($attr->{'-header'}) : []; | |||||||||||||||||||
62 | 6 | 13 | my $header_button_groups = ''; | ||||||||||||||||||||
63 | 6 | 100 | 26 | if(scalar keys @$header_attr) { | |||||||||||||||||||
64 | 1 | 3 | for my $attr (shift @$header_attr) { | ||||||||||||||||||||
65 | 1 | 50 | 5 | if($attr eq 'buttongroup') { | |||||||||||||||||||
66 | 1 | 6 | $header_button_groups .= bootstrap_buttongroup($c, class => 'pull-right', (shift @$header_attr)->@*); | ||||||||||||||||||||
67 | } | ||||||||||||||||||||||
68 | } | ||||||||||||||||||||||
69 | } | ||||||||||||||||||||||
70 | |||||||||||||||||||||||
71 | 6 | 100 | 73 | my $tag = qq{ | |||||||||||||||||||
72 | |
||||||||||||||||||||||
73 | } . (defined $title ? qq{ | ||||||||||||||||||||||
74 | |
||||||||||||||||||||||
75 | $header_button_groups$title |
||||||||||||||||||||||
76 | |||||||||||||||||||||||
77 | } : '') . qq{ | ||||||||||||||||||||||
78 | $body | ||||||||||||||||||||||
79 | |||||||||||||||||||||||
80 | }; | ||||||||||||||||||||||
81 | |||||||||||||||||||||||
82 | 6 | 26 | return out($tag); | ||||||||||||||||||||
83 | } | ||||||||||||||||||||||
84 | |||||||||||||||||||||||
85 | sub bootstrap_table { | ||||||||||||||||||||||
86 | 6 | 6 | 0 | 31832 | my $c = shift; | ||||||||||||||||||
87 | 6 | 50 | 24 | my $callback = ref $_[-1] eq 'CODE' ? pop : undef; | |||||||||||||||||||
88 | 6 | 100 | 17 | my $title = scalar @_ % 2 ? shift : undef; | |||||||||||||||||||
89 | 6 | 31 | my $attr = parse_attributes(@_); | ||||||||||||||||||||
90 | |||||||||||||||||||||||
91 | 6 | 22 | $attr = add_classes($attr, 'table', { table => 'table-%s' }); | ||||||||||||||||||||
92 | 6 | 42 | my $html = htmlify_attrs($attr); | ||||||||||||||||||||
93 | |||||||||||||||||||||||
94 | 6 | 22 | my $table = qq{ | ||||||||||||||||||||
95 |
|
||||||||||||||||||||||
98 | }; | ||||||||||||||||||||||
99 | |||||||||||||||||||||||
100 | 6 | 100 | 162 | if(defined $title) { | |||||||||||||||||||
101 | 2 | 12 | $attr->{'panel'} = add_classes($attr->{'panel'}, 'panel', { panel => 'panel-%s', panel_default => 'default'}); | ||||||||||||||||||||
102 | } | ||||||||||||||||||||||
103 | |||||||||||||||||||||||
104 | 6 | 100 | 25 | return defined $title ? create_panel($c, $title, $table, $attr->{'panel'}) : out($table); | |||||||||||||||||||
105 | } | ||||||||||||||||||||||
106 | |||||||||||||||||||||||
107 | sub htmlify_attrs { | ||||||||||||||||||||||
108 | 231 | 231 | 0 | 370 | my $attr = shift; | ||||||||||||||||||
109 | 231 | 50 | 469 | return '' if !defined $attr; | |||||||||||||||||||
110 | 231 | 842 | $attr = cleanup_attrs({$attr->%*}); #* Make a copy | ||||||||||||||||||||
111 | |||||||||||||||||||||||
112 | 231 | 593 | my $html = join ' ' => map { qq{$_="$attr->{ $_ }"} } grep { length $attr->{ $_ } } sort keys $attr->%*; | ||||||||||||||||||||
331 | 887 | ||||||||||||||||||||||
340 | 614 | ||||||||||||||||||||||
113 | 231 | 50 | 844 | return ' ' . $html if defined $html; | |||||||||||||||||||
114 | 0 | 0 | return ''; | ||||||||||||||||||||
115 | } | ||||||||||||||||||||||
116 | |||||||||||||||||||||||
117 | sub bootstrap_formgroup { | ||||||||||||||||||||||
118 | 12 | 12 | 0 | 67749 | my $c = shift; | ||||||||||||||||||
119 | 12 | 100 | 61 | my $title = ref $_[-1] eq 'CODE' ? pop | |||||||||||||||||||
100 | |||||||||||||||||||||||
120 | : scalar @_ % 2 ? shift | ||||||||||||||||||||||
121 | : undef; | ||||||||||||||||||||||
122 | 12 | 41 | my $attr = parse_attributes(@_); | ||||||||||||||||||||
123 | |||||||||||||||||||||||
124 | 12 | 100 | 35 | $attr->{'column_information'} = delete $attr->{'cols'} if ref $attr->{'cols'} eq 'HASH'; | |||||||||||||||||||
125 | |||||||||||||||||||||||
126 | 12 | 37 | my($id, $input) = fix_input($c, $attr); | ||||||||||||||||||||
127 | 12 | 100 | 121 | my $label = defined $title ? fix_label($c, $id, $title, $attr) : ''; | |||||||||||||||||||
128 | |||||||||||||||||||||||
129 | 12 | 893 | $attr = add_classes($attr, 'form-group', { size => 'form-group-%s'}); | ||||||||||||||||||||
130 | 12 | 31 | $attr = cleanup_attrs($attr); | ||||||||||||||||||||
131 | |||||||||||||||||||||||
132 | |||||||||||||||||||||||
133 | 12 | 47 | my $tag = qq{ | ||||||||||||||||||||
134 | |
||||||||||||||||||||||
135 | $label | ||||||||||||||||||||||
136 | $input | ||||||||||||||||||||||
137 | |||||||||||||||||||||||
138 | }; | ||||||||||||||||||||||
139 | |||||||||||||||||||||||
140 | 12 | 82 | return out($tag); | ||||||||||||||||||||
141 | } | ||||||||||||||||||||||
142 | |||||||||||||||||||||||
143 | sub bootstrap_button { | ||||||||||||||||||||||
144 | 51 | 51 | 0 | 27473 | my $c = shift; | ||||||||||||||||||
145 | 51 | 100 | 128 | my $content = ref $_[-1] eq 'CODE' ? pop : shift; | |||||||||||||||||||
146 | 51 | 100 | 121 | $content = '' if !defined $content; | |||||||||||||||||||
147 | |||||||||||||||||||||||
148 | 51 | 100 | 124 | my @url = shift->@* if ref $_[0] eq 'ARRAY'; | |||||||||||||||||||
149 | 51 | 116 | my $attr = parse_attributes(@_); | ||||||||||||||||||||
150 | |||||||||||||||||||||||
151 | 51 | 100 | 66 | 202 | my $caret = exists $attr->{'__caret'} && $attr->{'__caret'} ? (length $content ? ' ' : '') . q{} : ''; | ||||||||||||||||||
100 | |||||||||||||||||||||||
152 | |||||||||||||||||||||||
153 | 51 | 100 | 100 | 197 | $attr->{'type'} = 'button' if !scalar @url && !exists $attr->{'type'}; | ||||||||||||||||||
154 | 51 | 208 | $attr = add_classes($attr, 'btn', { size => 'btn-%s', button => 'btn-%s', button_default => 'default' }); | ||||||||||||||||||||
155 | 51 | 100 | 171 | $attr = add_classes($attr, 'active') if $attr->{'__active'}; | |||||||||||||||||||
156 | 51 | 100 | 117 | $attr = add_classes($attr, 'block') if $attr->{'__block'}; | |||||||||||||||||||
157 | 51 | 153 | $attr = add_disabled($attr, scalar @url); | ||||||||||||||||||||
158 | 51 | 102 | $attr = cleanup_attrs($attr); | ||||||||||||||||||||
159 | |||||||||||||||||||||||
160 | # We have an url | ||||||||||||||||||||||
161 | 51 | 100 | 113 | if(scalar @url) { | |||||||||||||||||||
162 | 12 | 44 | $attr->{'href'} = url_for($c, \@url); | ||||||||||||||||||||
163 | |||||||||||||||||||||||
164 | 12 | 2428 | my $html = htmlify_attrs($attr); | ||||||||||||||||||||
165 | 12 | 41 | return out(qq{} . content_single($content) . qq{$caret}); | ||||||||||||||||||||
166 | } | ||||||||||||||||||||||
167 | else { | ||||||||||||||||||||||
168 | 39 | 114 | my $html = htmlify_attrs($attr); | ||||||||||||||||||||
169 | 39 | 134 | return out(qq{}); | ||||||||||||||||||||
170 | } | ||||||||||||||||||||||
171 | |||||||||||||||||||||||
172 | } | ||||||||||||||||||||||
173 | |||||||||||||||||||||||
174 | sub bootstrap_submit { | ||||||||||||||||||||||
175 | 6 | 6 | 0 | 9001 | push @_ => (type => 'submit'); | ||||||||||||||||||
176 | 6 | 20 | return bootstrap_button(@_); | ||||||||||||||||||||
177 | } | ||||||||||||||||||||||
178 | |||||||||||||||||||||||
179 | sub bootstrap_context_menu { | ||||||||||||||||||||||
180 | 1 | 1 | 0 | 16888 | my $c = shift; | ||||||||||||||||||
181 | 1 | 5 | my %args = @_; | ||||||||||||||||||||
182 | 1 | 3 | my $items = delete $args{'items'}; | ||||||||||||||||||||
183 | 1 | 5 | my $list = make_dropdown_list($c, \%args, $items); | ||||||||||||||||||||
184 | |||||||||||||||||||||||
185 | 1 | 7 | return out($list); | ||||||||||||||||||||
186 | } | ||||||||||||||||||||||
187 | |||||||||||||||||||||||
188 | sub bootstrap_dropdown { | ||||||||||||||||||||||
189 | 2 | 2 | 0 | 17 | my $meat = make_dropdown_meat(shift, shift->@*); | ||||||||||||||||||
190 | |||||||||||||||||||||||
191 | 2 | 33 | my $dropdown = qq{ | ||||||||||||||||||||
192 | |
||||||||||||||||||||||
193 | $meat | ||||||||||||||||||||||
194 | |||||||||||||||||||||||
195 | }; | ||||||||||||||||||||||
196 | 2 | 12 | return out($dropdown); | ||||||||||||||||||||
197 | } | ||||||||||||||||||||||
198 | |||||||||||||||||||||||
199 | sub make_dropdown_meat { | ||||||||||||||||||||||
200 | 11 | 11 | 0 | 23 | my $c = shift; | ||||||||||||||||||
201 | |||||||||||||||||||||||
202 | 11 | 22 | my $button_text = shift; | ||||||||||||||||||||
203 | 11 | 100 | 37 | my @url = ref $_[0] eq 'ARRAY' ? shift->@* : (); | |||||||||||||||||||
204 | 11 | 30 | my $attr = parse_attributes(@_); | ||||||||||||||||||||
205 | |||||||||||||||||||||||
206 | 11 | 50 | 36 | my $items = delete $attr->{'items'} || []; | |||||||||||||||||||
207 | 11 | 100 | 40 | my $ulattr = { __right => exists $attr->{'__right'} ? delete $attr->{'__right'} : 0 }; | |||||||||||||||||||
208 | 11 | 32 | my $listhtml = make_dropdown_list($c, $ulattr, $items); | ||||||||||||||||||||
209 | |||||||||||||||||||||||
210 | 11 | 69 | $attr = add_classes($attr, 'dropdown-toggle'); | ||||||||||||||||||||
211 | 11 | 43 | $attr->{'data-toggle'} = 'dropdown'; | ||||||||||||||||||||
212 | 11 | 30 | $attr->{'type'} = 'button'; | ||||||||||||||||||||
213 | 11 | 49 | my $button = bootstrap_button($c, $button_text, @url, $attr->%*); | ||||||||||||||||||||
214 | |||||||||||||||||||||||
215 | 11 | 98 | my $out = qq{ | ||||||||||||||||||||
216 | $button | ||||||||||||||||||||||
217 | $listhtml | ||||||||||||||||||||||
218 | }; | ||||||||||||||||||||||
219 | 11 | 103 | return out($out); | ||||||||||||||||||||
220 | } | ||||||||||||||||||||||
221 | |||||||||||||||||||||||
222 | sub make_dropdown_list { | ||||||||||||||||||||||
223 | 12 | 12 | 0 | 31 | my $c = shift; | ||||||||||||||||||
224 | 12 | 21 | my $attr = shift; | ||||||||||||||||||||
225 | 12 | 20 | my $items = shift; | ||||||||||||||||||||
226 | |||||||||||||||||||||||
227 | 12 | 48 | $attr = add_classes($attr, 'dropdown-menu'); | ||||||||||||||||||||
228 | 12 | 100 | 44 | $attr = add_classes($attr, 'dropdown-menu-right') if $attr->{'__right'}; | |||||||||||||||||||
229 | 12 | 33 | my $attrhtml = htmlify_attrs($attr); | ||||||||||||||||||||
230 | 12 | 27 | my $menuitems = ''; | ||||||||||||||||||||
231 | |||||||||||||||||||||||
232 | ITEM: | ||||||||||||||||||||||
233 | 12 | 69 | foreach my $item ($items->@*) { | ||||||||||||||||||||
234 | 49 | 100 | 453 | if(ref $item eq '') { | |||||||||||||||||||
235 | 1 | 3 | $menuitems .= qq{ |
||||||||||||||||||||
236 | } | ||||||||||||||||||||||
237 | 49 | 100 | 100 | next ITEM if ref $item ne 'ARRAY'; | |||||||||||||||||||
238 | 48 | 100 | 108 | if(!scalar $item->@*) { | |||||||||||||||||||
239 | 12 | 26 | $menuitems .= q{} ; | ||||||||||||||||||||
240 | } | ||||||||||||||||||||||
241 | else { | ||||||||||||||||||||||
242 | 36 | 87 | $menuitems .= create_dropdown_menuitem($c, $item->@*); | ||||||||||||||||||||
243 | } | ||||||||||||||||||||||
244 | |||||||||||||||||||||||
245 | } | ||||||||||||||||||||||
246 | 12 | 161 | my $out = qq{ | ||||||||||||||||||||
247 | |
||||||||||||||||||||||
248 | $menuitems | ||||||||||||||||||||||
249 | |||||||||||||||||||||||
250 | }; | ||||||||||||||||||||||
251 | 12 | 29 | return out($out); | ||||||||||||||||||||
252 | } | ||||||||||||||||||||||
253 | |||||||||||||||||||||||
254 | sub create_dropdown_menuitem { | ||||||||||||||||||||||
255 | 36 | 36 | 0 | 57 | my $c = shift; | ||||||||||||||||||
256 | 36 | 50 | 87 | my $item_text = iscoderef($_[-1]) ? pop : shift; | |||||||||||||||||||
257 | 36 | 85 | my @url = shift->@*; | ||||||||||||||||||||
258 | |||||||||||||||||||||||
259 | 36 | 73 | my $attr = parse_attributes(@_); | ||||||||||||||||||||
260 | 36 | 75 | $attr = add_classes($attr, 'menuitem'); | ||||||||||||||||||||
261 | 36 | 100 | 114 | my $liattr = { __disabled => exists $attr->{'__disabled'} ? delete $attr->{'__disabled'} : 0 }; | |||||||||||||||||||
262 | 36 | 78 | $liattr = add_disabled($liattr, 1); | ||||||||||||||||||||
263 | 36 | 100 | 154 | $attr->{'tabindex'} ||= -1; | |||||||||||||||||||
264 | 36 | 78 | $attr->{'href'} = url_for($c, \@url); | ||||||||||||||||||||
265 | |||||||||||||||||||||||
266 | 36 | 12613 | my $html = htmlify_attrs($attr); | ||||||||||||||||||||
267 | 36 | 77 | my $lihtml = htmlify_attrs($liattr); | ||||||||||||||||||||
268 | |||||||||||||||||||||||
269 | 36 | 93 | my $tag = qq{ |
||||||||||||||||||||
270 | |||||||||||||||||||||||
271 | 36 | 81 | return out($tag); | ||||||||||||||||||||
272 | } | ||||||||||||||||||||||
273 | |||||||||||||||||||||||
274 | sub bootstrap_buttongroup { | ||||||||||||||||||||||
275 | 11 | 11 | 0 | 17526 | my $c = shift; | ||||||||||||||||||
276 | |||||||||||||||||||||||
277 | #* Shortcut for one button menus | ||||||||||||||||||||||
278 | 11 | 100 | 35 | if(ref $_[0] eq 'ARRAY') { | |||||||||||||||||||
279 | 2 | 7 | my $meat = make_dropdown_meat($c, $_[0]->@*); | ||||||||||||||||||||
280 | 2 | 17 | my $menu = qq{ $meat }; |
||||||||||||||||||||
281 | 2 | 10 | return out($menu); | ||||||||||||||||||||
282 | } | ||||||||||||||||||||||
283 | 9 | 27 | my($buttons, $html) = make_buttongroup_meat($c, @_); | ||||||||||||||||||||
284 | |||||||||||||||||||||||
285 | 9 | 49 | my $tag = qq{ | ||||||||||||||||||||
286 | |
||||||||||||||||||||||
287 | $buttons | ||||||||||||||||||||||
288 | }; | ||||||||||||||||||||||
289 | |||||||||||||||||||||||
290 | 9 | 23 | return out($tag); | ||||||||||||||||||||
291 | } | ||||||||||||||||||||||
292 | |||||||||||||||||||||||
293 | sub make_buttongroup_meat { | ||||||||||||||||||||||
294 | 10 | 10 | 0 | 21 | my $c = shift; | ||||||||||||||||||
295 | |||||||||||||||||||||||
296 | 10 | 30 | my $attr = parse_attributes(@_); | ||||||||||||||||||||
297 | 10 | 26 | my $buttons_info = delete $attr->{'buttons'}; | ||||||||||||||||||||
298 | |||||||||||||||||||||||
299 | 10 | 100 | 31 | my $button_group_class = delete $attr->{'__vertical'} ? 'btn-group-vertical' : 'btn-group'; | |||||||||||||||||||
300 | 10 | 100 | 27 | my $justified_class = delete $attr->{'__justified'} ? 'btn-group-justified' : (); | |||||||||||||||||||
301 | |||||||||||||||||||||||
302 | 10 | 43 | $attr = add_classes($attr, { size => 'btn-group-%s' }); | ||||||||||||||||||||
303 | |||||||||||||||||||||||
304 | #* For the possible inner btn-group, use the same base classes (except justified/vertical/pull-right). | ||||||||||||||||||||||
305 | #* We add possible .dropup in the loop | ||||||||||||||||||||||
306 | 10 | 46 | my $inner_attr = add_classes({ class => $attr->{'class'} }, 'btn-group'); | ||||||||||||||||||||
307 | 10 | 29 | $inner_attr->{'class'} =~ s{\bpull-right\b}{}; | ||||||||||||||||||||
308 | |||||||||||||||||||||||
309 | #* These must come after the inner button group has been given the classes. | ||||||||||||||||||||||
310 | 10 | 22 | $attr = add_classes($attr, $button_group_class, $justified_class); | ||||||||||||||||||||
311 | 10 | 29 | my $html = htmlify_attrs($attr); | ||||||||||||||||||||
312 | |||||||||||||||||||||||
313 | |||||||||||||||||||||||
314 | 10 | 20 | my $buttons = ''; | ||||||||||||||||||||
315 | |||||||||||||||||||||||
316 | BUTTON: | ||||||||||||||||||||||
317 | 10 | 23 | foreach my $button ($buttons_info->@*) { | ||||||||||||||||||||
318 | 29 | 50 | 96 | next BUTTON if ref $button ne 'ARRAY'; | |||||||||||||||||||
319 | |||||||||||||||||||||||
320 | 29 | 54 | my $button_text = shift $button->@*; | ||||||||||||||||||||
321 | 29 | 100 | 77 | my @url = ref $button->[0] eq 'ARRAY' ? shift $button->@* : (); | |||||||||||||||||||
322 | 29 | 64 | my $button_attr = parse_attributes($button->@*); | ||||||||||||||||||||
323 | 29 | 100 | 120 | my $items = delete $button_attr->{'items'} || []; | |||||||||||||||||||
324 | |||||||||||||||||||||||
325 | 29 | 100 | 71 | if(!scalar $items->@*) { | |||||||||||||||||||
326 | 23 | 63 | my $bootstrap_button = bootstrap_button($c, $button_text, @url, $button_attr->%*); | ||||||||||||||||||||
327 | |||||||||||||||||||||||
328 | #* Justified + No url -> button -> must nest | ||||||||||||||||||||||
329 | 23 | 100 | 100 | 200 | if(length $justified_class && !scalar @url) { | ||||||||||||||||||
330 | 3 | 9 | $buttons .= qq{ $bootstrap_button }; |
||||||||||||||||||||
331 | } | ||||||||||||||||||||||
332 | else { | ||||||||||||||||||||||
333 | 20 | 123 | $buttons .= $bootstrap_button; | ||||||||||||||||||||
334 | } | ||||||||||||||||||||||
335 | 23 | 164 | next BUTTON; | ||||||||||||||||||||
336 | } | ||||||||||||||||||||||
337 | |||||||||||||||||||||||
338 | 6 | 100 | 19 | my $dropup_class = delete $button_attr->{'__dropup'} ? 'dropup' : (); | |||||||||||||||||||
339 | 6 | 15 | $inner_attr = add_classes($inner_attr, $dropup_class); | ||||||||||||||||||||
340 | 6 | 17 | my $inner_html = htmlify_attrs($inner_attr); | ||||||||||||||||||||
341 | 6 | 100 | 32 | my $meat = make_dropdown_meat($c, $button_text, (scalar @url ? \@url : ()), $button_attr->%*, items => $items); | |||||||||||||||||||
342 | 6 | 53 | $buttons .= qq{ | ||||||||||||||||||||
343 | |
||||||||||||||||||||||
344 | $meat | ||||||||||||||||||||||
345 | |||||||||||||||||||||||
346 | }; | ||||||||||||||||||||||
347 | |||||||||||||||||||||||
348 | } | ||||||||||||||||||||||
349 | 10 | 95 | return ($buttons, $html); | ||||||||||||||||||||
350 | } | ||||||||||||||||||||||
351 | |||||||||||||||||||||||
352 | sub bootstrap_toolbar { | ||||||||||||||||||||||
353 | 1 | 1 | 0 | 9 | my $c = shift; | ||||||||||||||||||
354 | |||||||||||||||||||||||
355 | 1 | 6 | my $attr = parse_attributes(@_); | ||||||||||||||||||||
356 | 1 | 3 | my $groups = delete $attr->{'groups'}; | ||||||||||||||||||||
357 | |||||||||||||||||||||||
358 | 1 | 6 | $attr = add_classes($attr, 'btn-toolbar'); | ||||||||||||||||||||
359 | 1 | 13 | my $html = htmlify_attrs($attr); | ||||||||||||||||||||
360 | |||||||||||||||||||||||
361 | 1 | 9 | my $toolbar = ''; | ||||||||||||||||||||
362 | 1 | 4 | foreach my $group ($groups->@*) { | ||||||||||||||||||||
363 | 2 | 47 | $toolbar .= bootstrap_buttongroup($c, $group->%*); | ||||||||||||||||||||
364 | } | ||||||||||||||||||||||
365 | |||||||||||||||||||||||
366 | 1 | 12 | my $tag = qq{ | ||||||||||||||||||||
367 | |
||||||||||||||||||||||
368 | $toolbar | ||||||||||||||||||||||
369 | |||||||||||||||||||||||
370 | }; | ||||||||||||||||||||||
371 | |||||||||||||||||||||||
372 | 1 | 3 | return out($tag); | ||||||||||||||||||||
373 | } | ||||||||||||||||||||||
374 | |||||||||||||||||||||||
375 | sub bootstrap_navbar { | ||||||||||||||||||||||
376 | 5 | 5 | 0 | 36 | my $c = shift; | ||||||||||||||||||
377 | |||||||||||||||||||||||
378 | 5 | 14 | my($possible_toggler_id, $navbar_header) = (); | ||||||||||||||||||||
379 | |||||||||||||||||||||||
380 | 5 | 13 | my $content_html = ''; | ||||||||||||||||||||
381 | 5 | 9 | my $has_inverse = 0; | ||||||||||||||||||||
382 | 5 | 12 | my $container = 'fluid'; | ||||||||||||||||||||
383 | |||||||||||||||||||||||
384 | 5 | 16 | while(scalar @_) { | ||||||||||||||||||||
385 | 20 | 31 | my $key = shift; | ||||||||||||||||||||
386 | 20 | 40 | my @arguments = ($c, shift); | ||||||||||||||||||||
387 | |||||||||||||||||||||||
388 | 20 | 100 | 77 | $content_html .= $key eq 'nav' ? make_navbar_nav(@arguments) | |||||||||||||||||||
100 | |||||||||||||||||||||||
100 | |||||||||||||||||||||||
100 | |||||||||||||||||||||||
389 | : $key eq 'form' ? make_navbar_form(@arguments) | ||||||||||||||||||||||
390 | : $key eq 'button' ? make_navbar_button(@arguments) | ||||||||||||||||||||||
391 | : $key eq 'p' ? make_navbar_p(@arguments) | ||||||||||||||||||||||
392 | : '' | ||||||||||||||||||||||
393 | ; | ||||||||||||||||||||||
394 | 20 | 100 | 163 | if($key eq 'header') { | |||||||||||||||||||
395 | 5 | 16 | ($possible_toggler_id, $navbar_header) = make_navbar_header(@arguments); | ||||||||||||||||||||
396 | } | ||||||||||||||||||||||
397 | 20 | 100 | 44 | if($key eq '__inverse') { | |||||||||||||||||||
398 | 2 | 4 | $has_inverse = 1; | ||||||||||||||||||||
399 | } | ||||||||||||||||||||||
400 | 20 | 100 | 57 | if($key eq 'container') { | |||||||||||||||||||
401 | 1 | 4 | $container = $arguments[1]; | ||||||||||||||||||||
402 | } | ||||||||||||||||||||||
403 | |||||||||||||||||||||||
404 | } | ||||||||||||||||||||||
405 | 5 | 100 | 12 | $container = $container eq 'normal' ? 'container' : 'container-fluid'; | |||||||||||||||||||
406 | |||||||||||||||||||||||
407 | 5 | 100 | 13 | my $attr = $has_inverse ? { __inverse => 1 } : {}; | |||||||||||||||||||
408 | 5 | 16 | $attr = add_classes($attr, 'navbar', { navbar => 'navbar-%s', navbar_default => 'default' }); | ||||||||||||||||||||
409 | 5 | 16 | my $html = htmlify_attrs($attr); | ||||||||||||||||||||
410 | 5 | 100 | 11 | if(length $content_html) { | |||||||||||||||||||
411 | 4 | 16 | $content_html = qq{ | ||||||||||||||||||||
412 | |||||||||||||||||||||||
413 | $content_html | ||||||||||||||||||||||
414 | |||||||||||||||||||||||
415 | }; | ||||||||||||||||||||||
416 | } | ||||||||||||||||||||||
417 | |||||||||||||||||||||||
418 | 5 | 29 | my $tag = qq{ | ||||||||||||||||||||
419 | |||||||||||||||||||||||
420 | |
||||||||||||||||||||||
421 | $navbar_header | ||||||||||||||||||||||
422 | $content_html | ||||||||||||||||||||||
423 | |||||||||||||||||||||||
424 | |||||||||||||||||||||||
425 | }; | ||||||||||||||||||||||
426 | |||||||||||||||||||||||
427 | 5 | 12 | return out($tag); | ||||||||||||||||||||
428 | |||||||||||||||||||||||
429 | } | ||||||||||||||||||||||
430 | sub make_navbar_header { | ||||||||||||||||||||||
431 | 5 | 5 | 0 | 13 | my($c, $header, $html_header) = @_; | ||||||||||||||||||
432 | |||||||||||||||||||||||
433 | 5 | 50 | 14 | return (undef, $html_header) if $html_header; | |||||||||||||||||||
434 | |||||||||||||||||||||||
435 | 5 | 10 | my $brand = shift $header->@*; | ||||||||||||||||||||
436 | 5 | 50 | 24 | my $url = url_for($c, shift $header->@* || []); | |||||||||||||||||||
437 | 5 | 19 | my $header_attr = parse_attributes($header->@*); | ||||||||||||||||||||
438 | 5 | 33 | 16 | my $toggler_id = delete $header_attr->{'toggler'} || 'collapsable-' . String::Random->new->randregex('[a-z]{20}'); | |||||||||||||||||||
439 | 5 | 11 | my $has_hamburger = delete $header_attr->{'__hamburger'}; | ||||||||||||||||||||
440 | 5 | 50 | 18 | my $hamburger = $has_hamburger ? get_hamburger($toggler_id) : ''; | |||||||||||||||||||
441 | 5 | 12 | $header_attr = add_classes($header_attr, 'navbar-brand'); | ||||||||||||||||||||
442 | |||||||||||||||||||||||
443 | 5 | 50 | 19 | my $brand_html = defined $brand ? qq{$brand} : ''; | |||||||||||||||||||
444 | |||||||||||||||||||||||
445 | 5 | 15 | my $navbar_header = qq{ | ||||||||||||||||||||
446 | |||||||||||||||||||||||
447 | $hamburger | ||||||||||||||||||||||
448 | $brand_html | ||||||||||||||||||||||
449 | |||||||||||||||||||||||
450 | }; | ||||||||||||||||||||||
451 | |||||||||||||||||||||||
452 | 5 | 18 | return ($toggler_id, $navbar_header); | ||||||||||||||||||||
453 | |||||||||||||||||||||||
454 | } | ||||||||||||||||||||||
455 | |||||||||||||||||||||||
456 | sub make_navbar_nav { | ||||||||||||||||||||||
457 | 5 | 5 | 0 | 10 | my $c = shift; | ||||||||||||||||||
458 | 5 | 7 | my $nav = shift; | ||||||||||||||||||||
459 | |||||||||||||||||||||||
460 | 5 | 11 | my $attr = parse_attributes($nav->@*); | ||||||||||||||||||||
461 | 5 | 10 | my $items = delete $attr->{'items'}; | ||||||||||||||||||||
462 | 5 | 18 | $attr = add_classes($attr, 'nav', 'navbar-nav', { direction => 'navbar-%s' }); | ||||||||||||||||||||
463 | 5 | 15 | my $html = htmlify_attrs($attr); | ||||||||||||||||||||
464 | |||||||||||||||||||||||
465 | 5 | 14 | my $tag = "
|
||||||||||||||||||||
466 | 5 | 14 | $tag .= make_nav_meat($c, $items); | ||||||||||||||||||||
467 | |||||||||||||||||||||||
468 | 5 | 13 | $tag .= ''; | ||||||||||||||||||||
469 | 5 | 15 | return $tag; | ||||||||||||||||||||
470 | } | ||||||||||||||||||||||
471 | |||||||||||||||||||||||
472 | sub make_navbar_form { | ||||||||||||||||||||||
473 | 3 | 3 | 0 | 6 | my $c = shift; | ||||||||||||||||||
474 | 3 | 4 | my $form = shift; | ||||||||||||||||||||
475 | 3 | 7 | my $args = shift $form->@*; | ||||||||||||||||||||
476 | 3 | 6 | my $contents = shift $form->@*; | ||||||||||||||||||||
477 | 3 | 7 | my $url = shift $args->@*; | ||||||||||||||||||||
478 | |||||||||||||||||||||||
479 | 3 | 6 | my $attr = parse_attributes($args->@*); | ||||||||||||||||||||
480 | |||||||||||||||||||||||
481 | 3 | 11 | $attr = add_classes($attr, 'navbar-form', { direction => 'navbar-%s', direction_default => 'left' }); | ||||||||||||||||||||
482 | 3 | 12 | $attr = cleanup_attrs($attr); | ||||||||||||||||||||
483 | |||||||||||||||||||||||
484 | 3 | 7 | my $tag = ''; | ||||||||||||||||||||
485 | 3 | 10 | for (my $index = 0; $index < scalar $contents->@*; $index += 2) { | ||||||||||||||||||||
486 | 6 | 55 | my $key = $contents->[$index]; | ||||||||||||||||||||
487 | 6 | 17 | my @arguments = ($c, $contents->[$index + 1]->@*); | ||||||||||||||||||||
488 | |||||||||||||||||||||||
489 | 6 | 100 | 21 | if($key eq 'formgroup') { | |||||||||||||||||||
50 | |||||||||||||||||||||||
0 | |||||||||||||||||||||||
0 | |||||||||||||||||||||||
490 | 3 | 9 | $tag .= bootstrap_formgroup(@arguments); | ||||||||||||||||||||
491 | } | ||||||||||||||||||||||
492 | elsif($key eq 'submit_button') { | ||||||||||||||||||||||
493 | 3 | 12 | $tag .= bootstrap_submit(@arguments); | ||||||||||||||||||||
494 | } | ||||||||||||||||||||||
495 | elsif($key eq 'button') { | ||||||||||||||||||||||
496 | 0 | 0 | $tag .= bootstrap_button(@arguments) | ||||||||||||||||||||
497 | } | ||||||||||||||||||||||
498 | elsif($key eq 'input') { | ||||||||||||||||||||||
499 | 0 | 0 | $tag .= bootstrap_input(@arguments); | ||||||||||||||||||||
500 | } | ||||||||||||||||||||||
501 | } | ||||||||||||||||||||||
502 | |||||||||||||||||||||||
503 | 3 | 3 | 57 | $tag = Mojolicious::Plugin::TagHelpers::_form_for($c, $url->@*, $attr->%*, sub { $tag }); | |||||||||||||||||||
3 | 903 | ||||||||||||||||||||||
504 | 3 | 1230 | return out($tag); | ||||||||||||||||||||
505 | |||||||||||||||||||||||
506 | } | ||||||||||||||||||||||
507 | |||||||||||||||||||||||
508 | 2 | 2 | 0 | 4 | sub make_navbar_button($c, $arg) { | ||||||||||||||||||
2 | 5 | ||||||||||||||||||||||
2 | 3 | ||||||||||||||||||||||
2 | 4 | ||||||||||||||||||||||
509 | 2 | 4 | my $text = shift $arg->@*; | ||||||||||||||||||||
510 | 2 | 5 | my $url = shift $arg->@*; | ||||||||||||||||||||
511 | 2 | 5 | my $attr = parse_attributes($arg->@*); | ||||||||||||||||||||
512 | 2 | 8 | $attr = add_classes($attr, 'navbar-btn', { direction => 'navbar-%s' }); | ||||||||||||||||||||
513 | 2 | 9 | return bootstrap_button($c, $text, $url, $attr->%*); | ||||||||||||||||||||
514 | } | ||||||||||||||||||||||
515 | |||||||||||||||||||||||
516 | 2 | 2 | 0 | 3 | sub make_navbar_p($c, $arg) { | ||||||||||||||||||
2 | 4 | ||||||||||||||||||||||
2 | 3 | ||||||||||||||||||||||
2 | 4 | ||||||||||||||||||||||
517 | 2 | 3 | my $text = shift $arg->@*; | ||||||||||||||||||||
518 | 2 | 7 | my $attr = parse_attributes($arg->@*); | ||||||||||||||||||||
519 | 2 | 7 | $attr = add_classes($attr, 'navbar-text', { direction => 'navbar-%s' }); | ||||||||||||||||||||
520 | 2 | 6 | my $html = htmlify_attrs($attr); | ||||||||||||||||||||
521 | |||||||||||||||||||||||
522 | 2 | 8 | return out(qq{ $text }); |
||||||||||||||||||||
523 | } | ||||||||||||||||||||||
524 | |||||||||||||||||||||||
525 | sub get_hamburger { | ||||||||||||||||||||||
526 | 5 | 5 | 0 | 10 | my $toggler_id = shift; | ||||||||||||||||||
527 | |||||||||||||||||||||||
528 | 5 | 15 | my $tag = qq{ | ||||||||||||||||||||
529 | |||||||||||||||||||||||
530 | |||||||||||||||||||||||
531 | |||||||||||||||||||||||
532 | |||||||||||||||||||||||
533 | |||||||||||||||||||||||
534 | }; | ||||||||||||||||||||||
535 | 5 | 10 | return $tag; | ||||||||||||||||||||
536 | } | ||||||||||||||||||||||
537 | |||||||||||||||||||||||
538 | sub make_nav_meat { | ||||||||||||||||||||||
539 | 7 | 7 | 0 | 11 | my $c = shift; | ||||||||||||||||||
540 | 7 | 12 | my $contents = shift; | ||||||||||||||||||||
541 | |||||||||||||||||||||||
542 | 7 | 14 | my $tag = ''; | ||||||||||||||||||||
543 | CONTENT: | ||||||||||||||||||||||
544 | 7 | 18 | foreach my $content ($contents->@*) { | ||||||||||||||||||||
545 | 18 | 50 | 44 | next CONTENT if ref $content ne 'ARRAY'; | |||||||||||||||||||
546 | |||||||||||||||||||||||
547 | 18 | 32 | my $text = shift $content->@*; | ||||||||||||||||||||
548 | 18 | 39 | my $url = url_for($c, shift $content->@*); | ||||||||||||||||||||
549 | 18 | 40 | my $attr = parse_attributes($content->@*); | ||||||||||||||||||||
550 | |||||||||||||||||||||||
551 | 18 | 100 | 56 | my $items = delete $attr->{'items'} || []; | |||||||||||||||||||
552 | #* No sub menu | ||||||||||||||||||||||
553 | 18 | 100 | 43 | if(!scalar $items->@*) { | |||||||||||||||||||
554 | 14 | 25 | my $active = delete $attr->{'__active'}; | ||||||||||||||||||||
555 | 14 | 27 | my $disabled = delete $attr->{'__disabled'}; | ||||||||||||||||||||
556 | 14 | 100 | 29 | my $li_attr = exists $attr->{'-li'} ? parse_attributes(delete($attr->{'-li'})->@*) : {}; | |||||||||||||||||||
557 | 14 | 100 | 41 | $li_attr = add_classes($li_attr, $active ? 'active' : (), $disabled ? 'disabled' : ()); | |||||||||||||||||||
100 | |||||||||||||||||||||||
558 | 14 | 28 | my $li_html = htmlify_attrs($li_attr); | ||||||||||||||||||||
559 | |||||||||||||||||||||||
560 | 14 | 28 | my $a_attr = htmlify_attrs($attr); | ||||||||||||||||||||
561 | |||||||||||||||||||||||
562 | 14 | 36 | my $link_html = qq{$text}; | ||||||||||||||||||||
563 | 14 | 43 | $tag .= qq{ |
||||||||||||||||||||
564 | 14 | 42 | next CONTENT; | ||||||||||||||||||||
565 | } | ||||||||||||||||||||||
566 | else { | ||||||||||||||||||||||
567 | 4 | 10 | $attr = add_classes($attr, 'dropdown-toggle'); | ||||||||||||||||||||
568 | 4 | 11 | $attr->{'data-toggle'} = 'dropdown'; | ||||||||||||||||||||
569 | 4 | 10 | $attr->{'href'} = $url; | ||||||||||||||||||||
570 | 4 | 50 | 21 | my $caret = delete $attr->{'__caret'} ? ' ' : ''; | |||||||||||||||||||
571 | 4 | 10 | my $button_arg = htmlify_attrs($attr); | ||||||||||||||||||||
572 | 4 | 17 | my $button_html = qq{$text$caret}; | ||||||||||||||||||||
573 | |||||||||||||||||||||||
574 | 4 | 8 | my $lis = ''; | ||||||||||||||||||||
575 | ITEM: | ||||||||||||||||||||||
576 | 4 | 11 | foreach my $item ($items->@*) { | ||||||||||||||||||||
577 | 20 | 100 | 43 | if(!scalar $item->@*) { | |||||||||||||||||||
578 | 5 | 9 | $lis .= q{}; | ||||||||||||||||||||
579 | 5 | 13 | next ITEM; | ||||||||||||||||||||
580 | } | ||||||||||||||||||||||
581 | 15 | 22 | my $text = shift $item->@*; | ||||||||||||||||||||
582 | 15 | 28 | my $url = url_for($c, shift $item->@*); | ||||||||||||||||||||
583 | 15 | 30 | my $a_attr = parse_attributes($item->@*); | ||||||||||||||||||||
584 | 15 | 39 | $a_attr->{'href'} = $url; | ||||||||||||||||||||
585 | 15 | 27 | my $a_html = htmlify_attrs($a_attr); | ||||||||||||||||||||
586 | 15 | 42 | $lis .= qq{ |
||||||||||||||||||||
587 | } | ||||||||||||||||||||||
588 | 4 | 19 | $tag .= qq{ | ||||||||||||||||||||
589 | |
||||||||||||||||||||||
590 | $button_html | ||||||||||||||||||||||
591 | |||||||||||||||||||||||
592 | $lis | ||||||||||||||||||||||
593 | |||||||||||||||||||||||
594 | |||||||||||||||||||||||
595 | }; | ||||||||||||||||||||||
596 | } | ||||||||||||||||||||||
597 | } | ||||||||||||||||||||||
598 | 7 | 24 | return $tag; | ||||||||||||||||||||
599 | } | ||||||||||||||||||||||
600 | |||||||||||||||||||||||
601 | sub bootstrap_nav { | ||||||||||||||||||||||
602 | 2 | 2 | 0 | 12 | my $c = shift; | ||||||||||||||||||
603 | 2 | 9 | my $attr = parse_attributes(@_); | ||||||||||||||||||||
604 | 2 | 5 | my $pills = delete $attr->{'pills'}; | ||||||||||||||||||||
605 | 2 | 4 | my $tabs = delete $attr->{'tabs'}; | ||||||||||||||||||||
606 | |||||||||||||||||||||||
607 | 2 | 50 | 9 | my $which = $pills ? 'nav-pills' | |||||||||||||||||||
100 | |||||||||||||||||||||||
608 | : $tabs ? 'nav-tabs' | ||||||||||||||||||||||
609 | : () | ||||||||||||||||||||||
610 | ; | ||||||||||||||||||||||
611 | 2 | 100 | 6 | my $justified = delete $attr->{'__justified'} ? 'nav-justified' : (); | |||||||||||||||||||
612 | 2 | 9 | $attr = add_classes($attr, 'nav', $which, $justified); | ||||||||||||||||||||
613 | 2 | 8 | my $html = htmlify_attrs($attr); | ||||||||||||||||||||
614 | 2 | 66 | 9 | my $either = $pills || $tabs; | |||||||||||||||||||
615 | |||||||||||||||||||||||
616 | 2 | 7 | my $tag = make_nav_meat($c, $either); | ||||||||||||||||||||
617 | 2 | 14 | $tag = qq{
|
||||||||||||||||||||
618 | |||||||||||||||||||||||
619 | 2 | 8 | return out($tag); | ||||||||||||||||||||
620 | } | ||||||||||||||||||||||
621 | |||||||||||||||||||||||
622 | sub bootstrap_badge { | ||||||||||||||||||||||
623 | 3 | 3 | 0 | 16447 | my $c = shift; | ||||||||||||||||||
624 | 3 | 50 | 9 | my $content = iscoderef($_[-1]) ? pop : shift; | |||||||||||||||||||
625 | 3 | 9 | my $attr = parse_attributes(@_); | ||||||||||||||||||||
626 | |||||||||||||||||||||||
627 | 3 | 9 | $attr = add_classes($attr, 'badge', { direction => 'pull-%s' }); | ||||||||||||||||||||
628 | 3 | 33 | my $html = htmlify_attrs($attr); | ||||||||||||||||||||
629 | |||||||||||||||||||||||
630 | 3 | 50 | 33 | 15 | my $badge = defined $content && length $content ? qq{$content} : ''; | ||||||||||||||||||
631 | |||||||||||||||||||||||
632 | 3 | 7 | return out($badge); | ||||||||||||||||||||
633 | } | ||||||||||||||||||||||
634 | |||||||||||||||||||||||
635 | sub bootstrap_icon { | ||||||||||||||||||||||
636 | 4 | 4 | 0 | 40896 | my $c = shift; | ||||||||||||||||||
637 | 4 | 10 | my $icon = shift; | ||||||||||||||||||||
638 | |||||||||||||||||||||||
639 | 4 | 28 | my $icon_class = $c->config->{'Plugin::BootstrapHelpers'}{'icons'}{'class'}; | ||||||||||||||||||||
640 | 4 | 126 | my $formatter = $c->config->{'Plugin::BootstrapHelpers'}{'icons'}{'formatter'}; | ||||||||||||||||||||
641 | |||||||||||||||||||||||
642 | 4 | 69 | my $this_icon = sprintf $formatter => $icon; | ||||||||||||||||||||
643 | 4 | 19 | my $attr = parse_attributes(@_); | ||||||||||||||||||||
644 | 4 | 16 | $attr = add_classes($attr, $icon_class, $this_icon); | ||||||||||||||||||||
645 | 4 | 18 | my $html = htmlify_attrs($attr); | ||||||||||||||||||||
646 | |||||||||||||||||||||||
647 | 4 | 50 | 33 | 63 | return '' if !defined $icon || !length $icon; | ||||||||||||||||||
648 | 4 | 18 | return out(qq{}); | ||||||||||||||||||||
649 | } | ||||||||||||||||||||||
650 | |||||||||||||||||||||||
651 | sub bootstrap_input { | ||||||||||||||||||||||
652 | 5 | 5 | 0 | 28140 | my $c = shift; | ||||||||||||||||||
653 | 5 | 21 | my $attr = parse_attributes(@_); | ||||||||||||||||||||
654 | |||||||||||||||||||||||
655 | 5 | 17 | my $prepend = delete $attr->{'prepend'}; | ||||||||||||||||||||
656 | 5 | 13 | my $append = delete $attr->{'append'}; | ||||||||||||||||||||
657 | |||||||||||||||||||||||
658 | 5 | 23 | my(undef, $input_tag) = fix_input($c, (delete $attr->{'input'}) ); | ||||||||||||||||||||
659 | 5 | 64 | $attr = add_classes($attr, 'input-group', { size => 'input-group-%s' }); | ||||||||||||||||||||
660 | 5 | 18 | my $html = htmlify_attrs($attr); | ||||||||||||||||||||
661 | |||||||||||||||||||||||
662 | 5 | 14 | my($prepend_tag, $append_tag) = undef; | ||||||||||||||||||||
663 | |||||||||||||||||||||||
664 | 5 | 100 | 13 | if($prepend) { | |||||||||||||||||||
665 | 3 | 10 | $prepend_tag = fix_input_ender($c, $prepend); | ||||||||||||||||||||
666 | } | ||||||||||||||||||||||
667 | 5 | 100 | 13 | if($append) { | |||||||||||||||||||
668 | 3 | 9 | $append_tag = fix_input_ender($c, $append); | ||||||||||||||||||||
669 | } | ||||||||||||||||||||||
670 | |||||||||||||||||||||||
671 | 5 | 100 | 48 | my $tag = qq{ | |||||||||||||||||||
100 | |||||||||||||||||||||||
672 | |
||||||||||||||||||||||
673 | } . ($prepend_tag || '') . qq{ | ||||||||||||||||||||||
674 | $input_tag | ||||||||||||||||||||||
675 | } . ($append_tag || '') . qq{ | ||||||||||||||||||||||
676 | |||||||||||||||||||||||
677 | }; | ||||||||||||||||||||||
678 | |||||||||||||||||||||||
679 | 5 | 14 | return out($tag); | ||||||||||||||||||||
680 | |||||||||||||||||||||||
681 | } | ||||||||||||||||||||||
682 | |||||||||||||||||||||||
683 | sub fix_input_ender { | ||||||||||||||||||||||
684 | 6 | 6 | 0 | 12 | my $c = shift; | ||||||||||||||||||
685 | 6 | 28 | my $ender = shift; | ||||||||||||||||||||
686 | 6 | 17 | my $where = shift; | ||||||||||||||||||||
687 | |||||||||||||||||||||||
688 | 6 | 100 | 18 | if(ref $ender eq '') { | |||||||||||||||||||
689 | 1 | 3 | return qq{$ender}; | ||||||||||||||||||||
690 | } | ||||||||||||||||||||||
691 | |||||||||||||||||||||||
692 | 5 | 15 | my $key = (keys $ender->%*)[0]; | ||||||||||||||||||||
693 | 5 | 12 | my $tag = undef; | ||||||||||||||||||||
694 | 5 | 100 | 100 | 32 | if($key eq 'check_box' || $key eq 'radio_button') { | ||||||||||||||||||
100 | |||||||||||||||||||||||
50 | |||||||||||||||||||||||
695 | 2 | 100 | 6 | my $type = $key eq 'check_box' ? 'checkbox' : 'radio'; | |||||||||||||||||||
696 | 2 | 9 | my $extra_input = Mojolicious::Plugin::TagHelpers::_input($c, $ender->{ $key }->@*, type => $type); | ||||||||||||||||||||
697 | 2 | 297 | $tag = qq{ | ||||||||||||||||||||
698 | $extra_input | ||||||||||||||||||||||
699 | }; | ||||||||||||||||||||||
700 | } | ||||||||||||||||||||||
701 | elsif($key eq 'button') { | ||||||||||||||||||||||
702 | 1 | 5 | my $button = bootstrap_button($c, $ender->{ $key }->@*); | ||||||||||||||||||||
703 | 1 | 10 | $tag = qq{ | ||||||||||||||||||||
704 | $button | ||||||||||||||||||||||
705 | }; | ||||||||||||||||||||||
706 | } | ||||||||||||||||||||||
707 | elsif($key eq 'buttongroup') { | ||||||||||||||||||||||
708 | 2 | 50 | 8 | return '' if ref $ender->{ $key } ne 'ARRAY'; | |||||||||||||||||||
709 | my($button_group) = scalar $ender->{ $key }->@* == 1 ? make_dropdown_meat($c, $ender->{ $key }[0]->@*) | ||||||||||||||||||||||
710 | 2 | 100 | 15 | : make_buttongroup_meat($c, $ender->{ $key }->@*) | |||||||||||||||||||
711 | ; | ||||||||||||||||||||||
712 | 2 | 13 | $tag = qq{ | ||||||||||||||||||||
713 | $button_group |
||||||||||||||||||||||
714 | } | ||||||||||||||||||||||
715 | } | ||||||||||||||||||||||
716 | 0 | 0 | else { $tag = $key; } | ||||||||||||||||||||
717 | |||||||||||||||||||||||
718 | 5 | 32 | return $tag; | ||||||||||||||||||||
719 | } | ||||||||||||||||||||||
720 | |||||||||||||||||||||||
721 | sub iscoderef { | ||||||||||||||||||||||
722 | 39 | 39 | 0 | 100 | return ref shift eq 'CODE'; | ||||||||||||||||||
723 | } | ||||||||||||||||||||||
724 | sub url_for { | ||||||||||||||||||||||
725 | 86 | 86 | 0 | 152 | my $c = shift; | ||||||||||||||||||
726 | 86 | 122 | my $url = shift; | ||||||||||||||||||||
727 | 86 | 50 | 199 | return '' if ref $url ne 'ARRAY'; | |||||||||||||||||||
728 | 86 | 100 | 66 | 373 | return $url->[0] if scalar $url->@* == 1 && substr ($url->[0], 0, 1) eq '#'; | ||||||||||||||||||
729 | 43 | 624 | return $c->url_for($url->@*)->to_string; | ||||||||||||||||||||
730 | } | ||||||||||||||||||||||
731 | |||||||||||||||||||||||
732 | sub fix_input { | ||||||||||||||||||||||
733 | 17 | 17 | 0 | 35 | my $c = shift; | ||||||||||||||||||
734 | 17 | 25 | my $attr = shift; | ||||||||||||||||||||
735 | |||||||||||||||||||||||
736 | 17 | 48 | my $tagname; | ||||||||||||||||||||
737 | my $info; | ||||||||||||||||||||||
738 | |||||||||||||||||||||||
739 | 17 | 100 | 50 | if((grep { exists $attr->{"${_}_field"} } qw/date datetime month time week color email number range search tel text url password/)[0]) { | |||||||||||||||||||
238 | 50 | 454 | |||||||||||||||||||||
740 | 16 | 43 | $tagname = (grep { exists $attr->{"${_}_field"} } qw/date datetime month time week color email number range search tel text url password/)[0]; | ||||||||||||||||||||
224 | 376 | ||||||||||||||||||||||
741 | 16 | 35 | $info = $attr->{"${tagname}_field"}; | ||||||||||||||||||||
742 | } | ||||||||||||||||||||||
743 | elsif(exists $attr->{'text_area'}) { | ||||||||||||||||||||||
744 | 1 | 2 | $tagname = 'textarea'; | ||||||||||||||||||||
745 | 1 | 2 | $info = $attr->{'text_area'}; | ||||||||||||||||||||
746 | } | ||||||||||||||||||||||
747 | 17 | 45 | my $id = shift $info->@*; | ||||||||||||||||||||
748 | |||||||||||||||||||||||
749 | # if odd number of elements, the first one is the value (shortcut to avoid having to: value => 'value') | ||||||||||||||||||||||
750 | 17 | 100 | 45 | if($info->@* % 2) { | |||||||||||||||||||
751 | 2 | 7 | push $info->@* => (value => shift $info->@*); | ||||||||||||||||||||
752 | } | ||||||||||||||||||||||
753 | 17 | 44 | my $tag_attr = { $info->@* }; | ||||||||||||||||||||
754 | |||||||||||||||||||||||
755 | 17 | 63 | my @column_classes = get_column_classes($attr->{'column_information'}, 1); | ||||||||||||||||||||
756 | 17 | 69 | $tag_attr = add_classes($tag_attr, 'form-control', { size => 'input-%s' }); | ||||||||||||||||||||
757 | |||||||||||||||||||||||
758 | 17 | 50 | 33 | 98 | $tag_attr->{'id'} = $id if defined $id && !exists $tag_attr->{'id'}; | ||||||||||||||||||
759 | 17 | 50 | 61 | my $name_attr = defined $id ? $id =~ s{-}{_}rg : undef; | |||||||||||||||||||
760 | |||||||||||||||||||||||
761 | 17 | 46 | $tag_attr = cleanup_attrs($tag_attr); | ||||||||||||||||||||
762 | |||||||||||||||||||||||
763 | 17 | 100 | 50 | my $horizontal_before = scalar @column_classes ? qq{ ' : ''; |
|||||||||||||||||||
764 | 17 | 100 | 75 | my $horizontal_after = scalar @column_classes ? '' : ''; | |||||||||||||||||||
765 | 17 | 100 | 103 | my $input = exists $attr->{'text_area'} ? Mojolicious::Plugin::TagHelpers::_text_area($c, $name_attr, delete $tag_attr->{'value'}, $tag_attr->%*) | |||||||||||||||||||
766 | : Mojolicious::Plugin::TagHelpers::_input($c, $name_attr, $tag_attr->%*, type => $tagname) | ||||||||||||||||||||||
767 | ; | ||||||||||||||||||||||
768 | |||||||||||||||||||||||
769 | 17 | 21425 | return ($id => $horizontal_before . $input . $horizontal_after); | ||||||||||||||||||||
770 | |||||||||||||||||||||||
771 | } | ||||||||||||||||||||||
772 | |||||||||||||||||||||||
773 | sub fix_label { | ||||||||||||||||||||||
774 | 8 | 8 | 0 | 17 | my $c = shift; | ||||||||||||||||||
775 | 8 | 14 | my $for = shift; | ||||||||||||||||||||
776 | 8 | 13 | my $title = shift; | ||||||||||||||||||||
777 | 8 | 13 | my $attr = shift; | ||||||||||||||||||||
778 | |||||||||||||||||||||||
779 | 8 | 22 | my @column_classes = get_column_classes($attr->{'column_information'}, 0); | ||||||||||||||||||||
780 | 8 | 32 | my @args = (class => trim join ' ' => ('control-label', @column_classes)); | ||||||||||||||||||||
781 | 8 | 100 | 171 | ref $title eq 'CODE' ? push @args => $title : unshift @args => $title; | |||||||||||||||||||
782 | |||||||||||||||||||||||
783 | 8 | 28 | return Mojolicious::Plugin::TagHelpers::_label_for($c, $for, @args); | ||||||||||||||||||||
784 | } | ||||||||||||||||||||||
785 | |||||||||||||||||||||||
786 | sub parse_call { | ||||||||||||||||||||||
787 | 4 | 4 | 0 | 12 | my $c = shift; | ||||||||||||||||||
788 | 4 | 8 | my $title = shift; | ||||||||||||||||||||
789 | 4 | 100 | 18 | my $callback = ref $_[-1] eq 'CODE' ? pop : undef; | |||||||||||||||||||
790 | 4 | 50 | 16 | my $content = scalar @_ % 2 ? pop : ''; | |||||||||||||||||||
791 | 4 | 17 | my $attr = parse_attributes(@_); | ||||||||||||||||||||
792 | |||||||||||||||||||||||
793 | 4 | 17 | return ($c, $title, $callback, $content, $attr); | ||||||||||||||||||||
794 | } | ||||||||||||||||||||||
795 | |||||||||||||||||||||||
796 | sub parse_attributes { | ||||||||||||||||||||||
797 | 226 | 226 | 0 | 528 | my %attr = @_; | ||||||||||||||||||
798 | 226 | 100 | 66 | 586 | if($attr{'data'} && ref $attr{'data'} eq 'HASH') { | ||||||||||||||||||
799 | 9 | 17 | while(my($key, $value) = each %{ $attr{'data'} }) { | ||||||||||||||||||||
18 | 68 | ||||||||||||||||||||||
800 | 9 | 24 | $key =~ tr/_/-/; | ||||||||||||||||||||
801 | 9 | 42 | $attr{ lc("data-$key") } = $value; | ||||||||||||||||||||
802 | } | ||||||||||||||||||||||
803 | 9 | 20 | delete $attr{'data'}; | ||||||||||||||||||||
804 | } | ||||||||||||||||||||||
805 | 226 | 488 | return \%attr; | ||||||||||||||||||||
806 | } | ||||||||||||||||||||||
807 | |||||||||||||||||||||||
808 | sub get_column_classes { | ||||||||||||||||||||||
809 | 25 | 25 | 0 | 87 | my $attr = shift; | ||||||||||||||||||
810 | 25 | 41 | my $index = shift; | ||||||||||||||||||||
811 | |||||||||||||||||||||||
812 | 25 | 46 | my @classes = (); | ||||||||||||||||||||
813 | 25 | 77 | foreach my $key (keys $attr->%*) { | ||||||||||||||||||||
814 | 6 | 16 | my $correct_name = get_size_for($key); | ||||||||||||||||||||
815 | 6 | 50 | 18 | if(defined $correct_name) { | |||||||||||||||||||
816 | 6 | 28 | push @classes => sprintf "col-%s-%d" => $correct_name, $attr->{ $key }[ $index ]; | ||||||||||||||||||||
817 | } | ||||||||||||||||||||||
818 | } | ||||||||||||||||||||||
819 | 25 | 84 | return sort @classes; | ||||||||||||||||||||
820 | } | ||||||||||||||||||||||
821 | |||||||||||||||||||||||
822 | sub add_classes { | ||||||||||||||||||||||
823 | 248 | 248 | 0 | 419 | my $attr = shift; | ||||||||||||||||||
824 | 248 | 100 | 556 | my $formatter = ref $_[-1] eq 'HASH' ? pop : undef; | |||||||||||||||||||
825 | |||||||||||||||||||||||
826 | 14 | 14 | 81459 | no warnings 'uninitialized'; | |||||||||||||||||||
14 | 47 | ||||||||||||||||||||||
14 | 17019 | ||||||||||||||||||||||
827 | |||||||||||||||||||||||
828 | 248 | 576 | my @classes = ($attr->{'class'}, @_); | ||||||||||||||||||||
829 | |||||||||||||||||||||||
830 | 248 | 100 | 554 | if($formatter) { | |||||||||||||||||||
831 | 127 | 100 | 275 | if(exists $formatter->{'size'}) { | |||||||||||||||||||
832 | 95 | 349 | push @classes => sprintfify_class($attr, $formatter->{'size'}, $formatter->{'size_default'}, _sizes()); | ||||||||||||||||||||
833 | } | ||||||||||||||||||||||
834 | 127 | 100 | 489 | if(exists $formatter->{'button'}) { | |||||||||||||||||||
835 | 51 | 122 | push @classes => sprintfify_class($attr, $formatter->{'button'}, $formatter->{'button_default'}, _button_contexts()); | ||||||||||||||||||||
836 | } | ||||||||||||||||||||||
837 | 127 | 100 | 370 | if(exists $formatter->{'panel'}) { | |||||||||||||||||||
838 | 6 | 28 | push @classes => sprintfify_class($attr, $formatter->{'panel'}, $formatter->{'panel_default'}, _panel_contexts()); | ||||||||||||||||||||
839 | } | ||||||||||||||||||||||
840 | 127 | 100 | 295 | if(exists $formatter->{'table'}) { | |||||||||||||||||||
841 | 6 | 21 | push @classes => sprintfify_class($attr, $formatter->{'table'}, $formatter->{'table_default'}, _table_contexts()); | ||||||||||||||||||||
842 | } | ||||||||||||||||||||||
843 | 127 | 100 | 267 | if(exists $formatter->{'direction'}) { | |||||||||||||||||||
844 | 15 | 47 | push @classes => sprintfify_class($attr, $formatter->{'direction'}, $formatter->{'direction_default'}, _direction_contexts()); | ||||||||||||||||||||
845 | } | ||||||||||||||||||||||
846 | 127 | 100 | 291 | if(exists $formatter->{'navbar'}) { | |||||||||||||||||||
847 | 5 | 16 | push @classes => sprintfify_class($attr, $formatter->{'navbar'}, $formatter->{'navbar_default'}, _navbar_contexts()); | ||||||||||||||||||||
848 | } | ||||||||||||||||||||||
849 | } | ||||||||||||||||||||||
850 | |||||||||||||||||||||||
851 | 248 | 414 | my %uniqs = (); | ||||||||||||||||||||
852 | 248 | 1666 | $attr->{'class'} = trim join ' ' => uniq sort @classes; | ||||||||||||||||||||
853 | |||||||||||||||||||||||
854 | 248 | 5564 | return $attr; | ||||||||||||||||||||
855 | |||||||||||||||||||||||
856 | } | ||||||||||||||||||||||
857 | |||||||||||||||||||||||
858 | sub sprintfify_class { | ||||||||||||||||||||||
859 | 178 | 178 | 0 | 312 | my $attr = shift; | ||||||||||||||||||
860 | 178 | 245 | my $format = shift; | ||||||||||||||||||||
861 | 178 | 244 | my $possibilities = pop; | ||||||||||||||||||||
862 | 178 | 314 | my $default = shift; | ||||||||||||||||||||
863 | |||||||||||||||||||||||
864 | 178 | 602 | my @founds = (grep { exists $attr->{ $_ } } (keys $possibilities->%*)); | ||||||||||||||||||||
2186 | 3463 | ||||||||||||||||||||||
865 | |||||||||||||||||||||||
866 | 178 | 100 | 100 | 753 | return if !scalar @founds && !defined $default; | ||||||||||||||||||
867 | 85 | 100 | 206 | push @founds => $default if !scalar @founds; | |||||||||||||||||||
868 | |||||||||||||||||||||||
869 | 85 | 132 | return map { sprintf $format => $possibilities->{ $_ } } @founds; | ||||||||||||||||||||
91 | 399 | ||||||||||||||||||||||
870 | |||||||||||||||||||||||
871 | } | ||||||||||||||||||||||
872 | |||||||||||||||||||||||
873 | sub add_disabled { | ||||||||||||||||||||||
874 | 87 | 87 | 0 | 142 | my $attr = shift; | ||||||||||||||||||
875 | 87 | 117 | my $add_as_class = shift; # if false, add as attribute | ||||||||||||||||||||
876 | |||||||||||||||||||||||
877 | 87 | 100 | 100 | 261 | if(exists $attr->{'__disabled'} && $attr->{'__disabled'}) { | ||||||||||||||||||
878 | 3 | 100 | 10 | if($add_as_class) { | |||||||||||||||||||
879 | 2 | 7 | $attr = add_classes($attr, 'disabled'); | ||||||||||||||||||||
880 | } | ||||||||||||||||||||||
881 | else { | ||||||||||||||||||||||
882 | 1 | 4 | $attr->{'disabled'} = 'disabled'; | ||||||||||||||||||||
883 | } | ||||||||||||||||||||||
884 | } | ||||||||||||||||||||||
885 | 87 | 141 | return $attr; | ||||||||||||||||||||
886 | } | ||||||||||||||||||||||
887 | |||||||||||||||||||||||
888 | sub contents { | ||||||||||||||||||||||
889 | 4 | 4 | 0 | 9 | my $callback = shift; | ||||||||||||||||||
890 | 4 | 10 | my $content = shift; | ||||||||||||||||||||
891 | |||||||||||||||||||||||
892 | 4 | 100 | 15 | return defined $callback ? $callback->() : xml_escape($content); | |||||||||||||||||||
893 | } | ||||||||||||||||||||||
894 | |||||||||||||||||||||||
895 | sub content_single { | ||||||||||||||||||||||
896 | 51 | 51 | 0 | 90 | my $content = shift; | ||||||||||||||||||
897 | |||||||||||||||||||||||
898 | 51 | 100 | 211 | return ref $content eq 'CODE' ? $content->() : xml_escape($content); | |||||||||||||||||||
899 | } | ||||||||||||||||||||||
900 | |||||||||||||||||||||||
901 | sub cleanup_attrs { | ||||||||||||||||||||||
902 | 314 | 314 | 0 | 491 | my $hash = shift; | ||||||||||||||||||
903 | |||||||||||||||||||||||
904 | #* delete all shortcuts (-> __*) | ||||||||||||||||||||||
905 | 314 | 694 | map { delete $hash->{ $_ } } grep { substr($_, 0, 2) eq '__' } keys $hash->%*; | ||||||||||||||||||||
98 | 259 | ||||||||||||||||||||||
616 | 1360 | ||||||||||||||||||||||
906 | |||||||||||||||||||||||
907 | #* delete all keys whose value is not a string | ||||||||||||||||||||||
908 | 314 | 50 | 613 | map { delete $hash->{ $_ } } grep { $_ ne 'data' && ref $hash->{ $_ } ne '' } keys $hash->%*; | |||||||||||||||||||
15 | 38 | ||||||||||||||||||||||
518 | 1737 | ||||||||||||||||||||||
909 | |||||||||||||||||||||||
910 | 314 | 562 | return $hash; | ||||||||||||||||||||
911 | } | ||||||||||||||||||||||
912 | |||||||||||||||||||||||
913 | sub get_size_for { | ||||||||||||||||||||||
914 | 6 | 6 | 0 | 9 | my $input = shift; | ||||||||||||||||||
915 | |||||||||||||||||||||||
916 | 6 | 11 | return _sizes()->{ $input }; | ||||||||||||||||||||
917 | } | ||||||||||||||||||||||
918 | |||||||||||||||||||||||
919 | sub _sizes { | ||||||||||||||||||||||
920 | return { | ||||||||||||||||||||||
921 | 101 | 101 | 841 | __xsmall => 'xs', xsmall => 'xs', xs => 'xs', | |||||||||||||||||||
922 | __small => 'sm', small => 'sm', sm => 'sm', | ||||||||||||||||||||||
923 | __medium => 'md', medium => 'md', md => 'md', | ||||||||||||||||||||||
924 | __large => 'lg', large => 'lg', lg => 'lg', | ||||||||||||||||||||||
925 | } | ||||||||||||||||||||||
926 | } | ||||||||||||||||||||||
927 | |||||||||||||||||||||||
928 | sub _button_contexts { | ||||||||||||||||||||||
929 | 51 | 51 | 126 | return { map { ("__$_" => $_, $_ => $_) } qw/default primary success info warning danger link/ }; | |||||||||||||||||||
357 | 1141 | ||||||||||||||||||||||
930 | } | ||||||||||||||||||||||
931 | sub _panel_contexts { | ||||||||||||||||||||||
932 | 6 | 6 | 19 | return { map { ("__$_" => $_, $_ => $_) } qw/default primary success info warning danger/ }; | |||||||||||||||||||
36 | 169 | ||||||||||||||||||||||
933 | } | ||||||||||||||||||||||
934 | sub _table_contexts { | ||||||||||||||||||||||
935 | 6 | 6 | 13 | return { map { ("__$_" => $_, $_ => $_) } qw/striped bordered hover condensed responsive/ }; | |||||||||||||||||||
30 | 96 | ||||||||||||||||||||||
936 | } | ||||||||||||||||||||||
937 | sub _direction_contexts { | ||||||||||||||||||||||
938 | 15 | 15 | 30 | return { map { ("__$_" => $_, $_ => $_) } qw/right block vertical justified dropup left/ }; | |||||||||||||||||||
90 | 287 | ||||||||||||||||||||||
939 | } | ||||||||||||||||||||||
940 | sub _menu_contexts { | ||||||||||||||||||||||
941 | 0 | 0 | 0 | return { map { ("__$_" => undef, $_ => undef) } qw/caret hamburger/ }; | |||||||||||||||||||
0 | 0 | ||||||||||||||||||||||
942 | } | ||||||||||||||||||||||
943 | sub _misc_contexts { | ||||||||||||||||||||||
944 | 0 | 0 | 0 | return { map { ("__$_" => $_, $_ => $_) } qw/active disabled/ }; | |||||||||||||||||||
0 | 0 | ||||||||||||||||||||||
945 | } | ||||||||||||||||||||||
946 | sub _navbar_contexts { | ||||||||||||||||||||||
947 | 5 | 5 | 11 | return { map { ("__$_" => $_, $_ => $_) } qw/default inverse/ }; | |||||||||||||||||||
10 | 44 | ||||||||||||||||||||||
948 | } | ||||||||||||||||||||||
949 | |||||||||||||||||||||||
950 | sub out { | ||||||||||||||||||||||
951 | 177 | 177 | 0 | 714 | my $tag = shift; | ||||||||||||||||||
952 | 177 | 615 | return Mojo::ByteStream->new($tag); | ||||||||||||||||||||
953 | } | ||||||||||||||||||||||
954 | |||||||||||||||||||||||
955 | 1; | ||||||||||||||||||||||
956 | |||||||||||||||||||||||
957 | __END__ |