Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Elements.replaceAll #1522

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 38 additions & 7 deletions src/main/java/org/jsoup/select/Elements.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,8 @@
import org.jsoup.nodes.TextNode;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.*;
import java.util.function.UnaryOperator;

/**
A list of {@link Element}s, with methods that act on every element in the list.
Expand Down Expand Up @@ -58,7 +54,42 @@ public Elements clone() {
return clone;
}

// attribute methods

/**
* Replace all selected elements in DOM using a new element generated by the operator.
* <p>
* Example:
* document.select("foo").replaceAll(element -> {
* return new Element("replacement");
* });
* This will replace all <code>foo</code> in <code>document</code> with <code>replacement</code>.
* </p>
* @param operator The way how the new element is generated.
*/
// CS304 issue link: https://github.com/jhy/jsoup/issues/1514
@Override
public void replaceAll(UnaryOperator<Element> operator)
{
// make sure operator is not null
if (operator == null)
throw new NullPointerException();
int expectedModCount = this.modCount;
int size = this.size();

for(int i = 0; this.modCount == expectedModCount && i < size; ++i)
{
Element old = this.get(i);
Element replacement = operator.apply(old);
old.replaceWith(replacement);
}

if (this.modCount != expectedModCount)
{
throw new ConcurrentModificationException();
}
}

// attribute methods
/**
Get an attribute value from the first matched element that has the attribute.
@param attributeKey The attribute key.
Expand Down
84 changes: 84 additions & 0 deletions src/test/java/org/jsoup/select/ElementsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -426,4 +426,88 @@ public void tail(Node node, int depth) {
assertEquals("http://example.com/bar", absAttrs.get(1));
assertEquals("http://example.com", absAttrs.get(2));
}

// CS304(manually written) issue link: https://github.com/jhy/jsoup/issues/1514
@Test public void replaceAllReplaceTagsWithAttributes()
{
// GIVEN
String html = "<html>" +
"<head>" +
"<meta content=\"text/html\">" +
"<meta name=\"theme-color\">" +
"</head>" +
"<body>" +
"</body>" +
"</html>";
Document document = Jsoup.parse(html);
// THEN
document.select("meta").replaceAll(element ->
{
return new Element("foo");
});
String expected = "<html>\n" +
" <head>\n" +
" <foo></foo><foo></foo>\n" +
" </head>\n" +
" <body></body>\n" +
"</html>";
//WHEN
assertEquals(expected,document.toString());
}

// CS304(manually written) issue link: https://github.com/jhy/jsoup/issues/1514
@Test public void replaceAllReplaceTagsWithoutAttribute()
{
// GIVEN
String html = "<html>" +
"<head>" +
"<meta content=\"text/html\">" +
"<meta name=\"theme-color\">" +
"</head>" +
"<body>" +
"</body>" +
"</html>";
Document document = Jsoup.parse(html);

// WHEN
document.select("head").replaceAll(element ->
{
return new Element("foo");
});
String expected = "<html>\n" +
" <foo></foo>\n" +
" <body></body>\n" +
"</html>";
// THEN
assertEquals(expected, document.toString());
}

// CS304(manually written) issue link: https://github.com/jhy/jsoup/issues/1514
@Test public void replaceAllIgnoreTagsNotInhtml()
{
// GIVEN
String html = "<html>" +
"<head>" +
"<meta content=\"text/html\">" +
"<meta name=\"theme-color\">" +
"</head>" +
"<body>" +
"</body>" +
"</html>";
Document document = Jsoup.parse(html);
// WHEN
document.select("a").replaceAll(element ->
{
return new Element("foo");
});
String expected = "<html>\n" +
" <head>\n" +
" <meta content=\"text/html\">\n" +
" <meta name=\"theme-color\">\n" +
" </head>\n" +
" <body></body>\n" +
"</html>";
// THEN
assertEquals(expected, document.toString());
}
}