001: // Copyright (C) 2003,2004,2005 by Object Mentor, Inc. All rights reserved.
002: // Released under the terms of the GNU General Public License version 2 or later.
003: package fitnesse.html;
004:
005: import java.util.*;
006:
007: public class HtmlTag extends HtmlElement {
008: public static final String IMAGE_TAG = "img";
009:
010: public LinkedList childTags = new LinkedList();
011:
012: protected List attributes = new LinkedList();
013:
014: protected String tagName = "youreIt";
015:
016: public String tail;
017:
018: public String head;
019:
020: private boolean addNewlineAfter = true;
021:
022: /** Creates a new HTML tag.
023: * If tagName is "img", the addNewlineAfter property will be initialized false;
024: * otherwise it will be initialized true.
025: */
026: // I've added the "a" tag to the new line escape condition so a bread crumb
027: // can be easily copied for tests. This causes other issues like preventing word wrap.
028: // TODO: Think more about this...
029: public HtmlTag(String tagName) {
030: this .tagName = tagName;
031: if (IMAGE_TAG.equals(tagName()) || "a".equals(tagName())) {
032: this .addNewlineAfter = false;
033: }
034: }
035:
036: public HtmlTag(String tagName, String content) {
037: this (tagName);
038: add(content);
039: }
040:
041: public HtmlTag(String tagName, HtmlElement child) {
042: this (tagName);
043: add(child);
044: }
045:
046: public boolean isAddNewlineAfter() {
047: return this .addNewlineAfter;
048: }
049:
050: /** If addNewlineAfter is true, the generated HTML will contain a newline
051: * after the close tag, making it more readable. If false, it will not,
052: * preventing extraneous whitespace.
053: */
054: public void setAddNewlineAfter(boolean addNewlineInside) {
055: this .addNewlineAfter = addNewlineInside;
056: }
057:
058: public String tagName() {
059: return tagName;
060: }
061:
062: public String html() throws Exception {
063: return html(0);
064: }
065:
066: public String html(int depth) throws Exception {
067: StringBuffer buffer = new StringBuffer();
068: addTabs(depth, buffer);
069:
070: if (head != null) {
071: buffer.append(head);
072: }
073:
074: buffer.append("<").append(tagName());
075: addAttributes(buffer);
076:
077: if (hasChildren()) {
078: buffer.append(">");
079: boolean tagWasAdded = addChildHtml(buffer, depth);
080: if (tagWasAdded) {
081: addTabs(depth, buffer);
082: }
083: buffer.append("</").append(tagName()).append(">");
084: } else {
085: buffer.append("/>");
086: }
087:
088: if (tail != null) {
089: buffer.append(tail);
090: }
091:
092: if (this .addNewlineAfter) {
093: buffer.append(endl);
094: }
095:
096: return buffer.toString();
097: }
098:
099: private void addAttributes(StringBuffer buffer) {
100: for (Iterator iterator = attributes.iterator(); iterator
101: .hasNext();) {
102: Attribute attribute = (Attribute) iterator.next();
103: buffer.append(" ").append(attribute.name).append("=\"")
104: .append(attribute.value).append("\"");
105: }
106: }
107:
108: protected void addTabs(int depth, StringBuffer buffer) {
109: // for(int i = 0; i < depth; i++)
110: // buffer.append('\t');
111: }
112:
113: private boolean addChildHtml(StringBuffer buffer, int depth)
114: throws Exception {
115: boolean addedTag = false;
116: int i = 0;
117: for (Iterator iterator = childTags.iterator(); iterator
118: .hasNext(); i++) {
119: HtmlElement element = (HtmlElement) iterator.next();
120: if (element instanceof HtmlTag) {
121: buffer.append(((HtmlTag) element).html(depth + 1));
122: addedTag = true;
123: } else {
124: buffer.append(element.html());
125: }
126: }
127:
128: return addedTag;
129: }
130:
131: private boolean hasChildren() {
132: return childTags.size() > 0;
133: }
134:
135: public void add(String s) {
136: add(new RawHtml(s));
137: }
138:
139: public void add(HtmlElement element) {
140: childTags.add(element);
141: }
142:
143: public void addAttribute(String key, String value) {
144: attributes.add(new Attribute(key, value));
145: }
146:
147: public void use(String s) {
148: use(new RawHtml(s));
149: }
150:
151: public void use(HtmlElement element) {
152: childTags.clear();
153: add(element);
154: }
155:
156: public String getAttribute(String key) {
157: for (Iterator iterator = attributes.iterator(); iterator
158: .hasNext();) {
159: Attribute attribute = (Attribute) iterator.next();
160: if (key != null && key.equals(attribute.name)) {
161: return attribute.value;
162: }
163: }
164: return null;
165: }
166:
167: public static class Attribute {
168: public String name;
169:
170: public String value;
171:
172: public Attribute(String name, String value) {
173: this.name = name;
174: this.value = value;
175: }
176: }
177: }
|