summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Kennke <roman@kennke.org>2006-11-30 19:38:04 +0000
committerRoman Kennke <roman@kennke.org>2006-11-30 19:38:04 +0000
commit73ee7fab7219cb0edb4ded57f73dea804846d6b2 (patch)
treeb498c8e2d6b7daa2127102e318928ac30866135f
parent5a7b622274d47160f2e755b7dbb7af2999196a51 (diff)
downloadclasspath-73ee7fab7219cb0edb4ded57f73dea804846d6b2.tar.gz
2006-11-30 Roman Kennke <kennke@aicas.com>
* javax/swing/text/html/FormSubmitEvent.java: New class. * javax/swing/text/html/FormView.java (SubmitThread): New class for submitting data in a separate thread. (actionPerformed): Fetch the actual for data. (addData): New helper method. (getElementFormData): New helper method. (getFormData): New helper method. (getInputFormData): New helper method. (submitData): Implemented. * javax/swing/text/html/FrameView.java (createComponent): Add this as hyperlink listener. Set the target document as frame document. (getTopEditorPane): New helper method. (hyperlinkUpdate): Implementation of the HyperlinkListener interface. (handleHyperlinkEvent): New helper method. (handleFormSubmitEvent): New helper method. * javax/swing/text/html/HTMLDocument.java (HTMLReader.BaseAction.start): Track the base target. (HTMLReader.BaseAction.end): Removed. (baseTarget): New field. (frameDocument): New field. (getBaseTarget): New property accessor. (isFrameDocument): New property accessor. (processHTMLFrameHyperlinkEvent): Implemented. (setFrameDocument): New property accessor. (updateFrame): New helper method. (updateFrameSet): New helper method. * javax/swing/text/html/HTMLEditorKit.java (LinkController.createHyperlinkEvent): Handle frame documents. (autoFormSubmission): New field. (HTMLEditorKit): Set autoFormSubmission to true. (isAutoFormSubmission): New property accessor. (setAutoFormSubmission): New property accessor.
-rw-r--r--ChangeLog36
-rw-r--r--javax/swing/text/html/FormSubmitEvent.java123
-rw-r--r--javax/swing/text/html/FormView.java357
-rw-r--r--javax/swing/text/html/FrameView.java133
-rw-r--r--javax/swing/text/html/HTMLDocument.java175
-rw-r--r--javax/swing/text/html/HTMLEditorKit.java70
6 files changed, 870 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index 019d81972..42162df60 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,41 @@
2006-11-30 Roman Kennke <kennke@aicas.com>
+ * javax/swing/text/html/FormSubmitEvent.java: New class.
+ * javax/swing/text/html/FormView.java
+ (SubmitThread): New class for submitting data in a separate thread.
+ (actionPerformed): Fetch the actual for data.
+ (addData): New helper method.
+ (getElementFormData): New helper method.
+ (getFormData): New helper method.
+ (getInputFormData): New helper method.
+ (submitData): Implemented.
+ * javax/swing/text/html/FrameView.java
+ (createComponent): Add this as hyperlink listener.
+ Set the target document as frame document.
+ (getTopEditorPane): New helper method.
+ (hyperlinkUpdate): Implementation of the HyperlinkListener interface.
+ (handleHyperlinkEvent): New helper method.
+ (handleFormSubmitEvent): New helper method.
+ * javax/swing/text/html/HTMLDocument.java
+ (HTMLReader.BaseAction.start): Track the base target.
+ (HTMLReader.BaseAction.end): Removed.
+ (baseTarget): New field.
+ (frameDocument): New field.
+ (getBaseTarget): New property accessor.
+ (isFrameDocument): New property accessor.
+ (processHTMLFrameHyperlinkEvent): Implemented.
+ (setFrameDocument): New property accessor.
+ (updateFrame): New helper method.
+ (updateFrameSet): New helper method.
+ * javax/swing/text/html/HTMLEditorKit.java
+ (LinkController.createHyperlinkEvent): Handle frame documents.
+ (autoFormSubmission): New field.
+ (HTMLEditorKit): Set autoFormSubmission to true.
+ (isAutoFormSubmission): New property accessor.
+ (setAutoFormSubmission): New property accessor.
+
+2006-11-30 Roman Kennke <kennke@aicas.com>
+
* javax/swing/text/ElementIterator.java
(ElementRef): New inner class.
(currentDepth): Removed.
diff --git a/javax/swing/text/html/FormSubmitEvent.java b/javax/swing/text/html/FormSubmitEvent.java
new file mode 100644
index 000000000..bc7c36f4b
--- /dev/null
+++ b/javax/swing/text/html/FormSubmitEvent.java
@@ -0,0 +1,123 @@
+/* FormSubmitEvent.java -- Event fired on form submit
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing.text.html;
+
+import java.net.URL;
+
+import javax.swing.text.Element;
+
+/**
+ * The event fired on form submit.
+ *
+ * @since 1.5
+ */
+public class FormSubmitEvent
+ extends HTMLFrameHyperlinkEvent
+{
+
+ // FIXME: Use enums when available.
+ /**
+ * The submit method.
+ */
+ public static class MethodType
+ {
+ /**
+ * Indicates a form submit with HTTP method POST.
+ */
+ public static final MethodType POST = new MethodType();
+
+ /**
+ * Indicates a form submit with HTTP method GET.
+ */
+ public static final MethodType GET = new MethodType();
+
+ private MethodType()
+ {
+ }
+ }
+
+ /**
+ * The submit method.
+ */
+ private MethodType method;
+
+ /**
+ * The actual submit data.
+ */
+ private String data;
+
+ /**
+ * Creates a new FormSubmitEvent.
+ *
+ * @param source the source
+ * @param type the type of hyperlink update
+ * @param url the action url
+ * @param el the associated element
+ * @param target the target attribute
+ * @param m the submit method
+ * @param d the submit data
+ */
+ FormSubmitEvent(Object source, EventType type, URL url, Element el,
+ String target, MethodType m, String d)
+ {
+ super(source, type, url, el, target);
+ method = m;
+ data = d;
+ }
+
+ /**
+ * Returns the submit data.
+ *
+ * @return the submit data
+ */
+ public String getData()
+ {
+ return data;
+ }
+
+ /**
+ * Returns the HTTP submit method.
+ *
+ * @return the HTTP submit method
+ */
+ public MethodType getMethod()
+ {
+ return method;
+ }
+}
diff --git a/javax/swing/text/html/FormView.java b/javax/swing/text/html/FormView.java
index 031a8b7a4..340f85490 100644
--- a/javax/swing/text/html/FormView.java
+++ b/javax/swing/text/html/FormView.java
@@ -44,24 +44,32 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
+import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
import javax.swing.ButtonModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
+import javax.swing.JEditorPane;
import javax.swing.JPasswordField;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
+import javax.swing.SwingUtilities;
import javax.swing.UIManager;
+import javax.swing.event.HyperlinkEvent;
import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
import javax.swing.text.ComponentView;
import javax.swing.text.Document;
import javax.swing.text.Element;
+import javax.swing.text.ElementIterator;
import javax.swing.text.StyleConstants;
/**
@@ -113,6 +121,214 @@ public class FormView
}
/**
+ * Actually submits the form data.
+ */
+ private class SubmitThread
+ extends Thread
+ {
+ /**
+ * The submit data.
+ */
+ private String data;
+
+ /**
+ * Creates a new SubmitThread.
+ *
+ * @param d the submit data
+ */
+ SubmitThread(String d)
+ {
+ data = d;
+ }
+
+ /**
+ * Actually performs the submit.
+ */
+ public void run()
+ {
+ if (data.length() > 0)
+ {
+ final String method = getMethod();
+ final URL actionURL = getActionURL();
+ final String target = getTarget();
+ URLConnection conn;
+ final JEditorPane editor = (JEditorPane) getContainer();
+ final HTMLDocument doc = (HTMLDocument) editor.getDocument();
+ HTMLEditorKit kit = (HTMLEditorKit) editor.getEditorKit();
+ if (kit.isAutoFormSubmission())
+ {
+ try
+ {
+ final URL url;
+ if (method != null && method.equals("post"))
+ {
+ // Perform POST.
+ url = actionURL;
+ conn = url.openConnection();
+ postData(conn);
+ }
+ else
+ {
+ // Default to GET.
+ url = new URL(actionURL + "?" + data);
+ }
+ Runnable loadDoc = new Runnable()
+ {
+ public void run()
+ {
+ if (doc.isFrameDocument())
+ {
+ editor.fireHyperlinkUpdate(createSubmitEvent(method,
+ actionURL,
+ target));
+ }
+ else
+ {
+ try
+ {
+ editor.setPage(url);
+ }
+ catch (IOException ex)
+ {
+ // Oh well.
+ ex.printStackTrace();
+ }
+ }
+ }
+ };
+ SwingUtilities.invokeLater(loadDoc);
+ }
+ catch (MalformedURLException ex)
+ {
+ ex.printStackTrace();
+ }
+ catch (IOException ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+ else
+ {
+ editor.fireHyperlinkUpdate(createSubmitEvent(method,actionURL,
+ target));
+ }
+ }
+ }
+
+ /**
+ * Determines the submit method.
+ *
+ * @return the submit method
+ */
+ private String getMethod()
+ {
+ AttributeSet formAtts = getFormAttributes();
+ String method = null;
+ if (formAtts != null)
+ {
+ method = (String) formAtts.getAttribute(HTML.Attribute.METHOD);
+ }
+ return method;
+ }
+
+ /**
+ * Determines the action URL.
+ *
+ * @return the action URL
+ */
+ private URL getActionURL()
+ {
+ AttributeSet formAtts = getFormAttributes();
+ HTMLDocument doc = (HTMLDocument) getElement().getDocument();
+ URL url = doc.getBase();
+ if (formAtts != null)
+ {
+ String action =
+ (String) formAtts.getAttribute(HTML.Attribute.ACTION);
+ if (action != null)
+ {
+ try
+ {
+ url = new URL(url, action);
+ }
+ catch (MalformedURLException ex)
+ {
+ url = null;
+ }
+ }
+ }
+ return url;
+ }
+
+ /**
+ * Fetches the target attribute.
+ *
+ * @return the target attribute or _self if none is present
+ */
+ private String getTarget()
+ {
+ AttributeSet formAtts = getFormAttributes();
+ String target = null;
+ if (formAtts != null)
+ {
+ target = (String) formAtts.getAttribute(HTML.Attribute.TARGET);
+ if (target != null)
+ target = target.toLowerCase();
+ }
+ if (target == null)
+ target = "_self";
+ return target;
+ }
+
+ /**
+ * Posts the form data over the specified connection.
+ *
+ * @param conn the connection
+ */
+ private void postData(URLConnection conn)
+ {
+ // TODO: Implement.
+ }
+
+ /**
+ * Determines the attributes from the relevant form tag.
+ *
+ * @return the attributes from the relevant form tag, <code>null</code>
+ * when there is no form tag
+ */
+ private AttributeSet getFormAttributes()
+ {
+ AttributeSet atts = null;
+ Element form = getFormElement();
+ if (form != null)
+ atts = form.getAttributes();
+ return atts;
+ }
+
+ /**
+ * Creates the submit event that should be fired.
+ *
+ * This is package private to avoid accessor methods.
+ *
+ * @param method the submit method
+ * @param actionURL the action URL
+ * @param target the target
+ *
+ * @return the submit event
+ */
+ FormSubmitEvent createSubmitEvent(String method, URL actionURL,
+ String target)
+ {
+ FormSubmitEvent.MethodType m = "post".equals(method)
+ ? FormSubmitEvent.MethodType.POST
+ : FormSubmitEvent.MethodType.GET;
+ return new FormSubmitEvent(FormView.this,
+ HyperlinkEvent.EventType.ACTIVATED,
+ actionURL, getElement(), target, m, data);
+ }
+ }
+
+ /**
* If the value attribute of an <code>&lt;input type=&quot;submit&quot;&gt>
* tag is not specified, then this string is used.
*
@@ -340,7 +556,7 @@ public class FormView
AttributeSet atts = el.getAttributes();
String type = (String) atts.getAttribute(HTML.Attribute.TYPE);
if (type.equals("submit"))
- submitData(""); // FIXME: How to fetch the actual form data?
+ submitData(getFormData());
}
// FIXME: Implement the remaining actions.
}
@@ -353,7 +569,8 @@ public class FormView
*/
protected void submitData(String data)
{
- // FIXME: Implement this.
+ SubmitThread submitThread = new SubmitThread(data);
+ submitThread.start();
}
/**
@@ -390,4 +607,140 @@ public class FormView
}
return data;
}
+
+ /**
+ * Determines and returns the enclosing form element if there is any.
+ *
+ * This is package private to avoid accessor methods.
+ *
+ * @return the enclosing form element, or <code>null</code> if there is no
+ * enclosing form element
+ */
+ Element getFormElement()
+ {
+ Element form = null;
+ Element el = getElement();
+ while (el != null && form == null)
+ {
+ AttributeSet atts = el.getAttributes();
+ if (atts.getAttribute(StyleConstants.NameAttribute) == HTML.Tag.FORM)
+ form = el;
+ else
+ el = el.getParentElement();
+ }
+ return form;
+ }
+
+ /**
+ * Determines the form data that is about to be submitted.
+ *
+ * @return the form data
+ */
+ private String getFormData()
+ {
+ Element form = getFormElement();
+ StringBuilder b = new StringBuilder();
+ if (form != null)
+ {
+ ElementIterator i = new ElementIterator(form);
+ Element next;
+ while ((next = i.next()) != null)
+ {
+ if (next.isLeaf())
+ {
+ AttributeSet atts = next.getAttributes();
+ String type = (String) atts.getAttribute(HTML.Attribute.TYPE);
+ if (type != null && type.equals("submit")
+ && next != getElement())
+ {
+ // Skip this. This is not the actual submit trigger.
+ }
+ else if (type == null || ! type.equals("image"))
+ {
+ getElementFormData(next, b);
+ }
+ }
+ }
+ }
+ return b.toString();
+ }
+
+ /**
+ * Fetches the form data from the specified element and appends it to
+ * the data string.
+ *
+ * @param el the element from which to fetch form data
+ * @param b the data string
+ */
+ private void getElementFormData(Element el, StringBuilder b)
+ {
+ AttributeSet atts = el.getAttributes();
+ String name = (String) atts.getAttribute(HTML.Attribute.NAME);
+ if (name != null)
+ {
+ String value = null;
+ HTML.Tag tag = (HTML.Tag) atts.getAttribute(StyleConstants.NameAttribute);
+ if (tag == HTML.Tag.INPUT)
+ value = getInputFormData(atts);
+ // TODO: Implement textarea and select.
+ if (name != null && value != null)
+ {
+ addData(b, name, value);
+ }
+ }
+ }
+
+ /**
+ * Fetches form data from an input tag.
+ *
+ * @param atts the attributes from which to fetch the data
+ *
+ * @return the field value
+ */
+ private String getInputFormData(AttributeSet atts)
+ {
+ String type = (String) atts.getAttribute(HTML.Attribute.TYPE);
+ Object model = atts.getAttribute(StyleConstants.ModelAttribute);
+ String value = null;
+ if (type.equals("text") || type.equals("password"))
+ {
+ Document doc = (Document) model;
+ try
+ {
+ value = doc.getText(0, doc.getLength());
+ }
+ catch (BadLocationException ex)
+ {
+ // Sigh.
+ assert false;
+ }
+ }
+ else if (type.equals("hidden") || type.equals("submit"))
+ {
+ value = (String) atts.getAttribute(HTML.Attribute.VALUE);
+ if (value == null)
+ value = "";
+ }
+ // TODO: Implement the others. radio, checkbox and file.
+ return value;
+ }
+
+ /**
+ * Actually adds the specified data to the string. It URL encodes
+ * the name and value and handles separation of the fields.
+ *
+ * @param b the string at which the form data to be added
+ * @param name the name of the field
+ * @param value the value
+ */
+ private void addData(StringBuilder b, String name, String value)
+ {
+ if (b.length() > 0)
+ b.append('&');
+ String encName = URLEncoder.encode(name);
+ b.append(encName);
+ b.append('=');
+ String encValue = URLEncoder.encode(value);
+ b.append(encValue);
+ }
}
diff --git a/javax/swing/text/html/FrameView.java b/javax/swing/text/html/FrameView.java
index e91c0c731..cd4e44a98 100644
--- a/javax/swing/text/html/FrameView.java
+++ b/javax/swing/text/html/FrameView.java
@@ -44,9 +44,12 @@ import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.JEditorPane;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.ComponentView;
import javax.swing.text.Element;
+import javax.swing.text.View;
/**
* A view that is responsible for rendering HTML frame tags.
@@ -55,6 +58,7 @@ import javax.swing.text.Element;
*/
class FrameView
extends ComponentView
+ implements HyperlinkListener
{
/**
@@ -78,6 +82,7 @@ class FrameView
Element el = getElement();
AttributeSet atts = el.getAttributes();
JEditorPane html = new JEditorPane();
+ html.addHyperlinkListener(this);
URL base = ((HTMLDocument) el.getDocument()).getBase();
String srcAtt = (String) atts.getAttribute(HTML.Attribute.SRC);
if (srcAtt != null && ! srcAtt.equals(""))
@@ -86,7 +91,7 @@ class FrameView
{
URL page = new URL(base, srcAtt);
html.setPage(page);
- System.err.println("loading: " + page);
+ ((HTMLDocument) html.getDocument()).setFrameDocument(true);
}
catch (MalformedURLException ex)
{
@@ -99,4 +104,130 @@ class FrameView
}
return html;
}
+
+ /**
+ * Catches hyperlink events on that frame's editor and forwards it to
+ * the outermost editorpane.
+ */
+ public void hyperlinkUpdate(HyperlinkEvent event)
+ {
+ JEditorPane outer = getTopEditorPane();
+ if (outer != null)
+ {
+ if (event instanceof HTMLFrameHyperlinkEvent)
+ {
+ HTMLFrameHyperlinkEvent hfhe = (HTMLFrameHyperlinkEvent) event;
+ if (hfhe.getEventType() == HyperlinkEvent.EventType.ACTIVATED)
+ {
+ String target = hfhe.getTarget();
+ if (event instanceof FormSubmitEvent)
+ {
+ handleFormSubmitEvent(hfhe, outer, target);
+ }
+ else // No FormSubmitEvent.
+ {
+ handleHyperlinkEvent(hfhe, outer, target);
+ }
+ }
+ }
+ else
+ {
+ // Simply forward this event.
+ outer.fireHyperlinkUpdate(event);
+ }
+ }
+ }
+
+ /**
+ * Handles normal hyperlink events.
+ *
+ * @param event the event
+ * @param outer the top editor
+ * @param target the target
+ */
+ private void handleHyperlinkEvent(HyperlinkEvent event,
+ JEditorPane outer, String target)
+ {
+ if (target.equals("_top"))
+ {
+ try
+ {
+ outer.setPage(event.getURL());
+ }
+ catch (IOException ex)
+ {
+ // Well...
+ ex.printStackTrace();
+ }
+ }
+ if (! outer.isEditable())
+ {
+ outer.fireHyperlinkUpdate
+ (new HTMLFrameHyperlinkEvent(outer,
+ event.getEventType(),
+ event.getURL(),
+ event.getDescription(),
+ getElement(),
+ target));
+ }
+ }
+
+ /**
+ * Handles form submit events.
+ *
+ * @param event the event
+ * @param outer the top editor
+ * @param target the target
+ */
+ private void handleFormSubmitEvent(HTMLFrameHyperlinkEvent event,
+ JEditorPane outer,
+ String target)
+ {
+ HTMLEditorKit kit = (HTMLEditorKit) outer.getEditorKit();
+ if (kit != null && kit.isAutoFormSubmission())
+ {
+ if (target.equals("_top"))
+ {
+ try
+ {
+ outer.setPage(event.getURL());
+ }
+ catch (IOException ex)
+ {
+ // Well...
+ ex.printStackTrace();
+ }
+ }
+ else
+ {
+ HTMLDocument doc =
+ (HTMLDocument) outer.getDocument();
+ doc.processHTMLFrameHyperlinkEvent(event);
+ }
+ }
+ else
+ {
+ outer.fireHyperlinkUpdate(event);
+ }
+ }
+
+ /**
+ * Determines the topmost editor in a nested frameset.
+ *
+ * @return the topmost editor in a nested frameset
+ */
+ private JEditorPane getTopEditorPane()
+ {
+ View parent = getParent();
+ View top = null;
+ while (parent != null)
+ {
+ if (parent instanceof FrameSetView)
+ top = parent;
+ }
+ JEditorPane editor = null;
+ if (top != null)
+ editor = (JEditorPane) top.getContainer();
+ return editor;
+ }
}
diff --git a/javax/swing/text/html/HTMLDocument.java b/javax/swing/text/html/HTMLDocument.java
index 701ede7a8..4f849f391 100644
--- a/javax/swing/text/html/HTMLDocument.java
+++ b/javax/swing/text/html/HTMLDocument.java
@@ -52,6 +52,8 @@ import java.util.Vector;
import javax.swing.DefaultButtonModel;
import javax.swing.JEditorPane;
import javax.swing.JToggleButton;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.UndoableEditEvent;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
@@ -89,7 +91,17 @@ public class HTMLDocument extends DefaultStyledDocument
boolean preservesUnknownTags = true;
int tokenThreshold = Integer.MAX_VALUE;
HTMLEditorKit.Parser parser;
-
+
+ /**
+ * Indicates whether this document is inside a frame or not.
+ */
+ private boolean frameDocument;
+
+ /**
+ * Package private to avoid accessor methods.
+ */
+ String baseTarget;
+
/**
* Constructs an HTML document using the default buffer size and a default
* StyleSheet.
@@ -365,11 +377,119 @@ public class HTMLDocument extends DefaultStyledDocument
}
public void processHTMLFrameHyperlinkEvent(HTMLFrameHyperlinkEvent event)
- throws NotImplementedException
{
- // TODO: Implement this properly.
+ String target = event.getTarget();
+ Element el = event.getSourceElement();
+ URL url = event.getURL();
+ if (target.equals("_self"))
+ {
+ updateFrame(el, url);
+ }
+ else if (target.equals("_parent"))
+ {
+ updateFrameSet(el.getParentElement(), url);
+ }
+ else
+ {
+ Element targetFrame = findFrame(target);
+ if (targetFrame != null)
+ updateFrame(targetFrame, url);
+ }
}
-
+
+ /**
+ * Finds the named frame inside this document.
+ *
+ * @param target the name to look for
+ *
+ * @return the frame if there is a matching frame, <code>null</code>
+ * otherwise
+ */
+ private Element findFrame(String target)
+ {
+ ElementIterator i = new ElementIterator(this);
+ Element next = null;
+ while ((next = i.next()) != null)
+ {
+ AttributeSet atts = next.getAttributes();
+ if (atts.getAttribute(StyleConstants.NameAttribute) == HTML.Tag.FRAME)
+ {
+ String name = (String) atts.getAttribute(HTML.Attribute.NAME);
+ if (name != null && name.equals(target))
+ break;
+ }
+ }
+ return next;
+ }
+
+ /**
+ * Updates the frame that is represented by the specified element to
+ * refer to the specified URL.
+ *
+ * @param el the element
+ * @param url the new url
+ */
+ private void updateFrame(Element el, URL url)
+ {
+ try
+ {
+ writeLock();
+ DefaultDocumentEvent ev =
+ new DefaultDocumentEvent(el.getStartOffset(), 1,
+ DocumentEvent.EventType.CHANGE);
+ AttributeSet elAtts = el.getAttributes();
+ AttributeSet copy = elAtts.copyAttributes();
+ MutableAttributeSet matts = (MutableAttributeSet) elAtts;
+ ev.addEdit(new AttributeUndoableEdit(el, copy, false));
+ matts.removeAttribute(HTML.Attribute.SRC);
+ matts.addAttribute(HTML.Attribute.SRC, url.toString());
+ ev.end();
+ fireChangedUpdate(ev);
+ fireUndoableEditUpdate(new UndoableEditEvent(this, ev));
+ }
+ finally
+ {
+ writeUnlock();
+ }
+ }
+
+ /**
+ * Updates the frameset that is represented by the specified element
+ * to create a frame that refers to the specified URL.
+ *
+ * @param el the element
+ * @param url the url
+ */
+ private void updateFrameSet(Element el, URL url)
+ {
+ int start = el.getStartOffset();
+ int end = el.getEndOffset();
+
+ StringBuilder html = new StringBuilder();
+ html.append("<frame");
+ if (url != null)
+ {
+ html.append(" src=\"");
+ html.append(url.toString());
+ html.append("\"");
+ }
+ html.append('>');
+ if (getParser() == null)
+ setParser(new HTMLEditorKit().getParser());
+ try
+ {
+ setOuterHTML(el, html.toString());
+ }
+ catch (BadLocationException ex)
+ {
+ ex.printStackTrace();
+ }
+ catch (IOException ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
/**
* Gets an iterator for the given HTML.Tag.
* @param t the requested HTML.Tag
@@ -954,20 +1074,9 @@ public class HTMLDocument extends DefaultStyledDocument
* of tags associated with this Action.
*/
public void start(HTML.Tag t, MutableAttributeSet a)
- throws NotImplementedException
{
- // FIXME: Implement.
+ baseTarget = (String) a.getAttribute(HTML.Attribute.TARGET);
}
-
- /**
- * Called when an end tag is seen for one of the types of tags associated
- * with this Action.
- */
- public void end(HTML.Tag t)
- throws NotImplementedException
- {
- // FIXME: Implement.
- }
}
class HeadAction extends BlockAction
@@ -1955,4 +2064,38 @@ public void setOuterHTML(Element elem, String htmlText)
}
super.insertUpdate(evt, att);
}
+
+ /**
+ * Returns <code>true</code> when this document is inside a frame,
+ * <code>false</code> otherwise.
+ *
+ * @return <code>true</code> when this document is inside a frame,
+ * <code>false</code> otherwise
+ */
+ boolean isFrameDocument()
+ {
+ return frameDocument;
+ }
+
+ /**
+ * Set <code>true</code> when this document is inside a frame,
+ * <code>false</code> otherwise.
+ *
+ * @param frameDoc <code>true</code> when this document is inside a frame,
+ * <code>false</code> otherwise
+ */
+ void setFrameDocument(boolean frameDoc)
+ {
+ frameDocument = frameDoc;
+ }
+
+ /**
+ * Returns the target that is specified in the base tag, if this is the case.
+ *
+ * @return the target that is specified in the base tag, if this is the case
+ */
+ String getBaseTarget()
+ {
+ return baseTarget;
+ }
}
diff --git a/javax/swing/text/html/HTMLEditorKit.java b/javax/swing/text/html/HTMLEditorKit.java
index 3f55e2dac..78b5df99f 100644
--- a/javax/swing/text/html/HTMLEditorKit.java
+++ b/javax/swing/text/html/HTMLEditorKit.java
@@ -243,10 +243,25 @@ public class HTMLEditorKit
{
url = null;
}
- // TODO: Handle frame documents and target here.
- HyperlinkEvent ev =
- new HyperlinkEvent(editor, HyperlinkEvent.EventType.ACTIVATED, url,
- href, el);
+ HyperlinkEvent ev;
+ if (doc.isFrameDocument())
+ {
+ String target = null;
+ if (anchor != null)
+ target = (String) anchor.getAttribute(HTML.Attribute.TARGET);
+ if (target == null || target.equals(""))
+ target = doc.getBaseTarget();
+ if (target == null || target.equals(""))
+ target = "_self";
+ ev = new HTMLFrameHyperlinkEvent(editor,
+ HyperlinkEvent.EventType.ACTIVATED,
+ url, href, el, target);
+ }
+ else
+ {
+ ev = new HyperlinkEvent(editor, HyperlinkEvent.EventType.ACTIVATED,
+ url, href, el);
+ }
return ev;
}
}
@@ -1065,13 +1080,22 @@ public class HTMLEditorKit
/** The editor pane used. */
JEditorPane editorPane;
-
+
+ /**
+ * Whether or not the editor kit handles form submissions.
+ *
+ * @see #isAutoFormSubmission()
+ * @see #setAutoFormSubmission(boolean)
+ */
+ private boolean autoFormSubmission;
+
/**
* Constructs an HTMLEditorKit, creates a StyleContext, and loads the style sheet.
*/
public HTMLEditorKit()
{
linkController = new LinkController();
+ autoFormSubmission = true;
}
/**
@@ -1415,4 +1439,40 @@ public class HTMLEditorKit
{
styleSheet = s;
}
+
+ /**
+ * Returns <code>true</code> when forms should be automatically submitted
+ * by the editor kit. Set this to <code>false</code> when you want to
+ * intercept form submission. In this case you'd want to listen for
+ * hyperlink events on the document and handle FormSubmitEvents specially.
+ *
+ * The default is <code>true</code>.
+ *
+ * @return <code>true</code> when forms should be automatically submitted
+ * by the editor kit, <code>false</code> otherwise
+ *
+ * @since 1.5
+ *
+ * @see #setAutoFormSubmission(boolean)
+ * @see FormSubmitEvent
+ */
+ public boolean isAutoFormSubmission()
+ {
+ return autoFormSubmission;
+ }
+
+ /**
+ * Sets whether or not the editor kit should automatically submit forms.
+ *
+ * @param auto <code>true</code> when the editor kit should handle form
+ * submission, <code>false</code> otherwise
+ *
+ * @since 1.5
+ *
+ * @see #isAutoFormSubmission()
+ */
+ public void setAutoFormSubmission(boolean auto)
+ {
+ autoFormSubmission = auto;
+ }
}