Skip Menu |

This queue is for tickets about the SVG CPAN distribution.

Report information
The Basics
Id: 36194
Status: resolved
Priority: 0/
Queue: SVG

People
Owner: Nobody in particular
Requestors: rkrimen [...] cpan.org
Cc: randomcoder1 [...] gmail.com
AdminCc:

Bug Information
Severity: (no value)
Broken in: 2.44
Fixed in: (no value)



Subject: cloneNode(1) does not handle id associations properly (reference to old element)
The following script has a warn and die which shouldn't trigger if cloneNode(1) and id handling worked as expected: #!/usr/bin/perl use strict; use warnings; use SVG; my $original_svg = my $svg = SVG->new(-nocredits => 1); $svg->g(id => "g"); #warn $svg->xmlify; $svg = $svg->cloneNode(1); $svg->getElementByID("g")->setAttribute("style", "stroke: #aaa"); warn "No stroke!" unless $svg->xmlify =~ m/#aaa/; die "Has stroke!" if $original_svg->xmlify =~ m/#aaa/;
I've read your bug-report , I've added a few lines to print some stuff and I will comment it. Since from Perl 5.7.3 we have Storable coming with Perl itself, why would we need to re-write a recursive cloning every time. So , in order to fix the problem , I think it's better we use dclone from Storable. Patch rolled in. #!/usr/bin/perl use strict; use warnings; use SVG; my $original_svg = my $svg = SVG->new(-nocredits => 1); $svg->g(id => "g"); #warn $svg->xmlify; $svg = $svg->cloneNode(1); #After this $svg != $original_svg #and $svg is now of type SVG::Element and $original_svg is SVG. $svg->getElementByID("g")->setAttribute("style", "stroke: #aaa"); #(1) now $svg will have attribute style "stroke: #aaa" on tag <g> #(2) and $original_svg will not. say $svg; say $original_svg; say $svg->getElementByID("g"); say $original_svg->getElementByID("g"); #we get output # #SVG::Element=HASH(0x97a0eb0) #SVG=HASH(0x9799e28) #SVG::Element=HASH(0x96f29c8) #SVG::Element=HASH(0x96f29c8) # So although our objects are distinct , some children of the cloned # nodes AREN'T !!! So cloneNode indeed does not do a proper cloning # although we have given as argument to cloneNode 1 which means we're # doin DEEP cloning. warn "No stroke!" unless $svg->xmlify =~ m/#aaa/; #this should not be shown because of (1) die "Has stroke!" if $original_svg->xmlify =~ m/#aaa/; #this should not die because of (2).
--- /tmp/DOM.pm 2009-08-22 04:09:57.000000000 +0300 +++ /usr/local/share/perl/5.10.0/SVG/DOM.pm 2009-08-22 04:13:03.000000000 +0300 @@ -1,6 +1,7 @@ package SVG::DOM; use strict; use warnings; +use Storable; use vars qw($VERSION); $VERSION = "2.44"; @@ -503,12 +504,7 @@ } } # We need to clone the children if deep is specified. - if($deep) { - foreach my $child (@{$self->{-childs}}) { - my $childClone = $child->cloneNode($deep); - $clone->appendChild($childClone); - } - } + $clone = Storable::dclone($self) if($deep); return $clone; } *cloneElement=\&cloneNode;
Robert, Petrea, The problem was that the docref element was never updated in the cloned element, causing problems down the road. I changed this and the method seems to work well now. Florent