Skip to content

Commit 26351ef

Browse files
committed
Restore the behavior of cssSelector before v1.16.2
1 parent ae4dfd2 commit 26351ef

File tree

2 files changed

+38
-12
lines changed

2 files changed

+38
-12
lines changed

src/main/java/org/jsoup/nodes/Element.java

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -937,6 +937,25 @@ public Element wrap(String html) {
937937
return (Element) super.wrap(html);
938938
}
939939

940+
private String idAsCssSelector() {
941+
String result = "";
942+
943+
if (!id().isEmpty()) {
944+
// prefer to return the ID - but check that it's actually unique first!
945+
String idSel = "#" + escapeCssIdentifier(id());
946+
Document doc = ownerDocument();
947+
if (doc != null) {
948+
Elements els = doc.select(idSel);
949+
if (els.size() == 1 && els.get(0) == this) // otherwise, continue to the nth-child impl
950+
result = idSel;
951+
} else {
952+
result = idSel; // no ownerdoc, return the ID selector
953+
}
954+
}
955+
956+
return result;
957+
}
958+
940959
/**
941960
* Get a CSS selector that will uniquely select this element.
942961
* <p>
@@ -948,22 +967,18 @@ public Element wrap(String html) {
948967
* @return the CSS Path that can be used to retrieve the element in a selector.
949968
*/
950969
public String cssSelector() {
951-
if (id().length() > 0) {
952-
// prefer to return the ID - but check that it's actually unique first!
953-
String idSel = "#" + escapeCssIdentifier(id());
954-
Document doc = ownerDocument();
955-
if (doc != null) {
956-
Elements els = doc.select(idSel);
957-
if (els.size() == 1 && els.get(0) == this) // otherwise, continue to the nth-child impl
958-
return idSel;
959-
} else {
960-
return idSel; // no ownerdoc, return the ID selector
961-
}
962-
}
970+
String idAsCssSelector = idAsCssSelector();
971+
if (!idAsCssSelector.isEmpty())
972+
return idAsCssSelector;
963973

964974
StringBuilder selector = StringUtil.borrowBuilder();
965975
Element el = this;
966976
while (el != null && !(el instanceof Document)) {
977+
idAsCssSelector = el.idAsCssSelector();
978+
if (!idAsCssSelector.isEmpty()) {
979+
selector.insert(0, idAsCssSelector);
980+
break;
981+
}
967982
selector.insert(0, el.cssSelectorComponent());
968983
el = el.parent();
969984
}

src/test/java/org/jsoup/nodes/ElementTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2592,6 +2592,17 @@ void prettySerializationRoundTrips(Document.OutputSettings settings) {
25922592
assertEquals("div", el.cssSelector());
25932593
}
25942594

2595+
@Test void cssSelectorParentWithId() {
2596+
// https://github.com/jhy/jsoup/issues/2282
2597+
Document doc = Jsoup.parse("<div><div id=\"id1\"><p>A</p></div><div><p>B</p></div><div class=\"c1 c2\"><p>C</p></div></div>");
2598+
Element divA = doc.select("div div p").get(0);
2599+
Element divB = doc.select("div div p").get(1);
2600+
Element divC = doc.select("div div p").get(2);
2601+
assertEquals("#id1 > p", divA.cssSelector());
2602+
assertEquals("html > body > div > div:nth-child(2) > p", divB.cssSelector());
2603+
assertEquals("html > body > div > div.c1.c2 > p", divC.cssSelector());
2604+
}
2605+
25952606
@Test void cssSelectorDoesntStackOverflow() {
25962607
// https://github.com/jhy/jsoup/issues/2001
25972608
Element element = new Element("element");

0 commit comments

Comments
 (0)