// We will always render the TD with tab label, and sometimes
// two extra margins
int tdsRendered = 1;
TabsContext context = getCurrentContext();
context.getPageContext().pushContainerInstance(getLabelsRegionInstance());
DOMOutputBuffer labelsBuffer =
(DOMOutputBuffer) getLabelsRegionInstance().getCurrentBuffer();
Styles tabStyles = attributes.getStyles();
// Get content value specified for ::mcs-label
Styles inactiveLabelStyles = (null == tabStyles ? null : tabStyles
.getNestedStyles(PseudoElements.MCS_LABEL));
StyleValue inactiveLabelContent = (null == inactiveLabelStyles ? null
: inactiveLabelStyles.getPropertyValues().getSpecifiedValue(
StylePropertyDetails.CONTENT));
// Get content value specified for ::mcs-label:active
Styles activeLabelStyles = (null == inactiveLabelStyles ? null
: inactiveLabelStyles
.getNestedStyles(StatefulPseudoClasses.ACTIVE));
StyleValue activeLabelContent = (null == activeLabelStyles ? null
: activeLabelStyles.getPropertyValues().getSpecifiedValue(
StylePropertyDetails.CONTENT));
// If no content was specified for active label,
// use content from inactive label
activeLabelContent = (null == activeLabelContent ? inactiveLabelContent
: activeLabelContent);
// If no content was specified for ::mcs-label, use default empty string
if (null == inactiveLabelContent) {
inactiveLabelContent = STYLE_VALUE_FACTORY.getString(null, "");
activeLabelContent = inactiveLabelContent;
} else {
// Normalize content values - they are provided as a list
inactiveLabelContent = getSingleStyleValue(inactiveLabelContent);
activeLabelContent = getSingleStyleValue(activeLabelContent);
}
// Check if image labels are used
context.getCurrentTabAndLabel().usesImageLabels =
(inactiveLabelContent instanceof StyleComponentURI);
// Prepare styles for labels
inactiveLabelStyles.getPropertyValues().setComputedAndSpecifiedValue(
StylePropertyDetails.WHITE_SPACE, WhiteSpaceKeywords.NOWRAP);
inactiveLabelStyles.getPropertyValues().setComputedAndSpecifiedValue(
StylePropertyDetails.DISPLAY, DisplayKeywords.TABLE_CELL);
// Remove copied styles specified on tab::mcs-label
inactiveLabelStyles.getPropertyValues().clearPropertyValue(
StylePropertyDetails.CONTENT);
inactiveLabelStyles.removeNestedStyles(PseudoElements.MCS_LABEL);
inactiveLabelStyles.removeNestedStyles(StatefulPseudoClasses.ACTIVE);
if (null != activeLabelStyles) {
activeLabelStyles.getPropertyValues()
.setComputedAndSpecifiedValue(
StylePropertyDetails.WHITE_SPACE,
WhiteSpaceKeywords.NOWRAP);
activeLabelStyles.getPropertyValues().clearPropertyValue(
StylePropertyDetails.CONTENT);
activeLabelStyles.removeNestedStyles(PseudoElements.MCS_LABEL);
context.getCurrentTabAndLabel().activeLabelStyles = activeLabelStyles;
}
// Rendering starts here
Element tdLeftMargin = null;
Element tdRightMargin = null;
// Generate left margin td (if necessary)
if (!context.getCurrentTabAndLabel().usesImageLabels) {
tdLeftMargin = renderLabelMarginTds(labelsBuffer,
inactiveLabelStyles, StylePropertyDetails.MARGIN_LEFT);
}
tdsRendered += (null == tdLeftMargin ? 0 : 1);
// Create a td with styles specified for tab label
String labelId = protocol.getMarinerPageContext().generateUniqueFCID();
Element labelTdElement = labelsBuffer.openStyledElement("td",
inactiveLabelStyles);
setElementLocked(protocol, labelTdElement);
labelTdElement.setAttribute("id", labelId);
context.getCurrentTabAndLabel().labelTdId = labelId;
// Open div inside td with no styles
Styles labelDivStyles = StylingFactory.getDefaultInstance()
.createStyles(null);
Element labelDivElement = labelsBuffer.openStyledElement("div",
labelDivStyles);
setElementLocked(protocol, labelDivElement);
// Set div width according to label width
applyWidthToChild(inactiveLabelStyles.getPropertyValues()
.getComputedValue(StylePropertyDetails.WIDTH), labelDivElement
.getStyles());
// Create styles for anchor
Styles anchorStyles = StylingFactory.getDefaultInstance().createStyles(
null);
anchorStyles.getPropertyValues().setComputedAndSpecifiedValue(
StylePropertyDetails.MCS_TEXT_UNDERLINE_STYLE,
MCSTextUnderlineStyleKeywords.NONE);
anchorStyles.getPropertyValues().setComputedAndSpecifiedValue(
StylePropertyDetails.COLOR,
StyleValueFactory.getDefaultInstance().getInherit());
anchorStyles.getPropertyValues().setComputedAndSpecifiedValue(
StylePropertyDetails.VERTICAL_ALIGN,
VerticalAlignKeywords.BOTTOM);
// Open anchor element with created styles
Element anchorElement = labelsBuffer.openStyledElement("a",
anchorStyles);
anchorElement.setAttribute("href", "javascript:void(null)");
setElementLocked(protocol, anchorElement);
String inactiveId = renderLabelContents(protocol, inactiveLabelContent,
true);
// Only write second content if it's different than the first one
String activeId = inactiveId;
if (inactiveLabelContent != activeLabelContent) {
activeId = renderLabelContents(protocol, activeLabelContent, false);
}
context.getCurrentTabAndLabel().inactiveContentId = inactiveId;
context.getCurrentTabAndLabel().activeContentId = activeId;
labelsBuffer.closeElement(anchorElement);
labelsBuffer.closeElement(labelDivElement);
labelsBuffer.closeElement(labelTdElement);
// Generate right margin td (if image labels not used)
if (!context.getCurrentTabAndLabel().usesImageLabels) {
tdRightMargin = renderLabelMarginTds(labelsBuffer,
inactiveLabelStyles, StylePropertyDetails.MARGIN_RIGHT);
}
tdsRendered += (null == tdRightMargin ? 0 : 1);
// In the end, we remove margin specified on tab label, as it has
// already been rendered in margin TDs and we don't want the margins
// rendered in CSS
if (!context.getCurrentTabAndLabel().usesImageLabels) {
inactiveLabelStyles.getPropertyValues().clearPropertyValue(
StylePropertyDetails.MARGIN_LEFT);
inactiveLabelStyles.getPropertyValues().clearPropertyValue(
StylePropertyDetails.MARGIN_RIGHT);
if (null != activeLabelStyles) {
activeLabelStyles.getPropertyValues().clearPropertyValue(
StylePropertyDetails.MARGIN_LEFT);
activeLabelStyles.getPropertyValues().clearPropertyValue(
StylePropertyDetails.MARGIN_RIGHT);
}
}
// Also, if image labels are used, set vertical-align:bottom for td
if (context.getCurrentTabAndLabel().usesImageLabels) {
labelTdElement.getStyles().getPropertyValues()
.setComputedAndSpecifiedValue(
StylePropertyDetails.VERTICAL_ALIGN,
VerticalAlignKeywords.BOTTOM);
}
context.getPageContext().popContainerInstance(getLabelsRegionInstance());
return tdsRendered;
}