File Coverage

blib/lib/CSS/Object/Value.pm
Criterion Covered Total %
statement 48 80 60.0
branch 8 36 22.2
condition 1 17 5.8
subroutine 13 18 72.2
pod 4 7 57.1
total 74 158 46.8


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   43 use strict;
  6         15  
  6         201  
14 6     6   29 use warnings;
  6         16  
  6         215  
15 6     6   36 use parent qw( CSS::Object::Element );
  6         14  
  6         31  
16 6     6   364 use CSS::Object::Comment;
  6         15  
  6         38  
17 6     6   1435 use CSS::Object::Format;
  6         16  
  6         37  
18 6     6   1270 use Devel::Confess;
  6         13  
  6         37  
19             use overload (
20 6         45 '""' => 'as_string',
21             fallback => 1,
22 6     6   434 );
  6         12  
23 6     6   5962 our $VERSION = 'v0.1.0';
24             };
25              
26             sub init
27             {
28 45     45 1 7377 my $self = shift( @_ );
29 45         169 my $val;
30 45 100       265 $val = shift( @_ ) if( ( scalar( @_ ) % 2 ) );
31 45         520 $self->{format} = '';
32 45         161 $self->{value} = '';
33 45         120 $self->{_init_strict_use_sub} = 1;
34 45         255 $self->SUPER::init( @_ );
35 45 100       329 $self->value( $val ) if( defined( $val ) );
36             # $self->message( 3, "Returning value object for value '", $self->value, "'." );
37 45         3457 return( $self );
38             }
39              
40             ## Inherited
41             ## sub format
42              
43             sub as_string
44             {
45 268     268 1 2320 my $self = shift( @_ );
46 268 50       1382 return( '' ) if( !$self->format );
47 268         5563 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_object_array_object( 'comment_after', 'CSS::Object::Comment', @_ ) ); }
56              
57 536     536 0 14908256 sub comment_after { return( shift->_set_get_object_array_object( 'comment_after', 'CSS::Object::Comment', @_ ) ); }
58              
59 538     538 0 41499 sub comment_before { return( shift->_set_get_object_array_object( 'comment_before', 'CSS::Object::Comment', @_ ) ); }
60              
61             sub value
62             {
63 312     312 1 14877851 my $self = shift( @_ );
64 312 100       1591 if( @_ )
65             {
66 44         130 my $val = shift( @_ );
67 44 50       157 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         817 while( $val =~ s/^[[:blank:]\h]*\/\*[[:blank:]\h]*(.*?)[[:blank:]\h]*\*\///s )
92             {
93 2         47 $self->message( 3, "Adding comment found before value: '$1'." );
94 2   50     63 my $cmt = CSS::Object::Comment->new( [split( /\r\n/, $1 )] ) ||
95             return( $self->error( "Cannot create comment object: ", CSS::Object::Comment->error ) );
96 2         149 $self->comment_before->push( $cmt );
97             }
98 44         386 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         446 $val =~ s/^[[:blank:]\h]*|[[:blank:]\h]*$//gs;
106             }
107 44         257 return( $self->_set_get_scalar_as_object( 'value', $val ) );
108             }
109 268         1407 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           my $cmt = $self->_comment_data_to_object( $opts->{before} );
120 0 0         defined( $cmt ) || return( $self->pass_error );
121 0 0 0       $self->comment_before->push( $cmt ) if( defined( $cmt ) && CORE::length( $cmt ) );
122             }
123 0 0         if( $opts->{after} )
124             {
125 0           my $cmt = $self->_comment_data_to_object( $opts->{after} );
126 0 0         defined( $cmt ) || return( $self->pass_error );
127 0 0 0       $self->comment_after->push( $cmt ) if( defined( $cmt ) && CORE::length( $cmt ) );
128             }
129 0           return( $self );
130             }
131              
132             sub _comment_data_to_object
133             {
134 0     0     my $self = shift( @_ );
135             # No data received, we silently return false
136 0   0       my $this = shift( @_ ) || return( '' );
137 0 0 0       if( $self->_is_a( $this, 'CSS::Objet::Comment' ) )
    0          
138             {
139 0           return( $this );
140             }
141             elsif( $self->_is_array( $this ) || !ref( $this ) )
142             {
143 0   0       my $cmt = CSS::Object::Comment->new( $this, debug => $self->debug ) ||
144             return( $self->error( "Cannot create a new comment from array provided in this property value: ", CSS::Object::Comment->error ) );
145 0           return( $cmt );
146             }
147             else
148             {
149 0           return( $self->error( "I do not know what to do with comment data \"$this\"." ) );
150             }
151             }
152              
153             1;
154              
155             __END__
156              
157             =encoding utf-8
158              
159             =head1 NAME
160              
161             CSS::Object::Value - CSS Object Oriented Value
162              
163             =head1 SYNOPSIS
164              
165             use CSS::Object::Value;
166             # For font-size property for example
167             my $val = CSS::Object::Value->new( '1.2rem',
168             debug => 3,
169             format => $format_object,
170             ) || die( CSS::Object::Value->error );
171              
172             # Adding value with comment inside
173             my $val = CSS::Object::Value->new( '1.2rem', with_comment =>
174             {
175             before => 'This is 12px',
176             after => ["Might want to change this", "to something else"],
177             }) || die( "Cannot add value with comments: ", CSS::Object::Value->error );
178            
179             my $val = CSS::Object::Value->new( '/* Might need to change this */ 1.2rem /* Maybe move this to px instead? */',
180             debug => 3,
181             format => $format_object,
182             ) || die( CSS::Object::Value->error );
183              
184             # or
185             $val->comment_before->push( $css->new_comment( "More comment before value" ));
186             #val->comment_after->push( $css->new_comment( "Another comment after too" ));
187              
188             # or
189             $val->with_comment({
190             before => 'This is 12px',
191             after => ["Might want to change this", "to something else"],
192             }) || die( $val->error );
193              
194             =head1 VERSION
195              
196             v0.1.0
197              
198             =head1 DESCRIPTION
199              
200             L<CSS::Object::Value> is a module to contain the CSS properties' value.
201              
202             =head1 CONSTRUCTOR
203              
204             =head2 new
205              
206             To instantiate a new L<CSS::Object::Value> object, pass an hash reference of following parameters:
207              
208             =over 4
209              
210             =item I<debug>
211              
212             This is an integer. The bigger it is and the more verbose is the output.
213              
214             =item I<format>
215              
216             This is a L<CSS::Object::Format> object or one of its child modules.
217              
218             =item I<value>
219              
220             The property value, which can also be called as the sole argument:
221              
222             # For display property for example
223             my $val = CSS::Object::Value->new( 'none' );
224              
225             =item I<with_comment>
226              
227             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.
228              
229             It returns our object
230              
231             =back
232              
233             =head1 METHODS
234              
235             =head2 as_string
236              
237             This calls the L</format> and its method L<CSS::Object::Format/value_as_string>
238              
239             It returns the css string produce or undef and sets an L<Module::Generic::Exception> upon error.
240              
241             =head2 format
242              
243             This is a L<CSS::Object::Format> object or one of its child modules.
244              
245             =head2 value
246              
247             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
248              
249             Alternatively, it accepts a L<CSS::Object::Value> and will call its L</value> method to get the actual string to store.
250              
251             It returns the value currently stored.
252              
253             =head2 with_comment
254              
255             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.
256              
257             It returns the object used to call this method, or undef if there was an error.
258              
259             =head1 AUTHOR
260              
261             Jacques Deguest E<lt>F<jack@deguest.jp>E<gt>
262              
263             =head1 SEE ALSO
264              
265             L<CSS::Object>
266              
267             =head1 COPYRIGHT & LICENSE
268              
269             Copyright (c) 2020 DEGUEST Pte. Ltd.
270              
271             You can use, copy, modify and redistribute this package and associated
272             files under the same terms as Perl itself.
273              
274             =cut