File Coverage

blib/lib/CSS/Object/Value.pm
Criterion Covered Total %
statement 48 78 61.5
branch 8 28 28.5
condition 1 15 6.6
subroutine 13 18 72.2
pod 4 7 57.1
total 74 146 50.6


line stmt bran cond sub pod time code
1             ##----------------------------------------------------------------------------
2             ## CSS Object Oriented - ~/lib/CSS/Object/Value.pm
3             ## Version v0.1.0
4             ## Copyright(c) 2020 DEGUEST Pte. Ltd.
5             ## Author: Jacques Deguest <@sitael.local>
6             ## Created 2020/06/21
7             ## Modified 2020/06/21
8             ##
9             ##----------------------------------------------------------------------------
10             package CSS::Object::Value;
11             BEGIN
12             {
13 6     6   41 use strict;
  6         13  
  6         198  
14 6     6   30 use warnings;
  6         18  
  6         210  
15 6     6   40 use parent qw( CSS::Object::Element );
  6         16  
  6         28  
16 6     6   381 use CSS::Object::Comment;
  6         13  
  6         33  
17 6     6   1547 use CSS::Object::Format;
  6         13  
  6         34  
18 6     6   1305 use Devel::Confess;
  6         13  
  6         33  
19             use overload (
20 6         33 '""' => 'as_string',
21             fallback => 1,
22 6     6   417 );
  6         11  
23 6     6   5599 our $VERSION = 'v0.1.0';
24             };
25              
26             sub init
27             {
28 45     45 1 3858 my $self = shift( @_ );
29 45         85 my $val;
30 45 100       224 $val = shift( @_ ) if( ( scalar( @_ ) % 2 ) );
31 45         428 $self->{format} = '';
32 45         161 $self->{value} = '';
33 45         115 $self->{_init_strict_use_sub} = 1;
34 45         226 $self->SUPER::init( @_ );
35 45 100       250 $self->value( $val ) if( defined( $val ) );
36             # $self->message( 3, "Returning value object for value '", $self->value, "'." );
37 45         2639 return( $self );
38             }
39              
40             ## Inherited
41             ## sub format
42              
43             sub as_string
44             {
45 210     210 1 1505 my $self = shift( @_ );
46 210 50       1217 return( '' ) if( !$self->format );
47 210         4119 return( $self->format->value_as_string( $self ) );
48             # return(
49             # $self->comment_before->map(sub{ $_->as_string })->scalar . ( $self->comment_before->length ? ' ' : '' ) .
50             # $self->format->value_as_string( $self ) .
51             # ( $self->comment_after->length ? ' ' : '' ) . $self->comment_after->map(sub{ $_->as_string })->scalar
52             # );
53             }
54              
55 0     0 0 0 sub comment { return( shift->_set_get_array_as_object( 'comment_after', @_ ) ); }
56              
57 420     420 0 9263743 sub comment_after { return( shift->_set_get_array_as_object( 'comment_after', @_ ) ); }
58              
59 422     422 0 25293 sub comment_before { return( shift->_set_get_array_as_object( 'comment_before', @_ ) ); }
60              
61             sub value
62             {
63 254     254 1 9246706 my $self = shift( @_ );
64 254 100       1491 if( @_ )
65             {
66 44         106 my $val = shift( @_ );
67 44 50       138 if( $self->_is_a( $val, 'CSS::Object::Value' ) )
68             {
69             ## If the value object provided has some comments attached to it
70             ## Make sure each data stored is an object, or else we create an object before adding it
71 0 0       0 if( $val->comment_after->length )
72             {
73             $val->comment_after->foreach(sub
74             {
75 0     0   0 my $cmt = $self->_comment_data_to_object( $_ );
76 0 0       0 $self->comment_after->push( $cmt ) if( defined( $cmt ) );
77 0         0 });
78             }
79 0 0       0 if( $val->comment_before->length )
80             {
81             $val->comment_before->foreach(sub
82             {
83 0     0   0 my $cmt = $self->_comment_data_to_object( $_ );
84 0 0       0 $self->comment_before->push( $cmt ) if( defined( $cmt ) );
85 0         0 });
86             }
87 0         0 $val = $val->value->scalar;
88             }
89             else
90             {
91 44         664 while( $val =~ s/^[[:blank:]\h]*\/\*[[:blank:]\h]*(.*?)[[:blank:]\h]*\*\///s )
92             {
93 2         35 $self->message( 3, "Adding comment found before value: '$1'." );
94 2   50     60 my $cmt = CSS::Object::Comment->new( [split( /\r\n/, $1 )] ) ||
95             return( $self->error( "Cannot create comment object: ", CSS::Object::Comment->error ) );
96 2         97 $self->comment_before->push( $cmt );
97             }
98 44         254 while( $val =~ s/[[:blank:]\h]*\/\*[[:blank:]\h]*(.*?)[[:blank:]\h]*\*\/$//s )
99             {
100 0         0 $self->message( 3, "Adding comment found after value: '$1'." );
101 0   0     0 my $cmt = CSS::Object::Comment->new( [split( /\r\n/, $1 )] ) ||
102             return( $self->error( "Cannot create comment object: ", CSS::Object::Comment->error ) );
103 0         0 $self->comment_after->push( $cmt );
104             }
105 44         425 $val =~ s/^[[:blank:]\h]*|[[:blank:]\h]*$//gs;
106             }
107 44         191 return( $self->_set_get_scalar_as_object( 'value', $val ) );
108             }
109 210         940 return( $self->_set_get_scalar_as_object( 'value' ) );
110             }
111              
112             sub with_comment
113             {
114 0     0 1   my $self = shift( @_ );
115 0           my $opts = {};
116 0 0         $opts = shift( @_ ) if( $self->_is_hash( $_[0] ) );
117 0 0         if( $opts->{before} )
118             {
119 0   0       my $cmt = $self->_comment_data_to_object( $opts->{before} ) || return;
120 0           $self->comment_before->push( $cmt );
121             }
122 0 0         if( $opts->{after} )
123             {
124 0   0       my $cmt = $self->_comment_data_to_object( $opts->{after} ) || return;
125 0           $self->comment_after->push( $cmt );
126             }
127 0           return( $self );
128             }
129              
130             sub _comment_data_to_object
131             {
132 0     0     my $self = shift( @_ );
133             ## No data received, we silently return undef
134 0   0       my $this = shift( @_ ) || return;
135 0 0 0       if( $self->_is_a( $this, 'CSS::Objet::Comment' ) )
    0          
136             {
137 0           return( $this );
138             }
139             elsif( $self->_is_array( $this ) || !ref( $this ) )
140             {
141 0   0       my $cmt = CSS::Object::Comment->new( $this, debug => $self->debug ) ||
142             return( $self->error( "Cannot create a new comment from array provided in this property value: ", CSS::Object::Comment->error ) );
143 0           return( $cmt );
144             }
145             else
146             {
147 0           return( $self->error( "I do not know what to do with comment data \"$this\"." ) );
148             }
149             }
150              
151             1;
152              
153             __END__
154              
155             =encoding utf-8
156              
157             =head1 NAME
158              
159             CSS::Object::Value - CSS Object Oriented Value
160              
161             =head1 SYNOPSIS
162              
163             use CSS::Object::Value;
164             # For font-size property for example
165             my $val = CSS::Object::Value->new( '1.2rem',
166             debug => 3,
167             format => $format_object,
168             ) || die( CSS::Object::Value->error );
169              
170             # Adding value with comment inside
171             my $val = CSS::Object::Value->new( '1.2rem', with_comment =>
172             {
173             before => 'This is 12px',
174             after => ["Might want to change this", "to something else"],
175             }) || die( "Cannot add value with comments: ", CSS::Object::Value->error );
176            
177             my $val = CSS::Object::Value->new( '/* Might need to change this */ 1.2rem /* Maybe move this to px instead? */',
178             debug => 3,
179             format => $format_object,
180             ) || die( CSS::Object::Value->error );
181              
182             # or
183             $val->comment_before->push( $css->new_comment( "More comment before value" ));
184             #val->comment_after->push( $css->new_comment( "Another comment after too" ));
185              
186             # or
187             $val->with_comment({
188             before => 'This is 12px',
189             after => ["Might want to change this", "to something else"],
190             }) || die( $val->error );
191              
192             =head1 VERSION
193              
194             v0.1.0
195              
196             =head1 DESCRIPTION
197              
198             L<CSS::Object::Value> is a module to contain the CSS properties' value.
199              
200             =head1 CONSTRUCTOR
201              
202             =head2 new
203              
204             To instantiate a new L<CSS::Object::Value> object, pass an hash reference of following parameters:
205              
206             =over 4
207              
208             =item I<debug>
209              
210             This is an integer. The bigger it is and the more verbose is the output.
211              
212             =item I<format>
213              
214             This is a L<CSS::Object::Format> object or one of its child modules.
215              
216             =item I<value>
217              
218             The property value, which can also be called as the sole argument:
219              
220             # For display property for example
221             my $val = CSS::Object::Value->new( 'none' );
222              
223             =item I<with_comment>
224              
225             This parameter must be an hash reference with 2 possible properties: I<before> and I<after>. Each of thoe properties can contain either a simple string, an array reference of string, or an L<CSS::Object::Comment> object.
226              
227             It returns our object
228              
229             =back
230              
231             =head1 METHODS
232              
233             =head2 as_string
234              
235             This calls the L</format> and its method L<CSS::Object::Format/value_as_string>
236              
237             It returns the css string produce or undef and sets an L<Module::Generic::Exception> upon error.
238              
239             =head2 format
240              
241             This is a L<CSS::Object::Format> object or one of its child modules.
242              
243             =head2 value
244              
245             Sets or gets the value for this property value. The value stored here becomes a L<Module::Generic::Scalar> and thus all its object methods can be used
246              
247             Alternatively, it accepts a L<CSS::Object::Value> and will call its L</value> method to get the actual string to store.
248              
249             It returns the value currently stored.
250              
251             =head2 with_comment
252              
253             This method takes an hash reference with 2 possible properties: I<before> and I<after>. Each of thoe properties can contain either a simple string, an array reference of string, or an L<CSS::Object::Comment> object.
254              
255             It returns the object used to call this method, or undef if there was an error.
256              
257             =head1 AUTHOR
258              
259             Jacques Deguest E<lt>F<jack@deguest.jp>E<gt>
260              
261             =head1 SEE ALSO
262              
263             L<CSS::Object>
264              
265             =head1 COPYRIGHT & LICENSE
266              
267             Copyright (c) 2020 DEGUEST Pte. Ltd.
268              
269             You can use, copy, modify and redistribute this package and associated
270             files under the same terms as Perl itself.
271              
272             =cut