/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* This is a writer for HTMLDocuments.
*
* @author Sunita Mani
*/
/*
* Stores all elements for which end tags have to
* be emitted.
*/
private boolean inContent = false;
private boolean inPre = false;
/** When inPre is true, this will indicate the end offset of the pre
* element. */
private int preEndOffset;
private boolean inTextArea = false;
private boolean newlineOutputed = false;
private boolean completeDoc;
/*
* Stores all embedded tags. Embedded tags are tags that are
* stored as attributes in other tags. Generally they're
* character level attributes. Examples include
* <b>, <i>, <font>, and <a>.
*/
/**
* Values for the tags.
*/
/**
* Used when writing out content.
*/
/*
* This is used in closeOutUnwantedEmbeddedTags.
*/
/**
* Set to true after the head has been output.
*/
private boolean wroteHead;
/**
* Set to true when entities (such as <) should be replaced.
*/
private boolean replaceEntities;
/**
* Temporary buffer.
*/
private char[] tempChars;
/**
* Creates a new HTMLWriter.
*
* @param w a Writer
* @param doc an HTMLDocument
*
*/
}
/**
* Creates a new HTMLWriter.
*
* @param w a Writer
* @param doc an HTMLDocument
* @param pos the document location from which to fetch the content
* @param len the amount to write out
*/
setLineLength(80);
}
/**
* Iterates over the
* Element tree and controls the writing out of
* all the tags and its attributes.
*
* @exception IOException on any I/O error
* @exception BadLocationException if pos represents an invalid
* location within the document.
*
*/
wroteHead = false;
replaceEntities = false;
setCanWrapLines(false);
}
inPre = false;
boolean forcedBody = false;
forcedBody = true;
}
else {
continue;
}
}
/*
if next is child of current increment indent
*/
incrIndent();
/*
next and current are not siblings
so emit end tags for items on the stack until the
item on top of the stack, is the parent of the
next.
*/
/*
pop() will return top.
*/
if (!synthesizedElement(top)) {
decrIndent();
}
}
}
/*
if next and current are siblings the indent level
is correct. But, we need to make sure that if current is
on the stack, we pop it off, and put out its end tag.
*/
}
}
}
} else {
}
}
/* Emit all remaining end tags */
/* A null parameter ensures that all embedded tags
currently in the tags vector have their
corresponding end tags written out.
*/
if (forcedBody) {
}
while (!blockElementStack.empty()) {
if (!synthesizedElement(current)) {
decrIndent();
}
}
}
if (completeDoc) {
}
}
/**
* Writes out the attribute set. Ignores all
* attributes with a key of type HTML.Tag,
* attributes with a key of type StyleConstants,
* and attributes with a key of type
* HTML.Attribute.ENDTAG.
*
* @param attr an AttributeSet
* @exception IOException on any I/O error
*
*/
// translate css attributes to html
while (names.hasMoreElements()) {
name instanceof StyleConstants ||
continue;
}
}
}
/**
* Writes out all empty elements (all tags that have no
* corresponding end tag).
*
* @param elem an Element
* @exception IOException on any I/O error
* @exception BadLocationException if pos represents an invalid
* location within the document.
*/
indentSmart();
}
inContent = true;
} else {
indentSmart();
}
boolean outputEndTag = false;
// If an instance of an UNKNOWN Tag, or an instance of a
// tag that is only visible during editing
//
outputEndTag = true;
}
if (outputEndTag) {
// Write out any styles.
}
wroteHead = true;
}
write('<');
if (outputEndTag) {
write('/');
}
write('>');
indentSmart();
}
}
}
}
/**
* Determines if the HTML.Tag associated with the
* element is a block tag.
*
* @param attr an AttributeSet
* @return true if tag is block tag, false otherwise.
*/
}
return false;
}
/**
* Writes out a start tag for the element.
* Ignores all synthesized elements.
*
* @param elem an Element
* @exception IOException on any I/O error
*/
if (synthesizedElement(elem)) {
return;
}
// Determine the name, as an HTML.Tag.
}
else {
}
inPre = true;
}
// write out end tags for item on stack
if (inContent) {
inContent = false;
newlineOutputed = false;
}
// If the head has not been output, output it and the styles.
wroteHead = true;
indentSmart();
write("<head>");
incrIndent();
decrIndent();
indentSmart();
write("</head>");
}
indentSmart();
write('<');
write('>');
}
// Write out the maps, which is not stored as Elements in
// the Document.
}
wroteHead = true;
incrIndent();
if (document.hasBaseTag()) {
indentSmart();
}
decrIndent();
}
}
/**
* Writes out text that is contained in a TEXTAREA form
* element.
*
* @param attr an AttributeSet
* @exception IOException on any I/O error
* @exception BadLocationException if pos represents an invalid
* location within the document.
*/
}
inTextArea = true;
incrIndent();
indentSmart();
setCanWrapLines(true);
replaceEntities = true;
replaceEntities = false;
setCanWrapLines(false);
inTextArea = false;
decrIndent();
}
}
}
/**
* Writes out text. If a range is specified when the constructor
* is invoked, then only the appropriate range of text is written
* out.
*
* @param elem an Element
* @exception IOException on any I/O error
* @exception BadLocationException if pos represents an invalid
* location within the document.
*/
}
newlineOutputed = false;
newlineOutputed = true;
}
}
else {
return;
}
}
replaceEntities = true;
setCanWrapLines(false);
replaceEntities = false;
}
}
}
/**
* Writes out the content of the SELECT form element.
*
* @param attr the AttributeSet associated with the form element
* @exception IOException on any I/O error
*/
incrIndent();
if (model instanceof OptionListModel) {
for (int i = 0; i < size; i++) {
}
} else if (model instanceof OptionComboBoxModel) {
for (int i = 0; i < size; i++) {
}
}
decrIndent();
}
/**
* Writes out the content of the Option form element.
* @param option an Option
* @exception IOException on any I/O error
*
*/
indentSmart();
write('<');
write("option");
// PENDING: should this be changed to check for null first?
}
if (option.isSelected()) {
write(" selected");
}
write('>');
}
}
/**
* Writes out an end tag for the element.
*
* @param elem an Element
* @exception IOException on any I/O error
*/
if (synthesizedElement(elem)) {
return;
}
// write out end tags for item on stack
if (inContent) {
if (!newlineOutputed && !inPre) {
}
newlineOutputed = false;
inContent = false;
}
if (!inPre) {
indentSmart();
}
inPre = false;
}
write('<');
write('/');
write('>');
}
/**
* Writes out comments.
*
* @param elem an Element
* @exception IOException on any I/O error
* @exception BadLocationException if pos represents an invalid
* location within the document.
*/
}
else {
}
}
}
/**
* Writes out comment string.
*
* @param string the comment
* @exception IOException on any I/O error
* @exception BadLocationException if pos represents an invalid
* location within the document.
*/
write("<!--");
}
write("-->");
indentSmart();
}
/**
* Writes out any additional comments (comments outside of the body)
* stored under the property HTMLDocument.AdditionalComments.
*/
counter++) {
}
}
}
/**
* Returns true if the element is a
* synthesized element. Currently we are only testing
* for the p-implied tag.
*/
return true;
}
return false;
}
/**
* Returns true if the StyleConstants.NameAttribute is
* equal to the tag that is passed in as a parameter.
*/
return true;
}
}
return false;
}
/**
* Searches for embedded tags in the AttributeSet
* and writes them out. It also stores these tags in a vector
* so that when appropriate the corresponding end tags can be
* written out.
*
* @exception IOException on any I/O error
*/
// translate css attributes to html
while (names.hasMoreElements()) {
continue;
}
write('<');
if (o != null && o instanceof AttributeSet) {
}
write('>');
tagValues.addElement(o);
}
}
}
/**
* Searches the attribute set for a tag, both of which
* are passed in as a parameter. Returns true if no match is found
* and false otherwise.
*/
return false;
}
}
return true;
}
/**
* Searches the attribute set and for each tag
* that is stored in the tag vector. If the tag isnt found,
* then the tag is removed from the vector and a corresponding
* end tag is written out.
*
* @exception IOException on any I/O error
*/
// translate css attributes to html
int firstIndex = -1;
// First, find all the tags that need to be removed.
firstIndex = i;
}
}
if (firstIndex != -1) {
// Then close them out.
tags.removeElementAt(i);
}
write('<');
write('/');
write('>');
}
// Have to output any tags after firstIndex that still remaing,
// as we closed them out, but they should remain open.
for (int i = firstIndex; i < size; i++) {
write('<');
if (o != null && o instanceof AttributeSet) {
}
write('>');
}
}
}
/**
* Determines if the element associated with the attributeset
* is a TEXTAREA or SELECT. If true, returns true else
* false
*/
}
/**
* Determines whether a the indentation needs to be
* incremented. Basically, if next is a child of current, and
* next is NOT a synthesized element, the indent level will be
* incremented. If there is a parent-child relationship and "next"
* is a synthesized element, then its children must be indented.
* This state is maintained by the indentNext boolean.
*
* @return boolean that's true if indent level
* needs incrementing.
*/
private boolean indentNext = false;
if (indentNext) {
indentNext = false;
return true;
} else if (synthesizedElement(next)) {
indentNext = true;
} else if (!synthesizedElement(current)){
return true;
}
}
return false;
}
/**
* Outputs the maps as elements. Maps are not stored as elements in
* the document, and as such this is used to output them.
*/
while(maps.hasMoreElements()) {
incrIndent();
indentSmart();
write("<map");
write(" name=\"");
write("\">");
}
else {
write('>');
}
incrIndent();
// Output the areas
indentSmart();
write("<area");
write("></area>");
}
}
decrIndent();
indentSmart();
write("</map>");
decrIndent();
}
}
}
/**
* Outputs the styles as a single element. Styles are not stored as
* elements, but part of the document. For the time being styles are
* written out as a comment, inside a style tag.
*/
boolean outputStyle = false;
while (styles.hasMoreElements()) {
// Don't write out the default style.
outputStyle = true;
}
}
if (outputStyle) {
}
}
}
}
/**
* Outputs the named style. <code>outputStyle</code> indicates
* whether or not a style has been output yet. This will return
* true if a style is written.
*/
throws IOException{
boolean didOutputStyle = false;
if (attributes != null) {
while (attributes.hasMoreElements()) {
if (!outputStyle) {
outputStyle = true;
}
if (!didOutputStyle) {
didOutputStyle = true;
indentSmart();
write(" {");
}
else {
write(";");
}
write(' ');
write(": ");
}
}
}
}
if (didOutputStyle) {
write(" }");
}
return didOutputStyle;
}
indentSmart();
incrIndent();
indentSmart();
write("<!--");
incrIndent();
}
decrIndent();
indentSmart();
write("-->");
decrIndent();
indentSmart();
write("</style>");
indentSmart();
}
// --- conversion support ---------------------------
/**
* Convert the give set of attributes to be html for
* the purpose of writing them out. Any keys that
* have been converted will not appear in the resultant
* set. Any keys not converted will appear in the
* resultant set the same as the received set.<p>
* This will put the converted values into <code>to</code>, unless
* it is null in which case a temporary AttributeSet will be returned.
*/
}
if (writeCSS) {
} else {
}
return to;
}
/**
* If true, the writer will emit CSS attributes in preference
* to HTML tags/attributes (i.e. It will emit an HTML 4.0
* style).
*/
private boolean writeCSS = false;
/**
* Buffer for the purpose of attribute conversion
*/
/**
* Buffer for the purpose of attribute conversion. This can be
* used if convAttr is being used.
*/
/**
* Create an older style of HTML attributes. This will
* convert character level attributes that have a StyleConstants
* will be placed in an HTML style attribute.
*/
return;
}
while (keys.hasMoreElements()) {
// add a bold tag is weight is bold
}
}
}
}
}
}
} else {
// default is to store in a HTML style attribute
}
}
} else {
if (attr instanceof AttributeSet) {
}
}
}
}
}
/**
* Add an attribute only if it doesn't exist so that we don't
* loose information replacing it with SimpleAttributeSet.EMPTY
*/
} else {
if (attr instanceof MutableAttributeSet &&
value instanceof AttributeSet) {
}
}
}
/**
* value of the attribute should be a MutableAttributeSet so
* that the attributes can be updated as they are discovered.
*/
fontAttr = new SimpleAttributeSet();
}
// edit the parameters to the font tag
}
}
/**
* Copies the given AttributeSet to a new set, converting
* any CSS attributes found to arguments of an HTML style
* attribute.
*/
while (keys.hasMoreElements()) {
} else {
}
}
}
}
//
// Overrides the writing methods to only break a string when
// canBreakString is true.
// In a future release it is likely AbstractWriter will get this
// functionality.
//
/**
* Writes the line separator. This is overriden to make sure we don't
* replace the newline content in case it is outside normal ascii.
* @since 1.3
*/
boolean oldReplace = replaceEntities;
replaceEntities = false;
super.writeLineSeparator();
indented = false;
}
/**
* This method is overriden to map any character entities, such as
* < to &lt;. <code>super.output</code> will be invoked to
* write the content.
* @since 1.3
*/
throws IOException {
if (!replaceEntities) {
return;
}
// This will change, we need better support character level
// entities.
// Character level entities.
case '<':
}
output("<");
break;
case '>':
}
output(">");
break;
case '&':
}
output("&");
break;
case '"':
}
output(""");
break;
// Special characters
case '\n':
case '\t':
case '\r':
break;
default:
}
// If the character is outside of ascii, write the
// numeric value.
output("&#");
output(";");
}
break;
}
}
}
}
/**
* This directly invokes super's <code>output</code> after converting
* <code>string</code> to a char[].
*/
}
}
private boolean indented = false;
/**
* Writes indent only once per line.
*/
if (!indented) {
indent();
indented = true;
}
}
}