File Coverage

lib/YAX/Element.pm
Criterion Covered Total %
statement 69 107 64.4
branch 8 32 25.0
condition 1 3 33.3
subroutine 21 25 84.0
pod 12 17 70.5
total 111 184 60.3


line stmt bran cond sub pod time code
1             package YAX::Element;
2              
3 3     3   20 use strict;
  3         5  
  3         142  
4              
5 3     3   16 use base qw/YAX::Node/;
  3         7  
  3         260  
6              
7 3     3   1420 use YAX;
  3         9  
  3         81  
8 3     3   17 use YAX::Query;
  3         5  
  3         64  
9 3     3   16 use YAX::Constants qw/ELEMENT_NODE/;
  3         4  
  3         142  
10              
11 3     3   15 use Carp ();
  3         6  
  3         52  
12 3     3   14 use Scalar::Util qw/weaken/;
  3         4  
  3         209  
13              
14             use overload
15 3         34 '@{}' => \&children,
16             '%{}' => \&attributes,
17             '""' => \&as_string,
18 3     3   15 fallback => 1;
  3         4  
19              
20             sub NAME () { 0 }
21             sub ATTR () { 1 }
22             sub KIDS () { 2 }
23             sub PRNT () { 3 }
24              
25             sub new {
26 32     32 0 40 my $class = shift;
27 32         68 my ( $name, %atts ) = @_;
28 32         131 my $self = bless \[ $name, \%atts, [ ] ], $class;
29 32         94 $self;
30             }
31              
32 9     9 1 40 sub type { ELEMENT_NODE() }
33              
34             sub name {
35 259     259 1 21547 my $self = shift;
36 259 50       486 $$self->[NAME] = shift if @_;
37 259         1205 $$self->[NAME];
38             }
39              
40             sub clone {
41 0     0 1 0 my $self = shift;
42 0         0 my $deep = shift;
43 0         0 my $copy = ref( $self )->new( $self->name, %$self );
44 0 0       0 @$copy = map { $_->clone( $deep ) } @$self if $deep;
  0         0  
45 0         0 return $copy;
46             }
47              
48             sub query {
49 14     14 1 3214 my ( $self, $expr ) = @_;
50 14         73 YAX::Query->new( $self )->select( $expr );
51             }
52              
53             sub parent {
54 48     48 1 51 my $self = shift;
55 48 100       279 weaken( $$self->[PRNT] = $_[0] ) if @_;
56 48         98 $$self->[PRNT];
57             }
58              
59             sub children {
60 342     342 1 492 my $self = shift;
61 342         1047 $$self->[KIDS];
62             }
63              
64             sub attributes {
65 76     76 1 2972 my $self = shift;
66 76         345 $$self->[ATTR];
67             }
68              
69             sub append {
70 6     6 1 7 my $self = shift;
71 6         12 my $node = shift;
72 6 50       36 if ( UNIVERSAL::isa( $node, 'YAX::Fragment' ) ) {
73 0         0 $self->append( $_ ) for @$node;
74             } else {
75 6         83 push @$self, $self->adopt( $node );
76             }
77 6         15 $#$self;
78             }
79              
80             sub replace {
81 0     0 1 0 my ( $self, $new, $ref ) = @_;
82              
83 0         0 for ( my $x = 0; $x < @$self; $x++ ) {
84 0 0       0 if ( $self->[$x] == $ref ) {
85 0 0       0 if ( UNIVERSAL::isa( $new, 'YAX::Fragment' ) ) {
86 0         0 splice( @$self, $x, 1, map { $self->adopt( $_) } @$new );
  0         0  
87             } else {
88 0         0 splice( @$self, $x, 1, $self->adopt( $new ) );
89             }
90 0         0 return $x;
91             }
92             }
93             }
94              
95             sub remove {
96 0     0 1 0 my ( $self, $chld ) = @_;
97 0 0       0 return unless $chld->parent == $self;
98 0         0 for ( my $x = 0; $x < @$self; $x++ ) {
99 0 0       0 if ( $self->[$x] == $chld ) {
100 0         0 splice( @$self, $x, 1 );
101 0         0 $chld->parent( undef );
102 0         0 return $x;
103             }
104             }
105             }
106              
107             sub insert {
108 0     0 1 0 my ( $self, $new, $ref ) = @_;
109              
110 0 0       0 unless ( defined $ref ) {
111 0 0       0 if ( UNIVERSAL::isa( $new, 'YAX::Fragment' ) ) {
112 0         0 unshift( @$self, map { $self->adopt( $_ ) } @$new );
  0         0  
113             } else {
114 0         0 unshift( @$self, $self->adopt( $new ) );
115             }
116 0         0 return 0;
117             }
118              
119 0         0 for ( my $x = 0; $x < @$self; $x++ ) {
120 0 0       0 if ( $self->[$x] == $ref ) {
121 0 0       0 if ( UNIVERSAL::isa( $new, 'YAX::Fragment' ) ) {
122 0         0 splice( @$self, $x, 0, map { $self->adopt( $_ ) } @$new );
  0         0  
123             } else {
124 0         0 splice( @$self, $x, 0, $self->adopt( $new ) );
125             }
126 0         0 return $x;
127             }
128             }
129             }
130              
131             sub adopt {
132 6     6 0 10 my ( $self, $node ) = @_;
133 6 50       25 unless ( UNIVERSAL::isa( $node, 'YAX::Node' ) ) {
134 0         0 Carp::croak( "cannot insert `$node' into the document tree" );
135             }
136 6         20 my $prnt = $node->parent;
137 6 50 33     26 if ( defined $prnt and $prnt != $self ) {
138 0         0 $prnt->remove( $node );
139             }
140 6         15 $node->parent( $self );
141 6         16 return $node;
142             }
143              
144             sub as_string {
145 2     2 1 73 my $self = shift;
146 2         5 my $name = $self->name;
147 2         5 my $atts = $self->attributes_as_string;
148              
149 2 50       3 return "<$name $atts />" unless @{ $self->children };
  2         4  
150              
151 2         3 my $kids = $self->children_as_string;
152 2 50       21 return "<$name".( $atts ? " $atts" : '' ).">".$kids."";
153             }
154              
155             sub attributes_as_string {
156 2     2 0 3 my $self = shift;
157 4         7 return join(' ', map {
158 2         3 $_.'="'.quote( $self->{$_} ).'"'
159             } keys %$self);
160             }
161              
162             sub children_as_string {
163 2     2 0 3 my $self = shift;
164 2         2 join( '', map { $_->as_string } @{ $self->children } );
  4         10  
  2         3  
165             }
166              
167             sub quote {
168 4     4 0 5 my $str = pop;
169 4         5 $str =~ s/"/"/gs;
170 4         11 $str;
171             }
172              
173             1;
174             __END__