This checkin enables CurrentPage.getSource() to return the actual source

bytes, including whitespace, that is being shown in the BrowserControl.
The source actually comes from the browser's cache, and is not
re-fetched over the network unless the browser doesn't have an entry in
the cache.

Next step is to fix up the TestBrowser to show off this feature.

A src_moz/LoadCompleteProgressListener.cpp
A src_moz/LoadCompleteProgressListener.h

 * Simple nsIWebProgressListener that offers a "loadComplete" property
 * that can be queried to determine if the load has completed.

A test/manual/src/classes/org/mozilla/webclient/test/DOMAccessPanel.java
A test/manual/src/classes/org/mozilla/webclient/test/DOMCellRenderer.java
A test/manual/src/classes/org/mozilla/webclient/test/DOMTreeDumper.java
A test/manual/src/classes/org/mozilla/webclient/test/DOMTreeModel.java
A test/manual/src/classes/org/mozilla/webclient/test/DOMTreeNotifier.java
A test/manual/src/classes/org/mozilla/webclient/test/DOMViewerFrame.java

- move over from Old test browser.  Produces some thread issues.

M src_moz/CurrentPageImpl.cpp

- Leverage LoadCompleteProgressListener to discover when it's safe to
  call "selectAll" on the window.

M src_moz/Makefile.in

- add LoadCompleteProgressListener

M test/automated/src/classes/org/mozilla/webclient/CurrentPageTest.java

- re-enable GetSource test

M test/automated/src/test/ViewSourceTest.html

- re-edit for ease of comparison in CurrentPageTest

M test/manual/src/classes/org/mozilla/webclient/test/TestBrowser.java

- Hack: viewSource button.  A menu would be better.
This commit is contained in:
edburns%acm.org 2005-04-17 20:19:46 +00:00
Родитель 6ca1a2be0d
Коммит 5b8840178c
13 изменённых файлов: 1012 добавлений и 41 удалений

Просмотреть файл

