001: /* HTMLs.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Sat Dec 31 12:46:27 2005, Created by tomyeh
010: }}IS_NOTE
011:
012: Copyright (C) 2004 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019: package org.zkoss.xml;
020:
021: import java.util.Set;
022: import java.util.HashSet;
023:
024: /**
025: * Utilities for HTML attributes and styles.
026: *
027: * @author tomyeh
028: */
029: public class HTMLs {
030: /** Appends an attribute to the string buffer for HTML/XML (name="val").
031: * If val is null or empty (if String), nothing is generated.
032: *
033: * <p>Note: {@link XMLs#encodeAttribute} is called automatically
034: * to encode val.
035: */
036: public static final void appendAttribute(StringBuffer sb,
037: String name, String val) {
038: if (val != null && val.length() != 0)
039: sb.append(' ').append(name).append("=\"").append(
040: XMLs.encodeAttribute(val)).append('"');
041: }
042:
043: /** Appends an attribute with a int value to the string buffer for HTML/XML (name="val").
044: */
045: public static final void appendAttribute(StringBuffer sb,
046: String name, int val) {
047: sb.append(' ').append(name).append("=\"").append(val).append(
048: '"');
049: }
050:
051: /** Appends an attribute with a long value to the string buffer for HTML/XML (name="val").
052: * @since 3.0.2
053: */
054: public static final void appendAttribute(StringBuffer sb,
055: String name, long val) {
056: sb.append(' ').append(name).append("=\"").append(val).append(
057: '"');
058: }
059:
060: /** Appends an attribute with a short value to the string buffer for HTML/XML (name="val").
061: * @since 3.0.2
062: */
063: public static final void appendAttribute(StringBuffer sb,
064: String name, short val) {
065: sb.append(' ').append(name).append("=\"").append(val).append(
066: '"');
067: }
068:
069: /** Appends an attribute to the string buffer for HTML/XML (name="val").
070: */
071: public static final void appendAttribute(StringBuffer sb,
072: String name, boolean val) {
073: sb.append(' ').append(name).append("=\"").append(val).append(
074: '"');
075: }
076:
077: /** Appends a style value to the string buffer for HTML/XML (name:"val";).
078: * If val is null or empty (if String), nothing is generated.
079: */
080: public static final void appendStyle(StringBuffer sb, String name,
081: String val) {
082: if (val != null && val.length() != 0)
083: sb.append(name).append(':').append(val).append(';');
084: }
085:
086: /** Returns the position of the specified substyle, or -1 if not found.
087: *
088: * @param style the style
089: * @param substyle the sub-style, e.g., display.
090: * @exception IllegalArgumentException if style is null, or substyle is null
091: * or empty.
092: */
093: public static final int getSubstyleIndex(String style,
094: String substyle) {
095: if (style == null || substyle == null)
096: throw new IllegalArgumentException("null");
097: if (substyle.length() == 0)
098: throw new IllegalArgumentException("empty substyle");
099:
100: for (int j = 0, len = style.length();;) {
101: int k = -1, l = j;
102: for (; l < len; ++l) {
103: final char cc = style.charAt(l);
104: if (k < 0 && cc == ':')
105: k = l; //colon found
106: else if (cc == ';')
107: break; //done
108: }
109:
110: final String nm = (k >= 0 ? style.substring(j, k) : style
111: .substring(j, l)).trim();
112: if (nm.equals(substyle))
113: return j;
114: if (l >= len)
115: return -1;
116: j = l + 1;
117: }
118: }
119:
120: /** Returns the value starting at the specified index (never null).
121: *
122: * <p>Note: the index is usually the returned vale of {@link #getSubstyleIndex}.
123: *
124: * @param style the style
125: * @param j the index that the substyle starts at (including the style's name)
126: */
127: public static final String getSubstyleValue(final String style,
128: int j) {
129: final int len = style.length();
130: int k = -1, l = j;
131: for (; l < len; ++l) {
132: final char cc = style.charAt(l);
133: if (k < 0 && cc == ':')
134: k = l; //colon found
135: else if (cc == ';')
136: break; //done
137: }
138:
139: return k < 0 ? "" : style.substring(k + 1, l).trim();
140: }
141:
142: /** Retrieves text relevant CSS styles.
143: *
144: * <p>For example, if style is
145: * "border: 1px solid blue; font-size: 10px; padding: 3px; color: black;",
146: * then "font-size: 10px;color: black;" is returned.
147: *
148: * @return null if style is null. Otherwise, it never returns null.
149: */
150: public static final String getTextRelevantStyle(final String style) {
151: if (style == null)
152: return null;
153: if (style.length() == 0)
154: return "";
155:
156: final StringBuffer sb = new StringBuffer(64);
157: for (int j = 0, len = style.length();;) {
158: int k = -1, l = j;
159: for (; l < len; ++l) {
160: final char cc = style.charAt(l);
161: if (k < 0 && cc == ':')
162: k = l; //colon found
163: else if (cc == ';')
164: break; //done
165: }
166:
167: final String nm = (k >= 0 ? style.substring(j, k) : style
168: .substring(j, l)).trim();
169: if (nm.startsWith("font") || nm.startsWith("text")
170: || _txtstyles.contains(nm))
171: sb.append(l < len ? style.substring(j, l + 1) : style
172: .substring(j));
173:
174: if (l >= len)
175: return sb.toString();
176: j = l + 1;
177: }
178: }
179:
180: private final static Set _txtstyles;
181: static {
182: final String[] txts = { "color", "background-color",
183: "background", "white-space" };
184: _txtstyles = new HashSet();
185: for (int j = txts.length; --j >= 0;)
186: _txtstyles.add(txts[j]);
187: }
188:
189: /** Returns whether the specified tag is an 'orphan' tag.
190: * By orphan we mean it doesn't support the format of
191: * <xx> </xx>.
192: *
193: * <p>For example, br and img are orphan tags.
194: *
195: * @param tagname the tag name, e.g., br and tr.
196: * @since 3.0.0
197: */
198: public static final boolean isOrphanTag(String tagname) {
199: return _orphans.contains(tagname.toLowerCase());
200: }
201:
202: /** A set of tags that don't have child. */
203: private static final Set _orphans = new HashSet(29);
204: static {
205: final String[] orphans = { "area", "base", "basefont",
206: "bgsound", "br", "col", "embed", "hr", "img", "input",
207: "isindex", "keygen", "link", "meta", "plaintext",
208: "spacer", "wbr" };
209: for (int j = orphans.length; --j >= 0;)
210: _orphans.add(orphans[j]);
211: }
212: }
|