| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  |  | 
| 2 | 37 |  |  | 37 |  | 303 | use strict; | 
|  | 37 |  |  |  |  | 91 |  | 
|  | 37 |  |  |  |  | 1090 |  | 
| 3 | 37 |  |  | 37 |  | 222 | use warnings; | 
|  | 37 |  |  |  |  | 80 |  | 
|  | 37 |  |  |  |  | 39248 |  | 
| 4 |  |  |  |  |  |  |  | 
| 5 |  |  |  |  |  |  | package WWW::Shopify::Liquid::Element; | 
| 6 |  |  |  |  |  |  |  | 
| 7 | 215 |  |  | 215 | 0 | 806 | sub verify { return 1; } | 
| 8 |  |  |  |  |  |  |  | 
| 9 | 0 |  |  | 0 | 0 | 0 | sub subelements { qw(); } | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | sub tokens { | 
| 12 | 70 |  |  | 70 | 0 | 245 | my ($self) = @_; | 
| 13 | 70 | 100 |  |  |  | 338 | return ($self, map { $self->is_processed($_) ? $_ : $_->tokens } map { ref($_) eq 'ARRAY' ? @$_ : $_ } map { $self->{$_} } $self->subelements); | 
|  | 150 | 100 |  |  |  | 447 |  | 
|  | 85 |  |  |  |  | 407 |  | 
|  | 85 |  |  |  |  | 281 |  | 
| 14 |  |  |  |  |  |  | } | 
| 15 |  |  |  |  |  |  |  | 
| 16 | 0 |  |  | 0 | 0 | 0 | sub operate { return $_[0]; } | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | sub render_subelement($$$\$) { | 
| 19 | 2244 |  |  | 2244 | 0 | 5791 | my ($self, $renderer, $hash, $element) = @_; | 
| 20 | 2244 |  |  |  |  | 3903 | my $value; | 
| 21 | 2244 | 100 |  |  |  | 6138 | if (ref($element) eq 'ARRAY') { | 
| 22 | 2181 |  |  |  |  | 5095 | $value = []; | 
| 23 | 2181 |  |  |  |  | 4780 | eval { | 
| 24 | 2181 | 100 | 100 |  |  | 7912 | push(@$value, $self->is_processed($_) ? $_ : ($renderer->state && $renderer->state->{values}->{$_} ? delete $renderer->state->{values}->{$_} : $_->render($renderer, $hash))) for (@$element); | 
|  |  | 100 |  |  |  |  |  | 
| 25 |  |  |  |  |  |  | }; | 
| 26 | 2181 | 100 |  |  |  | 6836 | if (my $exp = $@) { | 
| 27 | 5 | 50 | 33 |  |  | 82 | $exp->value($element, $value) if blessed($exp) && $exp->isa('WWW::Shopify::Liquid::Exception::Control::Pause'); | 
| 28 | 5 |  |  |  |  | 28 | die $exp; | 
| 29 |  |  |  |  |  |  | } | 
| 30 |  |  |  |  |  |  | } else { | 
| 31 | 63 | 50 |  |  |  | 285 | $value = !$self->is_processed($$element) ? ($$element)->render($renderer, $hash) : $$element; | 
| 32 |  |  |  |  |  |  | } | 
| 33 | 2239 |  |  |  |  | 9316 | return $value; | 
| 34 |  |  |  |  |  |  | } | 
| 35 |  |  |  |  |  |  |  | 
| 36 |  |  |  |  |  |  | sub optimize_subelement($$$\$) { | 
| 37 | 185 |  |  | 185 | 0 | 416 | my ($self, $optimizer, $hash, $element) = @_; | 
| 38 | 185 |  |  |  |  | 310 | my $value; | 
| 39 | 185 | 100 |  |  |  | 462 | if (ref($element) eq 'ARRAY') { | 
| 40 | 172 |  |  |  |  | 535 | for my $idx (0..(int(@$element)-1)) { | 
| 41 | 190 |  |  |  |  | 410 | my $inner = $element->[$idx]; | 
| 42 | 190 | 100 |  |  |  | 527 | $element->[$idx] = !$self->is_processed($inner) ? $inner->optimize($optimizer, $hash) : $inner; | 
| 43 |  |  |  |  |  |  | } | 
| 44 |  |  |  |  |  |  | } else { | 
| 45 | 13 | 50 |  |  |  | 64 | $value = !$self->is_processed($$element) ? ($$element)->optimize($optimizer, $hash) : $$element; | 
| 46 | 13 |  |  |  |  | 41 | $$element = $value; | 
| 47 | 13 |  |  |  |  | 32 | $element = $$element; | 
| 48 |  |  |  |  |  |  | } | 
| 49 | 185 |  |  |  |  | 2353 | return $element; | 
| 50 |  |  |  |  |  |  | } | 
| 51 |  |  |  |  |  |  |  | 
| 52 |  |  |  |  |  |  | sub process_subelement { | 
| 53 | 2017 |  |  | 2017 | 0 | 5606 | my ($self, $hash, $action, $pipeline, $element) = @_; | 
| 54 | 2017 |  |  |  |  | 4336 | $action .= "_subelement"; | 
| 55 | 2017 |  |  |  |  | 6744 | return $self->$action($pipeline, $hash, $element); | 
| 56 |  |  |  |  |  |  | } | 
| 57 |  |  |  |  |  |  |  | 
| 58 |  |  |  |  |  |  | sub process_subelements { | 
| 59 | 1051 |  |  | 1051 | 0 | 2729 | my ($self, $hash, $action, $pipeline) = @_; | 
| 60 | 1051 | 100 |  |  |  | 3511 | return map { $self->process_subelement($hash, $action, $pipeline, ref($self->{$_}) eq 'ARRAY' ? $self->{$_} : (\$self->{$_})) } $self->subelements; | 
|  | 1127 |  |  |  |  | 5945 |  | 
| 61 |  |  |  |  |  |  | } | 
| 62 |  |  |  |  |  |  |  | 
| 63 |  |  |  |  |  |  | sub render { | 
| 64 | 5644 |  |  | 5644 | 0 | 13289 | my $self = shift; | 
| 65 | 5644 |  |  |  |  | 9639 | my $renderer = shift; | 
| 66 | 5644 | 100 | 100 |  |  | 16212 | return delete $renderer->state->{values}->{$self} if $renderer->state && exists $renderer->state->{values}->{$self}; | 
| 67 | 5640 |  |  |  |  | 11512 | my $return = eval { $self->process(@_, "render", $renderer); }; | 
|  | 5640 |  |  |  |  | 18687 |  | 
| 68 | 5640 |  |  |  |  | 24158 | my $exp = $@; | 
| 69 | 5640 | 100 |  |  |  | 13353 | if ($exp) { | 
| 70 | 31 | 100 | 100 |  |  | 365 | die $exp if (blessed($exp) && $exp->isa('WWW::Shopify::Liquid::Exception::Control')); | 
| 71 | 5 | 50 |  |  |  | 20 | if ($renderer->{silence_exceptions}) { | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 72 |  |  |  |  |  |  | } elsif ($renderer->{wrap_exceptions}) { | 
| 73 | 0 | 0 | 0 |  |  | 0 | die $exp if blessed($exp) && $exp->isa('WWW::Shopify::Liquid::Exception::Renderer::Wrapped'); | 
| 74 | 0 |  |  |  |  | 0 | die new WWW::Shopify::Liquid::Exception::Renderer::Wrapped($self, $exp); | 
| 75 |  |  |  |  |  |  | } elsif ($renderer->{print_exceptions}) { | 
| 76 | 0 | 0 | 0 |  |  | 0 | return blessed($exp) && $exp->can('english') ? $exp->english : "$exp"; | 
| 77 |  |  |  |  |  |  | } else { | 
| 78 | 0 |  |  |  |  | 0 | die $exp; | 
| 79 |  |  |  |  |  |  | } | 
| 80 |  |  |  |  |  |  | } | 
| 81 | 5614 | 100 | 100 |  |  | 17514 | return undef if $exp || !$self->is_processed($return) || !defined $return; | 
|  |  |  | 100 |  |  |  |  | 
| 82 | 5458 |  |  |  |  | 21625 | return $return; | 
| 83 |  |  |  |  |  |  | } | 
| 84 |  |  |  |  |  |  |  | 
| 85 |  |  |  |  |  |  | sub get_parameter { | 
| 86 | 0 |  |  | 0 | 0 | 0 | my ($self, $name, @arguments) = @_; | 
| 87 | 0 | 0 | 0 |  |  | 0 | my ($arg) = grep { ref($_) && ref($_) eq 'HASH' && int(keys(%$_)) == 1 && exists $_->{$name} } @arguments; | 
|  | 0 |  | 0 |  |  | 0 |  | 
| 88 | 0 | 0 |  |  |  | 0 | return $arg ? $arg->{$name} : undef; | 
| 89 |  |  |  |  |  |  | } | 
| 90 |  |  |  |  |  |  |  | 
| 91 |  |  |  |  |  |  | sub optimize { | 
| 92 | 762 |  |  | 762 | 0 | 1733 | my $self = shift; | 
| 93 | 762 |  |  |  |  | 1171 | my $optimizer = shift; | 
| 94 | 762 | 50 | 33 |  |  | 5101 | die new WWW::Shopify::Liquid::Exception($self, "Cannot optimize without a valid optimizer.") | 
|  |  |  | 33 |  |  |  |  | 
| 95 |  |  |  |  |  |  | unless $optimizer && blessed($optimizer) && $optimizer->isa('WWW::Shopify::Liquid::Optimizer'); | 
| 96 | 762 |  |  |  |  | 3059 | return $self->process(@_, "optimize", $optimizer); | 
| 97 |  |  |  |  |  |  | } | 
| 98 | 0 |  |  | 0 | 0 | 0 | sub process { return $_[0]; } | 
| 99 |  |  |  |  |  |  | # Determines whether or not the element is part of the strict subset of liquid that Shopify uses. | 
| 100 | 0 |  |  | 0 | 0 | 0 | sub is_strict { return 0; } | 
| 101 |  |  |  |  |  |  |  | 
| 102 | 37 |  |  | 37 |  | 330 | use Scalar::Util qw(looks_like_number blessed); | 
|  | 37 |  |  |  |  | 103 |  | 
|  | 37 |  |  |  |  | 6498 |  | 
| 103 |  |  |  |  |  |  |  | 
| 104 | 24697 |  |  | 24697 | 0 | 72941 | sub is_processed { return WWW::Shopify::Liquid::Pipeline->is_processed($_[1]); } | 
| 105 |  |  |  |  |  |  | sub ensure_numerical { | 
| 106 | 103 | 100 | 100 | 103 | 0 | 658 | return $_[1] if defined $_[1] && looks_like_number($_[1]); | 
| 107 | 18 | 100 | 66 |  |  | 595 | return $_[1] if ref($_[1]) && ref($_[1]) eq "DateTime"; | 
| 108 | 2 |  |  |  |  | 5 | return 0; | 
| 109 |  |  |  |  |  |  | } | 
| 110 |  |  |  |  |  |  |  | 
| 111 |  |  |  |  |  |  | 1; |