@ -36,9 +36,11 @@
#include "rdf_util.h"
#include "NativeBrowserControl.h"
#include "EmbedWindow.h"
#include "LoadCompleteProgressListener.h"
#include "nsIWebBrowser.h"
#include "nsIWebPageDescriptor.h"
#include "nsIWebProgressListener.h"
#include "nsIDocShell.h"
#include "nsIWebBrowserFind.h"
#include "nsIWebBrowserPrint.h"
@ -492,34 +494,47 @@ JNIEXPORT void JNICALL Java_org_mozilla_webclient_impl_wrapper_1native_CurrentPa
return;
}
// create a new nsIDocShell
EmbedWindow *embedWindow = new EmbedWindow();
rv = embedWindow->InitNoChrome(nativeBrowserControl);
EmbedWindow *sourceWindow = new EmbedWindow();
sourceWindow->InitNoChrome(nativeBrowserControl);
rv = sourceWindow->CreateWindow_(0,0);
if (NS_FAILED(rv)) {
::util_ThrowExceptionToJava(env, "Exception: Can't init new window for view source");
::util_ThrowExceptionToJava(env, "Exception: Can't create window for view source window");
return;
}
rv = embedWindow->CreateWindow_(0,0);
nsCOMPtr<nsIWebBrowser> newWebBrowser = nsnull;
rv = sourceWindow->GetWebBrowser(getter_AddRefs(newWebBrowser));
if (NS_FAILED(rv)) {
::util_ThrowExceptionToJava(env, "Exception: Can't create new window for view source");
::util_ThrowExceptionToJava(env, "Exception: Can't get existing webBrowser for new view source window");
return;
}
// get the new page descriptor
nsCOMPtr<nsIWebBrowser> webBrowser = nsnull;
rv = embedWindow->GetWebBrowser(getter_AddRefs(webBrowser));
// create and install the LoadCompleteProgressListener on the new
// window
LoadCompleteProgressListener *loadCompleteListener =
new LoadCompleteProgressListener();
loadCompleteListener->Init(nativeBrowserControl);
nsCOMPtr<nsISupports> loadCompleteGuard =
NS_STATIC_CAST(nsIWebProgressListener *, loadCompleteListener);
nsCOMPtr<nsISupportsWeakReference> supportsWeak;
supportsWeak = do_QueryInterface(loadCompleteGuard);
nsCOMPtr<nsIWeakReference> weakRef;
supportsWeak->GetWeakReference(getter_AddRefs(weakRef));
rv = newWebBrowser->AddWebBrowserListener(weakRef,
nsIWebProgressListener::GetIID());
if (NS_FAILED(rv)) {
::util_ThrowExceptionToJava(env, "Exception: Can't get webBrowser for view source window");
::util_ThrowExceptionToJava(env, "Exception: install progress listener for view source window");
return;
}
nsCOMPtr<nsIDocShell> newDocShell = do_GetInterface(webBrowser);
nsCOMPtr<nsIDocShell> newDocShell = do_GetInterface(newWebBrowser);
if (!newDocShell) {
::util_ThrowExceptionToJava(env, "Exception: Can't get docShell for view source window");
::util_ThrowExceptionToJava(env, "Exception: Can't get existing docShell for new view source window");
return;
}
// get the page descriptor from the new window
nsCOMPtr<nsIWebPageDescriptor> newPageDesc = do_GetInterface(newDocShell);
if (!newPageDesc) {
::util_ThrowExceptionToJava(env, "Exception: Can't get pageDescriptor for view source window");
@ -531,16 +546,26 @@ JNIEXPORT void JNICALL Java_org_mozilla_webclient_impl_wrapper_1native_CurrentPa
::util_ThrowExceptionToJava(env, "Exception: Can't load page for view source window");
return;
}
// allow the page load to complete
nativeBrowserControl->GetWrapperFactory()->ProcessEventLoop();
rv = embedWindow->SelectAll();
// allow the page load to complete
PRBool loadComplete = PR_FALSE;
while (!loadComplete) {
nativeBrowserControl->GetWrapperFactory()->ProcessEventLoop();
rv = loadCompleteListener->IsLoadComplete(&loadComplete);
if (NS_FAILED(rv)) {
::util_ThrowExceptionToJava(env, "Exception: Error getting status of load in view source window");
return;
}
}
rv = sourceWindow->SelectAll();
if (NS_FAILED(rv)) {
::util_ThrowExceptionToJava(env, "Exception: Can't select all for view source window");
return;
}
rv = embedWindow->GetSelection(env, selection);
rv = sourceWindow->GetSelection(env, selection);
if (NS_FAILED(rv)) {
::util_ThrowExceptionToJava(env, "Exception: Can't get seletion for view source window");
return;
@ -548,8 +573,13 @@ JNIEXPORT void JNICALL Java_org_mozilla_webclient_impl_wrapper_1native_CurrentPa
newPageDesc = nsnull;
newDocShell = nsnull;
webBrowser = nsnull;
delete embedWindow;
sourceWindow->ReleaseChildren();
delete sourceWindow;
weakRef = nsnull;
supportsWeak = nsnull;
loadCompleteGuard = nsnull;
// not necessary to delete sourceWindow, the guard takes care of it.
return;
}

Просмотреть файл

