19 package org.sleuthkit.autopsy.contentviewers;
21 import java.io.IOException;
22 import java.io.StringReader;
23 import java.util.List;
24 import java.util.logging.Level;
26 import javafx.application.Platform;
27 import javafx.beans.value.ChangeListener;
28 import javafx.beans.value.ObservableValue;
29 import javafx.concurrent.Worker;
30 import javafx.scene.web.WebView;
31 import javafx.embed.swing.JFXPanel;
32 import javafx.scene.Scene;
33 import net.htmlparser.jericho.Attribute;
34 import net.htmlparser.jericho.OutputDocument;
35 import net.htmlparser.jericho.Source;
36 import org.openide.util.NbBundle.Messages;
37 import org.w3c.dom.Document;
38 import org.w3c.dom.NodeList;
39 import org.w3c.dom.events.EventTarget;
44 @SuppressWarnings(
"PMD.SingularField")
45 public final class
HtmlPanel extends javax.swing.JPanel {
48 private static final long serialVersionUID = 1L;
49 private static final String TEXT_TYPE =
"text/plain";
50 private final JFXPanel jfxPanel =
new JFXPanel();
59 Platform.runLater(() -> {
60 webView =
new WebView();
62 webView.setContextMenuEnabled(
false);
64 webView.getEngine().setJavaScriptEnabled(
false);
66 webView.getEngine().getLoadWorker().stateProperty().addListener(
new ChangeListener<Worker.State>() {
68 public void changed(ObservableValue<? extends Worker.State> observable, Worker.State oldValue, Worker.State newValue) {
69 if (newValue == Worker.State.SUCCEEDED) {
74 Scene scene =
new Scene(webView);
75 jfxPanel.setScene(scene);
76 jfxPanel.setPreferredSize(htmlJPanel.getPreferredSize());
77 htmlJPanel.add(jfxPanel);
87 this.htmlText = htmlText;
95 Platform.runLater(() -> {
96 webView.getEngine().loadContent(
"", TEXT_TYPE);
98 showImagesToggleButton.setEnabled(
false);
109 String returnString =
"";
111 Source source =
new Source(
new StringReader(htmlInString));
112 OutputDocument document =
new OutputDocument(source);
114 source.getAllTags().stream().filter((tag) -> (tag.toString().contains(
"background-image"))).forEachOrdered((tag) -> {
115 document.remove(tag);
118 source.getAllElements(
"img").forEach((element) -> {
119 document.remove(element.getAllTags());
122 source.getAllElements(
"frame").forEach((element) -> {
123 document.remove(element.getAllTags());
126 source.getAllElements(
"iframe").forEach((element) -> {
127 document.remove(element.getAllTags());
130 source.getAllElements(
"picture").forEach((element) -> {
131 document.remove(element.getAllTags());
134 source.getAllElements(
"svg").forEach((element) -> {
135 document.remove(element.getAllTags());
138 source.getAllElements(
"audio").forEach((element) -> {
139 document.remove(element.getAllTags());
142 source.getAllElements(
"video").forEach((element) -> {
143 document.remove(element.getAllTags());
146 source.getAllElements(
"track").forEach((element) -> {
147 document.remove(element.getAllTags());
150 source.getAllElements(
"embed").forEach((element) -> {
151 document.remove(element.getAllTags());
154 source.getAllElements(
"link").forEach((element) -> {
155 document.remove(element.getAllTags());
158 List<Attribute> attributesToRemove = source.getURIAttributes();
159 document.remove(attributesToRemove);
160 returnString = document.toString();
161 }
catch (IOException ex) {
162 logger.log(Level.WARNING,
"Unable to read html for cleaning out URI elements with Jericho", ex);
171 "HtmlPanel_showImagesToggleButton_show=Download Images",
172 "HtmlPanel_showImagesToggleButton_hide=Hide Images",
173 "Html_text_display_error=The HTML text cannot be displayed, it may not be correctly formed HTML.",})
175 if (
false == htmlText.isEmpty()) {
177 if (showImagesToggleButton.isSelected()) {
178 showImagesToggleButton.setText(Bundle.HtmlPanel_showImagesToggleButton_hide());
179 Platform.runLater(() -> {
180 webView.getEngine().loadContent(htmlText);
183 showImagesToggleButton.setText(Bundle.HtmlPanel_showImagesToggleButton_show());
184 Platform.runLater(() -> {
185 webView.getEngine().loadContent(cleanseHTML(htmlText));
188 showImagesToggleButton.setEnabled(
true);
189 }
catch (Exception ignored) {
190 Platform.runLater(() -> {
191 webView.getEngine().loadContent(Bundle.Html_text_display_error(), TEXT_TYPE);
202 @SuppressWarnings(
"unchecked")
204 private
void initComponents() {
206 showImagesToggleButton =
new javax.swing.JToggleButton();
207 htmlJPanel =
new javax.swing.JPanel();
209 org.openide.awt.Mnemonics.setLocalizedText(showImagesToggleButton,
org.openide.util.NbBundle.getMessage(
HtmlPanel.class,
"HtmlPanel.showImagesToggleButton.text"));
210 showImagesToggleButton.addActionListener(
new java.awt.event.ActionListener() {
211 public void actionPerformed(java.awt.event.ActionEvent evt) {
212 showImagesToggleButtonActionPerformed(evt);
216 htmlJPanel.setLayout(
new java.awt.BorderLayout());
218 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
219 this.setLayout(layout);
220 layout.setHorizontalGroup(
221 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
222 .addGroup(layout.createSequentialGroup()
223 .addComponent(showImagesToggleButton)
224 .addGap(0, 75, Short.MAX_VALUE))
225 .addComponent(htmlJPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
227 layout.setVerticalGroup(
228 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
229 .addGroup(layout.createSequentialGroup()
230 .addComponent(showImagesToggleButton)
231 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
232 .addComponent(htmlJPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 33, Short.MAX_VALUE))
245 Platform.runLater(() -> {
246 Document document = webView.getEngine().getDocument();
247 if (document != null) {
248 NodeList nodeList = document.getElementsByTagName(
"a");
249 for (
int i = 0; i < nodeList.getLength(); i++) {
250 ((EventTarget) nodeList.item(i)).addEventListener(
"click", (evt) -> {
251 evt.preventDefault();
252 evt.stopPropagation();
javax.swing.JPanel htmlJPanel
void showImagesToggleButtonActionPerformed(java.awt.event.ActionEvent evt)
javax.swing.JToggleButton showImagesToggleButton
void setHtmlText(String htmlText)
synchronized static Logger getLogger(String name)
String cleanseHTML(String htmlInString)