use of com.codename1.rad.models.Tags in project CodeRAD by shannah.
the class UIBuilder method textArea.
public TextAreaPropertyView textArea(Tag... tags) {
FieldNode fn = new FieldNode(UI.tags(tags));
fn.setParent(parentNode);
return new TextAreaPropertyView(new TextArea(), entity, fn);
}
use of com.codename1.rad.models.Tags in project CodeRAD by shannah.
the class ViewPropertyParameter method createBindingParam.
public static <V> ViewPropertyParameter<V> createBindingParam(ViewProperty<V> property, Tag... tags) {
ViewPropertyParameter<V> out = new ViewPropertyParameter<V>();
out.tags = new Tags(tags);
out.property = property;
return out;
}
use of com.codename1.rad.models.Tags in project CodeRAD by shannah.
the class PropertySelector method addPropertyChangeListener.
/**
* Adds a change listener on property.
* @param l The listener to add.
*/
public void addPropertyChangeListener(ActionListener<PropertyChangeEvent> l) {
if (root != null) {
Property prop = property;
if (prop == null && tags != null) {
prop = root.getEntity().findProperty(tags);
}
if (prop != null) {
root.getEntity().addPropertyChangeListener(prop, pcl());
}
} else {
Entity leafEntity = getLeafEntity();
Property leafProperty = getLeafProperty();
if (leafEntity != null && leafProperty != null) {
leafEntity.getEntity().addPropertyChangeListener(leafProperty, pcl());
}
parent.addVetoablePropertyChangeListener(vpcl());
parent.addListChangeListener(listChangeListener());
}
if (listeners == null) {
listeners = new EventDispatcher();
}
listeners.addListener(l);
}
use of com.codename1.rad.models.Tags in project CodenameOne by codenameone.
the class CSSEngine method applyStyleToUIElement.
// //////
// CSS2 additions end
// /////
/**
* Applies the given CSS directives to the component
*
* @param ui The component representing (part of) the element that the style should be applied to
* @param selector The style attributes relating to this element
* @param element The element the style should be applied to
* @param htmlC The HTMLComponent to which this element belongs to
* @param focus true if the style should be applied only to the selected state iof the ui (a result of pseudo-class selector a:focus etc.)
*/
private void applyStyleToUIElement(Component ui, CSSElement selector, HTMLElement element, HTMLComponent htmlC) {
// count++;
// This is relevant only for non recursive types - otherwise we need to recheck everytime since it depends on the specific UI component class
int styles = getApplicableStyles(ui, selector);
// White spaces
if (HTMLComponent.FIXED_WIDTH) {
// This works well only in fixed width mode (Since we cannot "force" a newline in FlowLayout)
// TODO - enable in FIXED_WIDTH for pre vs. normal/nowrap
int space = selector.getAttrVal(CSSElement.CSS_WHITE_SPACE);
if (space != -1) {
switch(space) {
case WHITE_SPACE_NORMAL:
setWrapRecursive(element, htmlC);
break;
case WHITE_SPACE_NOWRAP:
setNowrapRecursive(element);
break;
case WHITE_SPACE_PRE:
// TODO - Not implemented yet
break;
}
}
}
// Input format
String v = selector.getAttributeById(CSSElement.CSS_WAP_INPUT_FORMAT);
if ((v != null) && ((element.getTagId() == HTMLElement.TAG_TEXTAREA) || (element.getTagId() == HTMLElement.TAG_INPUT)) && (ui instanceof TextArea)) {
v = omitQuotesIfExist(v);
// This may return a new instance of TextField taht has to be updated in the tree. This is alos the reason why input format is the first thing checked - see HTMLInputFormat.applyConstraints
ui = htmlC.setInputFormat((TextArea) ui, v);
element.setAssociatedComponents(ui);
}
// Input emptyOK
int inputRequired = selector.getAttrVal(CSSElement.CSS_WAP_INPUT_REQUIRED);
if ((inputRequired != -1) && ((element.getTagId() == HTMLElement.TAG_TEXTAREA) || (element.getTagId() == HTMLElement.TAG_INPUT)) && (ui instanceof TextArea)) {
if (inputRequired == INPUT_REQUIRED_TRUE) {
htmlC.setInputRequired(((TextArea) ui), true);
} else if (inputRequired == INPUT_REQUIRED_FALSE) {
htmlC.setInputRequired(((TextArea) ui), false);
}
}
// Display
int disp = selector.getAttrVal(CSSElement.CSS_DISPLAY);
switch(disp) {
case DISPLAY_NONE:
if (ui.getParent() != null) {
ui.getParent().removeComponent(ui);
} else {
// special case for display in the BODY tag
if (ui instanceof Container) {
((Container) ui).removeAll();
}
}
return;
case // Animate component (ticker-like)
DISPLAY_MARQUEE:
htmlC.marqueeComponents.addElement(ui);
break;
}
// Visibility
int visibility = selector.getAttrVal(CSSElement.CSS_VISIBILITY);
if (visibility != -1) {
boolean visible = (visibility == VISIBILITY_VISIBLE);
setVisibleRecursive(ui, visible);
if (!visible) {
// Don't waste time on processing hidden elements, though technically the size of the element is still reserved and should be according to style
return;
} else {
// Need to turn on visibility of all component's parents, in case they were declared hidden
setParentsVisible(ui);
}
}
//
// Dimensions
//
// TODO - debug: Width and Height don't always work - for simple components they usually do, but for containers either they don't have any effect or some inner components (with size restrictions) disappear
// We use the entire display width and height as reference since htmlC still doesn't have a preferred size or actual size
// Width
// TODO - Width/Height is disabled currently, since it causes a lot of side effects, making some components disappear
/*
int width=selector.getAttrLengthVal(CSSElement.CSS_WIDTH,ui,Display.getInstance().getDisplayWidth());
// Height
int height=selector.getAttrLengthVal(CSSElement.CSS_HEIGHT,ui,Display.getInstance().getDisplayHeight());
if (!HTMLComponent.PROCESS_HTML_MP1_ONLY) {
int minWidth=selector.getAttrLengthVal(CSSElement.CSS_MIN_WIDTH,ui,Display.getInstance().getDisplayWidth());
int maxWidth=selector.getAttrLengthVal(CSSElement.CSS_MAX_WIDTH,ui,Display.getInstance().getDisplayWidth());
int minHeight=selector.getAttrLengthVal(CSSElement.CSS_MIN_HEIGHT,ui,Display.getInstance().getDisplayHeight());
int maxHeight=selector.getAttrLengthVal(CSSElement.CSS_MAX_HEIGHT,ui,Display.getInstance().getDisplayHeight());
if (width==-1) { // process min/max only if exact was not specified
if ((minWidth!=-1) && (minWidth>ui.getPreferredW())) {
width=minWidth;
}
if ((maxWidth!=-1) && (maxWidth<ui.getPreferredW())) {
width=maxWidth;
}
}
if (height==-1) { // process min/max only if exact was not specified
if ((minHeight!=-1) && (minHeight>ui.getPreferredH())) {
height=minHeight;
}
if ((maxHeight!=-1) && (maxHeight<ui.getPreferredH())) {
height=maxHeight;
}
}
}
if ((width!=-1) || (height!=-1)) {
if (width==-1) {
width=ui.getPreferredW();
}
if (height==-1) {
height=ui.getPreferredH();
}
ui.setPreferredSize(new Dimension(width,height));
}
*/
//
// Colors
//
// Background Color
int bgColor = selector.getAttrVal(CSSElement.CSS_BACKGROUND_COLOR);
if (bgColor != -1) {
if ((styles & STYLE_UNSELECTED) != 0) {
ui.getUnselectedStyle().setBgColor(bgColor);
ui.getUnselectedStyle().setBgTransparency(255);
}
if ((styles & STYLE_SELECTED) != 0) {
ui.getSelectedStyle().setBgColor(bgColor);
ui.getSelectedStyle().setBgTransparency(255);
}
if ((styles & STYLE_PRESSED) != 0) {
((HTMLLink) ui).getPressedStyle().setBgColor(bgColor);
((HTMLLink) ui).getPressedStyle().setBgTransparency(255);
}
}
// Foreground color
int fgColor = selector.getAttrVal(CSSElement.CSS_COLOR);
if (fgColor != -1) {
setColorRecursive(ui, fgColor, selector);
}
// Background Image
v = selector.getAttributeById(CSSElement.CSS_BACKGROUND_IMAGE);
if (v != null) {
String url = getCSSUrl(v);
if (url != null) {
// Setting an alternative bgPainter that can support CSS background properties
CSSBgPainter bgPainter = new CSSBgPainter(ui);
// Background tiling
byte bgType = (byte) selector.getAttrVal(CSSElement.CSS_BACKGROUND_REPEAT);
if (bgType == -1) {
// default value
bgType = Style.BACKGROUND_IMAGE_TILE_BOTH;
}
// Note that we don't set transparency to 255, since the image may have its own transparency/opaque areas - we don't want to block the entire component/container entirely
if ((styles & STYLE_SELECTED) != 0) {
ui.getSelectedStyle().setBgPainter(bgPainter);
ui.getSelectedStyle().setBackgroundType(bgType);
}
if ((styles & STYLE_UNSELECTED) != 0) {
ui.getUnselectedStyle().setBgPainter(bgPainter);
ui.getUnselectedStyle().setBackgroundType(bgType);
}
if ((styles & STYLE_PRESSED) != 0) {
((HTMLLink) ui).getPressedStyle().setBgPainter(bgPainter);
((HTMLLink) ui).getPressedStyle().setBackgroundType(bgType);
}
// The background image itself
if (htmlC.showImages) {
if (htmlC.getDocumentInfo() != null) {
htmlC.getThreadQueue().addBgImage(ui, htmlC.convertURL(url), styles);
} else {
if (DocumentInfo.isAbsoluteURL(url)) {
htmlC.getThreadQueue().addBgImage(ui, url, styles);
} else {
if (htmlC.getHTMLCallback() != null) {
htmlC.getHTMLCallback().parsingError(HTMLCallback.ERROR_NO_BASE_URL, selector.getTagName(), selector.getAttributeName(new Integer(CSSElement.CSS_BACKGROUND_IMAGE)), url, "Ignoring background image file referred in a CSS file/segment (" + url + "), since page was set by setBody/setHTML/setDOM so there's no way to access relative URLs");
}
}
}
}
for (int i = CSSElement.CSS_BACKGROUND_POSITION_X; i <= CSSElement.CSS_BACKGROUND_POSITION_Y; i++) {
int pos = selector.getAttrVal(i);
if (pos != -1) {
bgPainter.setPosition(i, pos);
}
}
// or 'scroll' (default) which means the it moves with scrolling (Like usually in CodenameOne backgrounds)
if (selector.getAttrVal((CSSElement.CSS_BACKGROUND_ATTACHMENT)) == BG_ATTACHMENT_FIXED) {
bgPainter.setFixed();
}
}
}
// TODO - float: none/left/right
// TODO - clear: none/left/right/both
// Margin
Component marginComp = ui;
if (ui instanceof Label) {
// If this is a Label/HTMLLink we do not apply the margin individually to each word, but rather to the whole block
marginComp = ui.getParent();
} else if ((element.getTagId() == HTMLElement.TAG_LI) && (ui.getParent().getLayout() instanceof BorderLayout)) {
marginComp = ui.getParent();
}
for (int i = CSSElement.CSS_MARGIN_TOP; i <= CSSElement.CSS_MARGIN_RIGHT; i++) {
int marginPixels = -1;
if ((i == CSSElement.CSS_MARGIN_TOP) || (i == CSSElement.CSS_MARGIN_BOTTOM)) {
// Here the used component is ui and not marginComp, since we're interested in the font size (which will be corrent in Labels not in their containers)
marginPixels = selector.getAttrLengthVal(i, ui, htmlC.getHeight());
} else {
marginPixels = selector.getAttrLengthVal(i, ui, htmlC.getWidth());
}
if (marginPixels >= 0 && marginComp != null) {
if ((styles & STYLE_SELECTED) != 0) {
marginComp.getSelectedStyle().setMargin(i - CSSElement.CSS_MARGIN_TOP, marginPixels);
// parent when the link focuses
if ((ui instanceof HTMLLink) && (styles == STYLE_SELECTED)) {
((HTMLLink) ui).setParentChangesOnFocus();
}
}
if ((styles & STYLE_UNSELECTED) != 0) {
marginComp.getUnselectedStyle().setMargin(i - CSSElement.CSS_MARGIN_TOP, marginPixels);
}
// Since we don't apply the margin/padding on the component but rather on its parent
// There is no point in setting the PRESSED style since we don't have a pressed event from Button, nor do we have a pressedStyle for containers
// That's why we can't do the same trick as in selected style, and the benefit of this rather "edge" case (That is anyway not implemented in all browsers) seems rather small
// if ((styles & STYLE_PRESSED)!=0) {
// ((HTMLLink)ui).getPressedStyle().setMargin(i-CSSElement.CSS_MARGIN_TOP, marginPixels);
// }
}
}
Component padComp = ui;
if (ui instanceof Label) {
padComp = ui.getParent();
} else if ((element.getTagId() == HTMLElement.TAG_LI) && (ui.getParent().getLayout() instanceof BorderLayout)) {
padComp = ui.getParent();
}
for (int i = CSSElement.CSS_PADDING_TOP; i <= CSSElement.CSS_PADDING_RIGHT; i++) {
int padPixels = -1;
if ((i == CSSElement.CSS_PADDING_TOP) || (i == CSSElement.CSS_PADDING_BOTTOM)) {
padPixels = selector.getAttrLengthVal(i, ui, htmlC.getHeight());
} else {
padPixels = selector.getAttrLengthVal(i, ui, htmlC.getWidth());
}
if (padPixels >= 0) {
// Only positive or 0
if ((styles & STYLE_SELECTED) != 0) {
if (padComp != null) {
padComp.getSelectedStyle().setPadding(i - CSSElement.CSS_PADDING_TOP, padPixels);
}
if ((ui instanceof HTMLLink) && (styles == STYLE_SELECTED)) {
// See comment on margins
((HTMLLink) ui).setParentChangesOnFocus();
}
}
if ((styles & STYLE_UNSELECTED) != 0) {
if (padComp != null) {
padComp.getUnselectedStyle().setPadding(i - CSSElement.CSS_PADDING_TOP, padPixels);
}
}
// See comment in margin on why PRESSED was dropped
// if ((styles & STYLE_PRESSED)!=0) {
// ((HTMLLink)padComp).getPressedStyle().setPadding(i-CSSElement.CSS_PADDING_TOP, padPixels);
// }
}
}
//
// Text
//
// Text Alignment
int align = selector.getAttrVal(CSSElement.CSS_TEXT_ALIGN);
if (align != -1) {
switch(element.getTagId()) {
case HTMLElement.TAG_TD:
case HTMLElement.TAG_TH:
setTableCellAlignment(element, ui, align, true);
break;
case HTMLElement.TAG_TR:
setTableCellAlignmentTR(element, ui, align, true);
break;
case HTMLElement.TAG_TABLE:
setTableAlignment(ui, align, true);
break;
default:
// TODO - this sometimes may collide with the HTML align attribute. If the style of the same tag has alignment it overrides the align attribute, but if it is inherited, the align tag prevails
setTextAlignmentRecursive(ui, align);
}
}
// Vertical align
int valign = selector.getAttrVal(CSSElement.CSS_VERTICAL_ALIGN);
if (valign != -1) {
switch(element.getTagId()) {
case HTMLElement.TAG_TD:
case HTMLElement.TAG_TH:
setTableCellAlignment(element, ui, valign, false);
break;
case HTMLElement.TAG_TR:
setTableCellAlignmentTR(element, ui, valign, false);
break;
// break;
default:
}
}
// Text Transform
int transform = selector.getAttrVal(CSSElement.CSS_TEXT_TRANSFORM);
if (transform != -1) {
setTextTransformRecursive(ui, transform);
}
// Text indentation
int indent = selector.getAttrLengthVal(CSSElement.CSS_TEXT_INDENT, ui, htmlC.getWidth());
if (indent >= 0) {
// Only positive (0 also as it may cancel previous margins)
setTextIndentationRecursive(ui, indent);
}
//
// Font
//
// Font family
String fontFamily = selector.getAttributeById(CSSElement.CSS_FONT_FAMILY);
if (fontFamily != null) {
int index = fontFamily.indexOf(',');
if (index != -1) {
// Currently we ignore font families fall back (i.e. Arial,Helvetica,Sans-serif) since even finding a match for one font is quite expensive performance-wise
fontFamily = fontFamily.substring(0, index);
}
}
// Font Style
int fontStyle = selector.getAttrVal(CSSElement.CSS_FONT_STYLE);
// Font Weight
int fontWeight = selector.getAttrVal(CSSElement.CSS_FONT_WEIGHT);
int fontSize = selector.getAttrLengthVal(CSSElement.CSS_FONT_SIZE, ui, ui.getStyle().getFont().getHeight());
if (fontSize < -1) {
int curSize = ui.getStyle().getFont().getHeight();
if (fontSize == CSSElement.FONT_SIZE_LARGER) {
fontSize = curSize + 2;
} else if (fontSize == CSSElement.FONT_SIZE_SMALLER) {
fontSize = curSize - 2;
}
}
// Since J2ME doesn't support small-caps fonts, when a small-caps font varinat is requested
// the font-family is changed to "smallcaps" which should be loaded to HTMLComponent and the theme as a bitmap font
// If no smallcaps font is found at all, then the family stays the same, but if even only one is found - the best match will be used.
int fontVariant = selector.getAttrVal(CSSElement.CSS_FONT_VARIANT);
if ((fontVariant == FONT_VARIANT_SMALLCAPS) && (htmlC.isSmallCapsFontAvailable())) {
fontFamily = CSSElement.SMALL_CAPS_STRING;
}
// Process font only if once of the font CSS properties was mentioned and valid
if ((fontFamily != null) || (fontSize != -1) || (fontStyle != -1) || (fontWeight != -1)) {
setFontRecursive(htmlC, ui, fontFamily, fontSize, fontStyle, fontWeight, selector);
}
// List style
int listType = -1;
String listImg = null;
Component borderUi = ui;
if ((element.getTagId() == HTMLElement.TAG_LI) || (element.getTagId() == HTMLElement.TAG_UL) || (element.getTagId() == HTMLElement.TAG_OL) || (element.getTagId() == HTMLElement.TAG_DIR) || (element.getTagId() == HTMLElement.TAG_MENU)) {
int listPos = selector.getAttrVal(CSSElement.CSS_LIST_STYLE_POSITION);
if (listPos == LIST_STYLE_POSITION_INSIDE) {
// Padding and not margin since background color should affect also the indented space
ui.getStyle().setPadding(Component.LEFT, ui.getStyle().getMargin(Component.LEFT) + INDENT_LIST_STYLE_POSITION);
Container parent = ui.getParent();
if (parent.getLayout() instanceof BorderLayout) {
borderUi = parent;
}
}
listType = selector.getAttrVal(CSSElement.CSS_LIST_STYLE_TYPE);
listImg = getCSSUrl(selector.getAttributeById(CSSElement.CSS_LIST_STYLE_IMAGE));
}
// Border
Border[] borders = new Border[4];
// Used to prevent drawing a border in the middle of two words in the same segment
boolean leftBorder = false;
// Used to prevent drawing a border in the middle of two words in the same segment
boolean rightBorder = false;
boolean hasBorder = false;
if ((borderUi == ui) && (element.getUi().size() > 1)) {
if (element.getUi().firstElement() == borderUi) {
leftBorder = true;
} else if (element.getUi().lastElement() == borderUi) {
rightBorder = true;
}
} else {
leftBorder = true;
rightBorder = true;
}
for (int i = Component.TOP; i <= Component.RIGHT; i++) {
if ((i == Component.BOTTOM) || (i == Component.TOP) || ((i == Component.LEFT) && (leftBorder)) || ((i == Component.RIGHT) && (rightBorder))) {
borders[i] = createBorder(selector, borderUi, i, styles, BORDER);
if (borders[i] != null) {
hasBorder = true;
}
}
}
if (hasBorder) {
Border curBorder = borderUi.getUnselectedStyle().getBorder();
if (((styles & STYLE_SELECTED) != 0) && ((styles & STYLE_UNSELECTED) == 0)) {
curBorder = borderUi.getSelectedStyle().getBorder();
}
if ((styles & STYLE_PRESSED) != 0) {
curBorder = ((HTMLLink) borderUi).getSelectedStyle().getBorder();
}
// In case this element was assigned a top border for instance, and then by belonging to another tag/class/id it has also a bottom border - this merges the two (and gives priority to the new one)
if ((curBorder != null) && (curBorder.getCompoundBorders() != null)) {
// TODO - This doesn't cover the case of having another border (i.e. table/fieldset?) - Can also assign the non-CSS border to the other corners?
// curBorder.
Border[] oldBorders = curBorder.getCompoundBorders();
for (int i = Component.TOP; i <= Component.RIGHT; i++) {
if (borders[i] == null) {
borders[i] = oldBorders[i];
}
}
}
Border border = Border.createCompoundBorder(borders[Component.TOP], borders[Component.BOTTOM], borders[Component.LEFT], borders[Component.RIGHT]);
if (border != null) {
if ((styles & STYLE_SELECTED) != 0) {
borderUi.getSelectedStyle().setBorder(border);
}
if ((styles & STYLE_UNSELECTED) != 0) {
borderUi.getUnselectedStyle().setBorder(border);
}
if ((styles & STYLE_PRESSED) != 0) {
((HTMLLink) borderUi).getPressedStyle().setBorder(border);
}
if (borderUi.getParent() != null) {
borderUi.getParent().revalidate();
} else if (borderUi instanceof Container) {
((Container) borderUi).revalidate();
}
}
}
//
// Specific elements styling
//
// Access keys
v = selector.getAttributeById(CSSElement.CSS_WAP_ACCESSKEY);
if ((v != null) && (v.length() >= 1) && (// These are the only tags that can accpet an access key
(element.getTagId() == HTMLElement.TAG_INPUT) || (element.getTagId() == HTMLElement.TAG_TEXTAREA) || (element.getTagId() == HTMLElement.TAG_LABEL) || // For A tags this is applied only to the first word, no need to apply it to each word of the link
((element.getTagId() == HTMLElement.TAG_A) && (ui instanceof HTMLLink) && ((HTMLLink) ui).parentLink == null))) {
// The accesskey string may consist fallback assignments (comma seperated) and multiple assignments (space seperated) and any combination of those
// For example: "send *, #" (meaning: assign both the send and * keys, and if failed to assign one of those assign the # key instead)
int index = v.indexOf(',');
boolean assigned = false;
while (index != -1) {
// Handle fallback access keys
String key = v.substring(0, index).trim();
v = v.substring(index + 1);
assigned = processAccessKeys(key, htmlC, ui);
if (assigned) {
// comma denotes fallback, and once we succeeded assigning the accesskey, the others are irrelevant
break;
}
index = v.indexOf(',');
}
if (!assigned) {
processAccessKeys(v.trim(), htmlC, ui);
}
}
if (!HTMLComponent.PROCESS_HTML_MP1_ONLY) {
// Text decoration (In HTML-MP1 the only mandatory decoration is 'none')
int decoration = selector.getAttrVal(CSSElement.CSS_TEXT_DECORATION);
if (decoration == TEXT_DECOR_NONE) {
removeTextDecorationRecursive(ui, selector);
} else if (decoration == TEXT_DECOR_UNDERLINE) {
setTextDecorationRecursive(ui, Style.TEXT_DECORATION_UNDERLINE, selector);
} else if (decoration == TEXT_DECOR_LINETHROUGH) {
setTextDecorationRecursive(ui, Style.TEXT_DECORATION_STRIKETHRU, selector);
} else if (decoration == TEXT_DECOR_OVERLINE) {
setTextDecorationRecursive(ui, Style.TEXT_DECORATION_OVERLINE, selector);
}
// Word spacing
if (!HTMLComponent.FIXED_WIDTH) {
// The relative dimension is 0, since percentage doesn't work with word-spacing in browsers
int wordSpace = selector.getAttrLengthVal(CSSElement.CSS_WORD_SPACING, ui, 0);
if (wordSpace != -1) {
setWordSpacingRecursive(ui, wordSpace);
}
}
// Line height
// Technically the font height should be queried when actually resizing the line (since it may differ for a big block) - but since this would be ery time consuming and also major browsers don't take it into account - we'll do the same
// int lineHeight=selector.getAttrLengthVal(CSSElement.CSS_LINE_HEIGHT, ui, ui.getStyle().getFont().getHeight());
int lineHeight = selector.getAttrLengthVal(CSSElement.CSS_LINE_HEIGHT, ui, ui.getStyle().getFont().getHeight());
if (lineHeight != -1) {
// 100% means normal line height (don't add margin). Sizes below will not work, even they do in regular browsers
lineHeight = Math.max(0, lineHeight - ui.getStyle().getFont().getHeight());
setLineHeightRecursive(ui, lineHeight / 2);
}
// Quotes
String quotesStr = selector.getAttributeById(CSSElement.CSS_QUOTES);
if (quotesStr != null) {
Vector quotes = htmlC.getWords(quotesStr, Component.LEFT, false);
int size = quotes.size();
if ((size == 2) || (size == 4)) {
String[] quotesArr = new String[4];
for (int i = 0; i < size; i++) {
quotesArr[i] = omitQuotesIfExist((String) quotes.elementAt(i));
}
if (size == 2) {
// If only 2 quotes are specified they are used both as primary and secondary
quotesArr[2] = quotesArr[0];
quotesArr[3] = quotesArr[1];
}
setQuotesRecursive(ui, quotesArr);
}
}
// Outline
Border outline = createBorder(selector, borderUi, 0, styles, OUTLINE);
if (outline != null) {
if ((styles & STYLE_SELECTED) != 0) {
addOutlineToStyle(borderUi.getSelectedStyle(), outline);
}
if ((styles & STYLE_UNSELECTED) != 0) {
addOutlineToStyle(borderUi.getUnselectedStyle(), outline);
}
if ((styles & STYLE_PRESSED) != 0) {
addOutlineToStyle(((HTMLLink) borderUi).getPressedStyle(), outline);
}
if (borderUi.getParent() != null) {
borderUi.getParent().revalidate();
} else if (borderUi instanceof Container) {
((Container) borderUi).revalidate();
}
}
// Direction
int dir = selector.getAttrVal(CSSElement.CSS_DIRECTION);
if (dir != -1) {
setDirectionRecursive(ui, dir == DIRECTION_RTL);
}
// Table properties
if (ui instanceof HTMLTable) {
int tableProp = selector.getAttrVal(CSSElement.CSS_BORDER_COLLAPSE);
if (tableProp != -1) {
((HTMLTable) ui).setCollapseBorder(tableProp == BORDER_COLLAPSE_COLLAPSE);
}
tableProp = selector.getAttrVal(CSSElement.CSS_EMPTY_CELLS);
if (tableProp != -1) {
((HTMLTable) ui).setDrawEmptyCellsBorder(tableProp == EMPTY_CELLS_SHOW);
}
// bottom = 0 , top = 1
tableProp = selector.getAttrVal(CSSElement.CSS_CAPTION_SIDE);
if (tableProp != -1) {
Container tableParentCont = ui.getParent();
// should result in 0 when the caption is at the bottom, and 1 when the caption is on top
int tablePos = tableParentCont.getComponentIndex(ui);
if (tableProp != tablePos) {
Component caption = tableParentCont.getComponentAt((tablePos + 1) % 2);
tableParentCont.removeComponent(caption);
tableParentCont.addComponent(tablePos, caption);
}
}
String spacing = selector.getAttributeById(CSSElement.CSS_BORDER_SPACING);
if (spacing != null) {
spacing = spacing.trim();
int index = spacing.indexOf(' ');
int spaceH = 0;
int spaceV = 0;
if (index == -1) {
// one value only
spaceH = CSSElement.convertLengthVal(CSSElement.convertUnitsOrPercentage(spacing), ui, ui.getPreferredW());
spaceV = spaceH;
} else {
String spaceHoriz = spacing.substring(0, index);
String spaceVert = spacing.substring(index + 1);
spaceH = CSSElement.convertLengthVal(CSSElement.convertUnitsOrPercentage(spaceHoriz), ui, ui.getPreferredW());
spaceV = CSSElement.convertLengthVal(CSSElement.convertUnitsOrPercentage(spaceVert), ui, ui.getPreferredH());
}
((HTMLTable) ui).setBorderSpacing(spaceH, spaceV);
}
}
}
// This is since in some cases other elements can come between a OL/UL and its LI items (Though illegal in HTML, it can occur)
if ((listType != -1) || (listImg != null)) {
if (element.getTagId() == HTMLElement.TAG_LI) {
if (ui instanceof Container) {
Container liCont = (Container) ui;
Container liParent = liCont.getParent();
Component firstComp = liParent.getComponentAt(0);
if (firstComp instanceof Container) {
Container bulletCont = (Container) firstComp;
if (bulletCont.getComponentCount() > 0) {
Component listItemCmp = bulletCont.getComponentAt(0);
if (listItemCmp instanceof Component) {
HTMLListItem listItem = ((HTMLListItem) listItemCmp);
listItem.setStyleType(listType);
listItem.setImage(listImg);
}
}
}
}
} else if ((element.getTagId() == HTMLElement.TAG_UL) || (element.getTagId() == HTMLElement.TAG_OL) || (element.getTagId() == HTMLElement.TAG_DIR) || (element.getTagId() == HTMLElement.TAG_MENU)) {
Container ulCont = (Container) ui;
for (int i = 0; i < ulCont.getComponentCount(); i++) {
Component cmp = ulCont.getComponentAt(i);
if (cmp instanceof Container) {
Container liCont = (Container) cmp;
if (liCont.getComponentCount() >= 1) {
cmp = liCont.getComponentAt(0);
if (cmp instanceof Container) {
Container liContFirstLine = (Container) cmp;
if (liContFirstLine.getComponentCount() >= 1) {
cmp = liContFirstLine.getComponentAt(0);
if (cmp instanceof HTMLListItem) {
HTMLListItem listItem = (HTMLListItem) cmp;
listItem.setStyleType(listType);
listItem.setImage(listImg);
}
}
}
}
}
}
}
}
}
use of com.codename1.rad.models.Tags in project CodenameOne by codenameone.
the class HTMLComponent method processTag.
/**
* Processes the given tag. This is the main processing method that calls all others and uses itself in a recursive manner.
*
* @param element The element to process
* @param align The current alignment
*/
private void processTag(HTMLElement element, int align) {
if ((cancelled) && (!cancelledCaught)) {
return;
}
int curAlign = align;
HTMLFont oldFont = font;
int oldFontColor = textColor;
for (int i = 0; i < element.getNumChildren(); i++) {
if ((cancelled) && (!cancelledCaught)) {
break;
}
HTMLElement child = (HTMLElement) element.getChildAt(i);
// Process Tag Open
switch(child.getTagId()) {
case HTMLElement.TAG_TEXT:
// String text=child.getAttributeById(HTMLElement.ATTR_TITLE);
String text = child.getText();
if ((curComboBox != null) && (optionTag)) {
// Text is inside an OPTION tag, i.e. belongs to a ComboBox
OptionItem oi = new OptionItem(text, optionValue);
curComboBox.addItem(oi);
if (optionSelected) {
curComboBox.setSelectedItem(oi);
if (curForm != null) {
curForm.setDefaultValue(curComboBox, oi);
}
}
} else if (curTextArea != null) {
// Text is inside of a TEXTAREA tag
curTextArea.setText(text);
if (curForm != null) {
curForm.setDefaultValue(curTextArea, text);
}
} else if (element.getTagId() == HTMLElement.TAG_LEGEND) {
// Note: this is element, i.e. the child's parent (child is TAG_TEXT, and if parent is TAG_LEGEND then we process this block)
if (fieldsets.size() > 0) {
Container fset = (Container) fieldsets.lastElement();
fset.getStyle().setBorder(Border.createLineBorder(1, text));
fset.getStyle().setPadding(Component.TOP, fset.getStyle().getFont().getHeight() + 1);
}
} else if ((curTable != null) && (element.getTagId() == HTMLElement.TAG_CAPTION)) {
// Note: this is element, i.e. the child's parent (child is TAG_TEXT, and if parent is TAG_LEGEND then we process this block)
curTable.captionTextTag = child;
} else {
// long startTextTime=System.currentTimeMillis(); //debug code for performance measurement
Vector comps = null;
if (preTagCount != 0) {
comps = showPreTagText(text, curAlign);
} else {
if (FIXED_WIDTH) {
comps = showTextFixedWidth(text, curAlign);
} else {
comps = showText(text, curAlign);
}
}
if (loadCSS) {
child.setAssociatedComponents(comps);
}
// textTime+=(System.currentTimeMillis()-startTextTime); //debug code for performance measurement
}
break;
case HTMLElement.TAG_A:
link = child.getAttributeById(HTMLElement.ATTR_HREF);
if ((link != null) && (docInfo == null) && (!DocumentInfo.isAbsoluteURL(link))) {
if (htmlCallback != null) {
htmlCallback.parsingError(HTMLCallback.ERROR_NO_BASE_URL, child.getTagName(), child.getAttributeName(new Integer(HTMLElement.ATTR_HREF)), link, "Disabling relative link (" + link + "), since page was set by setBody/setHTML/setDOM so there's no way to access relative URLs");
}
link = null;
}
if ((link != null) && (htmlCallback != null)) {
int linkProps = htmlCallback.getLinkProperties(this, convertURL(link));
if ((linkProps & HTMLCallback.LINK_FORBIDDEN) != 0) {
link = null;
} else if ((linkProps & HTMLCallback.LINK_VISTED) != 0) {
linkVisited = true;
}
}
anchor = child.getAttributeById(HTMLElement.ATTR_NAME);
if (link != null) {
String aKey = child.getAttributeById(HTMLElement.ATTR_ACCESSKEY);
if ((aKey != null) && (aKey.length() == 1)) {
accesskey = aKey.charAt(0);
}
}
break;
case HTMLElement.TAG_H1:
case HTMLElement.TAG_H2:
case HTMLElement.TAG_H3:
case HTMLElement.TAG_H4:
case HTMLElement.TAG_H5:
case HTMLElement.TAG_H6:
font = (HTMLFont) fonts.get(child.getTagName());
if (font == null) {
font = oldFont;
}
// No break here intentionally
case HTMLElement.TAG_P:
curAlign = getHorizAlign(child.getAttributeById(HTMLElement.ATTR_ALIGN), align, true);
adjustAlignment(align, curAlign);
newLineIfNotEmpty(curAlign);
newLineIfLastWasNotEmpty(curAlign);
pushContainer(child);
break;
case HTMLElement.TAG_DIV:
case // CENTER is practically DIV align=CENTER
HTMLElement.TAG_CENTER:
curAlign = child.getTagId() == HTMLElement.TAG_DIV ? getHorizAlign(child.getAttributeById(HTMLElement.ATTR_ALIGN), align, true) : Component.CENTER;
adjustAlignment(align, curAlign);
newLineIfNotEmpty(curAlign);
pushContainer(child);
break;
case HTMLElement.TAG_FIELDSET:
newLineIfNotEmpty(curAlign);
Container newCont = new Container();
newCont.setUIID("HTMLFieldset");
if (fieldsets.size() == 0) {
// First fieldset shouldn't have margin
newCont.getStyle().setMargin(Component.LEFT, 0);
}
newCont.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
curContainer.addComponent(newCont);
fieldsets.addElement(newCont);
curContainer = newCont;
if (loadCSS) {
child.setAssociatedComponents(newCont);
}
break;
case HTMLElement.TAG_BR:
if (loadCSS) {
child.setAssociatedComponents(curLine);
}
newLine(curAlign);
break;
case HTMLElement.TAG_DL:
newLineIfNotEmpty(curAlign);
newLine(curAlign);
pushContainer(child);
break;
case HTMLElement.TAG_DT:
newLineIfNotEmpty(curAlign);
pushContainer(child);
break;
case HTMLElement.TAG_UL:
case HTMLElement.TAG_DIR:
case HTMLElement.TAG_MENU:
newLineIfNotEmpty(curAlign);
ulLevel++;
listIndent += INDENT_UL;
if ((ulLevel == 1) && (olIndex == Integer.MIN_VALUE)) {
// newline only if it's the first list
newLine(curAlign);
} else {
// extra indentation for level 2 and beyond
listIndent += INDENT_UL;
}
pushContainer(child);
break;
case HTMLElement.TAG_OL:
newLineIfNotEmpty(curAlign);
if (olIndex != Integer.MIN_VALUE) {
String indexStr = ORDERED_LIST_TYPE_IDENTIFIERS[listType] + "" + olIndex;
// new Integer(olIndex));
olUpperLevelIndex.addElement(indexStr);
}
// olIndex=1;
olIndex = getInt(child.getAttributeById(HTMLElement.ATTR_START), 1);
listType = getOrderedListType(child);
if ((olUpperLevelIndex.size() == 0) && (ulLevel == 0)) {
// newline only if it's the first list
newLine(curAlign);
} else {
// add indent only for second level - first one already gets it from the numbers alignment to a 4-digit number
listIndent += INDENT_OL;
}
pushContainer(child);
break;
case HTMLElement.TAG_LI:
Container listItemCont = new Container(new BorderLayout());
listItemCont.getStyle().setMargin(Component.LEFT, leftIndent + listIndent);
curContainer.addComponent(listItemCont);
containers.addElement(curContainer);
HTMLListItem bullet = null;
if (((HTMLElement) child.getParent()).getTagId() == HTMLElement.TAG_OL) {
olIndex = getInt(child.getAttributeById(HTMLElement.ATTR_VALUE), olIndex);
int itemListType = getOrderedListType(child, listType);
HTMLListIndex listIndex = new HTMLListIndex(olIndex, itemListType);
listIndex.getUnselectedStyle().setFgColor(textColor);
listIndex.getSelectedStyle().setFgColor(textColor);
listIndex.getUnselectedStyle().setFont(font.getFont());
bullet = listIndex;
// following aligns short and long numbers (assuming a 4-digit number as the maximum, as other browsers do)
bullet.getUnselectedStyle().setAlignment(Component.RIGHT);
bullet.setPreferredW(font.getFont().stringWidth("8888. "));
} else {
bullet = new HTMLBullet(getUnorderedListType(child, ulLevel), font.getFont().getHeight(), textColor, this);
}
Container bulletCont = new Container(new BorderLayout());
bulletCont.addComponent(BorderLayout.NORTH, bullet);
listItemCont.addComponent(BorderLayout.WEST, bulletCont);
Container listItemText = new Container(new BoxLayout(BoxLayout.Y_AXIS));
listItemCont.addComponent(BorderLayout.CENTER, listItemText);
curContainer = listItemText;
if (loadCSS) {
child.setAssociatedComponents(listItemText);
}
break;
case HTMLElement.TAG_BLOCKQUOTE:
newLineIfNotEmpty(curAlign);
updateMargin(INDENT_BLOCKQUOTE);
newLine(curAlign);
pushContainer(child);
break;
case HTMLElement.TAG_DD:
newLineIfNotEmpty(curAlign);
updateMargin(INDENT_DD);
pushContainer(child);
break;
case HTMLElement.TAG_HR:
newLineIfNotEmpty(curAlign);
Label hr = new Label();
hr.setUIID("HTMLHR");
// hr.getStyle().setBorder(Border.createBevelRaised());
int hrWidth = calcSize(width, child.getAttributeById(HTMLElement.ATTR_WIDTH), width, false);
int hrHeight = getInt(child.getAttributeById(HTMLElement.ATTR_SIZE), HR_THICKNESS);
hr.setPreferredW(hrWidth);
hr.setPreferredH(hrHeight);
curLine.addComponent(hr);
newLine(curAlign);
if (loadCSS) {
child.setAssociatedComponents(hr);
}
break;
case HTMLElement.TAG_STYLE:
break;
case HTMLElement.TAG_IMG:
handleImage(child, curAlign, null);
break;
case HTMLElement.TAG_PRE:
preTagCount++;
pushContainer(child);
case HTMLElement.TAG_EM:
case HTMLElement.TAG_STRONG:
case HTMLElement.TAG_DFN:
case HTMLElement.TAG_CODE:
case HTMLElement.TAG_SAMP:
case HTMLElement.TAG_KBD:
case HTMLElement.TAG_VAR:
case HTMLElement.TAG_CITE:
case HTMLElement.TAG_TT:
font = (HTMLFont) fonts.get(child.getTagName());
if (font == null) {
font = oldFont;
}
break;
case HTMLElement.TAG_B:
case HTMLElement.TAG_I:
case HTMLElement.TAG_BIG:
case HTMLElement.TAG_SMALL:
font = getCounterpartFont(child.getTagId(), font);
break;
case HTMLElement.TAG_FORM:
curForm = new HTMLForm(this, child.getAttributeById(HTMLElement.ATTR_ACTION), child.getAttributeById(HTMLElement.ATTR_METHOD), child.getAttributeById(HTMLElement.ATTR_ENCTYPE));
pushContainer(child);
break;
case HTMLElement.TAG_BUTTON:
handleInput(child, curAlign);
break;
case HTMLElement.TAG_INPUT:
handleInput(child, curAlign);
break;
case HTMLElement.TAG_SELECT:
String multi = child.getAttributeById(HTMLElement.ATTR_MULTIPLE);
// If a select tag has size specified, it will be shown as an open list, and not as Codename One combo, even if there's no multiple seection allowed
if ((multi != null) || (child.getAttributeById(HTMLElement.ATTR_SIZE) != null)) {
curComboBox = new MultiComboBox(multi != null);
Container comboCont = new Container(new BorderLayout());
curComboBox.setItemGap(0);
comboCont.setUIID("ComboBox");
curComboBox.setUIID("List");
comboCont.addComponent(BorderLayout.CENTER, curComboBox);
} else {
curComboBox = new HTMLComboBox();
}
String name = child.getAttributeById(HTMLElement.ATTR_NAME);
if (curForm != null) {
curForm.addInput(name, curComboBox, null);
}
// Even if CSS is off, we need to associate it for HTMLElement.getCurentValue
child.setAssociatedComponents(curComboBox);
if (eventsListener != null) {
eventsListener.registerComponent(curComboBox, child);
}
if ((!PROCESS_HTML_MP1_ONLY) && (child.getAttributeById(HTMLElement.ATTR_DISABLED) != null)) {
curComboBox.setEnabled(false);
}
break;
case HTMLElement.TAG_OPTGROUP:
if (curComboBox != null) {
String label = child.getAttributeById(HTMLElement.ATTR_LABEL);
if (label != null) {
curComboBox.addItem(label);
}
}
break;
case HTMLElement.TAG_OPTION:
optionTag = true;
optionValue = child.getAttributeById(HTMLElement.ATTR_VALUE);
if ((curComboBox != null) && (child.getAttributeById(HTMLElement.ATTR_SELECTED) != null)) {
optionSelected = true;
}
break;
case HTMLElement.TAG_TEXTAREA:
curTextArea = new TextArea(getInt(child.getAttributeById(HTMLElement.ATTR_ROWS), DEFAULT_TEXTAREA_ROWS), getInt(child.getAttributeById(HTMLElement.ATTR_COLS), DEFAULT_TEXTAREA_COLS));
if (!PROCESS_HTML_MP1_ONLY) {
if (child.getAttributeById(HTMLElement.ATTR_DISABLED) != null) {
curTextArea.setEnabled(false);
}
if (child.getAttributeById(HTMLElement.ATTR_READONLY) != null) {
curTextArea.setEditable(false);
}
}
addCmp(curTextArea, curAlign);
if (eventsListener != null) {
eventsListener.registerComponent(curTextArea, child);
}
// Even if CSS is off, we need to associate it for HTMLElement.getCurentValue
child.setAssociatedComponents(curTextArea);
String aKey = element.getAttributeById(HTMLElement.ATTR_ACCESSKEY);
if ((aKey != null) && (aKey.length() == 1)) {
// accessKeys.put(new Integer(aKey.charAt(0)), curTextArea);
addAccessKey(aKey.charAt(0), curTextArea, false);
}
break;
case HTMLElement.TAG_Q:
addQuote(child, curAlign, true);
quoteTagCount++;
break;
case HTMLElement.TAG_TABLE:
newLineIfNotEmpty(curAlign);
if (curTable != null) {
tables.addElement(curTable);
HTMLTableModel newTable = new HTMLTableModel();
curTable = newTable;
} else {
curTable = new HTMLTableModel();
}
// In fixed width mode we arbitrarily divide the size by a factor knowing that probably there are several cells (If we don't do it, labels inside the cell will be built up to the full width size, leaving no space for others)
width = width / 2;
break;
case HTMLElement.TAG_TR:
break;
case HTMLElement.TAG_TH:
case HTMLElement.TAG_TD:
if (curTable != null) {
handleTableCell(child, curAlign);
}
break;
case HTMLElement.TAG_LABEL:
labelForID = child.getAttributeById(HTMLElement.ATTR_FOR);
aKey = child.getAttributeById(HTMLElement.ATTR_ACCESSKEY);
if ((aKey != null) && (aKey.length() == 1)) {
accesskey = aKey.charAt(0);
}
break;
// HTML 4 tags
case HTMLElement.TAG_FONT:
// TODO - This will not work for nested font tags, need to either define color as a local parameter or create a vector stack
textColor = HTMLElement.getColor(child.getAttributeById(HTMLElement.ATTR_COLOR), textColor);
String family = child.getAttributeById(HTMLElement.ATTR_FACE);
int size = getInt(child.getAttributeById(HTMLElement.ATTR_SIZE));
if ((family != null) || (size != 0)) {
HTMLFont f = getClosestHTMLFont(family, size, 0, 0);
if (f != null) {
font = f;
}
}
break;
case HTMLElement.TAG_U:
case // INS (Inserted text) is rendered exactly like U (underline) in most browsers
HTMLElement.TAG_INS:
if (underlineCount == 0) {
textDecoration |= Style.TEXT_DECORATION_UNDERLINE;
}
underlineCount++;
break;
case HTMLElement.TAG_S:
case HTMLElement.TAG_STRIKE:
case // DEL (Deleted text) is rendered exactly like S (strikethru) in most browsers
HTMLElement.TAG_DEL:
if (strikethruCount == 0) {
textDecoration |= Style.TEXT_DECORATION_STRIKETHRU;
}
strikethruCount++;
break;
case HTMLElement.TAG_MAP:
String mapName = child.getAttributeById(HTMLElement.ATTR_NAME);
curImageMap = new ImageMapData(mapName);
break;
case HTMLElement.TAG_AREA:
handleImageMapArea(child);
break;
case HTMLElement.TAG_SUP:
superscript++;
break;
case HTMLElement.TAG_SUB:
superscript--;
break;
case HTMLElement.TAG_TBODY:
if (curTable != null) {
curTable.startSegment(HTMLTableModel.SEGMENT_TBODY);
}
break;
case HTMLElement.TAG_THEAD:
if (curTable != null) {
curTable.startSegment(HTMLTableModel.SEGMENT_THEAD);
}
break;
case HTMLElement.TAG_TFOOT:
if (curTable != null) {
curTable.startSegment(HTMLTableModel.SEGMENT_TFOOT);
}
break;
}
if (child.getNumChildren() > 0) {
processTag(child, curAlign);
}
// Process close tag
switch(child.getTagId()) {
case HTMLElement.TAG_H1:
case HTMLElement.TAG_H2:
case HTMLElement.TAG_H3:
case HTMLElement.TAG_H4:
case HTMLElement.TAG_H5:
case HTMLElement.TAG_H6:
font = oldFont;
case HTMLElement.TAG_P:
// Restore previous alignment
curAlign = align;
newLineIfNotEmpty(curAlign);
popContainer();
newLine(curAlign);
break;
case HTMLElement.TAG_DIV:
case HTMLElement.TAG_CENTER:
// Restore previous alignment
curAlign = align;
newLineIfNotEmpty(curAlign);
popContainer();
break;
case HTMLElement.TAG_FIELDSET:
newLineIfNotEmpty(curAlign);
Container fieldsetContainer = (Container) fieldsets.lastElement();
curContainer = fieldsetContainer.getParent();
fieldsets.removeElement(fieldsetContainer);
break;
case HTMLElement.TAG_BLOCKQUOTE:
newLineIfNotEmpty(curAlign);
newLine(curAlign);
updateMargin(-INDENT_BLOCKQUOTE);
popContainer();
break;
case HTMLElement.TAG_DT:
popContainer();
break;
case HTMLElement.TAG_DD:
newLineIfNotEmpty(curAlign);
updateMargin(-INDENT_DD);
popContainer();
break;
case HTMLElement.TAG_DL:
newLine(curAlign);
popContainer();
break;
case HTMLElement.TAG_A:
link = null;
linkVisited = false;
mainLink = null;
anchor = null;
accesskey = '\0';
break;
case HTMLElement.TAG_UL:
case HTMLElement.TAG_DIR:
case HTMLElement.TAG_MENU:
ulLevel--;
if ((ulLevel == 0) && (olIndex == Integer.MIN_VALUE)) {
newLine(curAlign);
} else {
// level 2 and beyond got extra indentation, so we remove it here
listIndent -= INDENT_UL;
}
listIndent -= INDENT_UL;
popContainer();
break;
case HTMLElement.TAG_OL:
if (olUpperLevelIndex.size() != 0) {
String indexStr = (String) olUpperLevelIndex.lastElement();
olUpperLevelIndex.removeElementAt(olUpperLevelIndex.size() - 1);
listType = getOrderedListType(indexStr.charAt(0), HTMLListIndex.LIST_NUMERIC);
olIndex = getInt(indexStr.substring(1));
// First level of ordered list doesn't get indentation, so we substract only if it's nested
listIndent -= INDENT_OL;
} else {
olIndex = Integer.MIN_VALUE;
}
if ((olIndex == Integer.MIN_VALUE) && (ulLevel == 0)) {
// new line only if it is the last nested list
newLine(curAlign);
}
popContainer();
break;
case HTMLElement.TAG_LI:
if (olIndex != Integer.MIN_VALUE) {
olIndex++;
}
newLineIfNotEmpty(curAlign);
// We can't use popContainer, since with LI the container is pushed even when CSS is ignored, to provide the spacing between the list item bullet/number and the text (in a nested way if needed)
Container prevContainer = (Container) containers.lastElement();
curContainer = prevContainer;
containers.removeElement(curContainer);
// curContainer=listItemParentContainer;
break;
case HTMLElement.TAG_PRE:
preTagCount--;
popContainer();
case HTMLElement.TAG_FONT:
textColor = oldFontColor;
case HTMLElement.TAG_EM:
case HTMLElement.TAG_STRONG:
case HTMLElement.TAG_DFN:
case HTMLElement.TAG_CODE:
case HTMLElement.TAG_SAMP:
case HTMLElement.TAG_KBD:
case HTMLElement.TAG_VAR:
case HTMLElement.TAG_CITE:
case HTMLElement.TAG_B:
case HTMLElement.TAG_I:
case HTMLElement.TAG_BIG:
case HTMLElement.TAG_SMALL:
case HTMLElement.TAG_TT:
font = oldFont;
break;
case HTMLElement.TAG_FORM:
if ((curForm != null) && (!curForm.hasSubmitButton) && (curForm.getNumFields() > 0)) {
// This is a fix for forms with no submit buttons which can be resulted due to the fact XHTML-MP doesn't support the BUTTON tag and also input type button with javascript
Button submitButton = new Button(curForm.createSubmitCommand(null, null));
addCmp(submitButton, curAlign);
}
curForm = null;
popContainer();
break;
case HTMLElement.TAG_TEXTAREA:
String name = child.getAttributeById(HTMLElement.ATTR_NAME);
if (curForm != null) {
// This was moved to the end tag to enable auto complete support (i.e. if there's an autocomplete it overrides the default value)
curForm.addInput(name, curTextArea, null);
}
curTextArea = null;
break;
case HTMLElement.TAG_SELECT:
if (curComboBox instanceof MultiComboBox) {
Container comboCont = curComboBox.getParent();
int minSize = Math.min(MIN_MULTI_COMBOBOX_ITEMS, curComboBox.size());
int maxSize = Math.min(curComboBox.size(), MAX_MULTI_COMBOBOX_ITEMS);
int size = Math.min(maxSize, Math.max(getInt(child.getAttributeById(HTMLElement.ATTR_SIZE)), minSize));
Component renderCmp = curComboBox.getRenderer().getListCellRendererComponent(curComboBox, "X", 0, false);
comboCont.setPreferredH((renderCmp.getPreferredH() + renderCmp.getStyle().getMargin(Component.TOP) + renderCmp.getStyle().getMargin(Component.BOTTOM) + curComboBox.getItemGap()) * size + curComboBox.getStyle().getPadding(Component.TOP) + curComboBox.getStyle().getPadding(Component.BOTTOM));
addCmp(comboCont, curAlign);
} else {
addCmp(curComboBox, curAlign);
}
curComboBox = null;
break;
case HTMLElement.TAG_OPTION:
optionTag = false;
optionSelected = false;
optionValue = null;
break;
case HTMLElement.TAG_Q:
quoteTagCount--;
addQuote(child, curAlign, false);
break;
case HTMLElement.TAG_TABLE:
newLineIfNotEmpty(curAlign);
// For a case that TR was not closed properly
curTable.commitRowIfNotEmpty();
if (curTable.getRowCount() != 0) {
// Don't add an empty table (Creates an exception in TableLayout and useless)
/*if (TABLES_LOCK_SIZE) {
for(int r=0;r<curTable.getRowCount();r++) {
for(int c=0;c<curTable.getColumnCount();c++) {
Component cmp=(Component)curTable.getValueAt(r, c);
if (cmp!=null) { // Can be null for cells that are "spanned over"
cmp.setPreferredSize(cmp.getPreferredSize());
}
}
}
}*/
HTMLTable table = new HTMLTable(curTable);
table.getStyle().setBgTransparency(0);
if (loadCSS) {
child.setAssociatedComponents(table);
}
int borderSize = getInt(child.getAttributeById(HTMLElement.ATTR_BORDER));
int[] borderPad = new int[4];
if (borderSize > 0) {
int frame = PROCESS_HTML_MP1_ONLY ? -1 : HTMLUtils.getStringVal(child.getAttributeById(HTMLElement.ATTR_FRAME), HTMLElement.ALLOWED_TABLE_FRAME_STRINGS);
Border border = Border.createLineBorder(borderSize);
if (frame == -1) {
for (int s = 0; s < borderPad.length; s++) {
borderPad[s] = borderSize;
}
} else {
Border[] borders = new Border[4];
for (int j = 0; j < HTMLElement.ALLOWED_TABLE_FRAME_VALS[frame].length; j++) {
int side = HTMLElement.ALLOWED_TABLE_FRAME_VALS[frame][j];
borders[side] = border;
borderPad[side] = borderSize;
}
border = Border.createCompoundBorder(borders[Component.TOP], borders[Component.BOTTOM], borders[Component.LEFT], borders[Component.RIGHT]);
}
table.getUnselectedStyle().setBorder(border);
table.getSelectedStyle().setBorder(border);
table.getUnselectedStyle().setPadding(borderPad[Component.TOP], borderPad[Component.BOTTOM], borderPad[Component.LEFT], borderPad[Component.RIGHT]);
table.getSelectedStyle().setPadding(borderPad[Component.TOP], borderPad[Component.BOTTOM], borderPad[Component.LEFT], borderPad[Component.RIGHT]);
} else {
table.getUnselectedStyle().setBorder(null);
table.getSelectedStyle().setBorder(null);
table.setDrawBorder(false);
}
if (!PROCESS_HTML_MP1_ONLY) {
int rules = HTMLUtils.getStringVal(child.getAttributeById(HTMLElement.ATTR_RULES), HTMLElement.ALLOWED_TABLE_RULES_STRINGS, Table.INNER_BORDERS_ALL);
table.setInnerBorderMode(rules);
int spacing = getInt(child.getAttributeById(HTMLElement.ATTR_CELLSPACING), -1);
if (spacing != -1) {
table.setBorderSpacing(spacing, spacing);
}
int padding = getInt(child.getAttributeById(HTMLElement.ATTR_CELLPADDING), -1);
if (padding != -1) {
for (int r = 0; r < curTable.getRowCount(); r++) {
for (int c = 0; c < curTable.getColumnCount(); c++) {
Component cmp = (Component) curTable.getValueAt(r, c);
if (cmp != null) {
// Can be null for cells that are "spanned over"
cmp.getUnselectedStyle().setPadding(padding, padding, padding, padding);
cmp.getSelectedStyle().setPadding(padding, padding, padding, padding);
}
}
}
}
}
if (curTable.captionTextTag != null) {
Container captionedTable = new Container(new BoxLayout(BoxLayout.Y_AXIS));
TextArea caption = new TextArea(curTable.captionTextTag.getText());
curTable.captionTextTag.setAssociatedComponents(caption);
caption.setUIID("HTMLTableCaption");
caption.setEditable(false);
caption.setFocusable(false);
caption.getStyle().setBorder(null);
caption.getStyle().setAlignment(Component.CENTER);
captionedTable.addComponent(caption);
captionedTable.addComponent(table);
addCmp(captionedTable, curAlign);
} else {
addCmp(table, curAlign);
}
newLineIfNotEmpty(curAlign);
}
if (tables.size() == 0) {
curTable = null;
} else {
curTable = (HTMLTableModel) tables.lastElement();
tables.removeElement(curTable);
}
// In fixed width mode we arbitrarily divide the size by a factor knowing that probably there are several cells - here we restore the size back
width = width * 2;
if (width > displayWidth) {
width = displayWidth;
}
break;
case HTMLElement.TAG_TR:
if (curTable != null) {
curTable.commitRow();
}
break;
case HTMLElement.TAG_TH:
case HTMLElement.TAG_TD:
if (curTable != null) {
newLineIfNotEmpty(curAlign);
curContainer = (Container) tableCells.lastElement();
tableCells.removeElement(curContainer);
}
break;
case HTMLElement.TAG_LABEL:
labelForID = null;
accesskey = '\0';
break;
// HTML 4 tags
case HTMLElement.TAG_U:
case HTMLElement.TAG_INS:
underlineCount--;
if (underlineCount == 0) {
textDecoration -= Style.TEXT_DECORATION_UNDERLINE;
}
break;
case HTMLElement.TAG_S:
case HTMLElement.TAG_STRIKE:
case HTMLElement.TAG_DEL:
strikethruCount--;
if (strikethruCount == 0) {
textDecoration -= Style.TEXT_DECORATION_STRIKETHRU;
}
break;
case HTMLElement.TAG_MAP:
if (curImageMap != null) {
if (imageMapData == null) {
imageMapData = new Hashtable();
}
imageMapData.put(curImageMap.name, curImageMap);
if ((imageMapComponents != null) && (imageMapComponents.containsKey(curImageMap.name))) {
HTMLImageMap imageMap = (HTMLImageMap) imageMapComponents.get(curImageMap.name);
imageMap.mapData = curImageMap;
}
curImageMap = null;
}
break;
case HTMLElement.TAG_SUP:
superscript--;
break;
case HTMLElement.TAG_SUB:
superscript++;
break;
case HTMLElement.TAG_TBODY:
case HTMLElement.TAG_THEAD:
case HTMLElement.TAG_TFOOT:
if (curTable != null) {
curTable.endSegment();
}
break;
}
}
}
Aggregations