@ -0,0 +1,138 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Christopher Blizzard.
* Portions created by Christopher Blizzard are Copyright (C)
* Christopher Blizzard. All Rights Reserved.
*
* Contributor(s):
* Christopher Blizzard <blizzard@mozilla.org>
*/
#include "LoadCompleteProgressListener.h"
#include <nsXPIDLString.h>
#include <nsIChannel.h>
#include <nsIHttpChannel.h>
#include <nsIUploadChannel.h>
#include <nsIInputStream.h>
#include <nsISeekableStream.h>
#include <nsIHttpHeaderVisitor.h>
#include "nsIURI.h"
#include "nsCRT.h"
#include "nsString.h"
#include "NativeBrowserControl.h"
#include "HttpHeaderVisitorImpl.h"
#include "ns_globals.h" // for prLogModuleInfo
LoadCompleteProgressListener::LoadCompleteProgressListener(void)
{
mOwner = nsnull;
mLoadComplete = PR_FALSE;
}
LoadCompleteProgressListener::~LoadCompleteProgressListener()
{
mOwner = nsnull;
mLoadComplete = PR_FALSE;
}
NS_IMPL_ISUPPORTS2(LoadCompleteProgressListener,
nsIWebProgressListener,
nsISupportsWeakReference)
nsresult
LoadCompleteProgressListener::Init(NativeBrowserControl *aOwner)
{
mOwner = aOwner;
return NS_OK;
}
NS_IMETHODIMP
LoadCompleteProgressListener::OnStateChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
PRUint32 aStateFlags,
nsresult aStatus)
{
if ((aStateFlags & STATE_IS_NETWORK) &&
(aStateFlags & STATE_START)) {
mLoadComplete = PR_FALSE;
}
if ((aStateFlags & STATE_IS_NETWORK) &&
(aStateFlags & STATE_STOP)) {
mLoadComplete = PR_TRUE;
}
return NS_OK;
}
NS_IMETHODIMP
LoadCompleteProgressListener::OnProgressChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
PRInt32 aCurSelfProgress,
PRInt32 aMaxSelfProgress,
PRInt32 aCurTotalProgress,
PRInt32 aMaxTotalProgress)
{
return NS_OK;
}
NS_IMETHODIMP
LoadCompleteProgressListener::OnLocationChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
nsIURI *aLocation)
{
return NS_OK;
}
NS_IMETHODIMP
LoadCompleteProgressListener::OnStatusChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
nsresult aStatus,
const PRUnichar *aMessage)
{
return NS_OK;
}
NS_IMETHODIMP
LoadCompleteProgressListener::OnSecurityChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
PRUint32 aState)
{
return NS_OK;
}
nsresult
LoadCompleteProgressListener::IsLoadComplete(PRBool *_retval)
{
if (!_retval) {
return NS_ERROR_NULL_POINTER;
}
*_retval = mLoadComplete;
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,61 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Christopher Blizzard.
* Portions created by Christopher Blizzard are Copyright (C)
* Christopher Blizzard. All Rights Reserved.
*
* Contributor(s):
* Christopher Blizzard <blizzard@mozilla.org>
*/
#ifndef __LoadCompleteProgressListener_h
#define __LoadCompleteProgressListener_h
#include <nsIWebProgressListener.h>
#include <nsWeakReference.h>
#include "jni_util.h"
class NativeBrowserControl;
/*
* Simple nsIWebProgressListener that offers a "loadComplete" property
* that can be queried to determine if the load has completed.
*
*/
class LoadCompleteProgressListener : public nsIWebProgressListener,
public nsSupportsWeakReference
{
public:
LoadCompleteProgressListener();
virtual ~LoadCompleteProgressListener();
nsresult Init(NativeBrowserControl *aOwner);
nsresult IsLoadComplete(PRBool *_retval);
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBPROGRESSLISTENER
private:
NativeBrowserControl *mOwner;
PRBool mLoadComplete;
};
#endif /* __LoadCompleteProgressListener_h */

Просмотреть файл

@ -101,6 +101,7 @@ CPPSRCS = \
NavigationActionEvents.cpp \
InputStreamShim.cpp \
NativeInputStreamImpl.cpp \
LoadCompleteProgressListener.cpp \
CurrentPageImpl.cpp \
NativeBrowserControl.cpp \
NativeWrapperFactory.cpp \

Просмотреть файл

@ -1,5 +1,5 @@
/*
* $Id: CurrentPageTest.java,v 1.11 2005-03-29 05:03:12 edburns%acm.org Exp $
* $Id: CurrentPageTest.java,v 1.12 2005-04-17 20:19:46 edburns%acm.org Exp $
*/
/*
@ -497,7 +497,7 @@ public class CurrentPageTest extends WebclientTestCase implements ClipboardOwner
BrowserControlFactory.deleteBrowserControl(firstBrowserControl);
}
public void NOTtestGetSource() throws Exception {
public void testGetSource() throws Exception {
BrowserControl firstBrowserControl = null;
DocumentLoadListenerImpl listener = null;
Selection selection = null;
@ -543,8 +543,7 @@ public class CurrentPageTest extends WebclientTestCase implements ClipboardOwner
}
String source = currentPage.getSource();
assertTrue(-1 != source.indexOf("<HTML>"));
assertTrue(-1 != source.indexOf("</HTML>"));
assertEquals("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"><html><head><title>View Source Test</title></head><body><h1>View Source Test</h1></body></html>", source);
frame.setVisible(false);
BrowserControlFactory.deleteBrowserControl(firstBrowserControl);

Просмотреть файл

@ -1,15 +1 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>View Source Test</title>
</head>
<body>
<h1>View Source Test</h1>
<hr>
<address><a href="mailto:b_edward@bellsouth.net"></a></address>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title>View Source Test</title></head><body><h1>View Source Test</h1></body></html>

Просмотреть файл

@ -0,0 +1,414 @@
/*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Initial Developer of the Original Code is Sun Microsystems,
* Inc. Portions created by Sun are Copyright (C) 1999 Sun Microsystems,
* Inc. All Rights Reserved.
*
* Contributor(s): Denis Sharypov <sdv@sparc.spb.su>
* Igor Kushnirskiy <idk@eng.sun.com>
*/
package org.mozilla.webclient.test;
import java.awt.*;
import java.awt.event.*;
import org.w3c.dom.*;
import org.mozilla.dom.*;
import javax.swing.*;
import javax.swing.tree.*; //idk
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.JFileChooser;
public class DOMAccessPanel extends JPanel implements ActionListener, ItemListener, TreeSelectionListener {
private JTextField name, aValue;
private JComboBox type, aName;
private JTextArea value;
private JButton newNode, insert, append, remove, set, removeAttr, save, viewSource;
private Node node, prv;
private NamedNodeMap attrMap;
private boolean updating;
private String[] types = {
"ELEMENT",
"ATTRIBUTE",
"TEXT",
"CDATA_SECTION",
"ENTITY_REF",
"ENTITY",
"PROC_INSTR",
"COMMENT",
"DOCUMENT",
"DOCUMENT_TYPE",
"DOC_FRAGM",
"NOTATION"
};
// private boolean debug = true;
private boolean debug = false;
private Component tree;
private DOMTreeNotifier treeNotifier;
private TreePath nodePath;
private DOMTreeDumper treeDumper;
private JFileChooser chooser;
public DOMAccessPanel() {
GridBagLayout layout = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
JPanel nodeInfo = new JPanel();
nodeInfo.setLayout(layout);
JLabel l = new JLabel("Name:");
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.BOTH;
layout.setConstraints(l, c);
nodeInfo.add(l);
l = new JLabel("Type:");
c.gridwidth = GridBagConstraints.REMAINDER; //end row
layout.setConstraints(l, c);
nodeInfo.add(l);
c.gridwidth = GridBagConstraints.RELATIVE; //new row
name = new JTextField(10);
layout.setConstraints(name, c);
nodeInfo.add(name);
c.gridwidth = GridBagConstraints.REMAINDER; //end row
type = new JComboBox(types);
layout.setConstraints(type, c);
nodeInfo.add(type);
// Attribute panel
JPanel attrPanel = new JPanel();
GridBagLayout attrLayout = new GridBagLayout();
attrPanel.setLayout(attrLayout);
c.gridwidth = GridBagConstraints.RELATIVE; //new row
aName = new JComboBox();
aName.setEditable(true);
aName.addItemListener(this);
attrLayout.setConstraints(aName, c);
attrPanel.add(aName);
JPanel p = new JPanel();
l = new JLabel("=");
p.add(l);
aValue = new JTextField(9);
p.add(aValue);
c.gridwidth = GridBagConstraints.REMAINDER; //end row
attrLayout.setConstraints(p, c);
attrPanel.add(p);
p = new JPanel();
set = new JButton("Set");
set.addActionListener(this);
p.add(set);
removeAttr = new JButton("Remove");
removeAttr.setActionCommand("remove_attr");
removeAttr.addActionListener(this);
p.add(removeAttr);
attrLayout.setConstraints(p, c);
attrPanel.add(p);
attrPanel.setBorder(new TitledBorder(new BevelBorder(BevelBorder.LOWERED), " Attributes "));
layout.setConstraints(attrPanel, c);
// End Attribute panel
nodeInfo.add(attrPanel);
l = new JLabel("Value:");
layout.setConstraints(l, c);
nodeInfo.add(l);
value = new JTextArea(5, 23);
value.addCaretListener (new CaretListener() {
public void caretUpdate(CaretEvent e) {
dbg("caret:");
if (node == null || updating) return;
String valueStr = value.getText();
if (!valueStr.equals("")) {
node.setNodeValue(valueStr);
}
}
});
c.fill = GridBagConstraints.BOTH;
JScrollPane valueScrollPane = new JScrollPane(value);
layout.setConstraints(valueScrollPane, c);
nodeInfo.add(valueScrollPane);
JPanel nodeButtonPanel = new JPanel();
GridLayout gl = new GridLayout(2, 2);
nodeButtonPanel.setLayout(gl);
newNode = new JButton("New");
newNode.setToolTipText("Create a new node");
newNode.addActionListener(this);
nodeButtonPanel.add(newNode);
insert = new JButton("Insert");
insert.setToolTipText("Inserts a node before the selected node ");
insert.addActionListener(this);
nodeButtonPanel.add(insert);
append = new JButton("Append");
append.setToolTipText("Adds a node to the end of the list of children of the selected node");
append.addActionListener(this);
nodeButtonPanel.add(append);
remove = new JButton("Remove");
remove.setToolTipText("Removes the selected node from the tree");
remove.addActionListener(this);
nodeButtonPanel.add(remove);
nodeButtonPanel.setBorder(new TitledBorder(new BevelBorder(BevelBorder.LOWERED), " Node Manipulation "));
c.fill = GridBagConstraints.HORIZONTAL;
layout.setConstraints(nodeButtonPanel, c);
nodeInfo.add(nodeButtonPanel);
nodeInfo.setBorder(new TitledBorder(new EtchedBorder(), " Node info "));
layout = new GridBagLayout();
setLayout(layout);
layout.setConstraints(nodeInfo, c);
add(nodeInfo);
save = new JButton("Dump Tree To File");
save.setActionCommand("save");
save.addActionListener(this);
c.anchor = GridBagConstraints.CENTER;
c.fill = GridBagConstraints.HORIZONTAL;
layout.setConstraints(save, c);
add(save);
viewSource = new JButton("View Source");
viewSource.setActionCommand("viewSource");
viewSource.addActionListener(this);
c.anchor = GridBagConstraints.CENTER;
c.fill = GridBagConstraints.HORIZONTAL;
layout.setConstraints(viewSource, c);
add(viewSource);
setMinimumSize(new Dimension(350, 500));
setButtonState();
}
public void setTreeNotifier(DOMTreeNotifier newTreeNotifier)
{
treeNotifier = newTreeNotifier;
}
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
dbg("AttrInfoPanel.actionPerformed: " + command);
if (command.equalsIgnoreCase("new")) {
prv = node;
updateInfo(null);
type.setEnabled(true);
insert.setEnabled(true);
append.setEnabled(true);
} else if (command.equalsIgnoreCase("insert")) {
insertNode();
treeNotifier.treeStructureChanged(
new TreeModelEvent(this, nodePath.getParentPath()));
} else if (command.equalsIgnoreCase("append")) {
appendNode();
treeNotifier.treeStructureChanged(
new TreeModelEvent(this, nodePath.getParentPath()));
} else if (command.equalsIgnoreCase("remove")) {
if (node == null) return;
Node parent = node.getParentNode();
parent.removeChild(node);
node = parent;
treeNotifier.treeStructureChanged(new TreeModelEvent(this, nodePath.getParentPath()));
} else if (command.equalsIgnoreCase("save")) {
saveDoc();
} else if (command.equalsIgnoreCase("viewSource")) {
viewSource();
} else if (command.equalsIgnoreCase("set")) {
((Element)node).setAttribute((String)aName.getSelectedItem(), aValue.getText());
updateInfo(node);
} else if (command.equalsIgnoreCase("remove_attr")) {
removeAttribute();
}
}
public void itemStateChanged(ItemEvent e) {
if ((node != null) && (aName.getSelectedItem() != null)) {
set.setEnabled(true);
if (((attrMap = node.getAttributes()) != null) &&
(aName.getSelectedIndex() >=0)) {
dbg("setting attr...");
aValue.setText(attrMap.item(aName.getSelectedIndex()).getNodeValue());
}
}
}
public void updateInfo(Node node) {
updating = true;
dbg("updateInfo" + node);
this.node = node;
setButtonState();
name.setText("");
value.setText("");
aValue.setText("");
aName.removeAllItems();
if (node == null) {
updating = false;
return;
}
prv = node;
name.setText(node.getNodeName());
type.setSelectedIndex(node.getNodeType() - 1);
dbg("1 update node name: " + node.getNodeName());
dbg("1 update node value:" + node.getNodeValue());
value.setText(node.getNodeValue());
dbg("2 update node name: " + node.getNodeName());
dbg("2 update node value:" + node.getNodeValue());
attrMap = node.getAttributes();
if (attrMap == null) {
updating = false;
return;
}
int length = attrMap.getLength();
for (int i=0; i < length; i++) {
Attr a = (Attr)attrMap.item(i);
aName.addItem(a.getName());
}
if (length > 0) {
aName.setSelectedIndex(0);
aValue.setText(attrMap.item(0).getNodeValue());
}
updating = false;
}
public void valueChanged(TreeSelectionEvent e) {
dbg("DOMAccessPanel.valueChanged");
if (e.isAddedPath()) {
updateInfo((Node)e.getPath().getLastPathComponent());
}
nodePath = e.getPath();
tree = (Component)e.getSource();
}
private Node createNode() {
int nodeType = type.getSelectedIndex();
Document doc = prv.getOwnerDocument();
Node newNode = null;
switch (nodeType + 1) {
case Node.ELEMENT_NODE:
dbg("ELEMENT");
newNode = doc.createElement(name.getText());
break;
case Node.ATTRIBUTE_NODE:
dbg("ATTRIBUTE");
return null;
case Node.TEXT_NODE:
dbg("TEXT");
newNode = doc.createTextNode(value.getText());
break;
case Node.CDATA_SECTION_NODE:
dbg("CDATA_SECTION");
return null;
case Node.ENTITY_REFERENCE_NODE:
dbg("ENTITY_REFERENCE");
return null;
case Node.ENTITY_NODE:
dbg("ENTITY");
return null;
case Node.PROCESSING_INSTRUCTION_NODE:
dbg("PROCESSING_INSTRUCTION");
return null;
case Node.COMMENT_NODE:
dbg("COMMENT");
newNode = doc.createComment(value.getText());
break;
case Node.DOCUMENT_NODE:
dbg("DOCUMENT");
return null;
case Node.DOCUMENT_TYPE_NODE:
dbg("DOCUMENT_TYPE");
return null;
case Node.DOCUMENT_FRAGMENT_NODE:
dbg("DOCUMENT_FRAGMENT");
return null;
case Node.NOTATION_NODE:
dbg("NOTATION");
return null;
}
return newNode;
}
private void insertNode() {
Node newNode = createNode();
if (newNode == null) return;
dbg("inserting...");
prv.getParentNode().insertBefore(newNode, prv);
}
private void appendNode() {
Node newNode = createNode();
if (newNode == null) return;
dbg("appending...");
prv.appendChild(newNode);
}
private void removeAttribute() {
((Element)node).removeAttribute((String)aName.getSelectedItem());
updateInfo(node);
}
private void saveDoc() {
if (chooser == null) {
chooser = new JFileChooser();
}
int returnVal = chooser.showSaveDialog(this);
if(returnVal == JFileChooser.APPROVE_OPTION) {
String fileName = chooser.getSelectedFile().getPath();
if (treeDumper == null) {
treeDumper = new DOMTreeDumper(debug);
}
treeDumper.dumpToFile(fileName, node.getOwnerDocument());
}
}
private void viewSource() {
if (treeDumper == null) {
treeDumper = new DOMTreeDumper(debug);
}
String source = treeDumper.dump(node.getOwnerDocument());
System.out.println(source);
}
private void setButtonState() {
boolean nodeExists = (node != null);
boolean attrExists = nodeExists && !(node.getAttributes() == null || node.getAttributes().getLength() == 0);
type.setEnabled(nodeExists);
newNode.setEnabled(nodeExists);
insert.setEnabled(nodeExists);
append.setEnabled(nodeExists);
save.setEnabled(nodeExists);
remove.setEnabled(nodeExists);
set.setEnabled(attrExists);
removeAttr.setEnabled(attrExists);
}
private void dbg(String str) {
if (debug) {
System.out.println(str);
}
}
}

