java.lang.Objectjavax.swing.text.html.CSS
All Implemented Interfaces:
Serializable
The following describes the CSS properties that are suppored by the rendering engine:
Note: for the time being we do not fully support relative units,
unless noted, so that
p { margin-top: 10% } will be treated as if no margin-top was specified.
The CSS parser uses the parseCssValue method to convert
a string to whatever format is appropriate a given key
(i.e. these convertors are stored in a map using the
CSS.Attribute as a key and the CssValue as the value).
The HTML to CSS conversion process first converts the
HTML.Attribute to a CSS.Attribute, and then calls
the parseHtmlValue method on the value of the HTML
attribute to produce the corresponding CSS value.
The StyleConstants to CSS conversion process first
converts the StyleConstants attribute to a
CSS.Attribute, and then calls the fromStyleConstants
method to convert the StyleConstants value to a
CSS value.
The CSS to StyleConstants conversion process first
converts the StyleConstants attribute to a
CSS.Attribute, and then calls the toStyleConstants
method to convert the CSS value to a StyleConstants
value. Also see:
Timothy
- PrinzingScott
- VioletNested Class Summary: public static final class CSS.Attribute Definitions to be used as a key on AttributeSet's
that might hold CSS attributes. Since this is a
closed set (i.e. defined exactly by the specification),
it is final and cannot be extended. static final class CSS.Value static class CSS.CssValue Base class to CSS values in the attribute sets. This
is intended to act as a convertor to/from other attribute
formats.
static class CSS.StringValue By default CSS attributes are represented as simple
strings. They also have no conversion to/from
StyleConstants by default. This class represents the
value as a string (via the superclass), but
provides StyleConstants conversion support for the
CSS attributes that are held as strings. class CSS.FontSize Represents a value for the CSS.FONT_SIZE attribute.
The binary format of the value can be one of several
types. If the type is Float,
the value is specified in terms of point or
percentage, depending upon the ending of the
associated string.
If the type is Integer, the value is specified
in terms of a size index. static class CSS.FontFamily static class CSS.FontWeight static class CSS.ColorValue static class CSS.BorderStyle static class CSS.LengthValue static class CSS.BorderWidthValue BorderWidthValue is used to model BORDER_XXX_WIDTH and adds support
for the thin/medium/thick values. static class CSS.CssValueMapper Handles uniquing of CSS values, like lists, and background image
repeating. static class CSS.BackgroundPosition Used for background images, to represent the position. static class CSS.BackgroundImage Used for BackgroundImages. static class CSS.LengthUnit Parses a length value, this is used internally, and never added
to an AttributeSet or returned to the developer. static class CSS.ShorthandFontParser Class used to parse font property. The font property is shorthand
for the other font properties. This expands the properties, placing
them in the attributeset. static class CSS.ShorthandBackgroundParser Parses the background property into its intrinsic values. static class CSS.ShorthandMarginParser Used to parser margin and padding. static class CSS.ShorthandBorderParser interface CSS.LayoutIterator An iterator to express the requirements to use when computing
layout. Field Summary static int baseFontSizeIndex Methods from java.lang.Object:
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait Method from javax.swing.text.html.CSS Detail: void addInternalCSSValue(MutableAttributeSet attr,
Attribute key,
String value)
{
if (key == CSS.Attribute.FONT) {
ShorthandFontParser.parseShorthandFont(this, value, attr);
}
else if (key == CSS.Attribute.BACKGROUND) {
ShorthandBackgroundParser.parseShorthandBackground
(this, value, attr);
}
else if (key == CSS.Attribute.MARGIN) {
ShorthandMarginParser.parseShorthandMargin(this, value, attr,
CSS.Attribute.ALL_MARGINS);
}
else if (key == CSS.Attribute.PADDING) {
ShorthandMarginParser.parseShorthandMargin(this, value, attr,
CSS.Attribute.ALL_PADDING);
}
else if (key == CSS.Attribute.BORDER_WIDTH) {
ShorthandMarginParser.parseShorthandMargin(this, value, attr,
CSS.Attribute.ALL_BORDER_WIDTHS);
}
else if (key == CSS.Attribute.BORDER_COLOR) {
ShorthandMarginParser.parseShorthandMargin(this, value, attr,
CSS.Attribute.ALL_BORDER_COLORS);
}
else if (key == CSS.Attribute.BORDER_STYLE) {
ShorthandMarginParser.parseShorthandMargin(this, value, attr,
CSS.Attribute.ALL_BORDER_STYLES);
}
else if ((key == CSS.Attribute.BORDER) ||
(key == CSS.Attribute.BORDER_TOP) ||
(key == CSS.Attribute.BORDER_RIGHT) ||
(key == CSS.Attribute.BORDER_BOTTOM) ||
(key == CSS.Attribute.BORDER_LEFT)) {
ShorthandBorderParser.parseShorthandBorder(attr, key, value);
}
else {
Object iValue = getInternalCSSValue(key, value);
if (iValue != null) {
attr.addAttribute(key, iValue);
}
}
}
Parses the CSS property
key
with value
value
placing the result in att
. static void calculateTiledLayout(LayoutIterator iter,
int targetSpan)
{
/*
* first pass, calculate the preferred sizes, adjustments needed because
* of margin collapsing, and the flexibility to adjust the sizes.
*/
long preferred = 0;
long currentPreferred;
int lastMargin = 0;
int totalSpacing = 0;
int n = iter.getCount();
int adjustmentWeightsCount = LayoutIterator.WorstAdjustmentWeight + 1;
//max gain we can get adjusting elements with adjustmentWeight < = i
long gain[] = new long[adjustmentWeightsCount];
//max loss we can get adjusting elements with adjustmentWeight < = i
long loss[] = new long[adjustmentWeightsCount];
for (int i = 0; i < adjustmentWeightsCount; i++) {
gain[i] = loss[i] = 0;
}
for (int i = 0; i < n; i++) {
iter.setIndex(i);
int margin0 = lastMargin;
int margin1 = (int) iter.getLeadingCollapseSpan();
iter.setOffset(Math.max(margin0, margin1));
totalSpacing += iter.getOffset();
currentPreferred = (long)iter.getPreferredSpan(targetSpan);
iter.setSpan((int) currentPreferred);
preferred += currentPreferred;
gain[iter.getAdjustmentWeight()] +=
(long)iter.getMaximumSpan(targetSpan) - currentPreferred;
loss[iter.getAdjustmentWeight()] +=
currentPreferred - (long)iter.getMinimumSpan(targetSpan);
lastMargin = (int) iter.getTrailingCollapseSpan();
}
totalSpacing += lastMargin;
totalSpacing += 2 * iter.getBorderWidth();
for (int i = 1; i < adjustmentWeightsCount; i++) {
gain[i] += gain[i - 1];
loss[i] += loss[i - 1];
}
/*
* Second pass, expand or contract by as much as possible to reach
* the target span. This takes the margin collapsing into account
* prior to adjusting the span.
*/
// determine the adjustment to be made
int allocated = targetSpan - totalSpacing;
long desiredAdjustment = allocated - preferred;
long adjustmentsArray[] = (desiredAdjustment > 0) ? gain : loss;
desiredAdjustment = Math.abs(desiredAdjustment);
int adjustmentLevel = 0;
for (;adjustmentLevel < = LayoutIterator.WorstAdjustmentWeight;
adjustmentLevel++) {
// adjustmentsArray[] is sorted. I do not bother about
// binary search though
if (adjustmentsArray[adjustmentLevel] >= desiredAdjustment) {
break;
}
}
float adjustmentFactor = 0.0f;
if (adjustmentLevel < = LayoutIterator.WorstAdjustmentWeight) {
desiredAdjustment -= (adjustmentLevel > 0) ?
adjustmentsArray[adjustmentLevel - 1] : 0;
if (desiredAdjustment != 0) {
float maximumAdjustment =
adjustmentsArray[adjustmentLevel] -
((adjustmentLevel > 0) ?
adjustmentsArray[adjustmentLevel - 1] : 0
);
adjustmentFactor = desiredAdjustment / maximumAdjustment;
}
}
// make the adjustments
int totalOffset = (int)iter.getBorderWidth();
for (int i = 0; i < n; i++) {
iter.setIndex(i);
iter.setOffset( iter.getOffset() + totalOffset);
if (iter.getAdjustmentWeight() < adjustmentLevel) {
iter.setSpan((int)
((allocated > preferred) ?
Math.floor(iter.getMaximumSpan(targetSpan)) :
Math.ceil(iter.getMinimumSpan(targetSpan))
)
);
} else if (iter.getAdjustmentWeight() == adjustmentLevel) {
int availableSpan = (allocated > preferred) ?
(int) iter.getMaximumSpan(targetSpan) - iter.getSpan() :
iter.getSpan() - (int) iter.getMinimumSpan(targetSpan);
int adj = (int)Math.floor(adjustmentFactor * availableSpan);
iter.setSpan(iter.getSpan() +
((allocated > preferred) ? adj : -adj));
}
totalOffset = (int) Math.min((long) iter.getOffset() +
(long) iter.getSpan(),
Integer.MAX_VALUE);
}
// while rounding we could lose several pixels.
int roundError = targetSpan - totalOffset -
(int)iter.getTrailingCollapseSpan() -
(int)iter.getBorderWidth();
int adj = (roundError > 0) ? 1 : -1;
roundError *= adj;
boolean canAdjust = true;
while (roundError > 0 && canAdjust) {
// check for infinite loop
canAdjust = false;
int offsetAdjust = 0;
// try to distribute roundError. one pixel per cell
for (int i = 0; i < n; i++) {
iter.setIndex(i);
iter.setOffset(iter.getOffset() + offsetAdjust);
int curSpan = iter.getSpan();
if (roundError > 0) {
int boundGap = (adj > 0) ?
(int)Math.floor(iter.getMaximumSpan(targetSpan)) - curSpan :
curSpan - (int)Math.ceil(iter.getMinimumSpan(targetSpan));
if (boundGap >= 1) {
canAdjust = true;
iter.setSpan(curSpan + adj);
offsetAdjust += adj;
roundError--;
}
}
}
}
}
Calculate a tiled layout for the given iterator.
This should be done collapsing the neighboring
margins to be a total of the maximum of the two
neighboring margin areas as described in the CSS spec.
static SizeRequirements calculateTiledRequirements(LayoutIterator iter,
SizeRequirements r)
{
long minimum = 0;
long maximum = 0;
long preferred = 0;
int lastMargin = 0;
int totalSpacing = 0;
int n = iter.getCount();
for (int i = 0; i < n; i++) {
iter.setIndex(i);
int margin0 = lastMargin;
int margin1 = (int) iter.getLeadingCollapseSpan();
totalSpacing += Math.max(margin0, margin1);
preferred += (int) iter.getPreferredSpan(0);
minimum += iter.getMinimumSpan(0);
maximum += iter.getMaximumSpan(0);
lastMargin = (int) iter.getTrailingCollapseSpan();
}
totalSpacing += lastMargin;
totalSpacing += 2 * iter.getBorderWidth();
// adjust for the spacing area
minimum += totalSpacing;
preferred += totalSpacing;
maximum += totalSpacing;
// set return value
if (r == null) {
r = new SizeRequirements();
}
r.minimum = (minimum > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int)minimum;
r.preferred = (preferred > Integer.MAX_VALUE) ? Integer.MAX_VALUE :(int) preferred;
r.maximum = (maximum > Integer.MAX_VALUE) ? Integer.MAX_VALUE :(int) maximum;
return r;
}
Calculate the requirements needed to tile the requirements
given by the iterator that would be tiled. The calculation
takes into consideration margin and border spacing.
static String colorToHex(Color color)
{
String colorstr = "#";
// Red
String str = Integer.toHexString(color.getRed());
if (str.length() > 2)
str = str.substring(0, 2);
else if (str.length() < 2)
colorstr += "0" + str;
else
colorstr += str;
// Green
str = Integer.toHexString(color.getGreen());
if (str.length() > 2)
str = str.substring(0, 2);
else if (str.length() < 2)
colorstr += "0" + str;
else
colorstr += str;
// Blue
str = Integer.toHexString(color.getBlue());
if (str.length() > 2)
str = str.substring(0, 2);
else if (str.length() < 2)
colorstr += "0" + str;
else
colorstr += str;
return colorstr;
}
Converts a type Color to a hex string
in the format "#RRGGBB"
Object cssValueToStyleConstantsValue(StyleConstants key,
Object value)
{
if (value instanceof CssValue) {
return ((CssValue)value).toStyleConstants(key, null);
}
return null;
}
Converts the passed in CSS value to a StyleConstants value.
key
identifies the CSS attribute being mapped. public static Attribute[] getAllAttributeKeys()
{
Attribute[] keys = new Attribute[Attribute.allAttributes.length];
System.arraycopy(Attribute.allAttributes, 0, keys, 0, Attribute.allAttributes.length);
return keys;
}
Return the set of all possible CSS attribute keys.
public static final Attribute getAttribute(String name)
{
return attributeMap.get(name);
}
Translates a string to a
CSS.Attribute
object.
This will return null
if there is no attribute
by the given name. int getBaseFontSize()
{
return baseFontSize;
}
Returns the base font size.
Color getColor(AttributeSet a,
Attribute key)
{
ColorValue cv = (ColorValue) a.getAttribute(key);
if (cv != null) {
return cv.getValue();
}
return null;
}
Takes a set of attributes and turn it into a color
specification. This might be used to specify things
like brighter, more hue, etc.
This will return null if there is no value for
key
. Object getCssValue(Attribute cssAttr,
String htmlAttrValue)
{
CssValue value = (CssValue)valueConvertor.get(cssAttr);
Object o = value.parseHtmlValue(htmlAttrValue);
return o;
}
Given a CSS.Attribute object and its corresponding HTML.Attribute's
value, this method returns a CssValue object to associate with the
CSS attribute.
Font getFont(StyleContext sc,
AttributeSet a,
int defaultSize,
StyleSheet ss)
{
ss = getStyleSheet(ss);
int size = getFontSize(a, defaultSize, ss);
/*
* If the vertical alignment is set to either superscirpt or
* subscript we reduce the font size by 2 points.
*/
StringValue vAlignV = (StringValue)a.getAttribute
(CSS.Attribute.VERTICAL_ALIGN);
if ((vAlignV != null)) {
String vAlign = vAlignV.toString();
if ((vAlign.indexOf("sup") >= 0) ||
(vAlign.indexOf("sub") >= 0)) {
size -= 2;
}
}
FontFamily familyValue = (FontFamily)a.getAttribute
(CSS.Attribute.FONT_FAMILY);
String family = (familyValue != null) ? familyValue.getValue() :
Font.SANS_SERIF;
int style = Font.PLAIN;
FontWeight weightValue = (FontWeight) a.getAttribute
(CSS.Attribute.FONT_WEIGHT);
if ((weightValue != null) && (weightValue.getValue() > 400)) {
style |= Font.BOLD;
}
Object fs = a.getAttribute(CSS.Attribute.FONT_STYLE);
if ((fs != null) && (fs.toString().indexOf("italic") >= 0)) {
style |= Font.ITALIC;
}
if (family.equalsIgnoreCase("monospace")) {
family = Font.MONOSPACED;
}
Font f = sc.getFont(family, style, size);
if (f == null
|| (f.getFamily().equals(Font.DIALOG)
&& ! family.equalsIgnoreCase(Font.DIALOG))) {
family = Font.SANS_SERIF;
f = sc.getFont(family, style, size);
}
return f;
}
Returns the font for the values in the passed in AttributeSet.
It is assumed the keys will be CSS.Attribute keys.
sc
is the StyleContext that will be messaged to get
the font once the size, name and style have been determined. static int getFontSize(AttributeSet attr,
int defaultSize,
StyleSheet ss)
{
// PENDING(prinz) this is a 1.1 based implementation, need to also
// have a 1.2 version.
FontSize sizeValue = (FontSize)attr.getAttribute(CSS.Attribute.
FONT_SIZE);
return (sizeValue != null) ? sizeValue.getValue(attr, ss)
: defaultSize;
}
static int getIndexOfSize(float pt,
int[] sizeMap)
{
for (int i = 0; i < sizeMap.length; i ++ )
if (pt < = sizeMap[i])
return i + 1;
return sizeMap.length;
}
static int getIndexOfSize(float pt,
StyleSheet ss)
{
int[] sizeMap = (ss != null) ? ss.getSizeMap() :
StyleSheet.sizeMapDefault;
return getIndexOfSize(pt, sizeMap);
}
Object getInternalCSSValue(Attribute key,
String value)
{
CssValue conv = (CssValue) valueConvertor.get(key);
Object r = conv.parseCssValue(value);
return r != null ? r : conv.parseCssValue(key.getDefaultValue());
}
Gets the internal CSS representation of
value
which is
a CSS value of the CSS attribute named key
. The receiver
should not modify value
, and the first count
strings are valid. float getLength(AttributeSet a,
Attribute key,
StyleSheet ss)
{
ss = getStyleSheet(ss);
LengthValue lv = (LengthValue) a.getAttribute(key);
boolean isW3CLengthUnits = (ss == null) ? false : ss.isW3CLengthUnits();
float len = (lv != null) ? lv.getValue(isW3CLengthUnits) : 0;
return len;
}
Returns the length of the attribute in
a
with
key key
. float getPointSize(String size,
StyleSheet ss)
{
int relSize, absSize, diff, index;
ss = getStyleSheet(ss);
if (size != null) {
if (size.startsWith("+")) {
relSize = Integer.valueOf(size.substring(1)).intValue();
return getPointSize(baseFontSize + relSize, ss);
} else if (size.startsWith("-")) {
relSize = -Integer.valueOf(size.substring(1)).intValue();
return getPointSize(baseFontSize + relSize, ss);
} else {
absSize = Integer.valueOf(size).intValue();
return getPointSize(absSize, ss);
}
}
return 0;
}
Returns the size of a font from the passed in string.
float getPointSize(int index,
StyleSheet ss)
{
ss = getStyleSheet(ss);
int[] sizeMap = (ss != null) ? ss.getSizeMap() :
StyleSheet.sizeMapDefault;
--index;
if (index < 0)
return sizeMap[0];
else if (index > sizeMap.length - 1)
return sizeMap[sizeMap.length - 1];
else
return sizeMap[index];
}
Return the point size, given a size index. Legal HTML index sizes
are 1-7.
static URL getURL(URL base,
String cssString)
{
if (cssString == null) {
return null;
}
if (cssString.startsWith("url(") &&
cssString.endsWith(")")) {
cssString = cssString.substring(4, cssString.length() - 1);
}
// Absolute first
try {
URL url = new URL(cssString);
if (url != null) {
return url;
}
} catch (MalformedURLException mue) {
}
// Then relative
if (base != null) {
// Relative URL, try from base
try {
URL url = new URL(base, cssString);
return url;
}
catch (MalformedURLException muee) {
}
}
return null;
}
Returns a URL for the given CSS url string. If relative,
base
is used as the parent. If a valid URL can not
be found, this will not throw a MalformedURLException, instead
null will be returned. static final Value getValue(String name)
{
return valueMap.get(name);
}
Translates a string to a
CSS.Value
object.
This will return null
if there is no value
by the given name. static final Color hexToColor(String value)
{
String digits;
int n = value.length();
if (value.startsWith("#")) {
digits = value.substring(1, Math.min(value.length(), 7));
} else {
digits = value;
}
String hstr = "0x" + digits;
Color c;
try {
c = Color.decode(hstr);
} catch (NumberFormatException nfe) {
c = null;
}
return c;
}
Convert a "#FFFFFF" hex string to a Color.
If the color specification is bad, an attempt
will be made to fix it up.
static String[] parseStrings(String value)
{
int current, last;
int length = (value == null) ? 0 : value.length();
Vector< String > temp = new Vector< String >(4);
current = 0;
while (current < length) {
// Skip ws
while (current < length && Character.isWhitespace
(value.charAt(current))) {
current++;
}
last = current;
while (current < length && !Character.isWhitespace
(value.charAt(current))) {
current++;
}
if (last != current) {
temp.addElement(value.substring(last, current));
}
current++;
}
String[] retValue = new String[temp.size()];
temp.copyInto(retValue);
return retValue;
}
void setBaseFontSize(int sz)
{
if (sz < 1)
baseFontSize = 0;
else if (sz > 7)
baseFontSize = 7;
else
baseFontSize = sz;
}
Sets the base font size.
sz
is a CSS value, and is
not necessarily the point size. Use getPointSize to determine the
point size corresponding to sz
. void setBaseFontSize(String size)
{
int relSize, absSize, diff;
if (size != null) {
if (size.startsWith("+")) {
relSize = Integer.valueOf(size.substring(1)).intValue();
setBaseFontSize(baseFontSize + relSize);
} else if (size.startsWith("-")) {
relSize = -Integer.valueOf(size.substring(1)).intValue();
setBaseFontSize(baseFontSize + relSize);
} else {
setBaseFontSize(Integer.valueOf(size).intValue());
}
}
}
Sets the base font size from the passed in string.
static Color stringToColor(String str)
{
Color color;
if (str == null) {
return null;
}
if (str.length() == 0)
color = Color.black;
else if (str.startsWith("rgb(")) {
color = parseRGB(str);
}
else if (str.charAt(0) == '#')
color = hexToColor(str);
else if (str.equalsIgnoreCase("Black"))
color = hexToColor("#000000");
else if(str.equalsIgnoreCase("Silver"))
color = hexToColor("#C0C0C0");
else if(str.equalsIgnoreCase("Gray"))
color = hexToColor("#808080");
else if(str.equalsIgnoreCase("White"))
color = hexToColor("#FFFFFF");
else if(str.equalsIgnoreCase("Maroon"))
color = hexToColor("#800000");
else if(str.equalsIgnoreCase("Red"))
color = hexToColor("#FF0000");
else if(str.equalsIgnoreCase("Purple"))
color = hexToColor("#800080");
else if(str.equalsIgnoreCase("Fuchsia"))
color = hexToColor("#FF00FF");
else if(str.equalsIgnoreCase("Green"))
color = hexToColor("#008000");
else if(str.equalsIgnoreCase("Lime"))
color = hexToColor("#00FF00");
else if(str.equalsIgnoreCase("Olive"))
color = hexToColor("#808000");
else if(str.equalsIgnoreCase("Yellow"))
color = hexToColor("#FFFF00");
else if(str.equalsIgnoreCase("Navy"))
color = hexToColor("#000080");
else if(str.equalsIgnoreCase("Blue"))
color = hexToColor("#0000FF");
else if(str.equalsIgnoreCase("Teal"))
color = hexToColor("#008080");
else if(str.equalsIgnoreCase("Aqua"))
color = hexToColor("#00FFFF");
else if(str.equalsIgnoreCase("Orange"))
color = hexToColor("#FF8000");
else
color = hexToColor(str); // sometimes get specified without leading #
return color;
}
Convert a color string such as "RED" or "#NNNNNN" or "rgb(r, g, b)"
to a Color.
Attribute styleConstantsKeyToCSSKey(StyleConstants sc)
{
return styleConstantToCssMap.get(sc);
}
Maps from a StyleConstants to a CSS Attribute.
Object styleConstantsValueToCSSValue(StyleConstants sc,
Object styleValue)
{
Attribute cssKey = styleConstantsKeyToCSSKey(sc);
if (cssKey != null) {
CssValue conv = (CssValue)valueConvertor.get(cssKey);
return conv.fromStyleConstants(sc, styleValue);
}
return null;
}
Maps from a StyleConstants value to a CSS value.
AttributeSet translateHTMLToCSS(AttributeSet htmlAttrSet)
{
MutableAttributeSet cssAttrSet = new SimpleAttributeSet();
Element elem = (Element)htmlAttrSet;
HTML.Tag tag = getHTMLTag(htmlAttrSet);
if ((tag == HTML.Tag.TD) || (tag == HTML.Tag.TH)) {
// translate border width into the cells, if it has non-zero value.
AttributeSet tableAttr = elem.getParentElement().
getParentElement().getAttributes();
int borderWidth;
try {
borderWidth = Integer.parseInt(
(String) tableAttr.getAttribute(HTML.Attribute.BORDER));
} catch (NumberFormatException e) {
borderWidth = 0;
}
if (borderWidth > 0) {
translateAttribute(HTML.Attribute.BORDER, tableAttr, cssAttrSet);
}
String pad = (String)tableAttr.getAttribute(HTML.Attribute.CELLPADDING);
if (pad != null) {
LengthValue v =
(LengthValue)getInternalCSSValue(CSS.Attribute.PADDING_TOP, pad);
v.span = (v.span < 0) ? 0 : v.span;
cssAttrSet.addAttribute(CSS.Attribute.PADDING_TOP, v);
cssAttrSet.addAttribute(CSS.Attribute.PADDING_BOTTOM, v);
cssAttrSet.addAttribute(CSS.Attribute.PADDING_LEFT, v);
cssAttrSet.addAttribute(CSS.Attribute.PADDING_RIGHT, v);
}
}
if (elem.isLeaf()) {
translateEmbeddedAttributes(htmlAttrSet, cssAttrSet);
} else {
translateAttributes(tag, htmlAttrSet, cssAttrSet);
}
if (tag == HTML.Tag.CAPTION) {
/*
* Navigator uses ALIGN for caption placement and IE uses VALIGN.
*/
Object v = htmlAttrSet.getAttribute(HTML.Attribute.ALIGN);
if ((v != null) && (v.equals("top") || v.equals("bottom"))) {
cssAttrSet.addAttribute(CSS.Attribute.CAPTION_SIDE, v);
cssAttrSet.removeAttribute(CSS.Attribute.TEXT_ALIGN);
} else {
v = htmlAttrSet.getAttribute(HTML.Attribute.VALIGN);
if (v != null) {
cssAttrSet.addAttribute(CSS.Attribute.CAPTION_SIDE, v);
}
}
}
return cssAttrSet;
}
Convert a set of HTML attributes to an equivalent
set of CSS attributes.