/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import javax.accessibility.*;
/**
* The Swing JEditorPane text component supports different kinds
* of content via a plug-in mechanism called an EditorKit. Because
* HTML is a very popular format of content, some support is provided
* by default. The default support is provided by this class, which
* supports HTML version 3.2 (with some extensions), and is migrating
* toward version 4.0.
* The <applet> tag is not supported, but some support is provided
* for the <object> tag.
* <p>
* There are several goals of the HTML EditorKit provided, that have
* an effect upon the way that HTML is modeled. These
* have influenced its design in a substantial way.
* <dl>
* <p>
* <dt>
* Support editing
* <dd>
* It might seem fairly obvious that a plug-in for JEditorPane
* should provide editing support, but that fact has several
* design considerations. There are a substantial number of HTML
* documents that don't properly conform to an HTML specification.
* These must be normalized somewhat into a correct form if one
* is to edit them. Additionally, users don't like to be presented
* with an excessive amount of structure editing, so using traditional
* text editing gestures is preferred over using the HTML structure
* exactly as defined in the HTML document.
* <p>
* The modeling of HTML is provided by the class <code>HTMLDocument</code>.
* Its documention describes the details of how the HTML is modeled.
* The editing support leverages heavily off of the text package.
* <p>
* <dt>
* <dd>
* To maximize the usefulness of this kit, a great deal of effort
* has gone into making it extendable. These are some of the
* features.
* <ol>
* <li>
* The parser is replacable. The default parser is the Hot Java
* parser which is DTD based. A different DTD can be used, or an
* entirely different parser can be used. To change the parser,
* reimplement the getParser method. The default parser is
* dynamically loaded when first asked for, so the class files
* will never be loaded if an alternative parser is used. The
* default parser is in a separate package called parser below
* this package.
* <li>
* The parser drives the ParserCallback, which is provided by
* HTMLDocument. To change the callback, subclass HTMLDocument
* and reimplement the createDefaultDocument method to return
* document that produces a different reader. The reader controls
* how the document is structured. Although the Document provides
* HTML support by default, there is nothing preventing support of
* non-HTML tags that result in alternative element structures.
* <li>
* The default view of the models are provided as a hierarchy of
* View implementations, so one can easily customize how a particular
* element is displayed or add capabilities for new kinds of elements
* by providing new View implementations. The default set of views
* are provided by the <code>HTMLFactory</code> class. This can
* be easily changed by subclassing or replacing the HTMLFactory
* and reimplementing the getViewFactory method to return the alternative
* factory.
* <li>
* The View implementations work primarily off of CSS attributes,
* which are kept in the views. This makes it possible to have
* multiple views mapped over the same model that appear substantially
* different. This can be especially useful for printing. For
* most HTML attributes, the HTML attributes are converted to CSS
* attributes for display. This helps make the View implementations
* more general purpose
* </ol>
* <p>
* <dt>
* Asynchronous Loading
* <dd>
* Larger documents involve a lot of parsing and take some time
* to load. By default, this kit produces documents that will be
* loaded asynchronously if loaded using <code>JEditorPane.setPage</code>.
* This is controlled by a property on the document. The method
* {@link #createDefaultDocument createDefaultDocument} can
* be overriden to change this. The batching of work is done
* by the <code>HTMLDocument.HTMLReader</code> class. The actual
* work is done by the <code>DefaultStyledDocument</code> and
* <code>AbstractDocument</code> classes in the text package.
* <p>
* <dt>
* Customization from current LAF
* <dd>
* HTML provides a well known set of features without exactly
* specifying the display characteristics. Swing has a theme
* mechanism for its look-and-feel implementations. It is desirable
* for the look-and-feel to feed display characteristics into the
* HTML views. An user with poor vision for example would want
* high contrast and larger than typical fonts.
* <p>
* The support for this is provided by the <code>StyleSheet</code>
* class. The presentation of the HTML can be heavily influenced
* by the setting of the StyleSheet property on the EditorKit.
* <p>
* <dt>
* Not lossy
* <dd>
* An EditorKit has the ability to be read and save documents.
* It is generally the most pleasing to users if there is no loss
* of data between the two operation. The policy of the HTMLEditorKit
* will be to store things not recognized or not necessarily visible
* so they can be subsequently written out. The model of the HTML document
* should therefore contain all information discovered while reading the
* document. This is constrained in some ways by the need to support
* editing (i.e. incorrect documents sometimes must be normalized).
* The guiding principle is that information shouldn't be lost, but
* some might be synthesized to produce a more correct model or it might
* be rearranged.
* </dl>
*
* @author Timothy Prinzing
*/
/**
* Constructs an HTMLEditorKit, creates a StyleContext,
* and loads the style sheet.
*/
public HTMLEditorKit() {
}
/**
* Get the MIME type of the data that this
* kit represents support for. This kit supports
*
* @return the type
*/
}
/**
* Fetch a factory that is suitable for producing
* views of any models that are produced by this
* kit.
*
* @return the factory
*/
return defaultFactory;
}
/**
* Create an uninitialized text storage model
* that is appropriate for this type of editor.
*
* @return the model
*/
return doc;
}
/**
* Try to get an HTML parser from the document. If no parser is set for
* the document, return the editor kit's default parser. It is an error
* if no parser could be obtained from the editor kit.
*/
if (p == null) {
p = getParser();
}
if (p == null) {
throw new IOException("Can't load parser");
}
return p;
}
/**
* Inserts content from the given stream. If <code>doc</code> is
* an instance of HTMLDocument, this will read
* HTML 3.2 text. Inserting HTML into a non-empty document must be inside
* the body Element, if you do not insert into the body an exception will
* be thrown. When inserting into a non-empty document all tags outside
* of the body (head, title) will be dropped.
*
* @param in the stream to read from
* @param doc the destination for the insertion
* @param pos the location in the document to place the
* content
* @exception IOException on any I/O error
* @exception BadLocationException if pos represents an invalid
* location within the document
* @exception RuntimeException (will eventually be a BadLocationException)
* if pos is invalid
*/
if (doc instanceof HTMLDocument) {
}
} else {
}
}
/**
* Inserts HTML into an existing document.
*
* @param doc the document to insert into
* @param offset the offset to insert HTML at
* @param popDepth the number of ElementSpec.EndTagTypes to generate before
* inserting
* @param pushDepth the number of ElementSpec.StartTagTypes with a direction
* of ElementSpec.JoinNextDirection that should be generated
* before inserting, but after the end tags have been generated
* @param insertTag the first tag to start inserting into document
* @exception RuntimeException (will eventually be a BadLocationException)
* if pos is invalid
*/
}
("IgnoreCharsetDirective");
false : ignoreCharset.booleanValue());
}
/**
* Write content from a document to the given stream
* in a format appropriate for this kind of content handler.
*
* @param out the stream to write to
* @param doc the source for the write
* @param pos the location in the document to fetch the
* content
* @param len the amount to write out
* @exception IOException on any I/O error
* @exception BadLocationException if pos represents an invalid
* location within the document
*/
throws IOException, BadLocationException {
if (doc instanceof HTMLDocument) {
w.write();
} else if (doc instanceof StyledDocument) {
w.write();
} else {
}
}
/**
* Called when the kit is being installed into the
* a JEditorPane.
*
* @param c the JEditorPane
*/
super.install(c);
theEditor = c;
}
/**
* Called when the kit is being removed from the
* JEditorPane. This is used to unregister any
* listeners that were attached.
*
* @param c the JEditorPane
*/
super.deinstall(c);
}
/**
* Default Cascading Style Sheet file that sets
* up the tag views.
*/
/**
* Set the set of styles to be used to render the various
* HTML elements. These styles are specified in terms of
* CSS specifications. Each document produced by the kit
* will have a copy of the sheet which it can add the
* document specific styles to. By default, the StyleSheet
* specified is shared by all HTMLEditorKit instances.
* This should be reimplemented to provide a finer granularity
* if desired.
*/
if (s == null) {
} else {
}
}
/**
* Get the set of styles currently being used to render the
* HTML elements. By default the resource specified by
* DEFAULT_CSS gets loaded, and is shared by all HTMLEditorKit
* instances.
*/
if (defaultStyles == null) {
defaultStyles = new StyleSheet();
try {
Reader r = new BufferedReader(
r.close();
} catch (Throwable e) {
// on error we simply have no styles... the html
// will look mighty wrong but still function.
}
}
return defaultStyles;
}
/**
* Fetch a resource relative to the HTMLEditorKit classfile.
* If this is called on 1.2 the loading will occur under the
* protection of a doPrivileged call to allow the HTMLEditorKit
* to function when used in an applet.
*
* @param name the name of the resource, relative to the
* HTMLEditorKit class
* @return a stream representing the resource
*/
try {
} catch (Throwable e) {
// If the class doesn't exist or we have some other
// problem we just try to call getResourceAsStream directly.
}
}
/**
* Fetches the command list for the editor. This is
* the list of commands supported by the superclass
* augmented by the collection of commands defined
* locally for style operations.
*
* @return the command list
*/
}
/**
* <code>set</code>. This does not copy component, icon, or element
* names attributes. Subclasses may wish to refine what is and what
* isn't copied here. But be sure to first remove all the attributes that
* are in <code>set</code>.<p>
* This is called anytime the caret moves over a different location.
*
*/
// PENDING: we need a better way to express what shouldn't be
// copied when editing...
// Remove the related image attributes, src, width, height
}
// Don't copy HRs or BRs either.
}
// Don't copy COMMENTs either
}
// or INPUT either
}
// Don't copy unknowns either:(
}
}
}
/**
* Gets the input attributes used for the styled
* editing actions.
*
* @return the attribute set
*/
}
return input;
}
/**
* Sets the default cursor.
*
* @since 1.3
*/
}
/**
* Returns the default cursor.
*
* @since 1.3
*/
return defaultCursor;
}
/**
* Sets the cursor to use over links.
*
* @since 1.3
*/
linkCursor = cursor;
}
/**
* Returns the cursor to use over hyper links.
* @since 1.3
*/
return linkCursor;
}
/**
* Indicates whether an html form submission is processed automatically
* or only <code>FormSubmitEvent</code> is fired.
*
* @return true if html form submission is processed automatically,
* false otherwise.
*
* @see #setAutoFormSubmission
* @since 1.5
*/
public boolean isAutoFormSubmission() {
return isAutoFormSubmission;
}
/**
* Specifies if an html form submission is processed
* automatically or only <code>FormSubmitEvent</code> is fired.
* By default it is set to true.
*
* @see #isAutoFormSubmission()
* @see FormSubmitEvent
* @since 1.5
*/
}
/**
* Creates a copy of the editor kit.
*
* @return the copy
*/
if (o != null) {
o.linkHandler = new LinkController();
}
return o;
}
/**
* Fetch the parser to use for reading HTML streams.
* This can be reimplemented to provide a different
* parser. The default implementation is loaded dynamically
* to avoid the overhead of loading the default parser if
* it's not used. The default parser is the HotJava parser
* using an HTML 3.2 DTD.
*/
if (defaultParser == null) {
try {
} catch (Throwable e) {
}
}
return defaultParser;
}
// ----- Accessibility support -----
/**
* returns the AccessibleContext associated with this editor kit
*
* @return the AccessibleContext associated with this editor kit
* @since 1.4
*/
return null;
}
if (accessibleContext == null) {
}
return accessibleContext;
}
// --- variables ------------------------------------------
/** Shared factory for creating HTML Views. */
private boolean isAutoFormSubmission = true;
/**
* Class to watch the associated component and fire
* hyperlink events on it when appropriate.
*/
public static class LinkController extends MouseAdapter implements MouseMotionListener, Serializable {
/**
* If true, the current element (curElem) represents an image.
*/
private boolean curElemImage = false;
/** This is used by viewToModel to avoid allocing a new array each
* time. */
/**
* Current offset.
*/
private int curOffset;
/**
* Called for a mouse click event.
* If the component is read-only (ie a browser) then
* the clicked event is used to drive an attempt to
* follow the reference specified by a link.
*
* @param e the mouse event
* @see MouseListener#mouseClicked
*/
if (pos >= 0) {
}
}
}
// ignore the drags
}
// track the moving of the mouse.
return;
}
boolean adjustCursor = true;
if (!editor.isEditable()) {
pos--;
}
}
curElemImage = false;
if (curElemImage) {
}
}
else {
}
}
// reference changed, fire event(s)
}
}
else {
adjustCursor = false;
}
}
else {
adjustCursor = false;
}
}
}
}
}
/**
* Returns a string anchor if the passed in element has a
* USEMAP that contains the passed in location.
*/
int x, int y) {
try {
} catch (BadLocationException ble) {
}
y - bounds.y,
HREF);
}
}
}
}
return null;
}
/**
* Returns true if the View representing <code>e</code> contains
* the location <code>x</code>, <code>y</code>. <code>offset</code>
* gives the offset into the Document to check for.
*/
int x, int y) {
try {
return false;
}
}
} catch (BadLocationException ble) {
}
}
return true;
}
/**
* Calls linkActivated on the associated JEditorPane
* if the given position represents a link.<p>This is implemented
* to forward to the method with the same name, but with the following
* args both == -1.
*
* @param pos the position
* @param editor the editor pane
*/
}
/**
* Calls linkActivated on the associated JEditorPane
* if the given position represents a link. If this was the result
* of a mouse click, <code>x</code> and
* <code>y</code> will give the location of the mouse, otherwise
* they will be < 0.
*
* @param pos the position
* @param html the editor pane
*/
if (doc instanceof HTMLDocument) {
AttributeSet a = e.getAttributes();
int x = -1;
int y = -1;
if (mouseEvent != null) {
x = mouseEvent.getX();
y = mouseEvent.getY();
}
}
else {
}
e, mouseEvent);
}
}
}
}
/**
* Creates and returns a new instance of HyperlinkEvent. If
* <code>hdoc</code> is a frame document a HTMLFrameHyperlinkEvent
* will be created.
*/
URL u;
try {
// Following is a workaround for 1.2, in which
// new URL("file://...", "#...") causes the filename to
// be lost.
}
}
} catch (MalformedURLException m) {
u = null;
}
if (!hdoc.isFrameDocument()) {
linkEvent = new HyperlinkEvent(
} else {
}
target = "_self";
}
linkEvent = new HTMLFrameHyperlinkEvent(
}
return linkEvent;
}
// fire an exited event on the old link
URL u;
try {
} catch (MalformedURLException m) {
u = null;
}
}
// fire an entered event on the new link
URL u;
try {
} catch (MalformedURLException m) {
u = null;
}
}
}
}
/**
* Interface to be supported by the parser. This enables
* providing a different parser while reusing some of the
* implementation provided by this editor kit.
*/
public static abstract class Parser {
/**
* Parse the given stream and drive the given callback
* with the results of the parse. This method should
* be implemented to be thread-safe.
*/
}
/**
* The result of parsing drives these callback methods.
* The open and close actions should be balanced. The
* <code>flush</code> method will be the last method
* called, to give the receiver a chance to flush any
* pending data into the document.
* <p>Refer to DocumentParser, the default parser used, for further
* information on the contents of the AttributeSets, the positions, and
* other info.
*
* @see javax.swing.text.html.parser.DocumentParser
*/
public static class ParserCallback {
/**
* This is passed as an attribute in the attributeset to indicate
* the element is implied eg, the string '<>foo<\t>'
* contains an implied html element and an implied body element.
*
* @since 1.3
*/
}
}
}
}
}
}
}
/**
* This is invoked after the stream has been parsed, but before
* <code>flush</code>. <code>eol</code> will be one of \n, \r
* or \r\n, which ever is encountered the most in parsing the
* stream.
*
* @since 1.3
*/
}
}
/**
* A factory to build views for HTML. The following
* table describes what this factory will build by
* default.
*
* <table summary="Describes the tag and view created by this factory by default">
* <tr>
* <th align=left>Tag<th align=left>View created
* </tr><tr>
* <td>HTML.Tag.CONTENT<td>InlineView
* </tr><tr>
* <td>HTML.Tag.IMPLIED<td>javax.swing.text.html.ParagraphView
* </tr><tr>
* <td>HTML.Tag.P<td>javax.swing.text.html.ParagraphView
* </tr><tr>
* <td>HTML.Tag.H1<td>javax.swing.text.html.ParagraphView
* </tr><tr>
* <td>HTML.Tag.H2<td>javax.swing.text.html.ParagraphView
* </tr><tr>
* <td>HTML.Tag.H3<td>javax.swing.text.html.ParagraphView
* </tr><tr>
* <td>HTML.Tag.H4<td>javax.swing.text.html.ParagraphView
* </tr><tr>
* <td>HTML.Tag.H5<td>javax.swing.text.html.ParagraphView
* </tr><tr>
* <td>HTML.Tag.H6<td>javax.swing.text.html.ParagraphView
* </tr><tr>
* <td>HTML.Tag.DT<td>javax.swing.text.html.ParagraphView
* </tr><tr>
* <td>HTML.Tag.MENU<td>ListView
* </tr><tr>
* <td>HTML.Tag.DIR<td>ListView
* </tr><tr>
* <td>HTML.Tag.UL<td>ListView
* </tr><tr>
* <td>HTML.Tag.OL<td>ListView
* </tr><tr>
* <td>HTML.Tag.LI<td>BlockView
* </tr><tr>
* <td>HTML.Tag.DL<td>BlockView
* </tr><tr>
* <td>HTML.Tag.DD<td>BlockView
* </tr><tr>
* <td>HTML.Tag.BODY<td>BlockView
* </tr><tr>
* <td>HTML.Tag.HTML<td>BlockView
* </tr><tr>
* <td>HTML.Tag.CENTER<td>BlockView
* </tr><tr>
* <td>HTML.Tag.DIV<td>BlockView
* </tr><tr>
* <td>HTML.Tag.BLOCKQUOTE<td>BlockView
* </tr><tr>
* <td>HTML.Tag.PRE<td>BlockView
* </tr><tr>
* <td>HTML.Tag.BLOCKQUOTE<td>BlockView
* </tr><tr>
* <td>HTML.Tag.PRE<td>BlockView
* </tr><tr>
* <td>HTML.Tag.IMG<td>ImageView
* </tr><tr>
* <td>HTML.Tag.HR<td>HRuleView
* </tr><tr>
* <td>HTML.Tag.BR<td>BRView
* </tr><tr>
* <td>HTML.Tag.TABLE<td>javax.swing.text.html.TableView
* </tr><tr>
* <td>HTML.Tag.INPUT<td>FormView
* </tr><tr>
* <td>HTML.Tag.SELECT<td>FormView
* </tr><tr>
* <td>HTML.Tag.TEXTAREA<td>FormView
* </tr><tr>
* <td>HTML.Tag.OBJECT<td>ObjectView
* </tr><tr>
* <td>HTML.Tag.FRAMESET<td>FrameSetView
* </tr><tr>
* <td>HTML.Tag.FRAME<td>FrameView
* </tr>
* </table>
*/
/**
* Creates a view from an element.
*
* @param elem the element
* @return the view
*/
return new InlineView(elem);
}
// paragraph
return new BodyBlockView(elem);
// vertical box
return new IsindexView(elem);
return new ObjectView(elem);
}
"no ROWS or COLS defined.");
return new HiddenTagView(elem);
return new CommentView(elem);
// Make the head never visible, and never load its
// children. For Cursor positioning,
// getNextVisualPositionFrom is overriden to always return
// the end offset of the element.
public float getPreferredSpan(int axis) {
return 0;
}
public float getMinimumSpan(int axis) {
return 0;
}
public float getMaximumSpan(int axis) {
return 0;
}
protected void loadChildren(ViewFactory f) {
}
return a;
}
public int getNextVisualPositionFrom(int pos,
return getElement().getEndOffset();
}
};
return new HiddenTagView(elem);
}
}
// If we get here, it's either an element we don't know about
// or something from StyledDocument that doesn't have a mapping to HTML.
return new ParagraphView(elem);
return new ComponentView(elem);
}
}
// default to text display
}
}
// reimplement major axis requirements to indicate that the
// block is flexible for the body element... so that it can
// be stretched to fill the background properly.
r = super.calculateMajorAxisRequirements(axis, r);
return r;
}
if (cachedViewPort != null) {
if (cachedObject != null) {
if (cachedObject != viewPort) {
}
} else {
}
}
if (cachedViewPort == null) {
viewPort.addComponentListener(this);
}
if (componentVisibleWidth > 0) {
//try to use viewVisibleWidth if it is smaller than targetSpan
}
} else {
if (cachedViewPort != null) {
if (cachedObject != null) {
}
}
}
}
//if parent == null unregister component listener
if (cachedViewPort != null) {
}
}
}
}
return;
}
if (doc instanceof AbstractDocument) {
try {
preferenceChanged(null, true, true);
} finally {
}
}
}
}
}
}
}
/*
* we keep weak reference to viewPort if and only if BodyBoxView is listening for ComponentEvents
* only in that case cachedViewPort is not equal to null.
* we need to keep this reference in order to remove BodyBoxView from viewPort listeners.
*
*/
private boolean isListening = false;
}
}
// --- Action implementations ------------------------------
/** The bold action identifier
*/
/** The italic action identifier
*/
/** The paragraph left indent action identifier
*/
/** The paragraph right indent action identifier
*/
/** The font size increase to next value action identifier
*/
/** The font size decrease to next value action identifier
*/
/** The Color choice action identifier
The color is passed as an argument
*/
/** The logical style choice action identifier
The logical style is passed in as an argument
*/
/**
* Align images at the top.
*/
/**
* Align images in the middle.
*/
/**
* Align images at the bottom.
*/
/**
* Align images at the border.
*/
/** HTML used when inserting tables. */
/** HTML used when inserting unordered lists. */
/** HTML used when inserting ordered lists. */
/** HTML used when inserting hr. */
/** HTML used when inserting pre. */
new NavigateLinkAction("next-link-action");
new NavigateLinkAction("previous-link-action");
new ActivateLinkAction("activate-link-action");
new InsertHRAction(),
new BeginAction(beginAction, false),
new BeginAction(selectionBeginAction, true)
};
// link navigation support
private boolean foundLink = false;
/**
* An abstract Action providing some convenience methods that may
* be useful in inserting HTML into an existing document.
* <p>NOTE: None of the convenience methods obtain a lock on the
* document. If you have another thread modifying the text these
* methods may have inconsistent behavior, or return the wrong thing.
*/
super(name);
}
/**
* @return HTMLDocument of <code>e</code>.
*/
Document d = e.getDocument();
if (d instanceof HTMLDocument) {
return (HTMLDocument) d;
}
throw new IllegalArgumentException("document must be HTMLDocument");
}
/**
* @return HTMLEditorKit for <code>e</code>.
*/
EditorKit k = e.getEditorKit();
if (k instanceof HTMLEditorKit) {
return (HTMLEditorKit) k;
}
throw new IllegalArgumentException("EditorKit must be HTMLEditorKit");
}
/**
* Returns an array of the Elements that contain <code>offset</code>.
* The first elements corresponds to the root.
*/
}
/**
* Recursive method used by getElementsAt.
*/
int depth) {
return retValue;
}
return retValue;
}
/**
* Returns number of elements, starting at the deepest leaf, needed
* to get to an element representing <code>tag</code>. This will
* return -1 if no elements is found representing <code>tag</code>,
* or 0 if the parent of the leaf at <code>offset</code> represents
* <code>tag</code>.
*/
int depth = -1;
e = e.getParentElement();
depth++;
}
if (e == null) {
return -1;
}
return depth;
}
/**
* Returns the deepest element at <code>offset</code> matching
* <code>tag</code>.
*/
while (e != null) {
if (e.getAttributes().getAttribute
lastMatch = e;
}
}
return lastMatch;
}
}
/**
* InsertHTMLTextAction can be used to insert an arbitrary string of HTML
* into an existing HTML document. At least two HTML.Tags need to be
* supplied. The first Tag, parentTag, identifies the parent in
* the document to add the elements to. The second tag, addTag,
* identifies the first tag that should be added to the document as
* seen in the HTML string. One important thing to remember, is that
* the parser is going to generate all the appropriate tags, even if
* they aren't in the HTML string passed in.<p>
* For example, lets say you wanted to create an action to insert
* a table into the body. The parentTag would be HTML.Tag.BODY,
* addTag would be HTML.Tag.TABLE, and the string could be something
* like <table><tr><td></td></tr></table>.
* <p>There is also an option to supply an alternate parentTag and
* addTag. These will be checked for if there is no parentTag at
* offset.
*/
}
alternateAddTag, true);
}
/* public */
boolean adjustSelection) {
super(name);
this.alternateParentTag = alternateParentTag;
this.alternateAddTag = alternateAddTag;
this.adjustSelection = adjustSelection;
}
/**
* A cover for HTMLEditorKit.insertHTML. If an exception it
* thrown it is wrapped in a RuntimeException and thrown.
*/
try {
addTag);
} catch (IOException ioe) {
} catch (BadLocationException ble) {
}
}
/**
* This is invoked when inserting at a boundary. It determines
* the number of pops, and then the number of pushes that need
* to be performed, and then invokes insertHTML.
* @since 1.3
*/
}
/**
* This is invoked when inserting at a boundary. It determines
* the number of pops, and then the number of pushes that need
* to be performed, and then invokes insertHTML.
* @deprecated As of Java 2 platform v1.3, use insertAtBoundary
*/
// Find the common parent.
Element e;
e = doc.getDefaultRootElement();
!e.isLeaf()) {
}
}
else {
// If inserting at the origin, the common parent is the
// insertElement.
}
if (commonParent != null) {
// Determine how many pops to do.
int pops = 0;
int pushes = 0;
e = commonParent;
pops++;
}
}
else {
e = commonParent;
offset--;
pops++;
}
// And how many pushes
e = commonParent;
offset++;
while (e != null && e != insertElement) {
pushes++;
}
}
// And insert!
}
}
/**
* If there is an Element with name <code>tag</code> at
* <code>offset</code>, this will invoke either insertAtBoundary
* or <code>insertHTML</code>. This returns true if there is
* a match, and one of the inserts is invoked.
*/
/*protected*/
return true;
}
else if (offset > 0) {
if (depth != -1) {
return true;
}
}
return false;
}
/**
* Called after an insertion to adjust the selection.
*/
/* protected */
int startOffset, int oldLength) {
if (startOffset > 0) {
try {
} catch (BadLocationException ble) {
}
}
else {
}
}
else {
}
}
}
/**
* Inserts the HTML into the document.
*
* @param ae the event
*/
boolean inserted;
// Try first choice
alternateParentTag != null) {
// Then alternate.
}
else {
inserted = true;
}
if (adjustSelection && inserted) {
}
}
}
/** HTML to insert. */
/** Tag to check for in the document. */
/** Tag in HTML to start adding tags from. */
/** Alternate Tag to check for in the document if parentTag is
* not found. */
/** Alternate tag in HTML to start adding tags from if parentTag
* is not found and alternateParentTag is found. */
/** True indicates the selection should be adjusted after an insert. */
boolean adjustSelection;
}
/**
* InsertHRAction is special, at actionPerformed time it will determine
* the parent HTML.Tag based on the paragraph element at the selection
* start.
*/
InsertHRAction() {
false);
}
/**
* Inserts the HTML into the document.
*
* @param ae the event
*/
super.actionPerformed(ae);
}
}
}
}
/*
* Returns the object in an AttributeSet matching a key
*/
while (names.hasMoreElements()) {
if (nextVal instanceof AttributeSet) {
return value;
}
return nextVal;
}
}
return null;
}
/*
* Action to move the focus on the next or previous hypertext link
* or object. TODO: This method relies on support from the
* javax.accessibility package. The text package should support
* keyboard navigation of text elements directly.
*/
new FocusHighlightPainter(null);
private final boolean focusBack;
/*
* Create this action with the appropriate identifier.
*/
super(actionName);
}
/**
* Called when the caret position is updated.
*
* @param e the caret event
*/
if (src instanceof JTextComponent) {
// TODO: The AccessibleContext for the editor should register
// as a listener for CaretEvents and forward the events to
// assistive technologies listening for such events.
}
}
}
/*
* The operation to perform when this action is triggered.
*/
return;
}
return;
}
// TODO: Should start successive iterations from the
// current caret position.
int prevStartOffset = -1;
int prevEndOffset = -1;
// highlight the next link or object after the current caret position
continue;
}
if (focusBack) {
if (elementOffset >= currentOffset &&
prevStartOffset >= 0) {
return;
}
} else { // focus forward
if (elementOffset > currentOffset) {
return;
}
}
}
}
}
/*
* Moves the caret from mark to dot
*/
if (h != null) {
try {
} else {
}
} catch (BadLocationException e) {
}
}
}
if (comp instanceof JEditorPane) {
if (kit instanceof HTMLEditorKit) {
return (HTMLEditorKit) kit;
}
}
return null;
}
/**
* A highlight painter that draws a one-pixel border around
* the highlighted area.
*/
static class FocusHighlightPainter extends
super(color);
}
/**
* Paints a portion of a highlight.
*
* @param g the graphics context
* @param offs0 the starting model offset >= 0
* @param offs1 the ending model offset >= offs1
* @param bounds the bounding box of the view, which is not
* necessarily the region to paint.
* @param c the editor
* @param view View painting for
* @return region in which drawing occurred
*/
g.setColor(c.getSelectionColor());
}
else {
}
// Contained in view, can just use bounds.
}
else {
}
return alloc;
}
else {
// Should only render part of View.
try {
// --- determine locations ---
bounds);
return r;
} catch (BadLocationException e) {
// can't render
}
}
// Only if exception
return null;
}
}
}
/*
* Action to activate the hypertext link that has focus.
* TODO: This method relies on support from the
* javax.accessibility package. The text package should support
* keyboard navigation of text elements directly.
*/
/**
* Create this action with the appropriate identifier.
*/
super(actionName);
}
/*
* activates the hyperlink at offset
*/
try {
} catch (MalformedURLException m) {
}
}
/*
* Invokes default action on the object in an element
*/
}
}
}
}
}
/*
* Returns the root view for a document
*/
}
/*
* Returns a view associated with an element
*/
try {
}
return null;
} finally {
}
}
return parent;
}
}
return null;
}
/*
* If possible acquires a lock on the Document. If a lock has been
* obtained a key will be retured that should be passed to
* <code>unlock</code>.
*/
if (document instanceof AbstractDocument) {
return document;
}
return null;
}
/*
* Releases a lock previously obtained via <code>lock</code>.
*/
}
}
/*
* The operation to perform when this action is triggered.
*/
JTextComponent c = getTextComponent(e);
if (c.isEditable() || !(c instanceof JEditorPane)) {
return;
}
if (d == null || !(d instanceof HTMLDocument)) {
return;
}
// invoke the next link or object action
return;
}
return;
}
}
}
}
}
}
return currElement.getStartOffset();
}
}
return 0;
}
/*
* Move the caret to the beginning of the document.
* @see DefaultEditorKit#beginAction
* @see HTMLEditorKit#getActions
*/
/* Create this object with the appropriate identifier. */
super(nm);
}
/** The operation to perform when this action is triggered. */
if (select) {
} else {
}
}
}
private boolean select;
}
}