File Coverage

blib/lib/Mojolicious/Plugin/LinkEmbedder/Link.pm
Criterion Covered Total %
statement 49 58 84.4
branch 13 18 72.2
condition 7 12 58.3
subroutine 14 16 87.5
pod 6 7 85.7
total 89 111 80.1


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::LinkEmbedder::Link;
2              
3             =head1 NAME
4              
5             Mojolicious::Plugin::LinkEmbedder::Link - Base class for links
6              
7             =cut
8              
9 24     24   12442 use Mojo::Base -base;
  24         6409  
  24         116  
10 24     24   2650 use Mojo::ByteStream;
  24         35254  
  24         745  
11 24     24   112 use Mojo::Util 'xml_escape';
  24         35  
  24         829  
12 24     24   613 use Mojolicious::Types;
  24         610  
  24         128  
13 24     24   467 use Scalar::Util 'blessed';
  24         29  
  24         973  
14              
15             # this may change in future version
16 24     24   89 use constant DEFAULT_VIDEO_HEIGHT => 390;
  24         26  
  24         1442  
17 24     24   93 use constant DEFAULT_VIDEO_WIDTH => 640;
  24         31  
  24         17580  
18              
19             =head1 ATTRIBUTES
20              
21             =head2 error
22              
23             my $err = $link->error;
24             $link = $link->error({message => "Some error"});
25              
26             Get or set error. Default to C on no error.
27              
28             =head2 etag
29              
30             =head2 media_id
31              
32             Returns the part of the URL identifying the media. Default is empty string.
33              
34             =head2 provider_name
35              
36             $str = $self->provider_name;
37              
38             Example: "Twitter".
39              
40             =head2 ua
41              
42             Holds a L object.
43              
44             =head2 url
45              
46             Holds a L object.
47              
48             =cut
49              
50             has error => undef;
51             has etag => sub {
52             eval { shift->_tx->res->headers->etag } // '';
53             };
54             has media_id => '';
55 1   50 1 1 12 sub provider_name { ucfirst(shift->url->host || '') }
56             has ua => sub { die "Required in constructor" };
57             has url => sub { shift->_tx->req->url };
58              
59             # should this be public?
60             has _tx => undef;
61              
62             has _types => sub {
63             my $types = Mojolicious::Types->new;
64             $types->type(mpg => 'video/mpeg');
65             $types->type(mpeg => 'video/mpeg');
66             $types->type(mov => 'video/quicktime');
67             $types;
68             };
69              
70             =head1 METHODS
71              
72             =head2 is
73              
74             $bool = $self->is($str);
75             $bool = $self->is('video');
76             $bool = $self->is('video-youtube');
77              
78             Convertes C<$str> using L and checks if C<$self>
79             is of that type:
80              
81             $self->isa('Mojolicious::Plugin::LinkEmbedder::Link::' .Mojo::Util::camelize($_[1]));
82              
83             =cut
84              
85             sub is {
86 4     4 1 775 $_[0]->isa(__PACKAGE__ . '::' . Mojo::Util::camelize($_[1]));
87             }
88              
89             =head2 learn
90              
91             $self->learn($c, $cb);
92              
93             This method can be used to learn more information about the link. This class
94             has no idea what to learn, so it simply calls the callback (C<$cb>) with
95             C<@cb_args>.
96              
97             =cut
98              
99             sub learn {
100 0     0 1 0 my ($self, $c, $cb) = @_;
101 0         0 $self->$cb;
102 0         0 $self;
103             }
104              
105             =head2 pretty_url
106              
107             Returns a pretty version of the L. The default is to return a cloned
108             version of L.
109              
110             =cut
111              
112 1     1 1 215 sub pretty_url { shift->url->clone }
113              
114             =head2 tag
115              
116             $bytestream = $self->tag(a => href => "http://google.com", sub { "link });
117              
118             Same as L.
119              
120             =cut
121              
122             sub tag {
123 29     29 1 176 my $self = shift;
124 29         28 my $name = shift;
125              
126             # Content
127 29 100       40 my $cb = ref $_[-1] eq 'CODE' ? pop : undef;
128 29 100       39 my $content = @_ % 2 ? pop : undef;
129              
130             # Start tag
131 29         27 my $tag = "<$name";
132              
133             # Attributes
134 29         47 my %attrs = @_;
135 29 50 33     45 if ($attrs{data} && ref $attrs{data} eq 'HASH') {
136 0         0 while (my ($key, $value) = each %{$attrs{data}}) {
  0         0  
137 0         0 $key =~ y/_/-/;
138 0         0 $attrs{lc("data-$key")} = $value;
139             }
140 0         0 delete $attrs{data};
141             }
142              
143 29         53 for my $k (sort keys %attrs) {
144 31 50 50     408 $tag .= defined $attrs{$k} ? qq{ $k="} . xml_escape($attrs{$k} // '') . '"' : " $k";
145             }
146              
147             # Empty element
148 29 100 100     180 unless ($cb || defined $content) { $tag .= '>' }
  4         5  
149              
150             # End tag
151 25 100       49 else { $tag .= '>' . ($cb ? $cb->() : xml_escape $content) . "" }
152              
153             # Prevent escaping
154 29         366 return Mojo::ByteStream->new($tag);
155             }
156              
157             =head2 to_embed
158              
159             Returns a link to the L, with target "_blank".
160              
161             =cut
162              
163             sub to_embed {
164 1     1 1 2 my $self = shift;
165 1         5 my $url = $self->url;
166 1         4 my @args;
167              
168 1 50       4 return sprintf '%s', $self->provider_name unless $url->host;
169              
170 1         31 push @args, target => '_blank';
171 1 50       2 push @args, title => "Content-Type: @{[$self->_tx->res->headers->content_type]}" if $self->_tx;
  1         6  
172              
173 1     1   26 return $self->tag(a => (href => $url, @args), sub {$url});
  1         3  
174             }
175              
176             # Mojo::JSON will automatically filter out ua and similar objects
177             sub TO_JSON {
178 1     1 0 453 my $self = shift;
179 1         5 my $url = $self->url;
180              
181             return {
182             # oembed
183             # author_name => "",
184             # author_url => "",
185             # cache_age => 86400,
186             # height => $self->DEFAULT_VIDEO_HEIGHT,
187             # version => '1.0', # not really 1.0...
188             # width => $self->DEFAULT_VIDEO_WIDTH,
189 1 50 50     5 html => $self->to_embed,
190             provider_name => $self->provider_name,
191             provider_url => $url->host ? Mojo::URL->new(host => $url->host, scheme => $url->scheme || 'http') : '',
192             type => 'rich',
193             url => $url,
194              
195             # extra
196             pretty_url => $self->pretty_url,
197             media_id => $self->media_id,
198             };
199             }
200              
201             sub _iframe {
202             shift->tag(
203 0     0     iframe => frameborder => 0,
204             allowfullscreen => undef,
205             webkitAllowFullScreen => undef,
206             mozallowfullscreen => undef,
207             scrolling => 'no',
208             class => 'link-embedder',
209             @_, 'Your browser is super old.',
210             );
211             }
212              
213             =head1 AUTHOR
214              
215             Jan Henning Thorsen - C
216              
217             =cut
218              
219             1;