Merge from mainline
[official-gcc.git] / libjava / classpath / javax / swing / text / html / HTMLDocument.java
blob5b2452b32f65deed97539a317c24313d18c4447f
1 /* HTMLDocument.java --
2 Copyright (C) 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.swing.text.html;
41 import java.net.URL;
43 import java.io.IOException;
45 import java.util.HashMap;
46 import java.util.Stack;
47 import java.util.Vector;
49 import javax.swing.event.DocumentEvent;
50 import javax.swing.event.UndoableEditEvent;
51 import javax.swing.text.AbstractDocument;
52 import javax.swing.text.AttributeSet;
53 import javax.swing.text.BadLocationException;
54 import javax.swing.text.DefaultStyledDocument;
55 import javax.swing.text.Element;
56 import javax.swing.text.ElementIterator;
57 import javax.swing.text.GapContent;
58 import javax.swing.text.MutableAttributeSet;
59 import javax.swing.text.SimpleAttributeSet;
60 import javax.swing.text.StyleConstants;
61 import javax.swing.text.html.HTML.Tag;
63 /**
64 * TODO: Add more comments here
66 * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
67 * @author Anthony Balkissoon (abalkiss@redhat.com)
68 * @author Lillian Angel (langel@redhat.com)
70 public class HTMLDocument extends DefaultStyledDocument
72 /** A key for document properies. The value for the key is
73 * a Vector of Strings of comments not found in the body.
74 */
75 public static final String AdditionalComments = "AdditionalComments";
76 URL baseURL = null;
77 boolean preservesUnknownTags = true;
78 int tokenThreshold = Integer.MAX_VALUE;
79 HTMLEditorKit.Parser parser;
80 StyleSheet styleSheet;
81 AbstractDocument.Content content;
83 /**
84 * Constructs an HTML document using the default buffer size and a default
85 * StyleSheet.
87 public HTMLDocument()
89 this(null);
92 /**
93 * Constructs an HTML document with the default content storage
94 * implementation and the specified style/attribute storage mechanism.
96 * @param styles - the style sheet
98 public HTMLDocument(StyleSheet styles)
100 this(new GapContent(BUFFER_SIZE_DEFAULT), styles);
104 * Constructs an HTML document with the given content storage implementation
105 * and the given style/attribute storage mechanism.
107 * @param c - the document's content
108 * @param styles - the style sheet
110 public HTMLDocument(AbstractDocument.Content c, StyleSheet styles)
112 this.content = c;
113 if (styles == null)
115 styles = new StyleSheet();
116 styles.importStyleSheet(getClass().getResource(HTMLEditorKit.
117 DEFAULT_CSS));
119 this.styleSheet = styles;
123 * Gets the style sheet with the document display rules (CSS) that were specified
124 * in the HTML document.
126 * @return - the style sheet
128 public StyleSheet getStyleSheet()
130 return styleSheet;
134 * Replaces the contents of the document with the given element specifications.
135 * This is called before insert if the loading is done in bursts. This is the
136 * only method called if loading the document entirely in one burst.
138 * @param data - the date that replaces the content of the document
140 protected void create(DefaultStyledDocument.ElementSpec[] data)
142 // FIXME: Not implemented
143 System.out.println("create not implemented");
144 super.create(data);
148 * This method creates a root element for the new document.
150 * @return the new default root
152 protected AbstractDocument.AbstractElement createDefaultRoot()
154 // FIXME: Not implemented
155 System.out.println("createDefaultRoot not implemented");
156 return super.createDefaultRoot();
160 * This method returns an HTMLDocument.RunElement object attached to
161 * parent representing a run of text from p0 to p1. The run has
162 * attributes described by a.
164 * @param parent - the parent element
165 * @param a - the attributes for the element
166 * @param p0 - the beginning of the range >= 0
167 * @param p1 - the end of the range >= p0
168 * @return the new element
170 protected Element createLeafElement(Element parent, AttributeSet a, int p0,
171 int p1)
173 // FIXME: Not implemented
174 System.out.println("createLeafElement not implemented");
175 return super.createLeafElement(parent, a, p0, p1);
178 /** This method returns an HTMLDocument.BlockElement object representing the
179 * attribute set a and attached to parent.
181 * @param parent - the parent element
182 * @param a - the attributes for the element
183 * @return the new element
185 protected Element createBranchElement(Element parent, AttributeSet a)
187 // FIXME: Not implemented
188 System.out.println("createBranchElement not implemented");
189 return super.createBranchElement(parent, a);
193 * Inserts new elements in bulk. This is how elements get created in the
194 * document. The parsing determines what structure is needed and creates the
195 * specification as a set of tokens that describe the edit while leaving the
196 * document free of a write-lock. This method can then be called in bursts by
197 * the reader to acquire a write-lock for a shorter duration (i.e. while the
198 * document is actually being altered).
200 * @param offset - the starting offset
201 * @param data - the element data
202 * @throws BadLocationException - if the given position does not
203 * represent a valid location in the associated document.
205 protected void insert(int offset, DefaultStyledDocument.ElementSpec[] data)
206 throws BadLocationException
208 super.insert(offset, data);
212 * Updates document structure as a result of text insertion. This will happen
213 * within a write lock. This implementation simply parses the inserted content
214 * for line breaks and builds up a set of instructions for the element buffer.
216 * @param chng - a description of the document change
217 * @param attr - the attributes
219 protected void insertUpdate(AbstractDocument.DefaultDocumentEvent chng,
220 AttributeSet attr)
222 // FIXME: Not implemented
223 System.out.println("insertUpdate not implemented");
224 super.insertUpdate(chng, attr);
228 * Returns the parser used by this HTMLDocument to insert HTML.
230 * @return the parser used by this HTMLDocument to insert HTML.
232 public HTMLEditorKit.Parser getParser()
234 return parser;
238 * Sets the parser used by this HTMLDocument to insert HTML.
240 * @param p the parser to use
242 public void setParser (HTMLEditorKit.Parser p)
244 parser = p;
247 * Sets the number of tokens to buffer before trying to display the
248 * Document.
250 * @param n the number of tokens to buffer
252 public void setTokenThreshold (int n)
254 tokenThreshold = n;
258 * Returns the number of tokens that are buffered before the document
259 * is rendered.
261 * @return the number of tokens buffered
263 public int getTokenThreshold ()
265 return tokenThreshold;
269 * Returns the location against which to resolve relative URLs.
270 * This is the document's URL if the document was loaded from a URL.
271 * If a <code>base</code> tag is found, it will be used.
272 * @return the base URL
274 public URL getBase()
276 return baseURL;
280 * Sets the location against which to resolve relative URLs.
281 * @param u the new base URL
283 public void setBase(URL u)
285 baseURL = u;
286 styleSheet.setBase(u);
290 * Returns whether or not the parser preserves unknown HTML tags.
291 * @return true if the parser preserves unknown tags
293 public boolean getPreservesUnknownTags()
295 return preservesUnknownTags;
299 * Sets the behaviour of the parser when it encounters unknown HTML tags.
300 * @param preservesTags true if the parser should preserve unknown tags.
302 public void setPreservesUnknownTags(boolean preservesTags)
304 preservesUnknownTags = preservesTags;
308 * An iterator to iterate through LeafElements in the document.
310 class LeafIterator extends Iterator
312 HTML.Tag tag;
313 HTMLDocument doc;
314 ElementIterator it;
316 public LeafIterator (HTML.Tag t, HTMLDocument d)
318 doc = d;
319 tag = t;
320 it = new ElementIterator(doc);
324 * Return the attributes for the tag associated with this iteartor
325 * @return the AttributeSet
327 public AttributeSet getAttributes()
329 if (it.current() != null)
330 return it.current().getAttributes();
331 return null;
335 * Get the end of the range for the current occurrence of the tag
336 * being defined and having the same attributes.
337 * @return the end of the range
339 public int getEndOffset()
341 if (it.current() != null)
342 return it.current().getEndOffset();
343 return -1;
347 * Get the start of the range for the current occurrence of the tag
348 * being defined and having the same attributes.
349 * @return the start of the range (-1 if it can't be found).
352 public int getStartOffset()
354 if (it.current() != null)
355 return it.current().getStartOffset();
356 return -1;
360 * Advance the iterator to the next LeafElement .
362 public void next()
364 it.next();
365 while (it.current()!= null && !it.current().isLeaf())
366 it.next();
370 * Indicates whether or not the iterator currently represents an occurrence
371 * of the tag.
372 * @return true if the iterator currently represents an occurrence of the
373 * tag.
375 public boolean isValid()
377 return it.current() != null;
381 * Type of tag for this iterator.
383 public Tag getTag()
385 return tag;
390 public void processHTMLFrameHyperlinkEvent(HTMLFrameHyperlinkEvent event)
392 // TODO: Implement this properly.
396 * Gets an iterator for the given HTML.Tag.
397 * @param t the requested HTML.Tag
398 * @return the Iterator
400 public HTMLDocument.Iterator getIterator (HTML.Tag t)
402 return new HTMLDocument.LeafIterator(t, this);
406 * An iterator over a particular type of tag.
408 public abstract static class Iterator
411 * Return the attribute set for this tag.
412 * @return the <code>AttributeSet</code> (null if none found).
414 public abstract AttributeSet getAttributes();
417 * Get the end of the range for the current occurrence of the tag
418 * being defined and having the same attributes.
419 * @return the end of the range
421 public abstract int getEndOffset();
424 * Get the start of the range for the current occurrence of the tag
425 * being defined and having the same attributes.
426 * @return the start of the range (-1 if it can't be found).
428 public abstract int getStartOffset();
431 * Move the iterator forward.
433 public abstract void next();
436 * Indicates whether or not the iterator currently represents an occurrence
437 * of the tag.
438 * @return true if the iterator currently represents an occurrence of the
439 * tag.
441 public abstract boolean isValid();
444 * Type of tag this iterator represents.
445 * @return the tag.
447 public abstract HTML.Tag getTag();
450 public class BlockElement extends AbstractDocument.BranchElement
452 public BlockElement (Element parent, AttributeSet a)
454 super (parent, a);
458 * Gets the resolving parent. Since HTML attributes are not
459 * inherited at the model level, this returns null.
461 public AttributeSet getResolveParent()
463 return null;
467 * Gets the name of the element.
469 * @return the name of the element if it exists, null otherwise.
471 public String getName()
473 return (String) getAttribute(StyleConstants.NameAttribute);
478 * RunElement represents a section of text that has a set of
479 * HTML character level attributes assigned to it.
481 public class RunElement extends AbstractDocument.LeafElement
485 * Constructs an element that has no children. It represents content
486 * within the document.
488 * @param parent - parent of this
489 * @param a - elements attributes
490 * @param start - the start offset >= 0
491 * @param end - the end offset
493 public RunElement(Element parent, AttributeSet a, int start, int end)
495 super(parent, a, start, end);
499 * Gets the name of the element.
501 * @return the name of the element if it exists, null otherwise.
503 public String getName()
505 return (String) getAttribute(StyleConstants.NameAttribute);
509 * Gets the resolving parent. HTML attributes do not inherit at the
510 * model level, so this method returns null.
512 * @return null
514 public AttributeSet getResolveParent()
516 return null;
521 * A reader to load an HTMLDocument with HTML structure.
523 * @author Anthony Balkissoon abalkiss at redhat dot com
525 public class HTMLReader extends HTMLEditorKit.ParserCallback
527 /** Holds the current character attribute set **/
528 protected MutableAttributeSet charAttr = new SimpleAttributeSet();
530 protected Vector parseBuffer = new Vector();
532 /** A stack for character attribute sets **/
533 Stack charAttrStack = new Stack();
535 /** A mapping between HTML.Tag objects and the actions that handle them **/
536 HashMap tagToAction;
538 /** Tells us whether we've received the '</html>' tag yet **/
539 boolean endHTMLEncountered = false;
541 /** Variables related to the constructor with explicit insertTag **/
542 int popDepth, pushDepth, offset;
543 HTML.Tag insertTag;
544 boolean insertTagEncountered = false;
546 /** A temporary variable that helps with the printing out of debug information **/
547 boolean debug = false;
549 void print (String line)
551 if (debug)
552 System.out.println (line);
555 public class TagAction
558 * This method is called when a start tag is seen for one of the types
559 * of tags associated with this Action. By default this does nothing.
561 public void start(HTML.Tag t, MutableAttributeSet a)
563 // Nothing to do here.
567 * Called when an end tag is seen for one of the types of tags associated
568 * with this Action. By default does nothing.
570 public void end(HTML.Tag t)
572 // Nothing to do here.
576 public class BlockAction extends TagAction
579 * This method is called when a start tag is seen for one of the types
580 * of tags associated with this Action.
582 public void start(HTML.Tag t, MutableAttributeSet a)
584 // Tell the parse buffer to open a new block for this tag.
585 blockOpen(t, a);
589 * Called when an end tag is seen for one of the types of tags associated
590 * with this Action.
592 public void end(HTML.Tag t)
594 // Tell the parse buffer to close this block.
595 blockClose(t);
599 public class CharacterAction extends TagAction
602 * This method is called when a start tag is seen for one of the types
603 * of tags associated with this Action.
605 public void start(HTML.Tag t, MutableAttributeSet a)
607 // Put the old attribute set on the stack.
608 pushCharacterStyle();
610 // And create the new one by adding the attributes in <code>a</code>.
611 if (a != null)
612 charAttr.addAttribute(t, a.copyAttributes());
616 * Called when an end tag is seen for one of the types of tags associated
617 * with this Action.
619 public void end(HTML.Tag t)
621 popCharacterStyle();
625 public class FormAction extends SpecialAction
628 * This method is called when a start tag is seen for one of the types
629 * of tags associated with this Action.
631 public void start(HTML.Tag t, MutableAttributeSet a)
633 // FIXME: Implement.
634 print ("FormAction.start not implemented");
638 * Called when an end tag is seen for one of the types of tags associated
639 * with this Action.
641 public void end(HTML.Tag t)
643 // FIXME: Implement.
644 print ("FormAction.end not implemented");
648 public class HiddenAction extends TagAction
651 * This method is called when a start tag is seen for one of the types
652 * of tags associated with this Action.
654 public void start(HTML.Tag t, MutableAttributeSet a)
656 // FIXME: Implement.
657 print ("HiddenAction.start not implemented");
661 * Called when an end tag is seen for one of the types of tags associated
662 * with this Action.
664 public void end(HTML.Tag t)
666 // FIXME: Implement.
667 print ("HiddenAction.end not implemented");
671 public class IsindexAction extends TagAction
674 * This method is called when a start tag is seen for one of the types
675 * of tags associated with this Action.
677 public void start(HTML.Tag t, MutableAttributeSet a)
679 // FIXME: Implement.
680 print ("IsindexAction.start not implemented");
684 * Called when an end tag is seen for one of the types of tags associated
685 * with this Action.
687 public void end(HTML.Tag t)
689 // FIXME: Implement.
690 print ("IsindexAction.end not implemented");
694 public class ParagraphAction extends BlockAction
697 * This method is called when a start tag is seen for one of the types
698 * of tags associated with this Action.
700 public void start(HTML.Tag t, MutableAttributeSet a)
702 // FIXME: Implement.
703 print ("ParagraphAction.start not implemented");
707 * Called when an end tag is seen for one of the types of tags associated
708 * with this Action.
710 public void end(HTML.Tag t)
712 // FIXME: Implement.
713 print ("ParagraphAction.end not implemented");
717 public class PreAction extends BlockAction
720 * This method is called when a start tag is seen for one of the types
721 * of tags associated with this Action.
723 public void start(HTML.Tag t, MutableAttributeSet a)
725 // FIXME: Implement.
726 print ("PreAction.start not implemented");
730 * Called when an end tag is seen for one of the types of tags associated
731 * with this Action.
733 public void end(HTML.Tag t)
735 // FIXME: Implement.
736 print ("PreAction.end not implemented");
740 public class SpecialAction extends TagAction
743 * This method is called when a start tag is seen for one of the types
744 * of tags associated with this Action.
746 public void start(HTML.Tag t, MutableAttributeSet a)
748 // FIXME: Implement.
749 print ("SpecialAction.start not implemented");
753 * Called when an end tag is seen for one of the types of tags associated
754 * with this Action.
756 public void end(HTML.Tag t)
758 // FIXME: Implement.
759 print ("SpecialAction.end not implemented");
763 class AreaAction extends TagAction
766 * This method is called when a start tag is seen for one of the types
767 * of tags associated with this Action.
769 public void start(HTML.Tag t, MutableAttributeSet a)
771 // FIXME: Implement.
772 print ("AreaAction.start not implemented");
776 * Called when an end tag is seen for one of the types of tags associated
777 * with this Action.
779 public void end(HTML.Tag t)
781 // FIXME: Implement.
782 print ("AreaAction.end not implemented");
786 class BaseAction extends TagAction
789 * This method is called when a start tag is seen for one of the types
790 * of tags associated with this Action.
792 public void start(HTML.Tag t, MutableAttributeSet a)
794 // FIXME: Implement.
795 print ("BaseAction.start not implemented");
799 * Called when an end tag is seen for one of the types of tags associated
800 * with this Action.
802 public void end(HTML.Tag t)
804 // FIXME: Implement.
805 print ("BaseAction.end not implemented");
809 class HeadAction extends BlockAction
812 * This method is called when a start tag is seen for one of the types
813 * of tags associated with this Action.
815 public void start(HTML.Tag t, MutableAttributeSet a)
817 // FIXME: Implement.
818 print ("HeadAction.start not implemented: "+t);
819 super.start(t, a);
823 * Called when an end tag is seen for one of the types of tags associated
824 * with this Action.
826 public void end(HTML.Tag t)
828 // FIXME: Implement.
829 print ("HeadAction.end not implemented: "+t);
830 super.end(t);
834 class LinkAction extends TagAction
837 * This method is called when a start tag is seen for one of the types
838 * of tags associated with this Action.
840 public void start(HTML.Tag t, MutableAttributeSet a)
842 // FIXME: Implement.
843 print ("LinkAction.start not implemented");
847 * Called when an end tag is seen for one of the types of tags associated
848 * with this Action.
850 public void end(HTML.Tag t)
852 // FIXME: Implement.
853 print ("LinkAction.end not implemented");
857 class MapAction extends TagAction
860 * This method is called when a start tag is seen for one of the types
861 * of tags associated with this Action.
863 public void start(HTML.Tag t, MutableAttributeSet a)
865 // FIXME: Implement.
866 print ("MapAction.start not implemented");
870 * Called when an end tag is seen for one of the types of tags associated
871 * with this Action.
873 public void end(HTML.Tag t)
875 // FIXME: Implement.
876 print ("MapAction.end not implemented");
880 class MetaAction extends TagAction
883 * This method is called when a start tag is seen for one of the types
884 * of tags associated with this Action.
886 public void start(HTML.Tag t, MutableAttributeSet a)
888 // FIXME: Implement.
889 print ("MetaAction.start not implemented");
893 * Called when an end tag is seen for one of the types of tags associated
894 * with this Action.
896 public void end(HTML.Tag t)
898 // FIXME: Implement.
899 print ("MetaAction.end not implemented");
903 class StyleAction extends TagAction
906 * This method is called when a start tag is seen for one of the types
907 * of tags associated with this Action.
909 public void start(HTML.Tag t, MutableAttributeSet a)
911 // FIXME: Implement.
912 print ("StyleAction.start not implemented");
916 * Called when an end tag is seen for one of the types of tags associated
917 * with this Action.
919 public void end(HTML.Tag t)
921 // FIXME: Implement.
922 print ("StyleAction.end not implemented");
926 class TitleAction extends TagAction
929 * This method is called when a start tag is seen for one of the types
930 * of tags associated with this Action.
932 public void start(HTML.Tag t, MutableAttributeSet a)
934 // FIXME: Implement.
935 print ("TitleAction.start not implemented");
939 * Called when an end tag is seen for one of the types of tags associated
940 * with this Action.
942 public void end(HTML.Tag t)
944 // FIXME: Implement.
945 print ("TitleAction.end not implemented");
949 public HTMLReader(int offset)
951 this (offset, 0, 0, null);
954 public HTMLReader(int offset, int popDepth, int pushDepth,
955 HTML.Tag insertTag)
957 print ("HTMLReader created with pop: "+popDepth
958 + " push: "+pushDepth + " offset: "+offset
959 + " tag: "+insertTag);
960 this.insertTag = insertTag;
961 this.offset = offset;
962 this.popDepth = popDepth;
963 this.pushDepth = pushDepth;
964 initTags();
967 void initTags()
969 tagToAction = new HashMap(72);
970 CharacterAction characterAction = new CharacterAction();
971 HiddenAction hiddenAction = new HiddenAction();
972 AreaAction areaAction = new AreaAction();
973 BaseAction baseAction = new BaseAction();
974 BlockAction blockAction = new BlockAction();
975 SpecialAction specialAction = new SpecialAction();
976 ParagraphAction paragraphAction = new ParagraphAction();
977 HeadAction headAction = new HeadAction();
978 FormAction formAction = new FormAction();
979 IsindexAction isindexAction = new IsindexAction();
980 LinkAction linkAction = new LinkAction();
981 MapAction mapAction = new MapAction();
982 PreAction preAction = new PreAction();
983 MetaAction metaAction = new MetaAction();
984 StyleAction styleAction = new StyleAction();
985 TitleAction titleAction = new TitleAction();
988 tagToAction.put(HTML.Tag.A, characterAction);
989 tagToAction.put(HTML.Tag.ADDRESS, characterAction);
990 tagToAction.put(HTML.Tag.APPLET, hiddenAction);
991 tagToAction.put(HTML.Tag.AREA, areaAction);
992 tagToAction.put(HTML.Tag.B, characterAction);
993 tagToAction.put(HTML.Tag.BASE, baseAction);
994 tagToAction.put(HTML.Tag.BASEFONT, characterAction);
995 tagToAction.put(HTML.Tag.BIG, characterAction);
996 tagToAction.put(HTML.Tag.BLOCKQUOTE, blockAction);
997 tagToAction.put(HTML.Tag.BODY, blockAction);
998 tagToAction.put(HTML.Tag.BR, specialAction);
999 tagToAction.put(HTML.Tag.CAPTION, blockAction);
1000 tagToAction.put(HTML.Tag.CENTER, blockAction);
1001 tagToAction.put(HTML.Tag.CITE, characterAction);
1002 tagToAction.put(HTML.Tag.CODE, characterAction);
1003 tagToAction.put(HTML.Tag.DD, blockAction);
1004 tagToAction.put(HTML.Tag.DFN, characterAction);
1005 tagToAction.put(HTML.Tag.DIR, blockAction);
1006 tagToAction.put(HTML.Tag.DIV, blockAction);
1007 tagToAction.put(HTML.Tag.DL, blockAction);
1008 tagToAction.put(HTML.Tag.DT, paragraphAction);
1009 tagToAction.put(HTML.Tag.EM, characterAction);
1010 tagToAction.put(HTML.Tag.FONT, characterAction);
1011 tagToAction.put(HTML.Tag.FORM, blockAction);
1012 tagToAction.put(HTML.Tag.FRAME, specialAction);
1013 tagToAction.put(HTML.Tag.FRAMESET, blockAction);
1014 tagToAction.put(HTML.Tag.H1, paragraphAction);
1015 tagToAction.put(HTML.Tag.H2, paragraphAction);
1016 tagToAction.put(HTML.Tag.H3, paragraphAction);
1017 tagToAction.put(HTML.Tag.H4, paragraphAction);
1018 tagToAction.put(HTML.Tag.H5, paragraphAction);
1019 tagToAction.put(HTML.Tag.H6, paragraphAction);
1020 tagToAction.put(HTML.Tag.HEAD, headAction);
1021 tagToAction.put(HTML.Tag.HR, specialAction);
1022 tagToAction.put(HTML.Tag.HTML, blockAction);
1023 tagToAction.put(HTML.Tag.I, characterAction);
1024 tagToAction.put(HTML.Tag.IMG, specialAction);
1025 tagToAction.put(HTML.Tag.INPUT, formAction);
1026 tagToAction.put(HTML.Tag.ISINDEX, isindexAction);
1027 tagToAction.put(HTML.Tag.KBD, characterAction);
1028 tagToAction.put(HTML.Tag.LI, blockAction);
1029 tagToAction.put(HTML.Tag.LINK, linkAction);
1030 tagToAction.put(HTML.Tag.MAP, mapAction);
1031 tagToAction.put(HTML.Tag.MENU, blockAction);
1032 tagToAction.put(HTML.Tag.META, metaAction);
1033 tagToAction.put(HTML.Tag.NOFRAMES, blockAction);
1034 tagToAction.put(HTML.Tag.OBJECT, specialAction);
1035 tagToAction.put(HTML.Tag.OL, blockAction);
1036 tagToAction.put(HTML.Tag.OPTION, formAction);
1037 tagToAction.put(HTML.Tag.P, paragraphAction);
1038 tagToAction.put(HTML.Tag.PARAM, hiddenAction);
1039 tagToAction.put(HTML.Tag.PRE, preAction);
1040 tagToAction.put(HTML.Tag.SAMP, characterAction);
1041 tagToAction.put(HTML.Tag.SCRIPT, hiddenAction);
1042 tagToAction.put(HTML.Tag.SELECT, formAction);
1043 tagToAction.put(HTML.Tag.SMALL, characterAction);
1044 tagToAction.put(HTML.Tag.STRIKE, characterAction);
1045 tagToAction.put(HTML.Tag.S, characterAction);
1046 tagToAction.put(HTML.Tag.STRONG, characterAction);
1047 tagToAction.put(HTML.Tag.STYLE, styleAction);
1048 tagToAction.put(HTML.Tag.SUB, characterAction);
1049 tagToAction.put(HTML.Tag.SUP, characterAction);
1050 tagToAction.put(HTML.Tag.TABLE, blockAction);
1051 tagToAction.put(HTML.Tag.TD, blockAction);
1052 tagToAction.put(HTML.Tag.TEXTAREA, formAction);
1053 tagToAction.put(HTML.Tag.TH, blockAction);
1054 tagToAction.put(HTML.Tag.TITLE, titleAction);
1055 tagToAction.put(HTML.Tag.TR, blockAction);
1056 tagToAction.put(HTML.Tag.TT, characterAction);
1057 tagToAction.put(HTML.Tag.U, characterAction);
1058 tagToAction.put(HTML.Tag.UL, blockAction);
1059 tagToAction.put(HTML.Tag.VAR, characterAction);
1063 * Pushes the current character style onto the stack.
1066 protected void pushCharacterStyle()
1068 charAttrStack.push(charAttr);
1072 * Pops a character style off of the stack and uses it as the
1073 * current character style.
1076 protected void popCharacterStyle()
1078 if (!charAttrStack.isEmpty())
1079 charAttr = (MutableAttributeSet) charAttrStack.pop();
1083 * Registers a given tag with a given Action. All of the well-known tags
1084 * are registered by default, but this method can change their behaviour
1085 * or add support for custom or currently unsupported tags.
1087 * @param t the Tag to register
1088 * @param a the Action for the Tag
1090 protected void registerTag(HTML.Tag t, HTMLDocument.HTMLReader.TagAction a)
1092 tagToAction.put (t, a);
1096 * This is the last method called on the HTMLReader, allowing any pending
1097 * changes to be flushed to the HTMLDocument.
1099 public void flush() throws BadLocationException
1101 DefaultStyledDocument.ElementSpec[] elements;
1102 elements = new DefaultStyledDocument.ElementSpec[parseBuffer.size()];
1103 parseBuffer.copyInto(elements);
1104 parseBuffer.removeAllElements();
1105 insert(offset, elements);
1106 offset += HTMLDocument.this.getLength() - offset;
1110 * This method is called by the parser to indicate a block of
1111 * text was encountered. Should insert the text appropriately.
1113 * @param data the text that was inserted
1114 * @param pos the position at which the text was inserted
1116 public void handleText(char[] data, int pos)
1118 if (data != null && data.length > 0)
1119 addContent(data, 0, data.length);
1123 * This method is called by the parser and should route the call to
1124 * the proper handler for the tag.
1126 * @param t the HTML.Tag
1127 * @param a the attribute set
1128 * @param pos the position at which the tag was encountered
1130 public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos)
1132 // Don't call the Action if we've already seen </html>.
1133 if (endHTMLEncountered)
1134 return;
1136 TagAction action = (TagAction) tagToAction.get(t);
1137 if (action != null)
1138 action.start(t, a);
1142 * This method called by parser to handle a comment block.
1144 * @param data the comment
1145 * @param pos the position at which the comment was encountered
1147 public void handleComment(char[] data, int pos)
1149 // Don't call the Action if we've already seen </html>.
1150 if (endHTMLEncountered)
1151 return;
1153 TagAction action = (TagAction) tagToAction.get(HTML.Tag.COMMENT);
1154 if (action != null)
1156 action.start(HTML.Tag.COMMENT, new SimpleAttributeSet());
1157 action.end (HTML.Tag.COMMENT);
1162 * This method is called by the parser and should route the call to
1163 * the proper handler for the tag.
1165 * @param t the HTML.Tag
1166 * @param pos the position at which the tag was encountered
1168 public void handleEndTag(HTML.Tag t, int pos)
1170 // Don't call the Action if we've already seen </html>.
1171 if (endHTMLEncountered)
1172 return;
1174 // If this is the </html> tag we need to stop calling the Actions
1175 if (t == HTML.Tag.HTML)
1176 endHTMLEncountered = true;
1178 TagAction action = (TagAction) tagToAction.get(t);
1179 if (action != null)
1180 action.end(t);
1184 * This is a callback from the parser that should be routed to the
1185 * appropriate handler for the tag.
1187 * @param t the HTML.Tag that was encountered
1188 * @param a the attribute set
1189 * @param pos the position at which the tag was encountered
1191 public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos)
1193 // Don't call the Action if we've already seen </html>.
1194 if (endHTMLEncountered)
1195 return;
1197 TagAction action = (TagAction) tagToAction.get (t);
1198 if (action != null)
1200 action.start(t, a);
1201 action.end(t);
1206 * This is invoked after the stream has been parsed but before it has been
1207 * flushed.
1209 * @param eol one of \n, \r, or \r\n, whichever was encountered the most in
1210 * parsing the stream
1211 * @since 1.3
1213 public void handleEndOfLineString(String eol)
1215 // FIXME: Implement.
1216 print ("HTMLReader.handleEndOfLineString not implemented yet");
1220 * Adds the given text to the textarea document. Called only when we are
1221 * within a textarea.
1223 * @param data the text to add to the textarea
1225 protected void textAreaContent(char[] data)
1227 // FIXME: Implement.
1228 print ("HTMLReader.textAreaContent not implemented yet");
1232 * Adds the given text that was encountered in a <PRE> element.
1234 * @param data the text
1236 protected void preContent(char[] data)
1238 // FIXME: Implement
1239 print ("HTMLReader.preContent not implemented yet");
1243 * Instructs the parse buffer to create a block element with the given
1244 * attributes.
1246 * @param t the tag that requires opening a new block
1247 * @param attr the attribute set for the new block
1249 protected void blockOpen(HTML.Tag t, MutableAttributeSet attr)
1251 printBuffer();
1252 DefaultStyledDocument.ElementSpec element;
1253 element = new DefaultStyledDocument.ElementSpec(attr.copyAttributes(),
1254 DefaultStyledDocument.ElementSpec.StartTagType);
1255 parseBuffer.addElement(element);
1256 printBuffer();
1260 * Instructs the parse buffer to close the block element associated with
1261 * the given HTML.Tag
1263 * @param t the HTML.Tag that is closing its block
1265 protected void blockClose(HTML.Tag t)
1267 printBuffer();
1268 DefaultStyledDocument.ElementSpec element;
1269 element = new DefaultStyledDocument.ElementSpec(null,
1270 DefaultStyledDocument.ElementSpec.EndTagType);
1271 parseBuffer.addElement(element);
1272 printBuffer();
1276 * Adds text to the appropriate context using the current character
1277 * attribute set.
1279 * @param data the text to add
1280 * @param offs the offset at which to add it
1281 * @param length the length of the text to add
1283 protected void addContent(char[] data, int offs, int length)
1285 addContent(data, offs, length, true);
1289 * Adds text to the appropriate context using the current character
1290 * attribute set, and possibly generating an IMPLIED Tag if necessary.
1292 * @param data the text to add
1293 * @param offs the offset at which to add it
1294 * @param length the length of the text to add
1295 * @param generateImpliedPIfNecessary whether or not we should generate
1296 * an HTML.Tag.IMPLIED tag if necessary
1298 protected void addContent(char[] data, int offs, int length,
1299 boolean generateImpliedPIfNecessary)
1301 // Copy the attribute set, don't use the same object because
1302 // it may change
1303 AttributeSet attributes = null;
1304 if (charAttr != null)
1305 attributes = charAttr.copyAttributes();
1307 DefaultStyledDocument.ElementSpec element;
1308 element = new DefaultStyledDocument.ElementSpec(attributes,
1309 DefaultStyledDocument.ElementSpec.ContentType,
1310 data, offs, length);
1312 printBuffer();
1313 // Add the element to the buffer
1314 parseBuffer.addElement(element);
1315 printBuffer();
1317 if (parseBuffer.size() > HTMLDocument.this.getTokenThreshold())
1321 flush();
1323 catch (BadLocationException ble)
1325 // TODO: what to do here?
1331 * Adds content that is specified in the attribute set.
1333 * @param t the HTML.Tag
1334 * @param a the attribute set specifying the special content
1336 protected void addSpecialElement(HTML.Tag t, MutableAttributeSet a)
1338 // FIXME: Implement
1339 print ("HTMLReader.addSpecialElement not implemented yet");
1342 void printBuffer()
1344 print ("\n*********BUFFER**********");
1345 for (int i = 0; i < parseBuffer.size(); i ++)
1346 print (" "+parseBuffer.get(i));
1347 print ("***************************");
1352 * Gets the reader for the parser to use when loading the document with HTML.
1354 * @param pos - the starting position
1355 * @return - the reader
1357 public HTMLEditorKit.ParserCallback getReader(int pos)
1359 return new HTMLReader(pos);
1363 * Gets the reader for the parser to use when loading the document with HTML.
1365 * @param pos - the starting position
1366 * @param popDepth - the number of EndTagTypes to generate before inserting
1367 * @param pushDepth - the number of StartTagTypes with a direction
1368 * of JoinNextDirection that should be generated before inserting,
1369 * but after the end tags have been generated.
1370 * @param insertTag - the first tag to start inserting into document
1371 * @return - the reader
1373 public HTMLEditorKit.ParserCallback getReader(int pos,
1374 int popDepth,
1375 int pushDepth,
1376 HTML.Tag insertTag)
1378 return new HTMLReader(pos, popDepth, pushDepth, insertTag);
1382 * Gets the child element that contains the attribute with the value or null.
1383 * Not thread-safe.
1385 * @param e - the element to begin search at
1386 * @param attribute - the desired attribute
1387 * @param value - the desired value
1388 * @return the element found with the attribute and value specified or null
1389 * if it is not found.
1391 public Element getElement(Element e, Object attribute, Object value)
1393 if (e != null)
1395 if (e.getAttributes().containsAttribute(attribute, value))
1396 return e;
1398 int count = e.getElementCount();
1399 for (int j = 0; j < count; j++)
1401 Element child = e.getElement(j);
1402 if (child.getAttributes().containsAttribute(attribute, value))
1403 return child;
1405 Element grandChild = getElement(child, attribute, value);
1406 if (grandChild != null)
1407 return grandChild;
1410 return null;
1414 * Returns the element that has the given id Attribute. If it is not found,
1415 * null is returned. This method works on an Attribute, not a character tag.
1416 * This is not thread-safe.
1418 * @param attrId - the Attribute id to look for
1419 * @return the element that has the given id.
1421 public Element getElement(String attrId)
1423 Element root = getDefaultRootElement();
1424 return getElement(root, HTML.getAttributeKey(attrId) , attrId);
1428 * Replaces the children of the given element with the contents of
1429 * the string. The document must have an HTMLEditorKit.Parser set.
1430 * This will be seen as at least two events, n inserts followed by a remove.
1432 * @param elem - the brance element whose children will be replaced
1433 * @param htmlText - the string to be parsed and assigned to element.
1434 * @throws BadLocationException
1435 * @throws IOException
1436 * @throws IllegalArgumentException - if elem is a leaf
1437 * @throws IllegalStateException - if an HTMLEditorKit.Parser has not been set
1439 public void setInnerHTML(Element elem, String htmlText)
1440 throws BadLocationException, IOException
1442 if (elem.isLeaf())
1443 throw new IllegalArgumentException("Element is a leaf");
1444 if (parser == null)
1445 throw new IllegalStateException("Parser has not been set");
1446 // FIXME: Not implemented fully, use InsertHTML* in HTMLEditorKit?
1447 System.out.println("setInnerHTML not implemented");
1451 * Replaces the given element in the parent with the string. When replacing
1452 * a leaf, this will attempt to make sure there is a newline present if one is
1453 * needed. This may result in an additional element being inserted.
1454 * This will be seen as at least two events, n inserts followed by a remove.
1455 * The HTMLEditorKit.Parser must be set.
1457 * @param elem - the branch element whose parent will be replaced
1458 * @param htmlText - the string to be parsed and assigned to elem
1459 * @throws BadLocationException
1460 * @throws IOException
1461 * @throws IllegalStateException - if parser is not set
1463 public void setOuterHTML(Element elem, String htmlText)
1464 throws BadLocationException, IOException
1466 if (parser == null)
1467 throw new IllegalStateException("Parser has not been set");
1468 // FIXME: Not implemented fully, use InsertHTML* in HTMLEditorKit?
1469 System.out.println("setOuterHTML not implemented");
1473 * Inserts the string before the start of the given element.
1474 * The parser must be set.
1476 * @param elem - the element to be the root for the new text.
1477 * @param htmlText - the string to be parsed and assigned to elem
1478 * @throws BadLocationException
1479 * @throws IOException
1480 * @throws IllegalStateException - if parser has not been set
1482 public void insertBeforeStart(Element elem, String htmlText)
1483 throws BadLocationException, IOException
1485 if (parser == null)
1486 throw new IllegalStateException("Parser has not been set");
1487 // FIXME: Not implemented fully, use InsertHTML* in HTMLEditorKit?
1488 System.out.println("insertBeforeStart not implemented");
1492 * Inserts the string at the end of the element. If elem's children
1493 * are leaves, and the character at elem.getEndOffset() - 1 is a newline,
1494 * then it will be inserted before the newline. The parser must be set.
1496 * @param elem - the element to be the root for the new text
1497 * @param htmlText - the text to insert
1498 * @throws BadLocationException
1499 * @throws IOException
1500 * @throws IllegalStateException - if parser is not set
1502 public void insertBeforeEnd(Element elem, String htmlText)
1503 throws BadLocationException, IOException
1505 if (parser == null)
1506 throw new IllegalStateException("Parser has not been set");
1507 // FIXME: Not implemented fully, use InsertHTML* in HTMLEditorKit?
1508 System.out.println("insertBeforeEnd not implemented");
1512 * Inserts the string after the end of the given element.
1513 * The parser must be set.
1515 * @param elem - the element to be the root for the new text
1516 * @param htmlText - the text to insert
1517 * @throws BadLocationException
1518 * @throws IOException
1519 * @throws IllegalStateException - if parser is not set
1521 public void insertAfterEnd(Element elem, String htmlText)
1522 throws BadLocationException, IOException
1524 if (parser == null)
1525 throw new IllegalStateException("Parser has not been set");
1526 // FIXME: Not implemented fully, use InsertHTML* in HTMLEditorKit?
1527 System.out.println("insertAfterEnd not implemented");
1531 * Inserts the string at the start of the element.
1532 * The parser must be set.
1534 * @param elem - the element to be the root for the new text
1535 * @param htmlText - the text to insert
1536 * @throws BadLocationException
1537 * @throws IOException
1538 * @throws IllegalStateException - if parser is not set
1540 public void insertAfterStart(Element elem, String htmlText)
1541 throws BadLocationException, IOException
1543 if (parser == null)
1544 throw new IllegalStateException("Parser has not been set");
1545 // FIXME: Not implemented fully, use InsertHTML* in HTMLEditorKit?
1546 System.out.println("insertAfterStart not implemented");
1550 * This method sets the attributes associated with the paragraph containing
1551 * offset. If replace is false, s is merged with existing attributes. The
1552 * length argument determines how many characters are affected by the new
1553 * attributes. This is often the entire paragraph.
1555 * @param offset -
1556 * the offset into the paragraph (must be at least 0)
1557 * @param length -
1558 * the number of characters affected (must be at least 0)
1559 * @param s -
1560 * the attributes
1561 * @param replace -
1562 * whether to replace existing attributes, or merge them
1564 public void setParagraphAttributes(int offset, int length, AttributeSet s,
1565 boolean replace)
1567 // FIXME: Not implemented.
1568 System.out.println("setParagraphAttributes not implemented");
1569 super.setParagraphAttributes(offset, length, s, replace);
1573 * This method flags a change in the document.
1575 * @param e - the Document event
1577 protected void fireChangedUpdate(DocumentEvent e)
1579 // FIXME: Not implemented.
1580 System.out.println("fireChangedUpdate not implemented");
1581 super.fireChangedUpdate(e);
1585 * This method fires an event intended to be caught by Undo listeners. It
1586 * simply calls the super version inherited from DefaultStyledDocument. With
1587 * this method, an HTML editor could easily provide undo support.
1589 * @param e - the UndoableEditEvent
1591 protected void fireUndoableEditUpdate(UndoableEditEvent e)
1593 super.fireUndoableEditUpdate(e);