Skip to content

Commit

Permalink
DocumentFragment#dup avoids unnecessary copies.
Browse files Browse the repository at this point in the history
[fixes #1063]
  • Loading branch information
flavorjones committed Dec 4, 2018
1 parent 0b5cf87 commit 46a3c7d
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ If you're offended by what happened here, I'd kindly ask that you comment on the
* [MRI] OpenBSD installation should be a bit easier now. [#1685] (Thanks, @jeremyevans!)
* [MRI] Cross-built Windows gems now support Ruby 2.5
* Node#dup supports copying a node directly to a new document. See the method documentation for details.
* [MRI] DocumentFragment#dup is now more memory-efficient, avoiding making unnecessary copies. [#1063]


## Bug fixes
Expand Down
9 changes: 9 additions & 0 deletions lib/nokogiri/xml/document_fragment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ def initialize document, tags = nil, ctx = nil
children.each { |child| child.parent = self }
end

def dup
new_document = document.dup
new_fragment = XML::DocumentFragment.new(new_document)
children.each do |child|
child.dup(1, new_document).parent = new_fragment
end
new_fragment
end

###
# return the name for DocumentFragment
def name
Expand Down
14 changes: 14 additions & 0 deletions test/xml/test_document_fragment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,20 @@ def test_issue_1077_parsing_of_frozen_strings
Nokogiri::XML::DocumentFragment.parse(input) # assert_nothing_raised
end

def test_dup_creates_tree_with_identical_structure
original = Nokogiri::XML::DocumentFragment.parse("<div><p>hello</p></div>")
duplicate = original.dup
assert_equal original.to_html, duplicate.to_html
end

def test_dup_creates_mutable_tree
original = Nokogiri::XML::DocumentFragment.parse("<div><p>hello</p></div>")
duplicate = original.dup
duplicate.at_css("div").add_child("<b>hello there</b>")
assert_nil original.at_css("b")
assert_not_nil duplicate.at_css("b")
end

if Nokogiri.uses_libxml?
def test_for_libxml_in_context_fragment_parsing_bug_workaround
10.times do
Expand Down

0 comments on commit 46a3c7d

Please sign in to comment.