/*
GNU GENERAL LICENSE
Copyright (C) 2006 The Lobo Project. Copyright (C) 2014 - 2017 Lobo Evolution
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
verion 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General License for more details.
You should have received a copy of the GNU General Public
along with this program. If not, see <http://www.gnu.org/licenses/>.
Contact info: lobochief@users.sourceforge.net; ivan.difrancesco@yahoo.it
*/
package org.lobobrowser.primary.ext;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import org.lobobrowser.gui.DefaultWindowFactory;
import org.lobobrowser.util.gui.WrapperLayout;
import org.lobobrowser.w3c.html.HTMLDocument;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* The Class DomViewerWindow.
*/
public class DomViewerWindow extends JFrame implements TreeSelectionListener {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;
/** The dom tree. */
private JTree domTree;
/** The text area. */
private JTextArea textArea;
/**
* Instantiates a new dom viewer window.
*/
public DomViewerWindow() {
super("Lobo DOM Viewer");
this.setIconImage(DefaultWindowFactory.getInstance().getDefaultImageIcon().getImage());
Container contentPane = this.getContentPane();
this.domTree = new JTree();
this.domTree.setRootVisible(false);
this.domTree.setShowsRootHandles(true);
this.domTree.addTreeSelectionListener(this);
JTextArea textArea = this.createTextArea();
this.textArea = textArea;
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(domTree),
new JScrollPane(textArea));
contentPane.setLayout(WrapperLayout.getInstance());
contentPane.add(splitPane);
}
/**
* Creates the text area.
*
* @return the j text area
*/
private JTextArea createTextArea() {
JTextArea textArea = new JTextArea();
textArea.setEditable(false);
return textArea;
}
/**
* Sets the document.
*
* @param document
* the new document
*/
public void setDocument(HTMLDocument document) {
this.domTree.setModel(new DefaultTreeModel(new DomTreeNode(document)));
}
/**
* The Class DomTreeNode.
*/
private class DomTreeNode extends DefaultMutableTreeNode {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;
/**
* Instantiates a new dom tree node.
*
* @param node
* the node
*/
public DomTreeNode(Node node) {
super(node);
NodeList childNodes = node.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node child = childNodes.item(i);
if (child.getNodeType() == Node.TEXT_NODE) {
if (child.getNodeValue().trim().length() > 0) {
this.add(new DomTreeNode(child));
}
} else {
this.add(new DomTreeNode(child));
}
}
}
/*
* (non-Javadoc)
*
* @see javax.swing.tree.DefaultMutableTreeNode#toString()
*/
@Override
public String toString() {
return getNode().getNodeName();
}
/**
* Gets the node.
*
* @return the node
*/
public Node getNode() {
return (Node) getUserObject();
}
}
/*
* (non-Javadoc)
*
* @see
* javax.swing.event.TreeSelectionListener#valueChanged(javax.swing.event.
* TreeSelectionEvent)
*/
@Override
public void valueChanged(TreeSelectionEvent treeselectionevent) {
TreePath path = treeselectionevent.getNewLeadSelectionPath();
if (path != null) {
DomTreeNode domNode = (DomTreeNode) path.getLastPathComponent();
Node node = domNode.getNode();
if ((node.getNodeType() == Node.TEXT_NODE) || (node.getNodeType() == Node.COMMENT_NODE)) {
this.textArea.setText(node.getNodeValue());
} else {
this.textArea.setText("");
this.appendNode(0, node);
}
this.textArea.setCaretPosition(0);
}
}
/**
* Append node.
*
* @param indent
* the indent
* @param node
* the node
*/
private void appendNode(int indent, Node node) {
if (node.getNodeType() == Node.TEXT_NODE) {
this.textArea.append(node.getNodeValue());
} else if (node.getNodeType() == Node.COMMENT_NODE) {
this.textArea.append("\n/* " + node.getNodeValue() + " */");
} else {
this.textArea.setText(this.textArea.getText().trim());
this.textArea.append("\n");
addIndent(indent);
this.textArea.append("<" + node.getNodeName());
this.addAttributes(node);
NodeList childNodes = node.getChildNodes();
if (childNodes.getLength() == 0) {
this.textArea.append("/");
}
this.textArea.append(">");
for (int i = 0; i < childNodes.getLength(); i++) {
appendNode(indent + 1, childNodes.item(i));
}
if (childNodes.getLength() > 0) {
this.textArea.append("\n");
addIndent(indent);
this.textArea.append("</" + node.getNodeName() + ">");
}
}
}
/**
* Adds the attributes.
*
* @param node
* the node
*/
private void addAttributes(Node node) {
NamedNodeMap attributes = node.getAttributes();
for (int i = 0; i < attributes.getLength(); i++) {
Node attr = attributes.item(i);
textArea.append(" ");
textArea.append(attr.getNodeName());
textArea.append("=\"");
textArea.append(attr.getNodeValue());
textArea.append("\"");
}
}
/**
* Adds the indent.
*
* @param indent
* the indent
*/
private void addIndent(int indent) {
for (int i = 0; i < indent; i++) {
this.textArea.append(" ");
}
}
}