Просмотреть файл

@ -0,0 +1,47 @@
/*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Initial Developer of the Original Code is Sun Microsystems,
* Inc. Portions created by Sun are Copyright (C) 1999 Sun Microsystems,
* Inc. All Rights Reserved.
*
* Contributor(s): Igor Kushnirskiy <idk@eng.sun.com>
*/
package org.mozilla.webclient.test;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.JTree;
import org.w3c.dom.Node;
import java.awt.Component;
class DOMCellRenderer implements TreeCellRenderer {
private TreeCellRenderer cellRenderer;
public DOMCellRenderer(TreeCellRenderer cellRenderer) {
this.cellRenderer = cellRenderer;
}
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected,
boolean expanded,
boolean leaf, int row,
boolean hasFocus) {
return cellRenderer.getTreeCellRendererComponent(tree,
((Node)value).getNodeName(),
selected,
expanded,
leaf, row,
hasFocus);
}
}

Просмотреть файл

Просмотреть файл

Просмотреть файл

Просмотреть файл

@ -0,0 +1,240 @@
/* -*- Mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is RaptorCanvas.
*
* The Initial Developer of the Original Code is Kirk Baker and
* Ian Wilkinson. Portions created by Kirk Baker and Ian Wilkinson are
* Copyright (C) 1999 Kirk Baker and Ian Wilkinson. All
* Rights Reserved.
*
* Contributor(s): Kirk Baker <kbaker@eb.com>
* Ian Wilkinson <iw@ennoble.com>
* Mark Goddard
* Ed Burns <edburns@acm.org>
* Jason Mawdsley <jason@macadamian.com>
* Louis-Philippe Gagnon <louisphilippe@macadamian.com>
*/
package org.mozilla.webclient.test;
import org.mozilla.util.Assert;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;
import org.w3c.dom.Document;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventTarget;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.MouseEvent;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JTree;
import javax.swing.tree.TreeSelectionModel;
import javax.swing.tree.TreePath;
import java.awt.BorderLayout;
import java.util.Stack;
/**
*
* A dom viewer Frame
*
* @version $Id: DOMViewerFrame.java,v 1.1 2005-04-17 20:19:46 edburns%acm.org Exp $
*
* @see org.mozilla.webclient.BrowserControlFactory
* Based on DOMViewerFactor.java by idk
* Contributor(s): Ed Burns <edburns@acm.org>
* Igor Kushnirskiy <idk@eng.sun.com>
*/
public class DOMViewerFrame extends JFrame implements EventListener {
private TestBrowser creator;
private Node rootNode;
private Node mouseOverNode = null;
private DOMAccessPanel elementPanel;
private JScrollPane treePane;
private JSplitPane splitPane;
private JPanel panel;
private JTree tree;
private Document doc;
private Stack pathStack;
public DOMViewerFrame (String title, TestBrowser Creator)
{
super(title);
creator = Creator;
this.getContentPane().setLayout(new BorderLayout());
// create the content for the top of the splitPane
treePane = new JScrollPane();
panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add("Center", treePane);
// create the content for the bottom of the splitPane
elementPanel = new DOMAccessPanel();
// create the splitPane, adding the top and bottom content
splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, panel, elementPanel);
// add the splitPane to myself
this.getContentPane().add(splitPane);
this.pack();
splitPane.setDividerLocation(0.35);
} // DOMViewerFrame() ctor
public void setDocument(Document newDocument)
{
if (null == newDocument) {
return;
}
EventTarget eventTarget = null;
if (null != doc) {
if (doc instanceof EventTarget) {
eventTarget = (EventTarget) doc;
eventTarget.removeEventListener("mousedown", this, false);
}
}
doc = newDocument;
if (doc instanceof EventTarget) {
eventTarget = (EventTarget) doc;
eventTarget.addEventListener("click", this, false);
eventTarget.addEventListener("mouseover", this, false);
}
try {
// store the document as the root node
Element e;
e = doc.getDocumentElement();
e.normalize();
rootNode = e;
// create a tree model for the DOM tree
DOMTreeModel treeModel = new DOMTreeModel(rootNode);
// hook the treeModel up to the elementPanel
elementPanel.setTreeNotifier(treeModel);
tree = new JTree(treeModel);
// hook the elementPanel up to the treeModel
tree.addTreeSelectionListener(elementPanel);
tree.setCellRenderer(new DOMCellRenderer(tree.getCellRenderer()));
tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
treePane.setViewportView(tree);
} catch (Exception e) {
e.printStackTrace();
}
}
//
// From org.w3c.dom.events.EventListener
//
public void handleEvent(Event e)
{
if (!(e instanceof MouseEvent)) {
return;
}
MouseEvent mouseEvent = (MouseEvent) e;
Node relatedNode = (Node) mouseEvent.getRelatedTarget();
if (null != relatedNode) {
mouseOverNode = relatedNode;
}
if (mouseEvent.getShiftKey() && 0 != mouseEvent.getDetail() &&
0 == mouseEvent.getButton()) {
if (null != mouseOverNode) {
selectNodeInTree(mouseOverNode);
}
}
}
protected void selectNodeInTree(Node node)
{
if (null == node) {
return;
}
if (null != pathStack) {
// use removeAllElements instead of clear for jdk1.1.x compatibility.
pathStack.removeAllElements();
}
populatePathStackFromNode(node);
if (null == pathStack || pathStack.isEmpty()) {
return;
}
// don't include the root
int i, j = 0, size = pathStack.size() - 1;
// reverse the stack
Object pathArray[] = new Object [size];
for (i=size; i > 0; i--) {
pathArray[j++] = pathStack.elementAt(i - 1);
}
TreePath nodePath = new TreePath(pathArray);
tree.clearSelection();
tree.setSelectionPath(nodePath);
tree.scrollPathToVisible(nodePath);
}
protected void populatePathStackFromNode(Node node)
{
if (null == node) {
return;
}
if (null == pathStack) {
// PENDING(edburns): perhaps provide default size
pathStack = new Stack();
}
if (null == pathStack) {
return;
}
pathStack.push(node);
Node parent = node.getParentNode();
if (null != parent) {
populatePathStackFromNode(parent);
}
}
}
// EOF

