File Coverage

blib/lib/Mojolicious/Plugin/DomIdHelper.pm
Criterion Covered Total %
statement 59 60 98.3
branch 9 14 64.2
condition 13 23 56.5
subroutine 9 9 100.0
pod 1 1 100.0
total 91 107 85.0


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::DomIdHelper;
2              
3 1     1   40809 use Mojo::Base 'Mojolicious::Plugin';
  1         3  
  1         9  
4 1     1   215 use Mojo::Util qw{xml_escape};
  1         2  
  1         68  
5 1     1   23 use Scalar::Util qw{blessed};
  1         2  
  1         1164  
6              
7             our $VERSION = '0.04';
8              
9             # Method used to retrieve the object's PK
10             my $METHOD = 'id';
11              
12             # Character used to delimitthe package name from object's PK
13             my $DELIMITER = '_';
14              
15             # Keep the full package name when generating the DOM ID, false = strip.
16             my $KEEP_NAMESPACE = 0;
17              
18             # If available we'll pluralize the package name when an array is used
19             my $HAVE_INFLECT = eval "require Lingua::EN::Inflect; 1";
20              
21             sub register
22             {
23 2     2 1 21038 my ($self, $app, $defaults) = @_;
24              
25 2   50     10 $defaults ||= {};
26 2   66     11 $defaults->{method} ||= $METHOD;
27 2   66     8 $defaults->{delimiter} ||= $DELIMITER;
28 2   66     11 $defaults->{keep_namespace} ||= $KEEP_NAMESPACE;
29            
30             $app->helper(
31             dom_id => sub {
32 6     6   8965 my $c = shift;
33 6         11 my $obj = shift;
34 6         30 my %config = (%$defaults, @_);
35 6         23 my $dom_id = $self->_generate_dom_id($obj, %config);
36              
37 6         21 xml_escape($dom_id);
38 2         36 });
39              
40             $app->helper(
41             dom_class => sub {
42 4     4   84 my $c = shift;
43 4         5 my $obj = shift;
44 4         18 my %config = (%$defaults, @_);
45 4         11 my $dom_class = $self->_generate_dom_class($obj, %config);
46              
47 4         13 xml_escape($dom_class);
48 2         250 });
49             }
50              
51             sub _generate_dom_id
52             {
53 6     6   16 my ($self, $obj, %config) = @_;
54 6         16 my $methods = $config{method};
55 6         9 my $delimiter = $config{delimiter};
56              
57 6         19 my $dom_id = $self->_generate_dom_class($obj, %config);
58 6 50       17 return unless $dom_id;
59              
60             # Append the ID suffix to blessed() refs only, others can't receive methods calls.
61 6 100       26 if(blessed($obj)) {
62 5 100       16 if(ref($methods) ne 'ARRAY') {
63 4         10 $methods = [$methods];
64             }
65            
66 5         5 my @suffix;
67 5         9 for my $method (@$methods) {
68 6         30 push @suffix, $obj->$method;
69             }
70            
71 5         45 @suffix = grep defined, @suffix;
72              
73 5 50       12 if(@suffix) {
74 5         8 $dom_id .= $delimiter;
75 5         12 $dom_id .= join '', @suffix;
76 5         15 $dom_id =~ s/\s+/$delimiter/g;
77             }
78             }
79              
80 6         19 $dom_id;
81             }
82              
83             sub _generate_dom_class
84             {
85 10     10   30 my ($self, $obj, %config) = @_;
86 10         24 my $type = $self->_instance_name($obj);
87 10 50       25 return unless $type;
88              
89 10         68 my @namespace = split /\b::\b/, $type;
90 10         20 my $delimiter = $config{delimiter};
91              
92             # Do we want to strip the prefix from the package name
93 10 100 100     46 if(!$config{keep_namespace} && @namespace > 1) {
94 6         20 @namespace = pop @namespace;
95             }
96            
97             # Split the package name on camelcase bounderies
98 14         32 my $dom_class = join $delimiter, map {
99 10         21 s/([^A-Z])([A-Z])/$1$delimiter$2/g;
100 14         25 s/([A-Z])([A-Z][^A-Z])/$1$delimiter$2/g;
101 14         53 lc;
102             } @namespace;
103            
104 10         36 $dom_class;
105             }
106              
107             sub _instance_name
108             {
109 10     10   12 my ($self, $obj) = @_;
110 10         17 my $type = ref $obj;
111            
112 10 0 33     87 if($type && $HAVE_INFLECT && $type eq 'ARRAY' && blessed($obj->[0])) {
      33        
      33        
113 0         0 $type = Lingua::EN::Inflect::PL(ref $obj->[0])
114             }
115            
116 10         21 $type;
117             }
118              
119             1;
120              
121             __END__