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.ua.UserAgentContext; import org.lobobrowser.util.gui.WrapperLayout; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.html.HTMLDocument; public class DomViewerWindow extends JFrame implements TreeSelectionListener { private static final long serialVersionUID = 5152758358370104207L; private final JTree domTree; private final JTextArea textArea; public DomViewerWindow() { super("Lobo DOM Viewer"); final UserAgentContext uaContext = null; // TODO this.setIconImage(DefaultWindowFactory.getInstance().getDefaultImageIcon(uaContext).getImage()); final Container contentPane = this.getContentPane(); this.domTree = new JTree(); this.domTree.setRootVisible(false); this.domTree.setShowsRootHandles(true); this.domTree.addTreeSelectionListener(this); final JTextArea textArea = createTextArea(); this.textArea = textArea; final JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(domTree), new JScrollPane(textArea)); contentPane.setLayout(WrapperLayout.getInstance()); contentPane.add(splitPane); } private static JTextArea createTextArea() { final JTextArea textArea = new JTextArea(); textArea.setEditable(false); return textArea; } public void setDocument(final HTMLDocument document) { this.domTree.setModel(new DefaultTreeModel(new DomTreeNode(document))); } private class DomTreeNode extends DefaultMutableTreeNode { private static final long serialVersionUID = -6118030836309592257L; public DomTreeNode(final Node node) { super(node); final NodeList childNodes = node.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { final 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)); } } } @Override public String toString() { return getNode().getNodeName(); } public Node getNode() { return (Node) getUserObject(); } } public void valueChanged(final TreeSelectionEvent treeselectionevent) { final TreePath path = treeselectionevent.getNewLeadSelectionPath(); if (path != null) { final DomTreeNode domNode = (DomTreeNode) path.getLastPathComponent(); final 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); } } private void appendNode(final int indent, final 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); final 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() + ">"); } } } private void addAttributes(final Node node) { final NamedNodeMap attributes = node.getAttributes(); for (int i = 0; i < attributes.getLength(); i++) { final Node attr = attributes.item(i); textArea.append(" "); textArea.append(attr.getNodeName()); textArea.append("=\""); textArea.append(attr.getNodeValue()); textArea.append("\""); } } private void addIndent(final int indent) { for (int i = 0; i < indent; i++) { this.textArea.append(" "); } } }