Просмотреть файл

@ -32,6 +32,10 @@ import java.net.MalformedURLException;
import java.util.Map;
import java.util.Iterator;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.mozilla.webclient.*;
/**
@ -56,10 +60,13 @@ public class TestBrowser extends JPanel {
BorderLayout borderLayout1 = new BorderLayout();
DOMViewerFrame domViewer = null;
JToolBar jBrowserToolBar = new JToolBar();
JButton jStopButton = new JButton("Stop",
new ImageIcon(getClass().getResource("images/Stop.png")));
JButton jViewSourceButton = new JButton("View Source",
new ImageIcon(getClass().getResource("images/Stop.png")));
JButton jRefreshButton = new JButton("Refresh",
new ImageIcon(getClass().getResource("images/Reload.png")));
JButton jForwardButton = new JButton("Forward",
@ -80,7 +87,7 @@ public class TestBrowser extends JPanel {
Navigation navigation;
History history;
EventRegistration eventRegistration;
CurrentPage currentPage;
CurrentPage2 currentPage;
Canvas browserControlCanvas;
public TestBrowser() {
@ -174,6 +181,14 @@ public class TestBrowser extends JPanel {
jStopButton.setMinimumSize(new Dimension(75, 27));
jStopButton.setPreferredSize(new Dimension(75, 27));
jStopButton.addActionListener(new TestBrowser_jStopButton_actionAdapter(this));
jViewSourceButton.setToolTipText("View Source");
jViewSourceButton.setVerifyInputWhenFocusTarget(true);
jViewSourceButton.setText("View Source");
jViewSourceButton.setEnabled(true);
jViewSourceButton.setMaximumSize(new Dimension(75, 27));
jViewSourceButton.setMinimumSize(new Dimension(75, 27));
jViewSourceButton.setPreferredSize(new Dimension(75, 27));
jViewSourceButton.addActionListener(new TestBrowser_jViewSourceButton_actionAdapter(this));
jAddressPanel.add(jAddressLabel, BorderLayout.WEST);
jAddressPanel.add(jAddressTextField, BorderLayout.CENTER);
jAddressPanel.add(jGoButton, BorderLayout.EAST);
@ -187,6 +202,7 @@ public class TestBrowser extends JPanel {
jBrowserToolBar.addSeparator();
jBrowserToolBar.add(jRefreshButton, null);
jBrowserToolBar.add(jStopButton, null);
jBrowserToolBar.add(jViewSourceButton, null);
// jBrowserToolBar.add(jCopyButton, null);
jBrowserToolBar.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEtchedBorder(),
@ -208,7 +224,7 @@ public class TestBrowser extends JPanel {
webBrowser.queryInterface(BrowserControl.HISTORY_NAME);
eventRegistration = (EventRegistration)
webBrowser.queryInterface(BrowserControl.EVENT_REGISTRATION_NAME);
currentPage = (CurrentPage)
currentPage = (CurrentPage2)
webBrowser.queryInterface(BrowserControl.CURRENT_PAGE_NAME);
browserControlCanvas = (Canvas)
webBrowser.queryInterface(BrowserControl.BROWSER_CONTROL_CANVAS_NAME);
@ -437,6 +453,33 @@ public class TestBrowser extends JPanel {
void jStopButton_actionPerformed(ActionEvent e) {
navigation.stop();
}
void jViewSourceButton_actionPerformed(ActionEvent e) {
try {
String source = currentPage.getSource();
System.out.println(source);
/*****
if (null != doc) {
Document doc = currentPage.getDOM();
currentPage.selectAll();
Selection selection = currentPage.getSelection();
System.out.println(selection.toString());
if (null == domViewer) {
domViewer = new DOMViewerFrame("DOM Viewer", this);
domViewer.setSize(new Dimension(300, 600));
domViewer.setLocation(645, 0);
}
domViewer.setDocument(doc);
domViewer.setVisible(true);
}
******/
}
catch (DOMException exc) {
System.out.println(exc.getMessage());
}
}
}
@ -516,6 +559,18 @@ class TestBrowser_jStopButton_actionAdapter implements java.awt.event.ActionList
}
}
class TestBrowser_jViewSourceButton_actionAdapter implements java.awt.event.ActionListener {
TestBrowser adaptee;
TestBrowser_jViewSourceButton_actionAdapter(TestBrowser adaptee) {
this.adaptee = adaptee;
}
public void actionPerformed(ActionEvent e) {
adaptee.jViewSourceButton_actionPerformed(e);
}
}
class TestBrowser_jGoButton_actionAdapter implements java.awt.event.ActionListener {
TestBrowser adaptee;