blob: 31604b6abd3d96be0fcb017decb4f95a6bb91c3d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013 Carsten Hiesserich and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Carsten Hiesserich - initial API and implementation
*******************************************************************************/
package org.eclipse.vex.core.internal.css;
import java.util.NoSuchElementException;
import org.eclipse.vex.core.provisional.dom.BaseNodeVisitorWithResult;
import org.eclipse.vex.core.provisional.dom.Filters;
import org.eclipse.vex.core.provisional.dom.IElement;
import org.eclipse.vex.core.provisional.dom.INode;
import org.eclipse.vex.core.provisional.dom.IProcessingInstruction;
import org.w3c.css.sac.LexicalUnit;
/**
* The -vex-content-outline CSS property. This property decides which content is shown in the outline view.<br />
* The value is either the name of a child element, an attribute or 'none'. As default the elements text content is used
* in the outline display.<br />
* Theis property can hold several element names as a "fallback" system. 'none' can be used to prevent the default usage
* of the element's text content.<br />
* <br />
* Example:
*
* <pre>
* chapter {
* -vex-outline-content: titleabbrev, title;
* }
* </pre>
*
*/
public class OutlineContentProperty extends AbstractProperty {
/**
* Class constructor.
*/
public OutlineContentProperty() {
super(CSS.OUTLINE_CONTENT);
}
/**
* Returns the node, which text content (or value, if the node is an attribute) should be used in the outline
* display as content for the given node. We don't return the actual text here, because then we had to recalculate
* the styles every time the text changes.
*/
@Override
public Object calculate(final LexicalUnit lu, final Styles parentStyles, final Styles styles, final INode node) {
if (node == null || !node.isAssociated()) {
return null;
}
return node.accept(new BaseNodeVisitorWithResult<Object>(null) {
@Override
public Object visit(final IElement element) {
LexicalUnit lexicalUnit = lu;
while (lexicalUnit != null) {
if (lexicalUnit.getLexicalUnitType() == LexicalUnit.SAC_ATTR) {
final String attrName = lexicalUnit.getStringValue();
final String attrValue = element.getAttributeValue(attrName);
if (attrValue != null) {
return element.getAttribute(attrName);
}
} else if (lexicalUnit.getLexicalUnitType() == LexicalUnit.SAC_IDENT) {
if (lexicalUnit.getStringValue().equals(CSS.NONE)) {
return null;
}
// lu is the name of a possible child
final String childName = lexicalUnit.getStringValue();
try {
final IElement childElement = element.childElements().matching(Filters.elementsNamed(childName)).first();
if (!childElement.getText().isEmpty()) {
return childElement;
}
} catch (final NoSuchElementException ex) {
}
}
lexicalUnit = lexicalUnit.getNextLexicalUnit();
}
// Return element text content as default
return element;
}
@Override
public Object visit(final IProcessingInstruction pi) {
return pi;
}
});
}
}