File Coverage

blib/lib/Mojolicious/Plugin/WebComponent.pm
Criterion Covered Total %
statement 87 96 90.6
branch 20 34 58.8
condition 6 15 40.0
subroutine 9 9 100.0
pod 1 1 100.0
total 123 155 79.3


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::WebComponent;
2 2     2   1045750 use v5.20;
  2         9  
3 2     2   560 use Mojo::Base 'Mojolicious::Plugin', -signatures;
  2         8644  
  2         10  
4 2     2   2915 use Carp;
  2         9  
  2         110  
5 2     2   507 use Data::Dumper;
  2         5896  
  2         2828  
6              
7             our $VERSION = "0.07";
8              
9             has route => sub {
10             my $self = shift;
11             my $root = $self->config->{path} ? $self->config->{path} : '/component';
12             $self->app->routes->any([ qw(HEAD GET) ] => "$root/:req/*component")->name('webcomponent')->to(cb => \&_serve);
13             };
14             has 'app';
15             has 'config';
16              
17 1     1 1 231806 sub register($self, $app, $config) {
  1         3  
  1         2  
  1         2  
  1         4  
18 1         4 $self->config($config);
19 1         12 $self->app($app);
20              
21 1         6 my $helper = 'component';
22              
23 1 50       6 if ($app->renderer->helpers->{$helper}) {
24 0         0 return $app->log->debug("WebComponent: Helper $helper() is already registered.");
25             }
26              
27 1         20 $app->defaults('webcomponent.helper' => $helper);
28              
29 1 100   3   28 $app->helper($helper => sub {@_ == 1 ? $self : $self->_component(@_)});
  3         37641  
30             }
31              
32             sub _serve {
33 1     1   5294 my $c = shift;
34 1         3 my $helper = $c->stash('webcomponent.helper');
35 1         53 my $self = $c->$helper;
36 1         6 my $app = $self->app;
37              
38 1         10 my $component = $c->param('component');
39 1         50 my $params = $self->_getAllParams($c)->to_hash;
40              
41 1         29 my $assetDir = $app->static->asset_dir;
42 1 50       32 my $javascriptPath = $self->config->{javascript_path} ? $self->config->{javascript_path} : "components";
43 1 50       9 my $templatePath = $self->config->{template_path} ? $self->config->{template_path} : "components";
44              
45 1         5 my $templateFile;
46             my $skipTemplate;
47 1 50       4 if (exists($params->{template})) {
48 0         0 my $template = $params->{template};
49 0 0 0     0 if ($template =~ m/(false|f|no|0)/i || !defined($template)) {
50 0         0 $skipTemplate = 1;
51             }
52             else {
53 0         0 $templateFile = $template;
54             }
55             }
56              
57 1         2 my $tmpl;
58 1 50       3 if (!defined($skipTemplate)) {
59 1         1 my $tmplHtml;
60             # if the template file is not set,
61 1   33     10 $templateFile //= $component =~ s/\.js//gr;
62 1         3 my $template = "$templatePath/$templateFile";
63 1 50       3 if ($app->renderer->{templates}->{"$template.html"}) {
64 1         10 $tmplHtml = $c->render_to_string($template, params => $params);
65             }
66              
67             # If the template file was not found, show it
68 1   33     1812 $tmplHtml //= "
404 - $template template not found
";
69              
70 1         6 $tmpl = qq{
71             let tmpl = document.createElement('template');
72             tmpl.innerHTML = `$tmplHtml`
73             };
74             }
75              
76             # my $publicPath = $app->static->{paths}->[0];
77 1         7 my $js = "/$assetDir/js/$javascriptPath/$component";
78 1         4 my $asset = $app->static->file($js);
79              
80 1         116 my $content;
81 1         5 my $fh = $asset->handle;
82 1         140 my $tmplInit = 0;
83 1         51 while (<$fh>) {
84 36 100 66     73 if ($tmpl && !$tmplInit) {
85 9 100       15 if ($_ =~ m/let tmpl;/) {
86 1         2 $content .= $tmpl;
87 1         2 $tmplInit = 1;
88 1         4 next;
89             }
90 8 50       12 if ($_ =~ m/shadowRoot.appendChild\(tmpl.content.cloneNode\(true\)\)/) {
91 0         0 $content .= $tmpl;
92 0         0 $tmplInit = 1;
93             }
94             }
95              
96 35         68 $content .= $_;
97             }
98              
99 1         6 $c->render(text => $content);
100             }
101              
102             sub _component {
103 2     2   3 my $self = shift;
104 2         3 my $c = shift;
105 2         5 my $name = shift;
106 2         3 my $opts = shift;
107 2         7 my $route = $self->route;
108              
109 2         545 my $base = $c->req->url->base->path->{path};
110 2 50       104 my $path = $base ? $base . $route->pattern->unparsed
111             : $route->pattern->unparsed;
112              
113 2 50       26 if (exists($opts->{template})) {
114 0 0       0 my $template = defined($opts->{template}) ? $opts->{template} : 'false';
115 0         0 $c->req->params->merge(template => $template);
116             }
117              
118 2         9 my $params = $self->_getAllParams($c);
119 2         6 my $paramString = $params->to_string;
120 2   66     400 my $reqId = $opts->{requestId} || $c->req->request_id;
121              
122 2 50       23 $name .= ".js" if $name !~ m/\.js$/;
123              
124             # :req/:component
125 2         9 $path =~ s/:req/$reqId/;
126 2         10 $path =~ s/\*component/$name/;
127 2 100       9 $path .= "?$paramString" if length($paramString);
128 2         4 my $ref = "";
129              
130 2         14 return Mojo::ByteStream->new($ref)
131             }
132              
133 3     3   8 sub _getAllParams($self, $c) {
  3         9  
  3         6  
  3         4  
134 3         10 my $rp = $c->req->params->to_hash;
135 3 100       481 %{$rp} = (%{$rp}, %{$c->stash->{'mojo.captures'}}) if $c->stash->{'mojo.captures'};
  2         14  
  2         18  
  2         4  
136 3         13 my $params = Mojo::Parameters->new(%{$rp});
  3         9  
137 3         62 delete $params->{cb}; # remove the callback routine
138 3         9 return $params;
139             }
140              
141             1;
142             __END__