File Coverage

blib/lib/Mojolicious/Plugin/LinkEmbedder/Link.pm
Criterion Covered Total %
statement 21 57 36.8
branch 0 16 0.0
condition 0 8 0.0
subroutine 7 15 46.6
pod 0 6 0.0
total 28 102 27.4


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::LinkEmbedder::Link;
2 1     1   9 use Mojo::Base -base;
  1         3  
  1         10  
3 1     1   171 use Mojo::ByteStream;
  1         3  
  1         37  
4 1     1   5 use Mojo::Util 'xml_escape';
  1         2  
  1         52  
5 1     1   376 use Mojolicious::Types;
  1         566  
  1         22  
6 1     1   45 use Scalar::Util 'blessed';
  1         3  
  1         48  
7              
8             # this may change in future version
9 1     1   6 use constant DEFAULT_VIDEO_HEIGHT => 390;
  1         3  
  1         45  
10 1     1   5 use constant DEFAULT_VIDEO_WIDTH => 640;
  1         2  
  1         791  
11              
12             has author_name => '';
13             has author_url => '';
14             has error => undef;
15             has etag => sub {
16             eval { shift->_tx->res->headers->etag } // '';
17             };
18              
19             has media_id => '';
20             has provider_name => sub { ucfirst shift->url->host };
21             has provider_url => sub {
22             my $self = shift;
23             return Mojo::URL->new(host => $self->url->host, scheme => $self->url->scheme);
24             };
25              
26             has title => '';
27             has ua => sub { die "Required in constructor" };
28             has url => sub { shift->_tx->req->url };
29              
30             # should this be public?
31             has _tx => undef;
32              
33             has _types => sub {
34             my $types = Mojolicious::Types->new;
35             $types->type(mpg => 'video/mpeg');
36             $types->type(mpeg => 'video/mpeg');
37             $types->type(mov => 'video/quicktime');
38             $types;
39             };
40              
41             sub is {
42 0     0 0   $_[0]->isa(__PACKAGE__ . '::' . Mojo::Util::camelize($_[1]));
43             }
44              
45             sub learn {
46 0     0 0   my ($self, $c, $cb) = @_;
47 0           $self->$cb;
48 0           $self;
49             }
50              
51 0     0 0   sub pretty_url { shift->url->clone }
52              
53             sub tag {
54 0     0 0   my $self = shift;
55 0           my $name = shift;
56              
57             # Content
58 0 0         my $cb = ref $_[-1] eq 'CODE' ? pop : undef;
59 0 0         my $content = @_ % 2 ? pop : undef;
60              
61             # Start tag
62 0           my $tag = "<$name";
63              
64             # Attributes
65 0           my %attrs = @_;
66 0 0 0       if ($attrs{data} && ref $attrs{data} eq 'HASH') {
67 0           while (my ($key, $value) = each %{$attrs{data}}) {
  0            
68 0           $key =~ y/_/-/;
69 0           $attrs{lc("data-$key")} = $value;
70             }
71 0           delete $attrs{data};
72             }
73              
74 0           for my $k (sort keys %attrs) {
75 0 0 0       $tag .= defined $attrs{$k} ? qq{ $k="} . xml_escape($attrs{$k} // '') . '"' : " $k";
76             }
77              
78             # Empty element
79 0 0 0       unless ($cb || defined $content) { $tag .= '>' }
  0            
80              
81             # End tag
82 0 0         else { $tag .= '>' . ($cb ? $cb->() : xml_escape $content) . "" }
83              
84             # Prevent escaping
85 0           return Mojo::ByteStream->new($tag);
86             }
87              
88             sub to_embed {
89 0     0 0   my $self = shift;
90 0           my $url = $self->url;
91 0           my @args;
92              
93 0 0         return sprintf '%s', $self->provider_name unless $url->host;
94              
95 0           push @args, target => '_blank';
96 0 0         push @args, title => "Content-Type: @{[$self->_tx->res->headers->content_type]}" if $self->_tx;
  0            
97              
98 0     0     return $self->tag(a => (href => $url, @args), sub {$url});
  0            
99             }
100              
101             # Mojo::JSON will automatically filter out ua and similar objects
102             sub TO_JSON {
103 0     0 0   my $self = shift;
104 0           my $url = $self->url;
105              
106             return {
107             # oembed
108             # cache_age => 86400,
109             # height => $self->DEFAULT_VIDEO_HEIGHT,
110             # version => '1.0', # not really 1.0...
111             # width => $self->DEFAULT_VIDEO_WIDTH,
112 0           author_name => $self->author_name,
113             author_url => $self->author_url,
114             html => $self->to_embed,
115             provider_name => $self->provider_name,
116             provider_url => $self->provider_url,
117             title => $self->title,
118             type => 'rich',
119             url => $url,
120              
121             # extra
122             pretty_url => $self->pretty_url,
123             media_id => $self->media_id,
124             };
125             }
126              
127             sub _iframe {
128             shift->tag(
129 0     0     iframe => frameborder => 0,
130             allowfullscreen => undef,
131             webkitAllowFullScreen => undef,
132             mozallowfullscreen => undef,
133             scrolling => 'no',
134             class => 'link-embedder',
135             @_, 'Your browser is super old.',
136             );
137             }
138              
139             1;