diff --git a/CHANGES b/CHANGES index 4a44e0f44e..ba970b7ceb 100644 --- a/CHANGES +++ b/CHANGES @@ -37,6 +37,9 @@ Release 1.16.2 [PENDING] thread after interrupting it. + * Bugfix: when tracking HTML source positions, the closing tags for H1...H6 elements were not tracked correctly. + + * Change: removed previously deprecated methods Document#normalise, Element#forEach(org.jsoup.helper.Consumer<>), Node#forEach(org.jsoup.helper.Consumer<>), and the org.jsoup.helper.Consumer interface; the latter being a previously required compatibility shim prior to Android's de-sugaring support. diff --git a/src/main/java/org/jsoup/parser/HtmlTreeBuilder.java b/src/main/java/org/jsoup/parser/HtmlTreeBuilder.java index be0498c5ae..2e49e6050a 100644 --- a/src/main/java/org/jsoup/parser/HtmlTreeBuilder.java +++ b/src/main/java/org/jsoup/parser/HtmlTreeBuilder.java @@ -424,20 +424,12 @@ Element popStackToClose(String elName) { // elnames is sorted, comes from Constants void popStackToClose(String... elNames) { for (int pos = stack.size() -1; pos >= 0; pos--) { - Element next = stack.get(pos); + Element el = stack.get(pos); stack.remove(pos); - if (inSorted(next.normalName(), elNames)) - break; - } - } - - void popStackToBefore(String elName) { - for (int pos = stack.size() -1; pos >= 0; pos--) { - Element next = stack.get(pos); - if (next.normalName().equals(elName)) { + if (inSorted(el.normalName(), elNames)) { + if (currentToken instanceof Token.EndTag) + onNodeClosed(el, currentToken); break; - } else { - stack.remove(pos); } } } diff --git a/src/test/java/org/jsoup/nodes/PositionTest.java b/src/test/java/org/jsoup/nodes/PositionTest.java index 069d5c6a9b..1db73c9e97 100644 --- a/src/test/java/org/jsoup/nodes/PositionTest.java +++ b/src/test/java/org/jsoup/nodes/PositionTest.java @@ -203,4 +203,20 @@ class PositionTest { } } + @Test void tracksClosingHeadingTags() { + // https://github.com/jhy/jsoup/issues/1987 + String html = "

One

Two

Ten"; + Document doc = Jsoup.parse(html, TrackingParser); + + Elements els = doc.body().children(); + for (Element el : els) { + assertTrue(el.sourceRange().isTracked()); + assertTrue(el.endSourceRange().isTracked()); + } + + Element h2 = doc.expectFirst("h2"); + assertEquals("1,13:12-1,17:16", h2.sourceRange().toString()); + assertEquals("1,20:19-1,25:24", h2.endSourceRange().toString()); + } + } \ No newline at end of file