Source code: com/hexidec/ekit/component/ExtendedHTMLDocument.java
1 /*
2 * @(#)HTMLDocument.java 1.148 02/04/09
3 *
4 * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
5 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6 */
7 package com.hexidec.ekit.component;
8
9 import java.awt.Color;
10 import java.awt.Component;
11 import java.util.*;
12 import java.net.URL;
13 import java.net.URLEncoder;
14 import java.net.MalformedURLException;
15 import java.io.*;
16 import javax.swing.*;
17 import javax.swing.event.*;
18 import javax.swing.text.*;
19 import javax.swing.undo.*;
20 import javax.swing.text.html.*;
21 import com.hexidec.ekit.component.ExtendedHTML;
22
23 /**
24 * A document that models HTML. The purpose of this model
25 * is to support both browsing and editing. As a result,
26 * the structure described by an HTML document is not
27 * exactly replicated by default. The element structure that
28 * is modeled by default, is built by the class
29 * <code>HTMLDocument.HTMLReader</code>, which implements
30 * the <code>HTMLEditorKit.ParserCallback</code> protocol
31 * that the parser expects. To change the structure one
32 * can subclass <code>HTMLReader</code>, and reimplement the method
33 * {@link #getReader(int)} to return the new reader
34 * implementation. The documentation for <code>HTMLReader</code>
35 * should be consulted for the details of
36 * the default structure created. The intent is that
37 * the document be non-lossy (although reproducing the
38 * HTML format may result in a different format).
39 * <p>
40 * The document models only HTML, and makes no attempt to
41 * store view attributes in it. The elements are identified
42 * by the <code>StyleContext.NameAttribute</code> attribute,
43 * which should always have a value of type <code>HTML.Tag</code>
44 * that identifies the kind of element. Some of the elements
45 * (such as comments) are synthesized. The <code>HTMLFactory</code>
46 * uses this attribute to determine what kind of view to build.
47 * <p>
48 * This document supports incremental loading. The
49 * <code>TokenThreshold</code> property controls how
50 * much of the parse is buffered before trying to update
51 * the element structure of the document. This property
52 * is set by the <code>EditorKit</code> so that subclasses can disable
53 * it.
54 * <p>
55 * The <code>Base</code> property determines the URL
56 * against which relative URLs are resolved.
57 * By default, this will be the
58 * <code>Document.StreamDescriptionProperty</code> if
59 * the value of the property is a URL. If a <BASE>
60 * tag is encountered, the base will become the URL specified
61 * by that tag. Because the base URL is a property, it
62 * can of course be set directly.
63 * <p>
64 * The default content storage mechanism for this document
65 * is a gap buffer (<code>GapContent</code>).
66 * Alternatives can be supplied by using the constructor
67 * that takes a <code>Content</code> implementation.
68 *
69 * @author Timothy Prinzing
70 * @author Scott Violet
71 * @author Sunita Mani
72 * @version 1.148 04/09/02
73 */
74 public class ExtendedHTMLDocument extends HTMLDocument {
75 /**
76 * Constructs an HTML document using the default buffer size
77 * and a default <code>StyleSheet</code>. This is a convenience
78 * method for the constructor
79 * <code>HTMLDocument(Content, StyleSheet)</code>.
80 */
81 public ExtendedHTMLDocument() {
82 super();
83 }
84
85 /**
86 * Constructs an HTML document with the default content
87 * storage implementation and the specified style/attribute
88 * storage mechanism. This is a convenience method for the
89 * constructor
90 * <code>HTMLDocument(Content, StyleSheet)</code>.
91 *
92 * @param styles the styles
93 */
94 public ExtendedHTMLDocument(StyleSheet styles) {
95 super(styles);
96 }
97
98 /**
99 * Constructs an HTML document with the given content
100 * storage implementation and the given style/attribute
101 * storage mechanism.
102 *
103 * @param c the container for the content
104 * @param styles the styles
105 */
106 public ExtendedHTMLDocument(Content c, StyleSheet styles) {
107 super(c, styles);
108 }
109
110
111
112 /**
113 * Fetches the reader for the parser to use when loading the document
114 * with HTML. This is implemented to return an instance of
115 * <code>HTMLDocument.HTMLReader</code>.
116 * Subclasses can reimplement this
117 * method to change how the document gets structured if desired.
118 * (For example, to handle custom tags, or structurally represent character
119 * style elements.)
120 *
121 * @param pos the starting position
122 * @return the reader used by the parser to load the document
123 */
124 public HTMLEditorKit.ParserCallback getReader(int pos) {
125 Object desc = getProperty(Document.StreamDescriptionProperty);
126 if (desc instanceof URL) {
127 setBase((URL)desc);
128 }
129 HTMLReader reader = new ExtendedHTMLReader(pos);
130 return reader;
131 }
132
133 /**
134 * Returns the reader for the parser to use to load the document
135 * with HTML. This is implemented to return an instance of
136 * <code>HTMLDocument.HTMLReader</code>.
137 * Subclasses can reimplement this
138 * method to change how the document gets structured if desired.
139 * (For example, to handle custom tags, or structurally represent character
140 * style elements.)
141 * <p>This is a convenience method for
142 * <code>getReader(int, int, int, HTML.Tag, TRUE)</code>.
143 *
144 * @param popDepth the number of <code>ElementSpec.EndTagTypes</code>
145 * to generate before inserting
146 * @param pushDepth the number of <code>ElementSpec.StartTagTypes</code>
147 * with a direction of <code>ElementSpec.JoinNextDirection</code>
148 * that should be generated before inserting,
149 * but after the end tags have been generated
150 * @param insertTag the first tag to start inserting into document
151 * @return the reader used by the parser to load the document
152 */
153 public HTMLEditorKit.ParserCallback getReader(int pos, int popDepth,
154 int pushDepth,
155 HTML.Tag insertTag) {
156 return getReader(pos, popDepth, pushDepth, insertTag, true);
157 }
158
159 /**
160 * Fetches the reader for the parser to use to load the document
161 * with HTML. This is implemented to return an instance of
162 * HTMLDocument.HTMLReader. Subclasses can reimplement this
163 * method to change how the document get structured if desired
164 * (e.g. to handle custom tags, structurally represent character
165 * style elements, etc.).
166 *
167 * @param popDepth the number of <code>ElementSpec.EndTagTypes</code>
168 * to generate before inserting
169 * @param pushDepth the number of <code>ElementSpec.StartTagTypes</code>
170 * with a direction of <code>ElementSpec.JoinNextDirection</code>
171 * that should be generated before inserting,
172 * but after the end tags have been generated
173 * @param insertTag the first tag to start inserting into document
174 * @param insertInsertTag false if all the Elements after insertTag should
175 * be inserted; otherwise insertTag will be inserted
176 * @return the reader used by the parser to load the document
177 */
178 HTMLEditorKit.ParserCallback getReader(int pos, int popDepth,
179 int pushDepth,
180 HTML.Tag insertTag,
181 boolean insertInsertTag) {
182 Object desc = getProperty(Document.StreamDescriptionProperty);
183 if (desc instanceof URL) {
184 setBase((URL)desc);
185 }
186 HTMLReader reader = new ExtendedHTMLReader(pos, popDepth, pushDepth,
187 insertTag, insertInsertTag, false,
188 true);
189 return reader;
190 }
191
192
193
194
195
196 public class ExtendedHTMLReader extends HTMLReader {
197
198 public ExtendedHTMLReader(int offset) {
199 super(offset);
200 }
201
202 public ExtendedHTMLReader(int offset, int popDepth, int pushDepth,
203 HTML.Tag insertTag) {
204 super(offset, popDepth, pushDepth, insertTag);
205 }
206
207
208 /**
209 * Generates a RuntimeException (will eventually generate
210 * a BadLocationException when API changes are alloced) if inserting
211 * into non empty document, <code>insertTag</code> is
212 * non-<code>null</code>, and <code>offset</code> is not in the body.
213 */
214 // PENDING(sky): Add throws BadLocationException and remove
215 // RuntimeException
216 ExtendedHTMLReader(int offset, int popDepth, int pushDepth,
217 HTML.Tag insertTag, boolean insertInsertTag,
218 boolean insertAfterImplied, boolean wantsTrailingNewline) {
219
220 super(offset, popDepth, pushDepth,insertTag);
221
222
223 TagAction na = new TagAction();
224 TagAction ba = new BlockAction();
225 TagAction pa = new ParagraphAction();
226 TagAction ca = new CharacterAction();
227 TagAction sa = new SpecialAction();
228 TagAction fa = new FormAction();
229 TagAction ha = new HiddenAction();
230
231
232 registerTag(HTML.Tag.DIV, pa);
233
234 // New tags to register
235 registerTag(ExtendedHTML.ExtendedTag.ATMLINX, ba);
236 registerTag(ExtendedHTML.ExtendedTag.DISPLAY,ba);
237 registerTag(ExtendedHTML.ExtendedTag.HTMLTEMPLATE,ba);
238 registerTag(ExtendedHTML.ExtendedTag.NODESPEC,ha);
239 registerTag(ExtendedHTML.ExtendedTag.SELECTION,ba);
240 registerTag(ExtendedHTML.ExtendedTag.STOP,ba);
241 registerTag(ExtendedHTML.ExtendedTag.START,ba);
242
243 }
244
245
246
247 // ---- tag handling support ------------------------------
248
249 /**
250 * Registers a handler for the given tag. By default
251 * all of the well-known tags will have been registered.
252 * This can be used to change the handling of a particular
253 * tag or to add support for custom tags.
254 */
255 public void registerTag(HTML.Tag t, TagAction a) {
256 super.registerTag(t, a);
257 }
258
259 }
260 }