Skip to content

Commit 55c4011

Browse files
yulian-gaponenkoiText-CI
authored andcommitted
Fix anchor links handling with destinations on elements handled by SpanTagWorker
DEVSIX-2774
1 parent db4b971 commit 55c4011

File tree

6 files changed

+57
-15
lines changed

6 files changed

+57
-15
lines changed

src/main/java/com/itextpdf/html2pdf/LogMessageConstant.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public final class LogMessageConstant {
4949

5050
/** The Constant ACROFORM_NOT_SUPPORTED_FOR_SELECT. */
5151
public static final String ACROFORM_NOT_SUPPORTED_FOR_SELECT = "AcroForm fields creation for select fields (ComboBoxField and ListBoxField) is not supported. They will be flattened instead.";
52+
public static final String ANCHOR_LINK_NOT_HANDLED = "The anchor link was not handled. Could not create a destination for element \"{0}\" with ID \"{1}\", which is processed by \"{2}\" tag worker class.";
5253
/** The Constant CONTENT_PROPERTY_INVALID. */
5354
public static final String CONTENT_PROPERTY_INVALID = "Content property \"{0}\" is either invalid or uses unsupported function.";
5455
/** The Constant CSS_PROPERTY_IN_PERCENTS_NOT_SUPPORTED. */
@@ -111,7 +112,7 @@ public final class LogMessageConstant {
111112
public static final String TEXT_WAS_NOT_PROCESSED = "Text was not processed: {0}";
112113
/** The Constant UNABLE_TO_PROCESS_EXTERNAL_CSS_FILE. */
113114
public static final String UNABLE_TO_PROCESS_EXTERNAL_CSS_FILE = "Unable to process external css file";
114-
/** The Constant UNABLE_TO_PROCESS_IMAGE_AS_SVG*/
115+
/** The Constant UNABLE_TO_PROCESS_IMAGE_AS_SVG */
115116
public static final String UNABLE_TO_PROCESS_IMAGE_AS_SVG = "Unable to process image found at {0} as an SVG";
116117
/** The Constant UNABLE_TO_RESOLVE_COUNTER. */
117118
public static final String UNABLE_TO_RESOLVE_COUNTER = "Unable to resolve counter \"{0}\"";

src/main/java/com/itextpdf/html2pdf/attach/impl/LinkContext.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ This file is part of the iText (R) project.
4343
package com.itextpdf.html2pdf.attach.impl;
4444

4545
import com.itextpdf.html2pdf.html.AttributeConstants;
46+
import com.itextpdf.html2pdf.html.TagConstants;
4647
import com.itextpdf.styledxmlparser.node.IElementNode;
4748
import com.itextpdf.styledxmlparser.node.INode;
4849

@@ -91,9 +92,12 @@ public LinkContext scanForIds(INode root) {
9192
while (!stk.isEmpty()) {
9293
INode n = stk.pop();
9394
if (n instanceof IElementNode) {
94-
IElementNode n2 = (IElementNode) n;
95-
if (n2.name().equals(AttributeConstants.a) && n2.getAttribute(AttributeConstants.HREF) != null && n2.getAttribute(AttributeConstants.HREF).startsWith("#")) {
96-
linkDestinations.add(n2.getAttribute(AttributeConstants.HREF).substring(1));
95+
IElementNode elem = (IElementNode) n;
96+
if (TagConstants.A.equals(elem.name())) {
97+
String href = elem.getAttribute(AttributeConstants.HREF);
98+
if (href != null && href.startsWith("#")){
99+
linkDestinations.add(href.substring(1));
100+
}
97101
}
98102
}
99103
if (!n.childNodes().isEmpty()) {

src/main/java/com/itextpdf/html2pdf/attach/util/LinkHelper.java

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,11 @@ This file is part of the iText (R) project.
4242
*/
4343
package com.itextpdf.html2pdf.attach.util;
4444

45+
import com.itextpdf.html2pdf.LogMessageConstant;
4546
import com.itextpdf.html2pdf.attach.ITagWorker;
4647
import com.itextpdf.html2pdf.attach.ProcessorContext;
48+
import com.itextpdf.html2pdf.attach.impl.tags.SpanTagWorker;
49+
import com.itextpdf.io.util.MessageFormatUtil;
4750
import com.itextpdf.kernel.geom.Rectangle;
4851
import com.itextpdf.kernel.pdf.PdfArray;
4952
import com.itextpdf.kernel.pdf.action.PdfAction;
@@ -56,6 +59,9 @@ This file is part of the iText (R) project.
5659
import com.itextpdf.layout.property.Property;
5760
import com.itextpdf.html2pdf.html.AttributeConstants;
5861
import com.itextpdf.styledxmlparser.node.IElementNode;
62+
import java.util.List;
63+
import org.slf4j.Logger;
64+
import org.slf4j.LoggerFactory;
5965

6066
/**
6167
* Helper class for links.
@@ -99,22 +105,33 @@ public static void applyLinkAnnotation(IPropertyContainer container, String url)
99105
* @param context the Processor context
100106
*/
101107
public static void createDestination(ITagWorker tagWorker, IElementNode element, ProcessorContext context) {
102-
if (element.getAttribute(AttributeConstants.ID) == null)
103-
return;
104-
105-
if (tagWorker == null)
108+
String id = element.getAttribute(AttributeConstants.ID);
109+
if (id == null)
106110
return;
107111

108-
IPropertyContainer propertyContainer = tagWorker.getElementResult();
109-
if (propertyContainer == null)
112+
if (!context.getLinkContext().isUsedLinkDestination(id)) {
110113
return;
114+
}
111115

112-
// get id
113-
String id = element.getAttribute(AttributeConstants.ID);
116+
IPropertyContainer propertyContainer = null;
117+
if (tagWorker != null) {
118+
if (tagWorker instanceof SpanTagWorker) {
119+
List<IPropertyContainer> spanElements = ((SpanTagWorker) tagWorker).getAllElements();
120+
if (!spanElements.isEmpty()) {
121+
propertyContainer = spanElements.get(0);
122+
}
123+
} else {
124+
propertyContainer = tagWorker.getElementResult();
125+
}
126+
}
114127

115-
// set property
116-
if (context.getLinkContext().isUsedLinkDestination(id)) {
117-
propertyContainer.setProperty(Property.DESTINATION, id);
128+
if (propertyContainer == null) {
129+
Logger logger = LoggerFactory.getLogger(LinkHelper.class);
130+
String tagWorkerClassName = tagWorker != null ? tagWorker.getClass().getName() : "null";
131+
logger.warn(MessageFormatUtil.format(LogMessageConstant.ANCHOR_LINK_NOT_HANDLED, element.name(), id, tagWorkerClassName));
132+
return;
118133
}
134+
135+
propertyContainer.setProperty(Property.DESTINATION, id);
119136
}
120137
}

src/test/java/com/itextpdf/html2pdf/element/LinkTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,4 +170,11 @@ public void linkTest12() throws IOException, InterruptedException {
170170
}
171171
Assert.assertNull(new CompareTool().compareByContent(destinationFolder + "linkTest12.pdf", sourceFolder + "cmp_linkTest12.pdf", destinationFolder, "diff12_"));
172172
}
173+
174+
@Test
175+
public void anchorLinkToSpanTest01() throws IOException, InterruptedException {
176+
String fileName = "anchorLinkToSpanTest01";
177+
HtmlConverter.convertToPdf(new File(sourceFolder + fileName + ".html"), new File(destinationFolder + fileName + ".pdf"));
178+
Assert.assertNull(new CompareTool().compareByContent(destinationFolder + fileName + ".pdf", sourceFolder + "cmp_" + fileName + ".pdf", destinationFolder));
179+
}
173180
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<html>
2+
<body>
3+
4+
<a id="main_q" href="#Welsh_Corgi">Who's a good boy?</a>
5+
<p style="page-break-before: always;">
6+
<span id="Welsh_Corgi">corgi</span>
7+
<a href="#main_q">Back to main question!</a>
8+
</p>
9+
10+
11+
</body>
12+
</html>
13+

0 commit comments

Comments
 (0)