| 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__ |