The items of content to be added should each be
either a text segment (a string), an HTML::Element object, or
an arrayref (which is fed thru C<new_from_lol>).
The unshift_content method will try to consolidate adjacent text segments
while adding to the content list. See above for a discussion of this.
=cut
sub unshift_content {
my $self = shift;
return $self unless @_;
my $content = ($self->{'_content'} ||= []);
for (reverse @_) { # so they get added in the order specified
if (ref($_) eq 'ARRAY') {
# magically call new_from_lol
unshift @$content, $self->new_from_lol($_);
$content->[0]->{'_parent'} = $self;
}
elsif (ref $_) { # insert an element
$_->detach if $_->{'_parent'};
$_->{'_parent'} = $self;
unshift(@$content, $_);
}
else { # insert text segment
if (@$content && !ref $content->[0]) {
# last content element is also text segment -- prepend
$content->[0] = $_ . $content->[0];
}
else {
unshift(@$content, $_);
}
}
}
return $self;
}
# Cf. splice ARRAY,OFFSET,LENGTH,LIST
=head2 $h->splice_content($offset, $length, $element_or_text, ...)
Detaches the elements from $h's list of content-nodes, starting at
$offset and continuing for $length items, replacing them with the
elements of the following list, if any. Returns the elements (if any)
removed from the content-list. If $offset is negative, then it starts
that far from the end of the array, just like Perl's normal C<splice>
function. If $length and the following list is omitted, removes
everything from $offset onward.
The items of content to be added (if any) should each be either a text
segment (a string), an arrayref (which is fed thru C<new_from_lol>),
or an HTML::Element object that's not already
a child of $h.
=cut
sub splice_content {
my($self, $offset, $length, @to_add) = @_;
Carp::croak "splice_content requires at least one argument"
if @_ < 2; # at least $h->splice_content($offset);
return $self unless @_;
my $content = ($self->{'_content'} ||= []);
# prep the list
my @out;
if (@_ > 2) { # self, offset, length, ...
foreach my $n (@to_add) {
if (ref($n) eq 'ARRAY') {
$n = $self->new_from_lol($n);
$n->{'_parent'} = $self;
}
elsif (ref($n)) {
$n->detach;
$n->{'_parent'} = $self;
}
}
@out = splice @$content, $offset, $length, @to_add;
}
else { # self, offset
@out = splice @$content, $offset;
}
foreach my $n (@out) {
$n->{'_parent'} = undef if ref $n;
}
return @out;
}
=head2 $h->detach()
This unlinks $h from its parent, by setting its 'parent' attribute to
undef, and by removing it from the content list of its parent (if it
had one). The return value is the parent that was detached from (or
undef, if $h had no parent to start with). Note that neither $h nor
its parent are explicitly destroyed.
=cut
=9= |