author | prr |
Mon, 14 Nov 2016 09:59:36 -0800 | |
changeset 42216 | 621af0ebf6c4 |
parent 40719 | 4ae72a69bd3b |
child 45025 | 9ad3afa82b5e |
permissions | -rw-r--r-- |
2 | 1 |
/* |
22567
5816a47fa4dd
8032047: Fix static lint warnings in client libraries
darcy
parents:
21982
diff
changeset
|
2 |
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
package javax.swing.text.html; |
|
26 |
||
6862 | 27 |
import sun.awt.AppContext; |
28 |
||
2 | 29 |
import java.awt.*; |
30 |
import java.awt.event.*; |
|
31 |
import java.io.*; |
|
32 |
import java.net.MalformedURLException; |
|
33 |
import java.net.URL; |
|
34 |
import javax.swing.text.*; |
|
35 |
import javax.swing.*; |
|
36 |
import javax.swing.event.*; |
|
37 |
import javax.swing.plaf.TextUI; |
|
38 |
import java.util.*; |
|
39 |
import javax.accessibility.*; |
|
40 |
import java.lang.ref.*; |
|
24157
84ccec128c31
8038962: KSS: javax.swing.text.html[.parser].ResourceLoader
malenkov
parents:
23697
diff
changeset
|
41 |
import java.security.AccessController; |
84ccec128c31
8038962: KSS: javax.swing.text.html[.parser].ResourceLoader
malenkov
parents:
23697
diff
changeset
|
42 |
import java.security.PrivilegedAction; |
40719
4ae72a69bd3b
8129854: Remove reflection from AWT/Swing classes
alexsch
parents:
32865
diff
changeset
|
43 |
import javax.swing.text.html.parser.ParserDelegator; |
2 | 44 |
|
45 |
/** |
|
46 |
* The Swing JEditorPane text component supports different kinds |
|
47 |
* of content via a plug-in mechanism called an EditorKit. Because |
|
48 |
* HTML is a very popular format of content, some support is provided |
|
49 |
* by default. The default support is provided by this class, which |
|
50 |
* supports HTML version 3.2 (with some extensions), and is migrating |
|
51 |
* toward version 4.0. |
|
52 |
* The <applet> tag is not supported, but some support is provided |
|
53 |
* for the <object> tag. |
|
54 |
* <p> |
|
55 |
* There are several goals of the HTML EditorKit provided, that have |
|
56 |
* an effect upon the way that HTML is modeled. These |
|
57 |
* have influenced its design in a substantial way. |
|
58 |
* <dl> |
|
59 |
* <dt> |
|
60 |
* Support editing |
|
61 |
* <dd> |
|
62 |
* It might seem fairly obvious that a plug-in for JEditorPane |
|
63 |
* should provide editing support, but that fact has several |
|
64 |
* design considerations. There are a substantial number of HTML |
|
65 |
* documents that don't properly conform to an HTML specification. |
|
66 |
* These must be normalized somewhat into a correct form if one |
|
67 |
* is to edit them. Additionally, users don't like to be presented |
|
68 |
* with an excessive amount of structure editing, so using traditional |
|
69 |
* text editing gestures is preferred over using the HTML structure |
|
70 |
* exactly as defined in the HTML document. |
|
71 |
* <p> |
|
72 |
* The modeling of HTML is provided by the class <code>HTMLDocument</code>. |
|
21278 | 73 |
* Its documentation describes the details of how the HTML is modeled. |
2 | 74 |
* The editing support leverages heavily off of the text package. |
21982 | 75 |
* |
2 | 76 |
* <dt> |
77 |
* Extendable/Scalable |
|
78 |
* <dd> |
|
79 |
* To maximize the usefulness of this kit, a great deal of effort |
|
80 |
* has gone into making it extendable. These are some of the |
|
81 |
* features. |
|
82 |
* <ol> |
|
83 |
* <li> |
|
21278 | 84 |
* The parser is replaceable. The default parser is the Hot Java |
2 | 85 |
* parser which is DTD based. A different DTD can be used, or an |
86 |
* entirely different parser can be used. To change the parser, |
|
87 |
* reimplement the getParser method. The default parser is |
|
88 |
* dynamically loaded when first asked for, so the class files |
|
89 |
* will never be loaded if an alternative parser is used. The |
|
90 |
* default parser is in a separate package called parser below |
|
91 |
* this package. |
|
92 |
* <li> |
|
93 |
* The parser drives the ParserCallback, which is provided by |
|
94 |
* HTMLDocument. To change the callback, subclass HTMLDocument |
|
95 |
* and reimplement the createDefaultDocument method to return |
|
96 |
* document that produces a different reader. The reader controls |
|
97 |
* how the document is structured. Although the Document provides |
|
98 |
* HTML support by default, there is nothing preventing support of |
|
99 |
* non-HTML tags that result in alternative element structures. |
|
100 |
* <li> |
|
101 |
* The default view of the models are provided as a hierarchy of |
|
102 |
* View implementations, so one can easily customize how a particular |
|
103 |
* element is displayed or add capabilities for new kinds of elements |
|
104 |
* by providing new View implementations. The default set of views |
|
105 |
* are provided by the <code>HTMLFactory</code> class. This can |
|
106 |
* be easily changed by subclassing or replacing the HTMLFactory |
|
107 |
* and reimplementing the getViewFactory method to return the alternative |
|
108 |
* factory. |
|
109 |
* <li> |
|
110 |
* The View implementations work primarily off of CSS attributes, |
|
111 |
* which are kept in the views. This makes it possible to have |
|
112 |
* multiple views mapped over the same model that appear substantially |
|
113 |
* different. This can be especially useful for printing. For |
|
114 |
* most HTML attributes, the HTML attributes are converted to CSS |
|
115 |
* attributes for display. This helps make the View implementations |
|
116 |
* more general purpose |
|
117 |
* </ol> |
|
21982 | 118 |
* |
2 | 119 |
* <dt> |
120 |
* Asynchronous Loading |
|
121 |
* <dd> |
|
122 |
* Larger documents involve a lot of parsing and take some time |
|
123 |
* to load. By default, this kit produces documents that will be |
|
124 |
* loaded asynchronously if loaded using <code>JEditorPane.setPage</code>. |
|
125 |
* This is controlled by a property on the document. The method |
|
7959 | 126 |
* {@link #createDefaultDocument createDefaultDocument} can |
2 | 127 |
* be overriden to change this. The batching of work is done |
128 |
* by the <code>HTMLDocument.HTMLReader</code> class. The actual |
|
129 |
* work is done by the <code>DefaultStyledDocument</code> and |
|
130 |
* <code>AbstractDocument</code> classes in the text package. |
|
21982 | 131 |
* |
2 | 132 |
* <dt> |
133 |
* Customization from current LAF |
|
134 |
* <dd> |
|
135 |
* HTML provides a well known set of features without exactly |
|
136 |
* specifying the display characteristics. Swing has a theme |
|
137 |
* mechanism for its look-and-feel implementations. It is desirable |
|
138 |
* for the look-and-feel to feed display characteristics into the |
|
139 |
* HTML views. An user with poor vision for example would want |
|
140 |
* high contrast and larger than typical fonts. |
|
141 |
* <p> |
|
142 |
* The support for this is provided by the <code>StyleSheet</code> |
|
143 |
* class. The presentation of the HTML can be heavily influenced |
|
144 |
* by the setting of the StyleSheet property on the EditorKit. |
|
21982 | 145 |
* |
2 | 146 |
* <dt> |
147 |
* Not lossy |
|
148 |
* <dd> |
|
149 |
* An EditorKit has the ability to be read and save documents. |
|
150 |
* It is generally the most pleasing to users if there is no loss |
|
151 |
* of data between the two operation. The policy of the HTMLEditorKit |
|
152 |
* will be to store things not recognized or not necessarily visible |
|
153 |
* so they can be subsequently written out. The model of the HTML document |
|
154 |
* should therefore contain all information discovered while reading the |
|
155 |
* document. This is constrained in some ways by the need to support |
|
156 |
* editing (i.e. incorrect documents sometimes must be normalized). |
|
157 |
* The guiding principle is that information shouldn't be lost, but |
|
158 |
* some might be synthesized to produce a more correct model or it might |
|
159 |
* be rearranged. |
|
160 |
* </dl> |
|
161 |
* |
|
162 |
* @author Timothy Prinzing |
|
163 |
*/ |
|
23697 | 164 |
@SuppressWarnings("serial") // Same-version serialization only |
2 | 165 |
public class HTMLEditorKit extends StyledEditorKit implements Accessible { |
166 |
||
167 |
private JEditorPane theEditor; |
|
168 |
||
169 |
/** |
|
170 |
* Constructs an HTMLEditorKit, creates a StyleContext, |
|
171 |
* and loads the style sheet. |
|
172 |
*/ |
|
173 |
public HTMLEditorKit() { |
|
174 |
||
175 |
} |
|
176 |
||
177 |
/** |
|
178 |
* Get the MIME type of the data that this |
|
179 |
* kit represents support for. This kit supports |
|
180 |
* the type <code>text/html</code>. |
|
181 |
* |
|
182 |
* @return the type |
|
183 |
*/ |
|
184 |
public String getContentType() { |
|
185 |
return "text/html"; |
|
186 |
} |
|
187 |
||
188 |
/** |
|
189 |
* Fetch a factory that is suitable for producing |
|
190 |
* views of any models that are produced by this |
|
191 |
* kit. |
|
192 |
* |
|
193 |
* @return the factory |
|
194 |
*/ |
|
195 |
public ViewFactory getViewFactory() { |
|
196 |
return defaultFactory; |
|
197 |
} |
|
198 |
||
199 |
/** |
|
200 |
* Create an uninitialized text storage model |
|
201 |
* that is appropriate for this type of editor. |
|
202 |
* |
|
203 |
* @return the model |
|
204 |
*/ |
|
205 |
public Document createDefaultDocument() { |
|
206 |
StyleSheet styles = getStyleSheet(); |
|
207 |
StyleSheet ss = new StyleSheet(); |
|
208 |
||
209 |
ss.addStyleSheet(styles); |
|
210 |
||
211 |
HTMLDocument doc = new HTMLDocument(ss); |
|
212 |
doc.setParser(getParser()); |
|
213 |
doc.setAsynchronousLoadPriority(4); |
|
214 |
doc.setTokenThreshold(100); |
|
215 |
return doc; |
|
216 |
} |
|
217 |
||
218 |
/** |
|
219 |
* Try to get an HTML parser from the document. If no parser is set for |
|
220 |
* the document, return the editor kit's default parser. It is an error |
|
221 |
* if no parser could be obtained from the editor kit. |
|
222 |
*/ |
|
223 |
private Parser ensureParser(HTMLDocument doc) throws IOException { |
|
224 |
Parser p = doc.getParser(); |
|
225 |
if (p == null) { |
|
226 |
p = getParser(); |
|
227 |
} |
|
228 |
if (p == null) { |
|
229 |
throw new IOException("Can't load parser"); |
|
230 |
} |
|
231 |
return p; |
|
232 |
} |
|
233 |
||
234 |
/** |
|
235 |
* Inserts content from the given stream. If <code>doc</code> is |
|
236 |
* an instance of HTMLDocument, this will read |
|
237 |
* HTML 3.2 text. Inserting HTML into a non-empty document must be inside |
|
238 |
* the body Element, if you do not insert into the body an exception will |
|
239 |
* be thrown. When inserting into a non-empty document all tags outside |
|
240 |
* of the body (head, title) will be dropped. |
|
241 |
* |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
242 |
* @param in the stream to read from |
2 | 243 |
* @param doc the destination for the insertion |
244 |
* @param pos the location in the document to place the |
|
245 |
* content |
|
246 |
* @exception IOException on any I/O error |
|
247 |
* @exception BadLocationException if pos represents an invalid |
|
248 |
* location within the document |
|
249 |
* @exception RuntimeException (will eventually be a BadLocationException) |
|
250 |
* if pos is invalid |
|
251 |
*/ |
|
252 |
public void read(Reader in, Document doc, int pos) throws IOException, BadLocationException { |
|
253 |
||
254 |
if (doc instanceof HTMLDocument) { |
|
255 |
HTMLDocument hdoc = (HTMLDocument) doc; |
|
256 |
if (pos > doc.getLength()) { |
|
257 |
throw new BadLocationException("Invalid location", pos); |
|
258 |
} |
|
259 |
||
260 |
Parser p = ensureParser(hdoc); |
|
261 |
ParserCallback receiver = hdoc.getReader(pos); |
|
262 |
Boolean ignoreCharset = (Boolean)doc.getProperty("IgnoreCharsetDirective"); |
|
263 |
p.parse(in, receiver, (ignoreCharset == null) ? false : ignoreCharset.booleanValue()); |
|
264 |
receiver.flush(); |
|
265 |
} else { |
|
266 |
super.read(in, doc, pos); |
|
267 |
} |
|
268 |
} |
|
269 |
||
270 |
/** |
|
271 |
* Inserts HTML into an existing document. |
|
272 |
* |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
273 |
* @param doc the document to insert into |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
274 |
* @param offset the offset to insert HTML at |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
275 |
* @param popDepth the number of ElementSpec.EndTagTypes to generate |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
276 |
* before inserting |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
277 |
* @param html the HTML string |
2 | 278 |
* @param pushDepth the number of ElementSpec.StartTagTypes with a direction |
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
279 |
* of ElementSpec.JoinNextDirection that should be generated |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
280 |
* before inserting, but after the end tags have been generated |
2 | 281 |
* @param insertTag the first tag to start inserting into document |
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
282 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
283 |
* @throws BadLocationException if {@code offset} is invalid |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
284 |
* @throws IOException on I/O error |
2 | 285 |
* @exception RuntimeException (will eventually be a BadLocationException) |
286 |
* if pos is invalid |
|
287 |
*/ |
|
288 |
public void insertHTML(HTMLDocument doc, int offset, String html, |
|
289 |
int popDepth, int pushDepth, |
|
290 |
HTML.Tag insertTag) throws |
|
291 |
BadLocationException, IOException { |
|
292 |
if (offset > doc.getLength()) { |
|
293 |
throw new BadLocationException("Invalid location", offset); |
|
294 |
} |
|
295 |
||
296 |
Parser p = ensureParser(doc); |
|
297 |
ParserCallback receiver = doc.getReader(offset, popDepth, pushDepth, |
|
298 |
insertTag); |
|
299 |
Boolean ignoreCharset = (Boolean)doc.getProperty |
|
300 |
("IgnoreCharsetDirective"); |
|
301 |
p.parse(new StringReader(html), receiver, (ignoreCharset == null) ? |
|
302 |
false : ignoreCharset.booleanValue()); |
|
303 |
receiver.flush(); |
|
304 |
} |
|
305 |
||
306 |
/** |
|
307 |
* Write content from a document to the given stream |
|
308 |
* in a format appropriate for this kind of content handler. |
|
309 |
* |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
310 |
* @param out the stream to write to |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
311 |
* @param doc the source for the write |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
312 |
* @param pos the location in the document to fetch the |
2 | 313 |
* content |
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
314 |
* @param len the amount to write out |
2 | 315 |
* @exception IOException on any I/O error |
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
316 |
* @exception BadLocationException if {@code pos} represents an invalid |
2 | 317 |
* location within the document |
318 |
*/ |
|
319 |
public void write(Writer out, Document doc, int pos, int len) |
|
320 |
throws IOException, BadLocationException { |
|
321 |
||
322 |
if (doc instanceof HTMLDocument) { |
|
323 |
HTMLWriter w = new HTMLWriter(out, (HTMLDocument)doc, pos, len); |
|
324 |
w.write(); |
|
325 |
} else if (doc instanceof StyledDocument) { |
|
326 |
MinimalHTMLWriter w = new MinimalHTMLWriter(out, (StyledDocument)doc, pos, len); |
|
327 |
w.write(); |
|
328 |
} else { |
|
329 |
super.write(out, doc, pos, len); |
|
330 |
} |
|
331 |
} |
|
332 |
||
333 |
/** |
|
334 |
* Called when the kit is being installed into the |
|
335 |
* a JEditorPane. |
|
336 |
* |
|
337 |
* @param c the JEditorPane |
|
338 |
*/ |
|
339 |
public void install(JEditorPane c) { |
|
340 |
c.addMouseListener(linkHandler); |
|
341 |
c.addMouseMotionListener(linkHandler); |
|
342 |
c.addCaretListener(nextLinkAction); |
|
343 |
super.install(c); |
|
344 |
theEditor = c; |
|
345 |
} |
|
346 |
||
347 |
/** |
|
348 |
* Called when the kit is being removed from the |
|
349 |
* JEditorPane. This is used to unregister any |
|
350 |
* listeners that were attached. |
|
351 |
* |
|
352 |
* @param c the JEditorPane |
|
353 |
*/ |
|
354 |
public void deinstall(JEditorPane c) { |
|
355 |
c.removeMouseListener(linkHandler); |
|
356 |
c.removeMouseMotionListener(linkHandler); |
|
357 |
c.removeCaretListener(nextLinkAction); |
|
358 |
super.deinstall(c); |
|
359 |
theEditor = null; |
|
360 |
} |
|
361 |
||
362 |
/** |
|
363 |
* Default Cascading Style Sheet file that sets |
|
364 |
* up the tag views. |
|
365 |
*/ |
|
366 |
public static final String DEFAULT_CSS = "default.css"; |
|
367 |
||
368 |
/** |
|
369 |
* Set the set of styles to be used to render the various |
|
370 |
* HTML elements. These styles are specified in terms of |
|
371 |
* CSS specifications. Each document produced by the kit |
|
372 |
* will have a copy of the sheet which it can add the |
|
373 |
* document specific styles to. By default, the StyleSheet |
|
374 |
* specified is shared by all HTMLEditorKit instances. |
|
375 |
* This should be reimplemented to provide a finer granularity |
|
376 |
* if desired. |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
377 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
378 |
* @param s a StyleSheet |
2 | 379 |
*/ |
380 |
public void setStyleSheet(StyleSheet s) { |
|
6862 | 381 |
if (s == null) { |
382 |
AppContext.getAppContext().remove(DEFAULT_STYLES_KEY); |
|
383 |
} else { |
|
384 |
AppContext.getAppContext().put(DEFAULT_STYLES_KEY, s); |
|
385 |
} |
|
2 | 386 |
} |
387 |
||
388 |
/** |
|
389 |
* Get the set of styles currently being used to render the |
|
390 |
* HTML elements. By default the resource specified by |
|
391 |
* DEFAULT_CSS gets loaded, and is shared by all HTMLEditorKit |
|
392 |
* instances. |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
393 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
394 |
* @return the StyleSheet |
2 | 395 |
*/ |
396 |
public StyleSheet getStyleSheet() { |
|
6862 | 397 |
AppContext appContext = AppContext.getAppContext(); |
398 |
StyleSheet defaultStyles = (StyleSheet) appContext.get(DEFAULT_STYLES_KEY); |
|
399 |
||
2 | 400 |
if (defaultStyles == null) { |
401 |
defaultStyles = new StyleSheet(); |
|
6862 | 402 |
appContext.put(DEFAULT_STYLES_KEY, defaultStyles); |
2 | 403 |
try { |
404 |
InputStream is = HTMLEditorKit.getResourceAsStream(DEFAULT_CSS); |
|
405 |
Reader r = new BufferedReader( |
|
406 |
new InputStreamReader(is, "ISO-8859-1")); |
|
407 |
defaultStyles.loadRules(r, null); |
|
408 |
r.close(); |
|
409 |
} catch (Throwable e) { |
|
410 |
// on error we simply have no styles... the html |
|
411 |
// will look mighty wrong but still function. |
|
412 |
} |
|
413 |
} |
|
414 |
return defaultStyles; |
|
415 |
} |
|
416 |
||
417 |
/** |
|
418 |
* Fetch a resource relative to the HTMLEditorKit classfile. |
|
419 |
* If this is called on 1.2 the loading will occur under the |
|
420 |
* protection of a doPrivileged call to allow the HTMLEditorKit |
|
421 |
* to function when used in an applet. |
|
422 |
* |
|
423 |
* @param name the name of the resource, relative to the |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
424 |
* HTMLEditorKit class |
2 | 425 |
* @return a stream representing the resource |
426 |
*/ |
|
24157
84ccec128c31
8038962: KSS: javax.swing.text.html[.parser].ResourceLoader
malenkov
parents:
23697
diff
changeset
|
427 |
static InputStream getResourceAsStream(final String name) { |
84ccec128c31
8038962: KSS: javax.swing.text.html[.parser].ResourceLoader
malenkov
parents:
23697
diff
changeset
|
428 |
return AccessController.doPrivileged( |
84ccec128c31
8038962: KSS: javax.swing.text.html[.parser].ResourceLoader
malenkov
parents:
23697
diff
changeset
|
429 |
new PrivilegedAction<InputStream>() { |
84ccec128c31
8038962: KSS: javax.swing.text.html[.parser].ResourceLoader
malenkov
parents:
23697
diff
changeset
|
430 |
public InputStream run() { |
84ccec128c31
8038962: KSS: javax.swing.text.html[.parser].ResourceLoader
malenkov
parents:
23697
diff
changeset
|
431 |
return HTMLEditorKit.class.getResourceAsStream(name); |
84ccec128c31
8038962: KSS: javax.swing.text.html[.parser].ResourceLoader
malenkov
parents:
23697
diff
changeset
|
432 |
} |
84ccec128c31
8038962: KSS: javax.swing.text.html[.parser].ResourceLoader
malenkov
parents:
23697
diff
changeset
|
433 |
}); |
2 | 434 |
} |
435 |
||
436 |
/** |
|
437 |
* Fetches the command list for the editor. This is |
|
438 |
* the list of commands supported by the superclass |
|
439 |
* augmented by the collection of commands defined |
|
440 |
* locally for style operations. |
|
441 |
* |
|
442 |
* @return the command list |
|
443 |
*/ |
|
444 |
public Action[] getActions() { |
|
22567
5816a47fa4dd
8032047: Fix static lint warnings in client libraries
darcy
parents:
21982
diff
changeset
|
445 |
return TextAction.augmentList(super.getActions(), defaultActions); |
2 | 446 |
} |
447 |
||
448 |
/** |
|
449 |
* Copies the key/values in <code>element</code>s AttributeSet into |
|
450 |
* <code>set</code>. This does not copy component, icon, or element |
|
451 |
* names attributes. Subclasses may wish to refine what is and what |
|
452 |
* isn't copied here. But be sure to first remove all the attributes that |
|
453 |
* are in <code>set</code>.<p> |
|
454 |
* This is called anytime the caret moves over a different location. |
|
455 |
* |
|
456 |
*/ |
|
457 |
protected void createInputAttributes(Element element, |
|
458 |
MutableAttributeSet set) { |
|
459 |
set.removeAttributes(set); |
|
460 |
set.addAttributes(element.getAttributes()); |
|
461 |
set.removeAttribute(StyleConstants.ComposedTextAttribute); |
|
462 |
||
463 |
Object o = set.getAttribute(StyleConstants.NameAttribute); |
|
464 |
if (o instanceof HTML.Tag) { |
|
465 |
HTML.Tag tag = (HTML.Tag)o; |
|
466 |
// PENDING: we need a better way to express what shouldn't be |
|
467 |
// copied when editing... |
|
468 |
if(tag == HTML.Tag.IMG) { |
|
469 |
// Remove the related image attributes, src, width, height |
|
470 |
set.removeAttribute(HTML.Attribute.SRC); |
|
471 |
set.removeAttribute(HTML.Attribute.HEIGHT); |
|
472 |
set.removeAttribute(HTML.Attribute.WIDTH); |
|
473 |
set.addAttribute(StyleConstants.NameAttribute, |
|
474 |
HTML.Tag.CONTENT); |
|
475 |
} |
|
476 |
else if (tag == HTML.Tag.HR || tag == HTML.Tag.BR) { |
|
477 |
// Don't copy HRs or BRs either. |
|
478 |
set.addAttribute(StyleConstants.NameAttribute, |
|
479 |
HTML.Tag.CONTENT); |
|
480 |
} |
|
481 |
else if (tag == HTML.Tag.COMMENT) { |
|
482 |
// Don't copy COMMENTs either |
|
483 |
set.addAttribute(StyleConstants.NameAttribute, |
|
484 |
HTML.Tag.CONTENT); |
|
485 |
set.removeAttribute(HTML.Attribute.COMMENT); |
|
486 |
} |
|
487 |
else if (tag == HTML.Tag.INPUT) { |
|
488 |
// or INPUT either |
|
489 |
set.addAttribute(StyleConstants.NameAttribute, |
|
490 |
HTML.Tag.CONTENT); |
|
491 |
set.removeAttribute(HTML.Tag.INPUT); |
|
492 |
} |
|
493 |
else if (tag instanceof HTML.UnknownTag) { |
|
494 |
// Don't copy unknowns either:( |
|
495 |
set.addAttribute(StyleConstants.NameAttribute, |
|
496 |
HTML.Tag.CONTENT); |
|
497 |
set.removeAttribute(HTML.Attribute.ENDTAG); |
|
498 |
} |
|
499 |
} |
|
500 |
} |
|
501 |
||
502 |
/** |
|
503 |
* Gets the input attributes used for the styled |
|
504 |
* editing actions. |
|
505 |
* |
|
506 |
* @return the attribute set |
|
507 |
*/ |
|
508 |
public MutableAttributeSet getInputAttributes() { |
|
509 |
if (input == null) { |
|
510 |
input = getStyleSheet().addStyle(null, null); |
|
511 |
} |
|
512 |
return input; |
|
513 |
} |
|
514 |
||
515 |
/** |
|
516 |
* Sets the default cursor. |
|
517 |
* |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
518 |
* @param cursor a cursor |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
519 |
* |
2 | 520 |
* @since 1.3 |
521 |
*/ |
|
522 |
public void setDefaultCursor(Cursor cursor) { |
|
523 |
defaultCursor = cursor; |
|
524 |
} |
|
525 |
||
526 |
/** |
|
527 |
* Returns the default cursor. |
|
528 |
* |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
529 |
* @return the cursor |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
530 |
* |
2 | 531 |
* @since 1.3 |
532 |
*/ |
|
533 |
public Cursor getDefaultCursor() { |
|
534 |
return defaultCursor; |
|
535 |
} |
|
536 |
||
537 |
/** |
|
538 |
* Sets the cursor to use over links. |
|
539 |
* |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
540 |
* @param cursor a cursor |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
541 |
* |
2 | 542 |
* @since 1.3 |
543 |
*/ |
|
544 |
public void setLinkCursor(Cursor cursor) { |
|
545 |
linkCursor = cursor; |
|
546 |
} |
|
547 |
||
548 |
/** |
|
549 |
* Returns the cursor to use over hyper links. |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
550 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
551 |
* @return the cursor |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
552 |
* |
2 | 553 |
* @since 1.3 |
554 |
*/ |
|
555 |
public Cursor getLinkCursor() { |
|
556 |
return linkCursor; |
|
557 |
} |
|
558 |
||
559 |
/** |
|
560 |
* Indicates whether an html form submission is processed automatically |
|
561 |
* or only <code>FormSubmitEvent</code> is fired. |
|
562 |
* |
|
563 |
* @return true if html form submission is processed automatically, |
|
564 |
* false otherwise. |
|
565 |
* |
|
566 |
* @see #setAutoFormSubmission |
|
567 |
* @since 1.5 |
|
568 |
*/ |
|
569 |
public boolean isAutoFormSubmission() { |
|
570 |
return isAutoFormSubmission; |
|
571 |
} |
|
572 |
||
573 |
/** |
|
574 |
* Specifies if an html form submission is processed |
|
575 |
* automatically or only <code>FormSubmitEvent</code> is fired. |
|
576 |
* By default it is set to true. |
|
577 |
* |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
578 |
* @param isAuto if {@code true}, html form submission is processed automatically. |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
579 |
* |
7959 | 580 |
* @see #isAutoFormSubmission() |
2 | 581 |
* @see FormSubmitEvent |
582 |
* @since 1.5 |
|
583 |
*/ |
|
584 |
public void setAutoFormSubmission(boolean isAuto) { |
|
585 |
isAutoFormSubmission = isAuto; |
|
586 |
} |
|
587 |
||
588 |
/** |
|
589 |
* Creates a copy of the editor kit. |
|
590 |
* |
|
591 |
* @return the copy |
|
592 |
*/ |
|
593 |
public Object clone() { |
|
594 |
HTMLEditorKit o = (HTMLEditorKit)super.clone(); |
|
595 |
if (o != null) { |
|
596 |
o.input = null; |
|
597 |
o.linkHandler = new LinkController(); |
|
598 |
} |
|
599 |
return o; |
|
600 |
} |
|
601 |
||
602 |
/** |
|
603 |
* Fetch the parser to use for reading HTML streams. |
|
604 |
* This can be reimplemented to provide a different |
|
605 |
* parser. The default implementation is loaded dynamically |
|
606 |
* to avoid the overhead of loading the default parser if |
|
607 |
* it's not used. The default parser is the HotJava parser |
|
608 |
* using an HTML 3.2 DTD. |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
609 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
610 |
* @return the parser |
2 | 611 |
*/ |
612 |
protected Parser getParser() { |
|
613 |
if (defaultParser == null) { |
|
40719
4ae72a69bd3b
8129854: Remove reflection from AWT/Swing classes
alexsch
parents:
32865
diff
changeset
|
614 |
defaultParser = new ParserDelegator(); |
2 | 615 |
} |
616 |
return defaultParser; |
|
617 |
} |
|
618 |
||
619 |
// ----- Accessibility support ----- |
|
620 |
private AccessibleContext accessibleContext; |
|
621 |
||
622 |
/** |
|
623 |
* returns the AccessibleContext associated with this editor kit |
|
624 |
* |
|
625 |
* @return the AccessibleContext associated with this editor kit |
|
626 |
* @since 1.4 |
|
627 |
*/ |
|
628 |
public AccessibleContext getAccessibleContext() { |
|
629 |
if (theEditor == null) { |
|
630 |
return null; |
|
631 |
} |
|
632 |
if (accessibleContext == null) { |
|
633 |
AccessibleHTML a = new AccessibleHTML(theEditor); |
|
634 |
accessibleContext = a.getAccessibleContext(); |
|
635 |
} |
|
636 |
return accessibleContext; |
|
637 |
} |
|
638 |
||
639 |
// --- variables ------------------------------------------ |
|
640 |
||
641 |
private static final Cursor MoveCursor = Cursor.getPredefinedCursor |
|
642 |
(Cursor.HAND_CURSOR); |
|
643 |
private static final Cursor DefaultCursor = Cursor.getPredefinedCursor |
|
644 |
(Cursor.DEFAULT_CURSOR); |
|
645 |
||
646 |
/** Shared factory for creating HTML Views. */ |
|
647 |
private static final ViewFactory defaultFactory = new HTMLFactory(); |
|
648 |
||
649 |
MutableAttributeSet input; |
|
6862 | 650 |
private static final Object DEFAULT_STYLES_KEY = new Object(); |
2 | 651 |
private LinkController linkHandler = new LinkController(); |
652 |
private static Parser defaultParser = null; |
|
653 |
private Cursor defaultCursor = DefaultCursor; |
|
654 |
private Cursor linkCursor = MoveCursor; |
|
655 |
private boolean isAutoFormSubmission = true; |
|
656 |
||
657 |
/** |
|
658 |
* Class to watch the associated component and fire |
|
659 |
* hyperlink events on it when appropriate. |
|
660 |
*/ |
|
23697 | 661 |
@SuppressWarnings("serial") // Same-version serialization only |
2 | 662 |
public static class LinkController extends MouseAdapter implements MouseMotionListener, Serializable { |
663 |
private Element curElem = null; |
|
664 |
/** |
|
665 |
* If true, the current element (curElem) represents an image. |
|
666 |
*/ |
|
667 |
private boolean curElemImage = false; |
|
668 |
private String href = null; |
|
669 |
/** This is used by viewToModel to avoid allocing a new array each |
|
670 |
* time. */ |
|
671 |
private transient Position.Bias[] bias = new Position.Bias[1]; |
|
672 |
/** |
|
673 |
* Current offset. |
|
674 |
*/ |
|
675 |
private int curOffset; |
|
676 |
||
677 |
/** |
|
678 |
* Called for a mouse click event. |
|
679 |
* If the component is read-only (ie a browser) then |
|
680 |
* the clicked event is used to drive an attempt to |
|
681 |
* follow the reference specified by a link. |
|
682 |
* |
|
683 |
* @param e the mouse event |
|
684 |
* @see MouseListener#mouseClicked |
|
685 |
*/ |
|
42216
621af0ebf6c4
8169518: Suppress Deprecation warnings for deprecated Swing APIs
prr
parents:
40719
diff
changeset
|
686 |
@SuppressWarnings("deprecation") |
2 | 687 |
public void mouseClicked(MouseEvent e) { |
688 |
JEditorPane editor = (JEditorPane) e.getSource(); |
|
689 |
||
690 |
if (! editor.isEditable() && editor.isEnabled() && |
|
691 |
SwingUtilities.isLeftMouseButton(e)) { |
|
692 |
Point pt = new Point(e.getX(), e.getY()); |
|
693 |
int pos = editor.viewToModel(pt); |
|
694 |
if (pos >= 0) { |
|
695 |
activateLink(pos, editor, e); |
|
696 |
} |
|
697 |
} |
|
698 |
} |
|
699 |
||
700 |
// ignore the drags |
|
701 |
public void mouseDragged(MouseEvent e) { |
|
702 |
} |
|
703 |
||
704 |
// track the moving of the mouse. |
|
42216
621af0ebf6c4
8169518: Suppress Deprecation warnings for deprecated Swing APIs
prr
parents:
40719
diff
changeset
|
705 |
@SuppressWarnings("deprecation") |
2 | 706 |
public void mouseMoved(MouseEvent e) { |
707 |
JEditorPane editor = (JEditorPane) e.getSource(); |
|
708 |
if (!editor.isEnabled()) { |
|
709 |
return; |
|
710 |
} |
|
711 |
||
712 |
HTMLEditorKit kit = (HTMLEditorKit)editor.getEditorKit(); |
|
713 |
boolean adjustCursor = true; |
|
714 |
Cursor newCursor = kit.getDefaultCursor(); |
|
715 |
if (!editor.isEditable()) { |
|
716 |
Point pt = new Point(e.getX(), e.getY()); |
|
717 |
int pos = editor.getUI().viewToModel(editor, pt, bias); |
|
718 |
if (bias[0] == Position.Bias.Backward && pos > 0) { |
|
719 |
pos--; |
|
720 |
} |
|
721 |
if (pos >= 0 &&(editor.getDocument() instanceof HTMLDocument)){ |
|
722 |
HTMLDocument hdoc = (HTMLDocument)editor.getDocument(); |
|
723 |
Element elem = hdoc.getCharacterElement(pos); |
|
724 |
if (!doesElementContainLocation(editor, elem, pos, |
|
725 |
e.getX(), e.getY())) { |
|
726 |
elem = null; |
|
727 |
} |
|
728 |
if (curElem != elem || curElemImage) { |
|
729 |
Element lastElem = curElem; |
|
730 |
curElem = elem; |
|
731 |
String href = null; |
|
732 |
curElemImage = false; |
|
733 |
if (elem != null) { |
|
734 |
AttributeSet a = elem.getAttributes(); |
|
735 |
AttributeSet anchor = (AttributeSet)a. |
|
736 |
getAttribute(HTML.Tag.A); |
|
737 |
if (anchor == null) { |
|
738 |
curElemImage = (a.getAttribute(StyleConstants. |
|
739 |
NameAttribute) == HTML.Tag.IMG); |
|
740 |
if (curElemImage) { |
|
741 |
href = getMapHREF(editor, hdoc, elem, a, |
|
742 |
pos, e.getX(), e.getY()); |
|
743 |
} |
|
744 |
} |
|
745 |
else { |
|
746 |
href = (String)anchor.getAttribute |
|
747 |
(HTML.Attribute.HREF); |
|
748 |
} |
|
749 |
} |
|
750 |
||
751 |
if (href != this.href) { |
|
752 |
// reference changed, fire event(s) |
|
753 |
fireEvents(editor, hdoc, href, lastElem, e); |
|
754 |
this.href = href; |
|
755 |
if (href != null) { |
|
756 |
newCursor = kit.getLinkCursor(); |
|
757 |
} |
|
758 |
} |
|
759 |
else { |
|
760 |
adjustCursor = false; |
|
761 |
} |
|
762 |
} |
|
763 |
else { |
|
764 |
adjustCursor = false; |
|
765 |
} |
|
766 |
curOffset = pos; |
|
767 |
} |
|
768 |
} |
|
769 |
if (adjustCursor && editor.getCursor() != newCursor) { |
|
770 |
editor.setCursor(newCursor); |
|
771 |
} |
|
772 |
} |
|
773 |
||
774 |
/** |
|
775 |
* Returns a string anchor if the passed in element has a |
|
776 |
* USEMAP that contains the passed in location. |
|
777 |
*/ |
|
42216
621af0ebf6c4
8169518: Suppress Deprecation warnings for deprecated Swing APIs
prr
parents:
40719
diff
changeset
|
778 |
@SuppressWarnings("deprecation") |
2 | 779 |
private String getMapHREF(JEditorPane html, HTMLDocument hdoc, |
780 |
Element elem, AttributeSet attr, int offset, |
|
781 |
int x, int y) { |
|
782 |
Object useMap = attr.getAttribute(HTML.Attribute.USEMAP); |
|
783 |
if (useMap != null && (useMap instanceof String)) { |
|
784 |
Map m = hdoc.getMap((String)useMap); |
|
785 |
if (m != null && offset < hdoc.getLength()) { |
|
786 |
Rectangle bounds; |
|
787 |
TextUI ui = html.getUI(); |
|
788 |
try { |
|
789 |
Shape lBounds = ui.modelToView(html, offset, |
|
790 |
Position.Bias.Forward); |
|
791 |
Shape rBounds = ui.modelToView(html, offset + 1, |
|
792 |
Position.Bias.Backward); |
|
793 |
bounds = lBounds.getBounds(); |
|
794 |
bounds.add((rBounds instanceof Rectangle) ? |
|
795 |
(Rectangle)rBounds : rBounds.getBounds()); |
|
796 |
} catch (BadLocationException ble) { |
|
797 |
bounds = null; |
|
798 |
} |
|
799 |
if (bounds != null) { |
|
800 |
AttributeSet area = m.getArea(x - bounds.x, |
|
801 |
y - bounds.y, |
|
802 |
bounds.width, |
|
803 |
bounds.height); |
|
804 |
if (area != null) { |
|
805 |
return (String)area.getAttribute(HTML.Attribute. |
|
806 |
HREF); |
|
807 |
} |
|
808 |
} |
|
809 |
} |
|
810 |
} |
|
811 |
return null; |
|
812 |
} |
|
813 |
||
814 |
/** |
|
815 |
* Returns true if the View representing <code>e</code> contains |
|
816 |
* the location <code>x</code>, <code>y</code>. <code>offset</code> |
|
817 |
* gives the offset into the Document to check for. |
|
818 |
*/ |
|
42216
621af0ebf6c4
8169518: Suppress Deprecation warnings for deprecated Swing APIs
prr
parents:
40719
diff
changeset
|
819 |
@SuppressWarnings("deprecation") |
2 | 820 |
private boolean doesElementContainLocation(JEditorPane editor, |
821 |
Element e, int offset, |
|
822 |
int x, int y) { |
|
823 |
if (e != null && offset > 0 && e.getStartOffset() == offset) { |
|
824 |
try { |
|
825 |
TextUI ui = editor.getUI(); |
|
826 |
Shape s1 = ui.modelToView(editor, offset, |
|
827 |
Position.Bias.Forward); |
|
828 |
if (s1 == null) { |
|
829 |
return false; |
|
830 |
} |
|
831 |
Rectangle r1 = (s1 instanceof Rectangle) ? (Rectangle)s1 : |
|
832 |
s1.getBounds(); |
|
833 |
Shape s2 = ui.modelToView(editor, e.getEndOffset(), |
|
834 |
Position.Bias.Backward); |
|
835 |
if (s2 != null) { |
|
836 |
Rectangle r2 = (s2 instanceof Rectangle) ? (Rectangle)s2 : |
|
837 |
s2.getBounds(); |
|
838 |
r1.add(r2); |
|
839 |
} |
|
840 |
return r1.contains(x, y); |
|
841 |
} catch (BadLocationException ble) { |
|
842 |
} |
|
843 |
} |
|
844 |
return true; |
|
845 |
} |
|
846 |
||
847 |
/** |
|
848 |
* Calls linkActivated on the associated JEditorPane |
|
849 |
* if the given position represents a link.<p>This is implemented |
|
850 |
* to forward to the method with the same name, but with the following |
|
851 |
* args both == -1. |
|
852 |
* |
|
853 |
* @param pos the position |
|
854 |
* @param editor the editor pane |
|
855 |
*/ |
|
856 |
protected void activateLink(int pos, JEditorPane editor) { |
|
857 |
activateLink(pos, editor, null); |
|
858 |
} |
|
859 |
||
860 |
/** |
|
861 |
* Calls linkActivated on the associated JEditorPane |
|
862 |
* if the given position represents a link. If this was the result |
|
863 |
* of a mouse click, <code>x</code> and |
|
864 |
* <code>y</code> will give the location of the mouse, otherwise |
|
21982 | 865 |
* they will be {@literal <} 0. |
2 | 866 |
* |
867 |
* @param pos the position |
|
868 |
* @param html the editor pane |
|
869 |
*/ |
|
870 |
void activateLink(int pos, JEditorPane html, MouseEvent mouseEvent) { |
|
871 |
Document doc = html.getDocument(); |
|
872 |
if (doc instanceof HTMLDocument) { |
|
873 |
HTMLDocument hdoc = (HTMLDocument) doc; |
|
874 |
Element e = hdoc.getCharacterElement(pos); |
|
875 |
AttributeSet a = e.getAttributes(); |
|
876 |
AttributeSet anchor = (AttributeSet)a.getAttribute(HTML.Tag.A); |
|
877 |
HyperlinkEvent linkEvent = null; |
|
878 |
String description; |
|
879 |
int x = -1; |
|
880 |
int y = -1; |
|
881 |
||
882 |
if (mouseEvent != null) { |
|
883 |
x = mouseEvent.getX(); |
|
884 |
y = mouseEvent.getY(); |
|
885 |
} |
|
886 |
||
887 |
if (anchor == null) { |
|
888 |
href = getMapHREF(html, hdoc, e, a, pos, x, y); |
|
889 |
} |
|
890 |
else { |
|
891 |
href = (String)anchor.getAttribute(HTML.Attribute.HREF); |
|
892 |
} |
|
893 |
||
894 |
if (href != null) { |
|
895 |
linkEvent = createHyperlinkEvent(html, hdoc, href, anchor, |
|
896 |
e, mouseEvent); |
|
897 |
} |
|
898 |
if (linkEvent != null) { |
|
899 |
html.fireHyperlinkUpdate(linkEvent); |
|
900 |
} |
|
901 |
} |
|
902 |
} |
|
903 |
||
904 |
/** |
|
905 |
* Creates and returns a new instance of HyperlinkEvent. If |
|
906 |
* <code>hdoc</code> is a frame document a HTMLFrameHyperlinkEvent |
|
907 |
* will be created. |
|
908 |
*/ |
|
909 |
HyperlinkEvent createHyperlinkEvent(JEditorPane html, |
|
910 |
HTMLDocument hdoc, String href, |
|
911 |
AttributeSet anchor, |
|
912 |
Element element, |
|
913 |
MouseEvent mouseEvent) { |
|
914 |
URL u; |
|
915 |
try { |
|
916 |
URL base = hdoc.getBase(); |
|
917 |
u = new URL(base, href); |
|
918 |
// Following is a workaround for 1.2, in which |
|
919 |
// new URL("file://...", "#...") causes the filename to |
|
920 |
// be lost. |
|
921 |
if (href != null && "file".equals(u.getProtocol()) && |
|
922 |
href.startsWith("#")) { |
|
923 |
String baseFile = base.getFile(); |
|
924 |
String newFile = u.getFile(); |
|
925 |
if (baseFile != null && newFile != null && |
|
926 |
!newFile.startsWith(baseFile)) { |
|
927 |
u = new URL(base, baseFile + href); |
|
928 |
} |
|
929 |
} |
|
930 |
} catch (MalformedURLException m) { |
|
931 |
u = null; |
|
932 |
} |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
438
diff
changeset
|
933 |
HyperlinkEvent linkEvent; |
2 | 934 |
|
935 |
if (!hdoc.isFrameDocument()) { |
|
936 |
linkEvent = new HyperlinkEvent( |
|
937 |
html, HyperlinkEvent.EventType.ACTIVATED, u, href, |
|
938 |
element, mouseEvent); |
|
939 |
} else { |
|
940 |
String target = (anchor != null) ? |
|
941 |
(String)anchor.getAttribute(HTML.Attribute.TARGET) : null; |
|
942 |
if ((target == null) || (target.equals(""))) { |
|
943 |
target = hdoc.getBaseTarget(); |
|
944 |
} |
|
945 |
if ((target == null) || (target.equals(""))) { |
|
946 |
target = "_self"; |
|
947 |
} |
|
948 |
linkEvent = new HTMLFrameHyperlinkEvent( |
|
949 |
html, HyperlinkEvent.EventType.ACTIVATED, u, href, |
|
950 |
element, mouseEvent, target); |
|
951 |
} |
|
952 |
return linkEvent; |
|
953 |
} |
|
954 |
||
955 |
void fireEvents(JEditorPane editor, HTMLDocument doc, String href, |
|
956 |
Element lastElem, MouseEvent mouseEvent) { |
|
957 |
if (this.href != null) { |
|
958 |
// fire an exited event on the old link |
|
959 |
URL u; |
|
960 |
try { |
|
961 |
u = new URL(doc.getBase(), this.href); |
|
962 |
} catch (MalformedURLException m) { |
|
963 |
u = null; |
|
964 |
} |
|
965 |
HyperlinkEvent exit = new HyperlinkEvent(editor, |
|
966 |
HyperlinkEvent.EventType.EXITED, u, this.href, |
|
967 |
lastElem, mouseEvent); |
|
968 |
editor.fireHyperlinkUpdate(exit); |
|
969 |
} |
|
970 |
if (href != null) { |
|
971 |
// fire an entered event on the new link |
|
972 |
URL u; |
|
973 |
try { |
|
974 |
u = new URL(doc.getBase(), href); |
|
975 |
} catch (MalformedURLException m) { |
|
976 |
u = null; |
|
977 |
} |
|
978 |
HyperlinkEvent entered = new HyperlinkEvent(editor, |
|
979 |
HyperlinkEvent.EventType.ENTERED, |
|
980 |
u, href, curElem, mouseEvent); |
|
981 |
editor.fireHyperlinkUpdate(entered); |
|
982 |
} |
|
983 |
} |
|
984 |
} |
|
985 |
||
986 |
/** |
|
987 |
* Interface to be supported by the parser. This enables |
|
988 |
* providing a different parser while reusing some of the |
|
989 |
* implementation provided by this editor kit. |
|
990 |
*/ |
|
32865
f9cb6e427f9e
8136783: Run blessed-modifier-order script on java.desktop
prr
parents:
25859
diff
changeset
|
991 |
public abstract static class Parser { |
2 | 992 |
/** |
993 |
* Parse the given stream and drive the given callback |
|
994 |
* with the results of the parse. This method should |
|
995 |
* be implemented to be thread-safe. |
|
24269
325ea76ea0e9
8042105: Fix some more doclint issues in javax.swing.text.html classes
yan
parents:
24157
diff
changeset
|
996 |
* |
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
997 |
* @param r a reader |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
998 |
* @param cb a parser callback |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
999 |
* @param ignoreCharSet if {@code true} charset is ignoring |
24269
325ea76ea0e9
8042105: Fix some more doclint issues in javax.swing.text.html classes
yan
parents:
24157
diff
changeset
|
1000 |
* @throws IOException if an I/O exception occurs |
2 | 1001 |
*/ |
1002 |
public abstract void parse(Reader r, ParserCallback cb, boolean ignoreCharSet) throws IOException; |
|
1003 |
||
1004 |
} |
|
1005 |
||
1006 |
/** |
|
1007 |
* The result of parsing drives these callback methods. |
|
1008 |
* The open and close actions should be balanced. The |
|
1009 |
* <code>flush</code> method will be the last method |
|
1010 |
* called, to give the receiver a chance to flush any |
|
1011 |
* pending data into the document. |
|
1012 |
* <p>Refer to DocumentParser, the default parser used, for further |
|
1013 |
* information on the contents of the AttributeSets, the positions, and |
|
1014 |
* other info. |
|
1015 |
* |
|
1016 |
* @see javax.swing.text.html.parser.DocumentParser |
|
1017 |
*/ |
|
1018 |
public static class ParserCallback { |
|
1019 |
/** |
|
1020 |
* This is passed as an attribute in the attributeset to indicate |
|
1021 |
* the element is implied eg, the string '<>foo<\t>' |
|
1022 |
* contains an implied html element and an implied body element. |
|
1023 |
* |
|
1024 |
* @since 1.3 |
|
1025 |
*/ |
|
1026 |
public static final Object IMPLIED = "_implied_"; |
|
1027 |
||
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1028 |
/** |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1029 |
* The last method called on the reader. It allows |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1030 |
* any pending changes to be flushed into the document. |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1031 |
* Since this is currently loading synchronously, the entire |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1032 |
* set of changes are pushed in at this point. |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1033 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1034 |
* @throws BadLocationException if the given position does not |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1035 |
* represent a valid location in the associated document. |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1036 |
*/ |
2 | 1037 |
public void flush() throws BadLocationException { |
1038 |
} |
|
1039 |
||
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1040 |
/** |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1041 |
* Called by the parser to indicate a block of text was |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1042 |
* encountered. |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1043 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1044 |
* @param data a data |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1045 |
* @param pos a position |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1046 |
*/ |
2 | 1047 |
public void handleText(char[] data, int pos) { |
1048 |
} |
|
1049 |
||
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1050 |
/** |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1051 |
* Called by the parser to indicate a block of comment was |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1052 |
* encountered. |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1053 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1054 |
* @param data a data |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1055 |
* @param pos a position |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1056 |
*/ |
2 | 1057 |
public void handleComment(char[] data, int pos) { |
1058 |
} |
|
1059 |
||
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1060 |
/** |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1061 |
* Callback from the parser. Route to the appropriate |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1062 |
* handler for the tag. |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1063 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1064 |
* @param t an HTML tag |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1065 |
* @param a a set of attributes |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1066 |
* @param pos a position |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1067 |
*/ |
2 | 1068 |
public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) { |
1069 |
} |
|
1070 |
||
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1071 |
/** |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1072 |
* Callback from the parser. Route to the appropriate |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1073 |
* handler for the tag. |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1074 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1075 |
* @param t an HTML tag |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1076 |
* @param pos a position |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1077 |
*/ |
2 | 1078 |
public void handleEndTag(HTML.Tag t, int pos) { |
1079 |
} |
|
1080 |
||
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1081 |
/** |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1082 |
* Callback from the parser. Route to the appropriate |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1083 |
* handler for the tag. |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1084 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1085 |
* @param t an HTML tag |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1086 |
* @param a a set of attributes |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1087 |
* @param pos a position |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1088 |
*/ |
2 | 1089 |
public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos) { |
1090 |
} |
|
1091 |
||
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1092 |
/** |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1093 |
* Callback from the parser. Route to the appropriate |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1094 |
* handler for the error. |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1095 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1096 |
* @param errorMsg a error message |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1097 |
* @param pos a position |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1098 |
*/ |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1099 |
public void handleError(String errorMsg, int pos) { |
2 | 1100 |
} |
1101 |
||
1102 |
/** |
|
1103 |
* This is invoked after the stream has been parsed, but before |
|
1104 |
* <code>flush</code>. <code>eol</code> will be one of \n, \r |
|
1105 |
* or \r\n, which ever is encountered the most in parsing the |
|
1106 |
* stream. |
|
1107 |
* |
|
24269
325ea76ea0e9
8042105: Fix some more doclint issues in javax.swing.text.html classes
yan
parents:
24157
diff
changeset
|
1108 |
* @param eol value of eol |
325ea76ea0e9
8042105: Fix some more doclint issues in javax.swing.text.html classes
yan
parents:
24157
diff
changeset
|
1109 |
* |
2 | 1110 |
* @since 1.3 |
1111 |
*/ |
|
1112 |
public void handleEndOfLineString(String eol) { |
|
1113 |
} |
|
1114 |
} |
|
1115 |
||
1116 |
/** |
|
1117 |
* A factory to build views for HTML. The following |
|
1118 |
* table describes what this factory will build by |
|
1119 |
* default. |
|
1120 |
* |
|
1121 |
* <table summary="Describes the tag and view created by this factory by default"> |
|
1122 |
* <tr> |
|
1123 |
* <th align=left>Tag<th align=left>View created |
|
1124 |
* </tr><tr> |
|
1125 |
* <td>HTML.Tag.CONTENT<td>InlineView |
|
1126 |
* </tr><tr> |
|
1127 |
* <td>HTML.Tag.IMPLIED<td>javax.swing.text.html.ParagraphView |
|
1128 |
* </tr><tr> |
|
1129 |
* <td>HTML.Tag.P<td>javax.swing.text.html.ParagraphView |
|
1130 |
* </tr><tr> |
|
1131 |
* <td>HTML.Tag.H1<td>javax.swing.text.html.ParagraphView |
|
1132 |
* </tr><tr> |
|
1133 |
* <td>HTML.Tag.H2<td>javax.swing.text.html.ParagraphView |
|
1134 |
* </tr><tr> |
|
1135 |
* <td>HTML.Tag.H3<td>javax.swing.text.html.ParagraphView |
|
1136 |
* </tr><tr> |
|
1137 |
* <td>HTML.Tag.H4<td>javax.swing.text.html.ParagraphView |
|
1138 |
* </tr><tr> |
|
1139 |
* <td>HTML.Tag.H5<td>javax.swing.text.html.ParagraphView |
|
1140 |
* </tr><tr> |
|
1141 |
* <td>HTML.Tag.H6<td>javax.swing.text.html.ParagraphView |
|
1142 |
* </tr><tr> |
|
1143 |
* <td>HTML.Tag.DT<td>javax.swing.text.html.ParagraphView |
|
1144 |
* </tr><tr> |
|
1145 |
* <td>HTML.Tag.MENU<td>ListView |
|
1146 |
* </tr><tr> |
|
1147 |
* <td>HTML.Tag.DIR<td>ListView |
|
1148 |
* </tr><tr> |
|
1149 |
* <td>HTML.Tag.UL<td>ListView |
|
1150 |
* </tr><tr> |
|
1151 |
* <td>HTML.Tag.OL<td>ListView |
|
1152 |
* </tr><tr> |
|
1153 |
* <td>HTML.Tag.LI<td>BlockView |
|
1154 |
* </tr><tr> |
|
1155 |
* <td>HTML.Tag.DL<td>BlockView |
|
1156 |
* </tr><tr> |
|
1157 |
* <td>HTML.Tag.DD<td>BlockView |
|
1158 |
* </tr><tr> |
|
1159 |
* <td>HTML.Tag.BODY<td>BlockView |
|
1160 |
* </tr><tr> |
|
1161 |
* <td>HTML.Tag.HTML<td>BlockView |
|
1162 |
* </tr><tr> |
|
1163 |
* <td>HTML.Tag.CENTER<td>BlockView |
|
1164 |
* </tr><tr> |
|
1165 |
* <td>HTML.Tag.DIV<td>BlockView |
|
1166 |
* </tr><tr> |
|
1167 |
* <td>HTML.Tag.BLOCKQUOTE<td>BlockView |
|
1168 |
* </tr><tr> |
|
1169 |
* <td>HTML.Tag.PRE<td>BlockView |
|
1170 |
* </tr><tr> |
|
1171 |
* <td>HTML.Tag.BLOCKQUOTE<td>BlockView |
|
1172 |
* </tr><tr> |
|
1173 |
* <td>HTML.Tag.PRE<td>BlockView |
|
1174 |
* </tr><tr> |
|
1175 |
* <td>HTML.Tag.IMG<td>ImageView |
|
1176 |
* </tr><tr> |
|
1177 |
* <td>HTML.Tag.HR<td>HRuleView |
|
1178 |
* </tr><tr> |
|
1179 |
* <td>HTML.Tag.BR<td>BRView |
|
1180 |
* </tr><tr> |
|
1181 |
* <td>HTML.Tag.TABLE<td>javax.swing.text.html.TableView |
|
1182 |
* </tr><tr> |
|
1183 |
* <td>HTML.Tag.INPUT<td>FormView |
|
1184 |
* </tr><tr> |
|
1185 |
* <td>HTML.Tag.SELECT<td>FormView |
|
1186 |
* </tr><tr> |
|
1187 |
* <td>HTML.Tag.TEXTAREA<td>FormView |
|
1188 |
* </tr><tr> |
|
1189 |
* <td>HTML.Tag.OBJECT<td>ObjectView |
|
1190 |
* </tr><tr> |
|
1191 |
* <td>HTML.Tag.FRAMESET<td>FrameSetView |
|
1192 |
* </tr><tr> |
|
1193 |
* <td>HTML.Tag.FRAME<td>FrameView |
|
1194 |
* </tr> |
|
1195 |
* </table> |
|
1196 |
*/ |
|
1197 |
public static class HTMLFactory implements ViewFactory { |
|
1198 |
||
1199 |
/** |
|
1200 |
* Creates a view from an element. |
|
1201 |
* |
|
1202 |
* @param elem the element |
|
1203 |
* @return the view |
|
1204 |
*/ |
|
1205 |
public View create(Element elem) { |
|
1206 |
AttributeSet attrs = elem.getAttributes(); |
|
1207 |
Object elementName = |
|
1208 |
attrs.getAttribute(AbstractDocument.ElementNameAttribute); |
|
1209 |
Object o = (elementName != null) ? |
|
1210 |
null : attrs.getAttribute(StyleConstants.NameAttribute); |
|
1211 |
if (o instanceof HTML.Tag) { |
|
1212 |
HTML.Tag kind = (HTML.Tag) o; |
|
1213 |
if (kind == HTML.Tag.CONTENT) { |
|
1214 |
return new InlineView(elem); |
|
1215 |
} else if (kind == HTML.Tag.IMPLIED) { |
|
1216 |
String ws = (String) elem.getAttributes().getAttribute( |
|
1217 |
CSS.Attribute.WHITE_SPACE); |
|
1218 |
if ((ws != null) && ws.equals("pre")) { |
|
1219 |
return new LineView(elem); |
|
1220 |
} |
|
1221 |
return new javax.swing.text.html.ParagraphView(elem); |
|
1222 |
} else if ((kind == HTML.Tag.P) || |
|
1223 |
(kind == HTML.Tag.H1) || |
|
1224 |
(kind == HTML.Tag.H2) || |
|
1225 |
(kind == HTML.Tag.H3) || |
|
1226 |
(kind == HTML.Tag.H4) || |
|
1227 |
(kind == HTML.Tag.H5) || |
|
1228 |
(kind == HTML.Tag.H6) || |
|
1229 |
(kind == HTML.Tag.DT)) { |
|
1230 |
// paragraph |
|
1231 |
return new javax.swing.text.html.ParagraphView(elem); |
|
1232 |
} else if ((kind == HTML.Tag.MENU) || |
|
1233 |
(kind == HTML.Tag.DIR) || |
|
1234 |
(kind == HTML.Tag.UL) || |
|
1235 |
(kind == HTML.Tag.OL)) { |
|
1236 |
return new ListView(elem); |
|
1237 |
} else if (kind == HTML.Tag.BODY) { |
|
1238 |
return new BodyBlockView(elem); |
|
1239 |
} else if (kind == HTML.Tag.HTML) { |
|
1240 |
return new BlockView(elem, View.Y_AXIS); |
|
1241 |
} else if ((kind == HTML.Tag.LI) || |
|
1242 |
(kind == HTML.Tag.CENTER) || |
|
1243 |
(kind == HTML.Tag.DL) || |
|
1244 |
(kind == HTML.Tag.DD) || |
|
1245 |
(kind == HTML.Tag.DIV) || |
|
1246 |
(kind == HTML.Tag.BLOCKQUOTE) || |
|
1247 |
(kind == HTML.Tag.PRE) || |
|
1248 |
(kind == HTML.Tag.FORM)) { |
|
1249 |
// vertical box |
|
1250 |
return new BlockView(elem, View.Y_AXIS); |
|
1251 |
} else if (kind == HTML.Tag.NOFRAMES) { |
|
1252 |
return new NoFramesView(elem, View.Y_AXIS); |
|
1253 |
} else if (kind==HTML.Tag.IMG) { |
|
1254 |
return new ImageView(elem); |
|
1255 |
} else if (kind == HTML.Tag.ISINDEX) { |
|
1256 |
return new IsindexView(elem); |
|
1257 |
} else if (kind == HTML.Tag.HR) { |
|
1258 |
return new HRuleView(elem); |
|
1259 |
} else if (kind == HTML.Tag.BR) { |
|
1260 |
return new BRView(elem); |
|
1261 |
} else if (kind == HTML.Tag.TABLE) { |
|
1262 |
return new javax.swing.text.html.TableView(elem); |
|
1263 |
} else if ((kind == HTML.Tag.INPUT) || |
|
1264 |
(kind == HTML.Tag.SELECT) || |
|
1265 |
(kind == HTML.Tag.TEXTAREA)) { |
|
1266 |
return new FormView(elem); |
|
1267 |
} else if (kind == HTML.Tag.OBJECT) { |
|
1268 |
return new ObjectView(elem); |
|
1269 |
} else if (kind == HTML.Tag.FRAMESET) { |
|
1270 |
if (elem.getAttributes().isDefined(HTML.Attribute.ROWS)) { |
|
1271 |
return new FrameSetView(elem, View.Y_AXIS); |
|
1272 |
} else if (elem.getAttributes().isDefined(HTML.Attribute.COLS)) { |
|
1273 |
return new FrameSetView(elem, View.X_AXIS); |
|
1274 |
} |
|
1275 |
throw new RuntimeException("Can't build a" + kind + ", " + elem + ":" + |
|
1276 |
"no ROWS or COLS defined."); |
|
1277 |
} else if (kind == HTML.Tag.FRAME) { |
|
1278 |
return new FrameView(elem); |
|
1279 |
} else if (kind instanceof HTML.UnknownTag) { |
|
1280 |
return new HiddenTagView(elem); |
|
1281 |
} else if (kind == HTML.Tag.COMMENT) { |
|
1282 |
return new CommentView(elem); |
|
1283 |
} else if (kind == HTML.Tag.HEAD) { |
|
1284 |
// Make the head never visible, and never load its |
|
1285 |
// children. For Cursor positioning, |
|
1286 |
// getNextVisualPositionFrom is overriden to always return |
|
1287 |
// the end offset of the element. |
|
1288 |
return new BlockView(elem, View.X_AXIS) { |
|
1289 |
public float getPreferredSpan(int axis) { |
|
1290 |
return 0; |
|
1291 |
} |
|
1292 |
public float getMinimumSpan(int axis) { |
|
1293 |
return 0; |
|
1294 |
} |
|
1295 |
public float getMaximumSpan(int axis) { |
|
1296 |
return 0; |
|
1297 |
} |
|
1298 |
protected void loadChildren(ViewFactory f) { |
|
1299 |
} |
|
1300 |
public Shape modelToView(int pos, Shape a, |
|
1301 |
Position.Bias b) throws BadLocationException { |
|
1302 |
return a; |
|
1303 |
} |
|
1304 |
public int getNextVisualPositionFrom(int pos, |
|
1305 |
Position.Bias b, Shape a, |
|
1306 |
int direction, Position.Bias[] biasRet) { |
|
1307 |
return getElement().getEndOffset(); |
|
1308 |
} |
|
1309 |
}; |
|
1310 |
} else if ((kind == HTML.Tag.TITLE) || |
|
1311 |
(kind == HTML.Tag.META) || |
|
1312 |
(kind == HTML.Tag.LINK) || |
|
1313 |
(kind == HTML.Tag.STYLE) || |
|
1314 |
(kind == HTML.Tag.SCRIPT) || |
|
1315 |
(kind == HTML.Tag.AREA) || |
|
1316 |
(kind == HTML.Tag.MAP) || |
|
1317 |
(kind == HTML.Tag.PARAM) || |
|
1318 |
(kind == HTML.Tag.APPLET)) { |
|
1319 |
return new HiddenTagView(elem); |
|
1320 |
} |
|
1321 |
} |
|
1322 |
// If we get here, it's either an element we don't know about |
|
1323 |
// or something from StyledDocument that doesn't have a mapping to HTML. |
|
1324 |
String nm = (elementName != null) ? (String)elementName : |
|
1325 |
elem.getName(); |
|
1326 |
if (nm != null) { |
|
1327 |
if (nm.equals(AbstractDocument.ContentElementName)) { |
|
1328 |
return new LabelView(elem); |
|
1329 |
} else if (nm.equals(AbstractDocument.ParagraphElementName)) { |
|
1330 |
return new ParagraphView(elem); |
|
1331 |
} else if (nm.equals(AbstractDocument.SectionElementName)) { |
|
1332 |
return new BoxView(elem, View.Y_AXIS); |
|
1333 |
} else if (nm.equals(StyleConstants.ComponentElementName)) { |
|
1334 |
return new ComponentView(elem); |
|
1335 |
} else if (nm.equals(StyleConstants.IconElementName)) { |
|
1336 |
return new IconView(elem); |
|
1337 |
} |
|
1338 |
} |
|
1339 |
||
1340 |
// default to text display |
|
1341 |
return new LabelView(elem); |
|
1342 |
} |
|
1343 |
||
1344 |
static class BodyBlockView extends BlockView implements ComponentListener { |
|
1345 |
public BodyBlockView(Element elem) { |
|
1346 |
super(elem,View.Y_AXIS); |
|
1347 |
} |
|
1348 |
// reimplement major axis requirements to indicate that the |
|
1349 |
// block is flexible for the body element... so that it can |
|
1350 |
// be stretched to fill the background properly. |
|
1351 |
protected SizeRequirements calculateMajorAxisRequirements(int axis, SizeRequirements r) { |
|
1352 |
r = super.calculateMajorAxisRequirements(axis, r); |
|
1353 |
r.maximum = Integer.MAX_VALUE; |
|
1354 |
return r; |
|
1355 |
} |
|
1356 |
||
1357 |
protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) { |
|
1358 |
Container container = getContainer(); |
|
1359 |
Container parentContainer; |
|
1360 |
if (container != null |
|
1361 |
&& (container instanceof javax.swing.JEditorPane) |
|
1362 |
&& (parentContainer = container.getParent()) != null |
|
1363 |
&& (parentContainer instanceof javax.swing.JViewport)) { |
|
1364 |
JViewport viewPort = (JViewport)parentContainer; |
|
1365 |
if (cachedViewPort != null) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
438
diff
changeset
|
1366 |
JViewport cachedObject = cachedViewPort.get(); |
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
438
diff
changeset
|
1367 |
if (cachedObject != null) { |
2 | 1368 |
if (cachedObject != viewPort) { |
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
438
diff
changeset
|
1369 |
cachedObject.removeComponentListener(this); |
2 | 1370 |
} |
1371 |
} else { |
|
1372 |
cachedViewPort = null; |
|
1373 |
} |
|
1374 |
} |
|
1375 |
if (cachedViewPort == null) { |
|
1376 |
viewPort.addComponentListener(this); |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
438
diff
changeset
|
1377 |
cachedViewPort = new WeakReference<JViewport>(viewPort); |
2 | 1378 |
} |
1379 |
||
1380 |
componentVisibleWidth = viewPort.getExtentSize().width; |
|
1381 |
if (componentVisibleWidth > 0) { |
|
1382 |
Insets insets = container.getInsets(); |
|
1383 |
viewVisibleWidth = componentVisibleWidth - insets.left - getLeftInset(); |
|
1384 |
//try to use viewVisibleWidth if it is smaller than targetSpan |
|
1385 |
targetSpan = Math.min(targetSpan, viewVisibleWidth); |
|
1386 |
} |
|
1387 |
} else { |
|
1388 |
if (cachedViewPort != null) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
438
diff
changeset
|
1389 |
JViewport cachedObject = cachedViewPort.get(); |
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
438
diff
changeset
|
1390 |
if (cachedObject != null) { |
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
438
diff
changeset
|
1391 |
cachedObject.removeComponentListener(this); |
2 | 1392 |
} |
1393 |
cachedViewPort = null; |
|
1394 |
} |
|
1395 |
} |
|
1396 |
super.layoutMinorAxis(targetSpan, axis, offsets, spans); |
|
1397 |
} |
|
1398 |
||
1399 |
public void setParent(View parent) { |
|
1400 |
//if parent == null unregister component listener |
|
1401 |
if (parent == null) { |
|
1402 |
if (cachedViewPort != null) { |
|
1403 |
Object cachedObject; |
|
1404 |
if ((cachedObject = cachedViewPort.get()) != null) { |
|
1405 |
((JComponent)cachedObject).removeComponentListener(this); |
|
1406 |
} |
|
1407 |
cachedViewPort = null; |
|
1408 |
} |
|
1409 |
} |
|
1410 |
super.setParent(parent); |
|
1411 |
} |
|
1412 |
||
1413 |
public void componentResized(ComponentEvent e) { |
|
1414 |
if ( !(e.getSource() instanceof JViewport) ) { |
|
1415 |
return; |
|
1416 |
} |
|
1417 |
JViewport viewPort = (JViewport)e.getSource(); |
|
1418 |
if (componentVisibleWidth != viewPort.getExtentSize().width) { |
|
1419 |
Document doc = getDocument(); |
|
1420 |
if (doc instanceof AbstractDocument) { |
|
1421 |
AbstractDocument document = (AbstractDocument)getDocument(); |
|
1422 |
document.readLock(); |
|
1423 |
try { |
|
1424 |
layoutChanged(X_AXIS); |
|
1425 |
preferenceChanged(null, true, true); |
|
1426 |
} finally { |
|
1427 |
document.readUnlock(); |
|
1428 |
} |
|
1429 |
||
1430 |
} |
|
1431 |
} |
|
1432 |
} |
|
1433 |
public void componentHidden(ComponentEvent e) { |
|
1434 |
} |
|
1435 |
public void componentMoved(ComponentEvent e) { |
|
1436 |
} |
|
1437 |
public void componentShown(ComponentEvent e) { |
|
1438 |
} |
|
1439 |
/* |
|
1440 |
* we keep weak reference to viewPort if and only if BodyBoxView is listening for ComponentEvents |
|
1441 |
* only in that case cachedViewPort is not equal to null. |
|
1442 |
* we need to keep this reference in order to remove BodyBoxView from viewPort listeners. |
|
1443 |
* |
|
1444 |
*/ |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
438
diff
changeset
|
1445 |
private Reference<JViewport> cachedViewPort = null; |
2 | 1446 |
private boolean isListening = false; |
1447 |
private int viewVisibleWidth = Integer.MAX_VALUE; |
|
1448 |
private int componentVisibleWidth = Integer.MAX_VALUE; |
|
1449 |
} |
|
1450 |
||
1451 |
} |
|
1452 |
||
1453 |
// --- Action implementations ------------------------------ |
|
1454 |
||
1455 |
/** The bold action identifier |
|
1456 |
*/ |
|
1457 |
public static final String BOLD_ACTION = "html-bold-action"; |
|
1458 |
/** The italic action identifier |
|
1459 |
*/ |
|
1460 |
public static final String ITALIC_ACTION = "html-italic-action"; |
|
1461 |
/** The paragraph left indent action identifier |
|
1462 |
*/ |
|
1463 |
public static final String PARA_INDENT_LEFT = "html-para-indent-left"; |
|
1464 |
/** The paragraph right indent action identifier |
|
1465 |
*/ |
|
1466 |
public static final String PARA_INDENT_RIGHT = "html-para-indent-right"; |
|
1467 |
/** The font size increase to next value action identifier |
|
1468 |
*/ |
|
1469 |
public static final String FONT_CHANGE_BIGGER = "html-font-bigger"; |
|
1470 |
/** The font size decrease to next value action identifier |
|
1471 |
*/ |
|
1472 |
public static final String FONT_CHANGE_SMALLER = "html-font-smaller"; |
|
1473 |
/** The Color choice action identifier |
|
1474 |
The color is passed as an argument |
|
1475 |
*/ |
|
1476 |
public static final String COLOR_ACTION = "html-color-action"; |
|
1477 |
/** The logical style choice action identifier |
|
1478 |
The logical style is passed in as an argument |
|
1479 |
*/ |
|
1480 |
public static final String LOGICAL_STYLE_ACTION = "html-logical-style-action"; |
|
1481 |
/** |
|
1482 |
* Align images at the top. |
|
1483 |
*/ |
|
1484 |
public static final String IMG_ALIGN_TOP = "html-image-align-top"; |
|
1485 |
||
1486 |
/** |
|
1487 |
* Align images in the middle. |
|
1488 |
*/ |
|
1489 |
public static final String IMG_ALIGN_MIDDLE = "html-image-align-middle"; |
|
1490 |
||
1491 |
/** |
|
1492 |
* Align images at the bottom. |
|
1493 |
*/ |
|
1494 |
public static final String IMG_ALIGN_BOTTOM = "html-image-align-bottom"; |
|
1495 |
||
1496 |
/** |
|
1497 |
* Align images at the border. |
|
1498 |
*/ |
|
1499 |
public static final String IMG_BORDER = "html-image-border"; |
|
1500 |
||
1501 |
||
1502 |
/** HTML used when inserting tables. */ |
|
1503 |
private static final String INSERT_TABLE_HTML = "<table border=1><tr><td></td></tr></table>"; |
|
1504 |
||
1505 |
/** HTML used when inserting unordered lists. */ |
|
1506 |
private static final String INSERT_UL_HTML = "<ul><li></li></ul>"; |
|
1507 |
||
1508 |
/** HTML used when inserting ordered lists. */ |
|
1509 |
private static final String INSERT_OL_HTML = "<ol><li></li></ol>"; |
|
1510 |
||
1511 |
/** HTML used when inserting hr. */ |
|
1512 |
private static final String INSERT_HR_HTML = "<hr>"; |
|
1513 |
||
1514 |
/** HTML used when inserting pre. */ |
|
1515 |
private static final String INSERT_PRE_HTML = "<pre></pre>"; |
|
1516 |
||
1517 |
private static final NavigateLinkAction nextLinkAction = |
|
1518 |
new NavigateLinkAction("next-link-action"); |
|
1519 |
||
1520 |
private static final NavigateLinkAction previousLinkAction = |
|
1521 |
new NavigateLinkAction("previous-link-action"); |
|
1522 |
||
1523 |
private static final ActivateLinkAction activateLinkAction = |
|
1524 |
new ActivateLinkAction("activate-link-action"); |
|
1525 |
||
1526 |
private static final Action[] defaultActions = { |
|
1527 |
new InsertHTMLTextAction("InsertTable", INSERT_TABLE_HTML, |
|
1528 |
HTML.Tag.BODY, HTML.Tag.TABLE), |
|
1529 |
new InsertHTMLTextAction("InsertTableRow", INSERT_TABLE_HTML, |
|
1530 |
HTML.Tag.TABLE, HTML.Tag.TR, |
|
1531 |
HTML.Tag.BODY, HTML.Tag.TABLE), |
|
1532 |
new InsertHTMLTextAction("InsertTableDataCell", INSERT_TABLE_HTML, |
|
1533 |
HTML.Tag.TR, HTML.Tag.TD, |
|
1534 |
HTML.Tag.BODY, HTML.Tag.TABLE), |
|
1535 |
new InsertHTMLTextAction("InsertUnorderedList", INSERT_UL_HTML, |
|
1536 |
HTML.Tag.BODY, HTML.Tag.UL), |
|
1537 |
new InsertHTMLTextAction("InsertUnorderedListItem", INSERT_UL_HTML, |
|
1538 |
HTML.Tag.UL, HTML.Tag.LI, |
|
1539 |
HTML.Tag.BODY, HTML.Tag.UL), |
|
1540 |
new InsertHTMLTextAction("InsertOrderedList", INSERT_OL_HTML, |
|
1541 |
HTML.Tag.BODY, HTML.Tag.OL), |
|
1542 |
new InsertHTMLTextAction("InsertOrderedListItem", INSERT_OL_HTML, |
|
1543 |
HTML.Tag.OL, HTML.Tag.LI, |
|
1544 |
HTML.Tag.BODY, HTML.Tag.OL), |
|
1545 |
new InsertHRAction(), |
|
1546 |
new InsertHTMLTextAction("InsertPre", INSERT_PRE_HTML, |
|
1547 |
HTML.Tag.BODY, HTML.Tag.PRE), |
|
1548 |
nextLinkAction, previousLinkAction, activateLinkAction, |
|
1549 |
||
1550 |
new BeginAction(beginAction, false), |
|
1551 |
new BeginAction(selectionBeginAction, true) |
|
1552 |
}; |
|
1553 |
||
1554 |
// link navigation support |
|
1555 |
private boolean foundLink = false; |
|
1556 |
private int prevHypertextOffset = -1; |
|
1557 |
private Object linkNavigationTag; |
|
1558 |
||
1559 |
||
1560 |
/** |
|
1561 |
* An abstract Action providing some convenience methods that may |
|
1562 |
* be useful in inserting HTML into an existing document. |
|
1563 |
* <p>NOTE: None of the convenience methods obtain a lock on the |
|
1564 |
* document. If you have another thread modifying the text these |
|
1565 |
* methods may have inconsistent behavior, or return the wrong thing. |
|
1566 |
*/ |
|
23697 | 1567 |
@SuppressWarnings("serial") // Superclass is not serializable across versions |
32865
f9cb6e427f9e
8136783: Run blessed-modifier-order script on java.desktop
prr
parents:
25859
diff
changeset
|
1568 |
public abstract static class HTMLTextAction extends StyledTextAction { |
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1569 |
|
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1570 |
/** |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1571 |
* Creates a new HTMLTextAction from a string action name. |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1572 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1573 |
* @param name the name of the action |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1574 |
*/ |
2 | 1575 |
public HTMLTextAction(String name) { |
1576 |
super(name); |
|
1577 |
} |
|
1578 |
||
1579 |
/** |
|
24269
325ea76ea0e9
8042105: Fix some more doclint issues in javax.swing.text.html classes
yan
parents:
24157
diff
changeset
|
1580 |
* @param e the JEditorPane |
2 | 1581 |
* @return HTMLDocument of <code>e</code>. |
1582 |
*/ |
|
1583 |
protected HTMLDocument getHTMLDocument(JEditorPane e) { |
|
1584 |
Document d = e.getDocument(); |
|
1585 |
if (d instanceof HTMLDocument) { |
|
1586 |
return (HTMLDocument) d; |
|
1587 |
} |
|
1588 |
throw new IllegalArgumentException("document must be HTMLDocument"); |
|
1589 |
} |
|
1590 |
||
1591 |
/** |
|
24269
325ea76ea0e9
8042105: Fix some more doclint issues in javax.swing.text.html classes
yan
parents:
24157
diff
changeset
|
1592 |
* @param e the JEditorPane |
2 | 1593 |
* @return HTMLEditorKit for <code>e</code>. |
1594 |
*/ |
|
1595 |
protected HTMLEditorKit getHTMLEditorKit(JEditorPane e) { |
|
1596 |
EditorKit k = e.getEditorKit(); |
|
1597 |
if (k instanceof HTMLEditorKit) { |
|
1598 |
return (HTMLEditorKit) k; |
|
1599 |
} |
|
1600 |
throw new IllegalArgumentException("EditorKit must be HTMLEditorKit"); |
|
1601 |
} |
|
1602 |
||
1603 |
/** |
|
1604 |
* Returns an array of the Elements that contain <code>offset</code>. |
|
1605 |
* The first elements corresponds to the root. |
|
24269
325ea76ea0e9
8042105: Fix some more doclint issues in javax.swing.text.html classes
yan
parents:
24157
diff
changeset
|
1606 |
* |
325ea76ea0e9
8042105: Fix some more doclint issues in javax.swing.text.html classes
yan
parents:
24157
diff
changeset
|
1607 |
* @param doc an instance of HTMLDocument |
325ea76ea0e9
8042105: Fix some more doclint issues in javax.swing.text.html classes
yan
parents:
24157
diff
changeset
|
1608 |
* @param offset value of offset |
325ea76ea0e9
8042105: Fix some more doclint issues in javax.swing.text.html classes
yan
parents:
24157
diff
changeset
|
1609 |
* @return an array of the Elements that contain <code>offset</code> |
2 | 1610 |
*/ |
1611 |
protected Element[] getElementsAt(HTMLDocument doc, int offset) { |
|
1612 |
return getElementsAt(doc.getDefaultRootElement(), offset, 0); |
|
1613 |
} |
|
1614 |
||
1615 |
/** |
|
1616 |
* Recursive method used by getElementsAt. |
|
1617 |
*/ |
|
1618 |
private Element[] getElementsAt(Element parent, int offset, |
|
1619 |
int depth) { |
|
1620 |
if (parent.isLeaf()) { |
|
1621 |
Element[] retValue = new Element[depth + 1]; |
|
1622 |
retValue[depth] = parent; |
|
1623 |
return retValue; |
|
1624 |
} |
|
1625 |
Element[] retValue = getElementsAt(parent.getElement |
|
1626 |
(parent.getElementIndex(offset)), offset, depth + 1); |
|
1627 |
retValue[depth] = parent; |
|
1628 |
return retValue; |
|
1629 |
} |
|
1630 |
||
1631 |
/** |
|
1632 |
* Returns number of elements, starting at the deepest leaf, needed |
|
1633 |
* to get to an element representing <code>tag</code>. This will |
|
1634 |
* return -1 if no elements is found representing <code>tag</code>, |
|
1635 |
* or 0 if the parent of the leaf at <code>offset</code> represents |
|
1636 |
* <code>tag</code>. |
|
24269
325ea76ea0e9
8042105: Fix some more doclint issues in javax.swing.text.html classes
yan
parents:
24157
diff
changeset
|
1637 |
* |
325ea76ea0e9
8042105: Fix some more doclint issues in javax.swing.text.html classes
yan
parents:
24157
diff
changeset
|
1638 |
* @param doc an instance of HTMLDocument |
325ea76ea0e9
8042105: Fix some more doclint issues in javax.swing.text.html classes
yan
parents:
24157
diff
changeset
|
1639 |
* @param offset an offset to start from |
325ea76ea0e9
8042105: Fix some more doclint issues in javax.swing.text.html classes
yan
parents:
24157
diff
changeset
|
1640 |
* @param tag tag to represent |
325ea76ea0e9
8042105: Fix some more doclint issues in javax.swing.text.html classes
yan
parents:
24157
diff
changeset
|
1641 |
* @return number of elements |
2 | 1642 |
*/ |
1643 |
protected int elementCountToTag(HTMLDocument doc, int offset, |
|
1644 |
HTML.Tag tag) { |
|
1645 |
int depth = -1; |
|
1646 |
Element e = doc.getCharacterElement(offset); |
|
1647 |
while (e != null && e.getAttributes().getAttribute |
|
1648 |
(StyleConstants.NameAttribute) != tag) { |
|
1649 |
e = e.getParentElement(); |
|
1650 |
depth++; |
|
1651 |
} |
|
1652 |
if (e == null) { |
|
1653 |
return -1; |
|
1654 |
} |
|
1655 |
return depth; |
|
1656 |
} |
|
1657 |
||
1658 |
/** |
|
1659 |
* Returns the deepest element at <code>offset</code> matching |
|
1660 |
* <code>tag</code>. |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1661 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1662 |
* @param doc an instance of HTMLDocument |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1663 |
* @param offset the specified offset >= 0 |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1664 |
* @param tag an instance of HTML.Tag |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1665 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1666 |
* @return the deepest element |
2 | 1667 |
*/ |
1668 |
protected Element findElementMatchingTag(HTMLDocument doc, int offset, |
|
1669 |
HTML.Tag tag) { |
|
1670 |
Element e = doc.getDefaultRootElement(); |
|
1671 |
Element lastMatch = null; |
|
1672 |
while (e != null) { |
|
1673 |
if (e.getAttributes().getAttribute |
|
1674 |
(StyleConstants.NameAttribute) == tag) { |
|
1675 |
lastMatch = e; |
|
1676 |
} |
|
1677 |
e = e.getElement(e.getElementIndex(offset)); |
|
1678 |
} |
|
1679 |
return lastMatch; |
|
1680 |
} |
|
1681 |
} |
|
1682 |
||
1683 |
||
1684 |
/** |
|
1685 |
* InsertHTMLTextAction can be used to insert an arbitrary string of HTML |
|
1686 |
* into an existing HTML document. At least two HTML.Tags need to be |
|
1687 |
* supplied. The first Tag, parentTag, identifies the parent in |
|
1688 |
* the document to add the elements to. The second tag, addTag, |
|
1689 |
* identifies the first tag that should be added to the document as |
|
1690 |
* seen in the HTML string. One important thing to remember, is that |
|
1691 |
* the parser is going to generate all the appropriate tags, even if |
|
1692 |
* they aren't in the HTML string passed in.<p> |
|
1693 |
* For example, lets say you wanted to create an action to insert |
|
1694 |
* a table into the body. The parentTag would be HTML.Tag.BODY, |
|
1695 |
* addTag would be HTML.Tag.TABLE, and the string could be something |
|
1696 |
* like <table><tr><td></td></tr></table>. |
|
1697 |
* <p>There is also an option to supply an alternate parentTag and |
|
1698 |
* addTag. These will be checked for if there is no parentTag at |
|
1699 |
* offset. |
|
1700 |
*/ |
|
23697 | 1701 |
@SuppressWarnings("serial") // Superclass is not serializable across versions |
2 | 1702 |
public static class InsertHTMLTextAction extends HTMLTextAction { |
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1703 |
|
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1704 |
/** |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1705 |
* Creates a new InsertHTMLTextAction. |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1706 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1707 |
* @param name a name of the action |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1708 |
* @param html an HTML string |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1709 |
* @param parentTag a parent tag |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1710 |
* @param addTag the first tag to start inserting into document |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1711 |
*/ |
2 | 1712 |
public InsertHTMLTextAction(String name, String html, |
1713 |
HTML.Tag parentTag, HTML.Tag addTag) { |
|
1714 |
this(name, html, parentTag, addTag, null, null); |
|
1715 |
} |
|
1716 |
||
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1717 |
/** |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1718 |
* Creates a new InsertHTMLTextAction. |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1719 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1720 |
* @param name a name of the action |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1721 |
* @param html an HTML string |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1722 |
* @param parentTag a parent tag |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1723 |
* @param addTag the first tag to start inserting into document |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1724 |
* @param alternateParentTag an alternative parent tag |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1725 |
* @param alternateAddTag an alternative tag |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1726 |
*/ |
2 | 1727 |
public InsertHTMLTextAction(String name, String html, |
1728 |
HTML.Tag parentTag, |
|
1729 |
HTML.Tag addTag, |
|
1730 |
HTML.Tag alternateParentTag, |
|
1731 |
HTML.Tag alternateAddTag) { |
|
1732 |
this(name, html, parentTag, addTag, alternateParentTag, |
|
1733 |
alternateAddTag, true); |
|
1734 |
} |
|
1735 |
||
1736 |
/* public */ |
|
1737 |
InsertHTMLTextAction(String name, String html, |
|
1738 |
HTML.Tag parentTag, |
|
1739 |
HTML.Tag addTag, |
|
1740 |
HTML.Tag alternateParentTag, |
|
1741 |
HTML.Tag alternateAddTag, |
|
1742 |
boolean adjustSelection) { |
|
1743 |
super(name); |
|
1744 |
this.html = html; |
|
1745 |
this.parentTag = parentTag; |
|
1746 |
this.addTag = addTag; |
|
1747 |
this.alternateParentTag = alternateParentTag; |
|
1748 |
this.alternateAddTag = alternateAddTag; |
|
1749 |
this.adjustSelection = adjustSelection; |
|
1750 |
} |
|
1751 |
||
1752 |
/** |
|
1753 |
* A cover for HTMLEditorKit.insertHTML. If an exception it |
|
1754 |
* thrown it is wrapped in a RuntimeException and thrown. |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1755 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1756 |
* @param editor an instance of JEditorPane |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1757 |
* @param doc the document to insert into |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1758 |
* @param offset the offset to insert HTML at |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1759 |
* @param html an HTML string |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1760 |
* @param popDepth the number of ElementSpec.EndTagTypes to generate |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1761 |
* before inserting |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1762 |
* @param pushDepth the number of ElementSpec.StartTagTypes with a direction |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1763 |
* of ElementSpec.JoinNextDirection that should be generated |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1764 |
* before inserting, but after the end tags have been generated |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1765 |
* @param addTag the first tag to start inserting into document |
2 | 1766 |
*/ |
1767 |
protected void insertHTML(JEditorPane editor, HTMLDocument doc, |
|
1768 |
int offset, String html, int popDepth, |
|
1769 |
int pushDepth, HTML.Tag addTag) { |
|
1770 |
try { |
|
1771 |
getHTMLEditorKit(editor).insertHTML(doc, offset, html, |
|
1772 |
popDepth, pushDepth, |
|
1773 |
addTag); |
|
1774 |
} catch (IOException ioe) { |
|
1775 |
throw new RuntimeException("Unable to insert: " + ioe); |
|
1776 |
} catch (BadLocationException ble) { |
|
1777 |
throw new RuntimeException("Unable to insert: " + ble); |
|
1778 |
} |
|
1779 |
} |
|
1780 |
||
1781 |
/** |
|
1782 |
* This is invoked when inserting at a boundary. It determines |
|
1783 |
* the number of pops, and then the number of pushes that need |
|
1784 |
* to be performed, and then invokes insertHTML. |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1785 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1786 |
* @param editor an instance of JEditorPane |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1787 |
* @param doc an instance of HTMLDocument |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1788 |
* @param offset an offset to start from |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1789 |
* @param insertElement an instance of Element |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1790 |
* @param html an HTML string |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1791 |
* @param parentTag a parent tag |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1792 |
* @param addTag the first tag to start inserting into document |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1793 |
* |
2 | 1794 |
* @since 1.3 |
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1795 |
* |
2 | 1796 |
*/ |
1797 |
protected void insertAtBoundary(JEditorPane editor, HTMLDocument doc, |
|
1798 |
int offset, Element insertElement, |
|
1799 |
String html, HTML.Tag parentTag, |
|
1800 |
HTML.Tag addTag) { |
|
1801 |
insertAtBoundry(editor, doc, offset, insertElement, html, |
|
1802 |
parentTag, addTag); |
|
1803 |
} |
|
1804 |
||
1805 |
/** |
|
1806 |
* This is invoked when inserting at a boundary. It determines |
|
1807 |
* the number of pops, and then the number of pushes that need |
|
1808 |
* to be performed, and then invokes insertHTML. |
|
1809 |
* @deprecated As of Java 2 platform v1.3, use insertAtBoundary |
|
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1810 |
* |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1811 |
* @param editor an instance of JEditorPane |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1812 |
* @param doc an instance of HTMLDocument |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1813 |
* @param offset an offset to start from |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1814 |
* @param insertElement an instance of Element |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1815 |
* @param html an HTML string |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1816 |
* @param parentTag a parent tag |
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
1817 |
* @param addTag the first tag to start inserting into document |
2 | 1818 |
*/ |
1819 |
@Deprecated |
|
1820 |
protected void insertAtBoundry(JEditorPane editor, HTMLDocument doc, |
|
1821 |
int offset, Element insertElement, |
|
1822 |
String html, HTML.Tag parentTag, |
|
1823 |
HTML.Tag addTag) { |
|
1824 |
// Find the common parent. |
|
1825 |
Element e; |
|
1826 |
Element commonParent; |
|
1827 |
boolean isFirst = (offset == 0); |
|
1828 |
||
1829 |
if (offset > 0 || insertElement == null) { |
|
1830 |
e = doc.getDefaultRootElement(); |
|
1831 |
while (e != null && e.getStartOffset() != offset && |
|
1832 |
!e.isLeaf()) { |
|
1833 |
e = e.getElement(e.getElementIndex(offset)); |
|
1834 |
} |
|
1835 |
commonParent = (e != null) ? e.getParentElement() : null; |
|
1836 |
} |
|
1837 |
else { |
|
1838 |
// If inserting at the origin, the common parent is the |
|
1839 |
// insertElement. |
|
1840 |
commonParent = insertElement; |
|
1841 |
} |
|
1842 |
if (commonParent != null) { |
|
1843 |
// Determine how many pops to do. |
|
1844 |
int pops = 0; |
|
1845 |
int pushes = 0; |
|
1846 |
if (isFirst && insertElement != null) { |
|
1847 |
e = commonParent; |
|
1848 |
while (e != null && !e.isLeaf()) { |
|
1849 |
e = e.getElement(e.getElementIndex(offset)); |
|
1850 |
pops++; |
|
1851 |
} |
|
1852 |
} |
|
1853 |
else { |
|
1854 |
e = commonParent; |
|
1855 |
offset--; |
|
1856 |
while (e != null && !e.isLeaf()) { |
|
1857 |
e = e.getElement(e.getElementIndex(offset)); |
|
1858 |
pops++; |
|
1859 |
} |
|
1860 |
||
1861 |
// And how many pushes |
|
1862 |
e = commonParent; |
|
1863 |
offset++; |
|
1864 |
while (e != null && e != insertElement) { |
|
1865 |
e = e.getElement(e.getElementIndex(offset)); |
|
1866 |
pushes++; |
|
1867 |
} |
|
1868 |
} |
|
1869 |
pops = Math.max(0, pops - 1); |
|
1870 |
||
1871 |
// And insert! |
|
1872 |
insertHTML(editor, doc, offset, html, pops, pushes, addTag); |
|
1873 |
} |
|
1874 |
} |
|
1875 |
||
1876 |
/** |
|
1877 |
* If there is an Element with name <code>tag</code> at |
|
1878 |
* <code>offset</code>, this will invoke either insertAtBoundary |
|
1879 |
* or <code>insertHTML</code>. This returns true if there is |
|
1880 |
* a match, and one of the inserts is invoked. |
|
1881 |
*/ |
|
1882 |
/*protected*/ |
|
1883 |
boolean insertIntoTag(JEditorPane editor, HTMLDocument doc, |
|
1884 |
int offset, HTML.Tag tag, HTML.Tag addTag) { |
|
1885 |
Element e = findElementMatchingTag(doc, offset, tag); |
|
1886 |
if (e != null && e.getStartOffset() == offset) { |
|
1887 |
insertAtBoundary(editor, doc, offset, e, html, |
|
1888 |
tag, addTag); |
|
1889 |
return true; |
|
1890 |
} |
|
1891 |
else if (offset > 0) { |
|
1892 |
int depth = elementCountToTag(doc, offset - 1, tag); |
|
1893 |
if (depth != -1) { |
|
1894 |
insertHTML(editor, doc, offset, html, depth, 0, addTag); |
|
1895 |
return true; |
|
1896 |
} |
|
1897 |
} |
|
1898 |
return false; |
|
1899 |
} |
|
1900 |
||
1901 |
/** |
|
1902 |
* Called after an insertion to adjust the selection. |
|
1903 |
*/ |
|
1904 |
/* protected */ |
|
1905 |
void adjustSelection(JEditorPane pane, HTMLDocument doc, |
|
1906 |
int startOffset, int oldLength) { |
|
1907 |
int newLength = doc.getLength(); |
|
1908 |
if (newLength != oldLength && startOffset < newLength) { |
|
1909 |
if (startOffset > 0) { |
|
1910 |
String text; |
|
1911 |
try { |
|
1912 |
text = doc.getText(startOffset - 1, 1); |
|
1913 |
} catch (BadLocationException ble) { |
|
1914 |
text = null; |
|
1915 |
} |
|
1916 |
if (text != null && text.length() > 0 && |
|
1917 |
text.charAt(0) == '\n') { |
|
1918 |
pane.select(startOffset, startOffset); |
|
1919 |
} |
|
1920 |
else { |
|
1921 |
pane.select(startOffset + 1, startOffset + 1); |
|
1922 |
} |
|
1923 |
} |
|
1924 |
else { |
|
1925 |
pane.select(1, 1); |
|
1926 |
} |
|
1927 |
} |
|
1928 |
} |
|
1929 |
||
1930 |
/** |
|
1931 |
* Inserts the HTML into the document. |
|
1932 |
* |
|
1933 |
* @param ae the event |
|
1934 |
*/ |
|
1935 |
public void actionPerformed(ActionEvent ae) { |
|
1936 |
JEditorPane editor = getEditor(ae); |
|
1937 |
if (editor != null) { |
|
1938 |
HTMLDocument doc = getHTMLDocument(editor); |
|
1939 |
int offset = editor.getSelectionStart(); |
|
1940 |
int length = doc.getLength(); |
|
1941 |
boolean inserted; |
|
1942 |
// Try first choice |
|
1943 |
if (!insertIntoTag(editor, doc, offset, parentTag, addTag) && |
|
1944 |
alternateParentTag != null) { |
|
1945 |
// Then alternate. |
|
1946 |
inserted = insertIntoTag(editor, doc, offset, |
|
1947 |
alternateParentTag, |
|
1948 |
alternateAddTag); |
|
1949 |
} |
|
1950 |
else { |
|
1951 |
inserted = true; |
|
1952 |
} |
|
1953 |
if (adjustSelection && inserted) { |
|
1954 |
adjustSelection(editor, doc, offset, length); |
|
1955 |
} |
|
1956 |
} |
|
1957 |
} |
|
1958 |
||
1959 |
/** HTML to insert. */ |
|
1960 |
protected String html; |
|
1961 |
/** Tag to check for in the document. */ |
|
1962 |
protected HTML.Tag parentTag; |
|
1963 |
/** Tag in HTML to start adding tags from. */ |
|
1964 |
protected HTML.Tag addTag; |
|
1965 |
/** Alternate Tag to check for in the document if parentTag is |
|
1966 |
* not found. */ |
|
1967 |
protected HTML.Tag alternateParentTag; |
|
1968 |
/** Alternate tag in HTML to start adding tags from if parentTag |
|
1969 |
* is not found and alternateParentTag is found. */ |
|
1970 |
protected HTML.Tag alternateAddTag; |
|
1971 |
/** True indicates the selection should be adjusted after an insert. */ |
|
1972 |
boolean adjustSelection; |
|
1973 |
} |
|
1974 |
||
1975 |
||
1976 |
/** |
|
1977 |
* InsertHRAction is special, at actionPerformed time it will determine |
|
1978 |
* the parent HTML.Tag based on the paragraph element at the selection |
|
1979 |
* start. |
|
1980 |
*/ |
|
23697 | 1981 |
@SuppressWarnings("serial") // Superclass is not serializable across versions |
2 | 1982 |
static class InsertHRAction extends InsertHTMLTextAction { |
1983 |
InsertHRAction() { |
|
1984 |
super("InsertHR", "<hr>", null, HTML.Tag.IMPLIED, null, null, |
|
1985 |
false); |
|
1986 |
} |
|
1987 |
||
1988 |
/** |
|
1989 |
* Inserts the HTML into the document. |
|
1990 |
* |
|
1991 |
* @param ae the event |
|
1992 |
*/ |
|
1993 |
public void actionPerformed(ActionEvent ae) { |
|
1994 |
JEditorPane editor = getEditor(ae); |
|
1995 |
if (editor != null) { |
|
1996 |
HTMLDocument doc = getHTMLDocument(editor); |
|
1997 |
int offset = editor.getSelectionStart(); |
|
1998 |
Element paragraph = doc.getParagraphElement(offset); |
|
1999 |
if (paragraph.getParentElement() != null) { |
|
2000 |
parentTag = (HTML.Tag)paragraph.getParentElement(). |
|
2001 |
getAttributes().getAttribute |
|
2002 |
(StyleConstants.NameAttribute); |
|
2003 |
super.actionPerformed(ae); |
|
2004 |
} |
|
2005 |
} |
|
2006 |
} |
|
2007 |
||
2008 |
} |
|
2009 |
||
2010 |
/* |
|
2011 |
* Returns the object in an AttributeSet matching a key |
|
2012 |
*/ |
|
32865
f9cb6e427f9e
8136783: Run blessed-modifier-order script on java.desktop
prr
parents:
25859
diff
changeset
|
2013 |
private static Object getAttrValue(AttributeSet attr, HTML.Attribute key) { |
25193
187a455af8f8
8043549: Fix raw and unchecked lint warnings in javax.swing.text.*
darcy
parents:
24269
diff
changeset
|
2014 |
Enumeration<?> names = attr.getAttributeNames(); |
2 | 2015 |
while (names.hasMoreElements()) { |
2016 |
Object nextKey = names.nextElement(); |
|
2017 |
Object nextVal = attr.getAttribute(nextKey); |
|
2018 |
if (nextVal instanceof AttributeSet) { |
|
2019 |
Object value = getAttrValue((AttributeSet)nextVal, key); |
|
2020 |
if (value != null) { |
|
2021 |
return value; |
|
2022 |
} |
|
2023 |
} else if (nextKey == key) { |
|
2024 |
return nextVal; |
|
2025 |
} |
|
2026 |
} |
|
2027 |
return null; |
|
2028 |
} |
|
2029 |
||
2030 |
/* |
|
2031 |
* Action to move the focus on the next or previous hypertext link |
|
2032 |
* or object. TODO: This method relies on support from the |
|
2033 |
* javax.accessibility package. The text package should support |
|
2034 |
* keyboard navigation of text elements directly. |
|
2035 |
*/ |
|
23697 | 2036 |
@SuppressWarnings("serial") // Superclass is not serializable across versions |
2 | 2037 |
static class NavigateLinkAction extends TextAction implements CaretListener { |
2038 |
||
2039 |
private static final FocusHighlightPainter focusPainter = |
|
2040 |
new FocusHighlightPainter(null); |
|
2041 |
private final boolean focusBack; |
|
2042 |
||
2043 |
/* |
|
2044 |
* Create this action with the appropriate identifier. |
|
2045 |
*/ |
|
2046 |
public NavigateLinkAction(String actionName) { |
|
2047 |
super(actionName); |
|
2048 |
focusBack = "previous-link-action".equals(actionName); |
|
2049 |
} |
|
2050 |
||
2051 |
/** |
|
2052 |
* Called when the caret position is updated. |
|
2053 |
* |
|
2054 |
* @param e the caret event |
|
2055 |
*/ |
|
2056 |
public void caretUpdate(CaretEvent e) { |
|
2057 |
Object src = e.getSource(); |
|
2058 |
if (src instanceof JTextComponent) { |
|
2059 |
JTextComponent comp = (JTextComponent) src; |
|
2060 |
HTMLEditorKit kit = getHTMLEditorKit(comp); |
|
2061 |
if (kit != null && kit.foundLink) { |
|
2062 |
kit.foundLink = false; |
|
2063 |
// TODO: The AccessibleContext for the editor should register |
|
2064 |
// as a listener for CaretEvents and forward the events to |
|
2065 |
// assistive technologies listening for such events. |
|
2066 |
comp.getAccessibleContext().firePropertyChange( |
|
2067 |
AccessibleContext.ACCESSIBLE_HYPERTEXT_OFFSET, |
|
438
2ae294e4518c
6613529: Avoid duplicate object creation within JDK packages
dav
parents:
2
diff
changeset
|
2068 |
Integer.valueOf(kit.prevHypertextOffset), |
2ae294e4518c
6613529: Avoid duplicate object creation within JDK packages
dav
parents:
2
diff
changeset
|
2069 |
Integer.valueOf(e.getDot())); |
2 | 2070 |
} |
2071 |
} |
|
2072 |
} |
|
2073 |
||
2074 |
/* |
|
2075 |
* The operation to perform when this action is triggered. |
|
2076 |
*/ |
|
2077 |
public void actionPerformed(ActionEvent e) { |
|
2078 |
JTextComponent comp = getTextComponent(e); |
|
2079 |
if (comp == null || comp.isEditable()) { |
|
2080 |
return; |
|
2081 |
} |
|
2082 |
||
2083 |
Document doc = comp.getDocument(); |
|
2084 |
HTMLEditorKit kit = getHTMLEditorKit(comp); |
|
2085 |
if (doc == null || kit == null) { |
|
2086 |
return; |
|
2087 |
} |
|
2088 |
||
2089 |
// TODO: Should start successive iterations from the |
|
2090 |
// current caret position. |
|
2091 |
ElementIterator ei = new ElementIterator(doc); |
|
2092 |
int currentOffset = comp.getCaretPosition(); |
|
2093 |
int prevStartOffset = -1; |
|
2094 |
int prevEndOffset = -1; |
|
2095 |
||
2096 |
// highlight the next link or object after the current caret position |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
438
diff
changeset
|
2097 |
Element nextElement; |
2 | 2098 |
while ((nextElement = ei.next()) != null) { |
2099 |
String name = nextElement.getName(); |
|
2100 |
AttributeSet attr = nextElement.getAttributes(); |
|
2101 |
||
2102 |
Object href = getAttrValue(attr, HTML.Attribute.HREF); |
|
2103 |
if (!(name.equals(HTML.Tag.OBJECT.toString())) && href == null) { |
|
2104 |
continue; |
|
2105 |
} |
|
2106 |
||
2107 |
int elementOffset = nextElement.getStartOffset(); |
|
2108 |
if (focusBack) { |
|
2109 |
if (elementOffset >= currentOffset && |
|
2110 |
prevStartOffset >= 0) { |
|
2111 |
||
2112 |
kit.foundLink = true; |
|
2113 |
comp.setCaretPosition(prevStartOffset); |
|
2114 |
moveCaretPosition(comp, kit, prevStartOffset, |
|
2115 |
prevEndOffset); |
|
2116 |
kit.prevHypertextOffset = prevStartOffset; |
|
2117 |
return; |
|
2118 |
} |
|
2119 |
} else { // focus forward |
|
2120 |
if (elementOffset > currentOffset) { |
|
2121 |
||
2122 |
kit.foundLink = true; |
|
2123 |
comp.setCaretPosition(elementOffset); |
|
2124 |
moveCaretPosition(comp, kit, elementOffset, |
|
2125 |
nextElement.getEndOffset()); |
|
2126 |
kit.prevHypertextOffset = elementOffset; |
|
2127 |
return; |
|
2128 |
} |
|
2129 |
} |
|
2130 |
prevStartOffset = nextElement.getStartOffset(); |
|
2131 |
prevEndOffset = nextElement.getEndOffset(); |
|
2132 |
} |
|
2133 |
if (focusBack && prevStartOffset >= 0) { |
|
2134 |
kit.foundLink = true; |
|
2135 |
comp.setCaretPosition(prevStartOffset); |
|
2136 |
moveCaretPosition(comp, kit, prevStartOffset, prevEndOffset); |
|
2137 |
kit.prevHypertextOffset = prevStartOffset; |
|
2138 |
} |
|
2139 |
} |
|
2140 |
||
2141 |
/* |
|
2142 |
* Moves the caret from mark to dot |
|
2143 |
*/ |
|
2144 |
private void moveCaretPosition(JTextComponent comp, HTMLEditorKit kit, |
|
2145 |
int mark, int dot) { |
|
2146 |
Highlighter h = comp.getHighlighter(); |
|
2147 |
if (h != null) { |
|
2148 |
int p0 = Math.min(dot, mark); |
|
2149 |
int p1 = Math.max(dot, mark); |
|
2150 |
try { |
|
2151 |
if (kit.linkNavigationTag != null) { |
|
2152 |
h.changeHighlight(kit.linkNavigationTag, p0, p1); |
|
2153 |
} else { |
|
2154 |
kit.linkNavigationTag = |
|
2155 |
h.addHighlight(p0, p1, focusPainter); |
|
2156 |
} |
|
2157 |
} catch (BadLocationException e) { |
|
2158 |
} |
|
2159 |
} |
|
2160 |
} |
|
2161 |
||
2162 |
private HTMLEditorKit getHTMLEditorKit(JTextComponent comp) { |
|
2163 |
if (comp instanceof JEditorPane) { |
|
2164 |
EditorKit kit = ((JEditorPane) comp).getEditorKit(); |
|
2165 |
if (kit instanceof HTMLEditorKit) { |
|
2166 |
return (HTMLEditorKit) kit; |
|
2167 |
} |
|
2168 |
} |
|
2169 |
return null; |
|
2170 |
} |
|
2171 |
||
2172 |
/** |
|
2173 |
* A highlight painter that draws a one-pixel border around |
|
2174 |
* the highlighted area. |
|
2175 |
*/ |
|
2176 |
static class FocusHighlightPainter extends |
|
2177 |
DefaultHighlighter.DefaultHighlightPainter { |
|
2178 |
||
2179 |
FocusHighlightPainter(Color color) { |
|
2180 |
super(color); |
|
2181 |
} |
|
2182 |
||
2183 |
/** |
|
2184 |
* Paints a portion of a highlight. |
|
2185 |
* |
|
2186 |
* @param g the graphics context |
|
21982 | 2187 |
* @param offs0 the starting model offset ≥ 0 |
2188 |
* @param offs1 the ending model offset ≥ offs1 |
|
2 | 2189 |
* @param bounds the bounding box of the view, which is not |
25148
1026dc322690
8046446: Fix doclint warnings in javax.swing.text.html package
yan
parents:
24269
diff
changeset
|
2190 |
* necessarily the region to paint. |
2 | 2191 |
* @param c the editor |
2192 |
* @param view View painting for |
|
2193 |
* @return region in which drawing occurred |
|
2194 |
*/ |
|
2195 |
public Shape paintLayer(Graphics g, int offs0, int offs1, |
|
2196 |
Shape bounds, JTextComponent c, View view) { |
|
2197 |
||
2198 |
Color color = getColor(); |
|
2199 |
||
2200 |
if (color == null) { |
|
2201 |
g.setColor(c.getSelectionColor()); |
|
2202 |
} |
|
2203 |
else { |
|
2204 |
g.setColor(color); |
|
2205 |
} |
|
2206 |
if (offs0 == view.getStartOffset() && |
|
2207 |
offs1 == view.getEndOffset()) { |
|
2208 |
// Contained in view, can just use bounds. |
|
2209 |
Rectangle alloc; |
|
2210 |
if (bounds instanceof Rectangle) { |
|
2211 |
alloc = (Rectangle)bounds; |
|
2212 |
} |
|
2213 |
else { |
|
2214 |
alloc = bounds.getBounds(); |
|
2215 |
} |
|
2216 |
g.drawRect(alloc.x, alloc.y, alloc.width - 1, alloc.height); |
|
2217 |
return alloc; |
|
2218 |
} |
|
2219 |
else { |
|
2220 |
// Should only render part of View. |
|
2221 |
try { |
|
2222 |
// --- determine locations --- |
|
2223 |
Shape shape = view.modelToView(offs0, Position.Bias.Forward, |
|
2224 |
offs1,Position.Bias.Backward, |
|
2225 |
bounds); |
|
2226 |
Rectangle r = (shape instanceof Rectangle) ? |
|
2227 |
(Rectangle)shape : shape.getBounds(); |
|
2228 |
g.drawRect(r.x, r.y, r.width - 1, r.height); |
|
2229 |
return r; |
|
2230 |
} catch (BadLocationException e) { |
|
2231 |
// can't render |
|
2232 |
} |
|
2233 |
} |
|
2234 |
// Only if exception |
|
2235 |
return null; |
|
2236 |
} |
|
2237 |
} |
|
2238 |
} |
|
2239 |
||
2240 |
/* |
|
2241 |
* Action to activate the hypertext link that has focus. |
|
2242 |
* TODO: This method relies on support from the |
|
2243 |
* javax.accessibility package. The text package should support |
|
2244 |
* keyboard navigation of text elements directly. |
|
2245 |
*/ |
|
23697 | 2246 |
@SuppressWarnings("serial") // Superclass is not serializable across versions |
2 | 2247 |
static class ActivateLinkAction extends TextAction { |
2248 |
||
2249 |
/** |
|
2250 |
* Create this action with the appropriate identifier. |
|
2251 |
*/ |
|
2252 |
public ActivateLinkAction(String actionName) { |
|
2253 |
super(actionName); |
|
2254 |
} |
|
2255 |
||
2256 |
/* |
|
2257 |
* activates the hyperlink at offset |
|
2258 |
*/ |
|
2259 |
private void activateLink(String href, HTMLDocument doc, |
|
2260 |
JEditorPane editor, int offset) { |
|
2261 |
try { |
|
2262 |
URL page = |
|
2263 |
(URL)doc.getProperty(Document.StreamDescriptionProperty); |
|
2264 |
URL url = new URL(page, href); |
|
2265 |
HyperlinkEvent linkEvent = new HyperlinkEvent |
|
2266 |
(editor, HyperlinkEvent.EventType. |
|
2267 |
ACTIVATED, url, url.toExternalForm(), |
|
2268 |
doc.getCharacterElement(offset)); |
|
2269 |
editor.fireHyperlinkUpdate(linkEvent); |
|
2270 |
} catch (MalformedURLException m) { |
|
2271 |
} |
|
2272 |
} |
|
2273 |
||
2274 |
/* |
|
2275 |
* Invokes default action on the object in an element |
|
2276 |
*/ |
|
2277 |
private void doObjectAction(JEditorPane editor, Element elem) { |
|
2278 |
View view = getView(editor, elem); |
|
2279 |
if (view != null && view instanceof ObjectView) { |
|
2280 |
Component comp = ((ObjectView)view).getComponent(); |
|
2281 |
if (comp != null && comp instanceof Accessible) { |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
438
diff
changeset
|
2282 |
AccessibleContext ac = comp.getAccessibleContext(); |
2 | 2283 |
if (ac != null) { |
2284 |
AccessibleAction aa = ac.getAccessibleAction(); |
|
2285 |
if (aa != null) { |
|
2286 |
aa.doAccessibleAction(0); |
|
2287 |
} |
|
2288 |
} |
|
2289 |
} |
|
2290 |
} |
|
2291 |
} |
|
2292 |
||
2293 |
/* |
|
2294 |
* Returns the root view for a document |
|
2295 |
*/ |
|
2296 |
private View getRootView(JEditorPane editor) { |
|
2297 |
return editor.getUI().getRootView(editor); |
|
2298 |
} |
|
2299 |
||
2300 |
/* |
|
2301 |
* Returns a view associated with an element |
|
2302 |
*/ |
|
2303 |
private View getView(JEditorPane editor, Element elem) { |
|
2304 |
Object lock = lock(editor); |
|
2305 |
try { |
|
2306 |
View rootView = getRootView(editor); |
|
2307 |
int start = elem.getStartOffset(); |
|
2308 |
if (rootView != null) { |
|
2309 |
return getView(rootView, elem, start); |
|
2310 |
} |
|
2311 |
return null; |
|
2312 |
} finally { |
|
2313 |
unlock(lock); |
|
2314 |
} |
|
2315 |
} |
|
2316 |
||
2317 |
private View getView(View parent, Element elem, int start) { |
|
2318 |
if (parent.getElement() == elem) { |
|
2319 |
return parent; |
|
2320 |
} |
|
2321 |
int index = parent.getViewIndex(start, Position.Bias.Forward); |
|
2322 |
||
2323 |
if (index != -1 && index < parent.getViewCount()) { |
|
2324 |
return getView(parent.getView(index), elem, start); |
|
2325 |
} |
|
2326 |
return null; |
|
2327 |
} |
|
2328 |
||
2329 |
/* |
|
2330 |
* If possible acquires a lock on the Document. If a lock has been |
|
2331 |
* obtained a key will be retured that should be passed to |
|
2332 |
* <code>unlock</code>. |
|
2333 |
*/ |
|
2334 |
private Object lock(JEditorPane editor) { |
|
2335 |
Document document = editor.getDocument(); |
|
2336 |
||
2337 |
if (document instanceof AbstractDocument) { |
|
2338 |
((AbstractDocument)document).readLock(); |
|
2339 |
return document; |
|
2340 |
} |
|
2341 |
return null; |
|
2342 |
} |
|
2343 |
||
2344 |
/* |
|
2345 |
* Releases a lock previously obtained via <code>lock</code>. |
|
2346 |
*/ |
|
2347 |
private void unlock(Object key) { |
|
2348 |
if (key != null) { |
|
2349 |
((AbstractDocument)key).readUnlock(); |
|
2350 |
} |
|
2351 |
} |
|
2352 |
||
2353 |
/* |
|
2354 |
* The operation to perform when this action is triggered. |
|
2355 |
*/ |
|
2356 |
public void actionPerformed(ActionEvent e) { |
|
2357 |
||
2358 |
JTextComponent c = getTextComponent(e); |
|
2359 |
if (c.isEditable() || !(c instanceof JEditorPane)) { |
|
2360 |
return; |
|
2361 |
} |
|
2362 |
JEditorPane editor = (JEditorPane)c; |
|
2363 |
||
2364 |
Document d = editor.getDocument(); |
|
2365 |
if (d == null || !(d instanceof HTMLDocument)) { |
|
2366 |
return; |
|
2367 |
} |
|
2368 |
HTMLDocument doc = (HTMLDocument)d; |
|
2369 |
||
2370 |
ElementIterator ei = new ElementIterator(doc); |
|
2371 |
int currentOffset = editor.getCaretPosition(); |
|
2372 |
||
2373 |
// invoke the next link or object action |
|
2374 |
String urlString = null; |
|
2375 |
String objString = null; |
|
1287
a04aca99c77a
6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents:
438
diff
changeset
|
2376 |
Element currentElement; |
2 | 2377 |
while ((currentElement = ei.next()) != null) { |
2378 |
String name = currentElement.getName(); |
|
2379 |
AttributeSet attr = currentElement.getAttributes(); |
|
2380 |
||
2381 |
Object href = getAttrValue(attr, HTML.Attribute.HREF); |
|
2382 |
if (href != null) { |
|
2383 |
if (currentOffset >= currentElement.getStartOffset() && |
|
2384 |
currentOffset <= currentElement.getEndOffset()) { |
|
2385 |
||
2386 |
activateLink((String)href, doc, editor, currentOffset); |
|
2387 |
return; |
|
2388 |
} |
|
2389 |
} else if (name.equals(HTML.Tag.OBJECT.toString())) { |
|
2390 |
Object obj = getAttrValue(attr, HTML.Attribute.CLASSID); |
|
2391 |
if (obj != null) { |
|
2392 |
if (currentOffset >= currentElement.getStartOffset() && |
|
2393 |
currentOffset <= currentElement.getEndOffset()) { |
|
2394 |
||
2395 |
doObjectAction(editor, currentElement); |
|
2396 |
return; |
|
2397 |
} |
|
2398 |
} |
|
2399 |
} |
|
2400 |
} |
|
2401 |
} |
|
2402 |
} |
|
2403 |
||
2404 |
private static int getBodyElementStart(JTextComponent comp) { |
|
2405 |
Element rootElement = comp.getDocument().getRootElements()[0]; |
|
2406 |
for (int i = 0; i < rootElement.getElementCount(); i++) { |
|
2407 |
Element currElement = rootElement.getElement(i); |
|
2408 |
if("body".equals(currElement.getName())) { |
|
2409 |
return currElement.getStartOffset(); |
|
2410 |
} |
|
2411 |
} |
|
2412 |
return 0; |
|
2413 |
} |
|
2414 |
||
2415 |
/* |
|
2416 |
* Move the caret to the beginning of the document. |
|
2417 |
* @see DefaultEditorKit#beginAction |
|
2418 |
* @see HTMLEditorKit#getActions |
|
2419 |
*/ |
|
23697 | 2420 |
@SuppressWarnings("serial") // Superclass is not serializable across versions |
2 | 2421 |
static class BeginAction extends TextAction { |
2422 |
||
2423 |
/* Create this object with the appropriate identifier. */ |
|
2424 |
BeginAction(String nm, boolean select) { |
|
2425 |
super(nm); |
|
2426 |
this.select = select; |
|
2427 |
} |
|
2428 |
||
2429 |
/** The operation to perform when this action is triggered. */ |
|
2430 |
public void actionPerformed(ActionEvent e) { |
|
2431 |
JTextComponent target = getTextComponent(e); |
|
2432 |
int bodyStart = getBodyElementStart(target); |
|
2433 |
||
2434 |
if (target != null) { |
|
2435 |
if (select) { |
|
2436 |
target.moveCaretPosition(bodyStart); |
|
2437 |
} else { |
|
2438 |
target.setCaretPosition(bodyStart); |
|
2439 |
} |
|
2440 |
} |
|
2441 |
} |
|
2442 |
||
2443 |
private boolean select; |
|
2444 |
} |
|
2445 |
} |