blob: b35b7d55433533e3d7a18d36532b9808aba72483 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004 IBM Corporation 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.wst.css.core.internal.document;
import java.util.Iterator;
import org.eclipse.wst.css.core.internal.contentmodel.PropCMProperty;
import org.eclipse.wst.css.core.internal.parserz.CSSRegionContexts;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSDocument;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSPrimitiveValue;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSStyleDeclItem;
import org.eclipse.wst.css.core.internal.provisional.document.ICounter;
import org.eclipse.wst.css.core.internal.util.CSSUtil;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.sse.core.internal.text.TextRegionListImpl;
import org.w3c.dom.css.CSSPrimitiveValue;
/**
*
*/
class CSSDeclarationItemParser {
/**
*
*/
final class FloatInfo {
/**
*
*/
FloatInfo(String text) {
parse(text);
}
/**
*
*/
void parse(String text) {
StringBuffer bufValue = new StringBuffer();
StringBuffer bufIdent = new StringBuffer();
boolean bNum = true;
int len = text.length();
for (int i = 0; i < len; i++) {
char c = text.charAt(i);
if (bNum) {
if ('0' <= c && c <= '9' || c == '.' || c == '+' || c == '-') {
bufValue.append(c);
}
else {
bufIdent.append(c);
bNum = false;
}
}
else {
bufIdent.append(c);
}
}
String valueStr = bufValue.toString();
fValue = Float.valueOf(valueStr).floatValue();
fIdentifier = bufIdent.toString();
fType = getFloatValueType(valueStr, fIdentifier);
}
/**
*
*/
float getValue() {
return fValue;
}
/**
*
*/
String getIdentifier() {
return fIdentifier;
}
/**
*
*/
short getValueType() {
return fType;
}
private float fValue = 0.0f;
private String fIdentifier = null;
private short fType = CSSPrimitiveValue.CSS_UNKNOWN;
}
final static int S_NORMAL = 0;
final static int S_FUNCTION = 1;
final static int S_FONT_SLASH = 2;
final static int S_COMMA_SEPARATION = 3;
private ICSSDocument fDocument = null;
private IStructuredDocumentRegion fParentRegion = null;
private boolean fTempStructuredDocument = false;
private CSSModelUpdateContext fUpdateContext = null;
/**
* CSSDeclarationItemParser constructor comment.
*/
CSSDeclarationItemParser(ICSSDocument doc) {
super();
fDocument = doc;
}
/**
*
*/
private CSSPrimitiveValueImpl createAttrValue(ITextRegionList regions) {
String funcName = getFunctionName(regions);
if (funcName == null || !funcName.toLowerCase().equals("attr")) { //$NON-NLS-1$
return null;
}
String accepts[] = {CSSRegionContexts.CSS_DECLARATION_VALUE_IDENT};
ITextRegionList valueRegions = getFunctionParameters(regions, accepts);
if (valueRegions.size() != 1) {
return null;
}
CSSPrimitiveValueImpl value = getCSSPrimitiveValue(CSSPrimitiveValue.CSS_ATTR);
if (value == null) {
return null;
}
ITextRegion region = valueRegions.get(0);
value.setValue(getText(region));
return value;
}
/**
*
*/
private CSSPrimitiveValueImpl createCountersValue(ITextRegionList regions) {
String funcName = getFunctionName(regions);
if (funcName == null || !funcName.toLowerCase().equals("counters")) { //$NON-NLS-1$
return null;
}
String accepts[] = {CSSRegionContexts.CSS_DECLARATION_VALUE_IDENT, CSSRegionContexts.CSS_DECLARATION_VALUE_STRING};
ITextRegionList valueRegions = getFunctionParameters(regions, accepts);
int size = valueRegions.size();
if (size != 2 && size != 3) {
return null;
}
CounterImpl value = getCounter();
if (value == null) {
return null;
}
for (int i = 0; i < size; i++) {
ITextRegion region = valueRegions.get(i);
String text = getText(region);
CSSAttrImpl attr = null;
switch (i) {
case 0 :
value.setIdentifier(text);
attr = value.getAttributeNode(ICounter.IDENTIFIER);
break;
case 1 :
value.setSeparator(text);
attr = value.getAttributeNode(ICounter.SEPARATOR);
break;
case 2 :
value.setListStyle(text);
attr = value.getAttributeNode(ICounter.LISTSTYLE);
break;
default :
break;
}
if (attr != null) {
attr.setRangeRegion(fParentRegion, region, region);
}
}
return value;
}
/**
*
*/
private CSSPrimitiveValueImpl createCounterValue(ITextRegionList regions) {
String funcName = getFunctionName(regions);
if (funcName == null || !funcName.toLowerCase().equals("counter")) { //$NON-NLS-1$
return null;
}
String accepts[] = {CSSRegionContexts.CSS_DECLARATION_VALUE_IDENT};
ITextRegionList valueRegions = getFunctionParameters(regions, accepts);
int size = valueRegions.size();
if (size != 1 && size != 2) {
return null;
}
CounterImpl value = getCounter();
if (value == null) {
return null;
}
for (int i = 0; i < size; i++) {
ITextRegion region = valueRegions.get(i);
String text = getText(region);
CSSAttrImpl attr = null;
switch (i) {
case 0 :
value.setIdentifier(text);
attr = value.getAttributeNode(ICounter.IDENTIFIER);
break;
case 1 :
value.setListStyle(text);
attr = value.getAttributeNode(ICounter.LISTSTYLE);
break;
default :
break;
}
if (attr != null) {
attr.setRangeRegion(fParentRegion, region, region);
}
}
return value;
}
/**
*
*/
private CSSStyleDeclItemImpl createDeclarationItem(ITextRegionList nodeRegions) {
CSSStyleDeclItemImpl item = null;
String name = getPropertyName(nodeRegions);
if (name != null) {
item = getCSSStyleDeclItem(name);
}
return item;
}
/**
*
*/
private CSSPrimitiveValueImpl createFloatValue(String text, String type) {
FloatInfo info = new FloatInfo(text);
CSSPrimitiveValueImpl value = getCSSPrimitiveValue(info.getValueType());
if (value != null) {
value.setValue(info.getValue());
}
return value;
}
/**
*
*/
private CSSPrimitiveValueImpl createFormatValue(ITextRegionList regions) {
String funcName = getFunctionName(regions);
if (funcName == null || !funcName.toLowerCase().equals("format")) { //$NON-NLS-1$
return null;
}
String accepts[] = {CSSRegionContexts.CSS_DECLARATION_VALUE_STRING};
ITextRegionList valueRegions = getFunctionParameters(regions, accepts);
// format can take variable args.
if (valueRegions.size() == 0) {
return null;
}
CSSPrimitiveValueImpl value = getCSSPrimitiveValue(ICSSPrimitiveValue.CSS_FORMAT);
if (value == null) {
return null;
}
ITextRegion region = valueRegions.get(0);
value.setValue(CSSUtil.extractStringContents(getText(region)));
return value;
}
/**
*
*/
private CSSPrimitiveValueImpl createLocalValue(ITextRegionList regions) {
String funcName = getFunctionName(regions);
if (funcName == null || !funcName.toLowerCase().equals("local")) { //$NON-NLS-1$
return null;
}
String accepts[] = {CSSRegionContexts.CSS_DECLARATION_VALUE_STRING};
ITextRegionList valueRegions = getFunctionParameters(regions, accepts);
if (valueRegions.size() != 1) {
return null;
}
CSSPrimitiveValueImpl value = getCSSPrimitiveValue(ICSSPrimitiveValue.CSS_LOCAL);
if (value == null) {
return null;
}
ITextRegion region = valueRegions.get(0);
value.setValue(CSSUtil.extractStringContents(getText(region)));
return value;
}
/**
*
*/
private CSSPrimitiveValueImpl createPrimitiveValue(ITextRegion region) {
if (region == null) {
return null;
}
CSSPrimitiveValueImpl value = null;
String type = region.getType();
String text = getText(region);
if (isBlank(type)) {
value = null;
}
else if (type == CSSRegionContexts.CSS_DECLARATION_VALUE_NUMBER || type == CSSRegionContexts.CSS_DECLARATION_VALUE_DIMENSION || type == CSSRegionContexts.CSS_DECLARATION_VALUE_PERCENTAGE) {
value = createFloatValue(text, type);
}
else if (type == CSSRegionContexts.CSS_DECLARATION_VALUE_STRING || type == CSSRegionContexts.CSS_DECLARATION_VALUE_URI || type == CSSRegionContexts.CSS_DECLARATION_VALUE_IDENT || type == CSSRegionContexts.CSS_DECLARATION_VALUE_HASH) {
value = createStringValue(text, type);
}
if (value == null) {
value = createStringValue(text, type);
}
if (!fTempStructuredDocument && value != null) {
value.setRangeRegion(fParentRegion, region, region);
}
return value;
}
/**
*
*/
private CSSPrimitiveValueImpl createPrimitiveValue(ITextRegionList regions) {
CSSPrimitiveValueImpl value = null;
CSSUtil.stripSurroundingSpace(regions);
if (regions.isEmpty()) {
return null;
}
ITextRegion region = regions.get(0);
if (region == null) {
return null;
}
String type = region.getType();
if (type == CSSRegionContexts.CSS_DECLARATION_VALUE_FUNCTION) {
String text = getText(region).toLowerCase();
if (text.equals("rgb(")) { //$NON-NLS-1$
value = createRgbValue(regions);
}
else if (text.equals("counter(")) { //$NON-NLS-1$
value = createCounterValue(regions);
}
else if (text.equals("counters(")) { //$NON-NLS-1$
value = createCountersValue(regions);
}
else if (text.equals("attr(")) { //$NON-NLS-1$
value = createAttrValue(regions);
}
else if (text.equals("format(")) { //$NON-NLS-1$
value = createFormatValue(regions);
}
else if (text.equals("local(")) { //$NON-NLS-1$
value = createLocalValue(regions);
}
else if (text.equals("rect(")) { //$NON-NLS-1$
value = createRectValue(regions);
}
if (value == null) {
value = createStringValue(regions);
}
}
else {
value = createStringValue(regions);
}
if (!fTempStructuredDocument && value != null) {
value.setRangeRegion(fParentRegion, regions.get(0), regions.get(regions.size() - 1));
}
return value;
}
/**
*
*/
private CSSPrimitiveValueImpl createRectValue(ITextRegionList regions) {
String funcName = getFunctionName(regions);
if (funcName == null || !funcName.toLowerCase().equals("rect")) { //$NON-NLS-1$
return null;
}
String accepts[] = {CSSRegionContexts.CSS_DECLARATION_VALUE_NUMBER, CSSRegionContexts.CSS_DECLARATION_VALUE_DIMENSION, CSSRegionContexts.CSS_DECLARATION_VALUE_IDENT}; // IDENT:
// for
// 'auto'
ITextRegionList valueRegions = getFunctionParameters(regions, accepts);
if (valueRegions.size() != 4) {
return null;
}
RectImpl value = getRect();
if (value == null) {
return null;
}
for (int i = 0; i < 4; i++) {
ITextRegion region = valueRegions.get(i);
CSSPrimitiveValueImpl childValue = null;
switch (i) {
case 0 :
childValue = (CSSPrimitiveValueImpl) value.getTop();
break;
case 1 :
childValue = (CSSPrimitiveValueImpl) value.getRight();
break;
case 2 :
childValue = (CSSPrimitiveValueImpl) value.getBottom();
break;
case 3 :
childValue = (CSSPrimitiveValueImpl) value.getLeft();
break;
default :
break;
}
if (childValue == null) {
return null;
}
String text = getText(region);
String type = region.getType();
if (type == CSSRegionContexts.CSS_DECLARATION_VALUE_IDENT) {
setStringValue(childValue, text, type);
}
else {
setFloatValue(childValue, text, type);
}
if (!fTempStructuredDocument) {
childValue.setRangeRegion(fParentRegion, region, region);
}
}
return value;
}
/**
*
*/
private CSSPrimitiveValueImpl createRgbValue(ITextRegionList regions) {
String funcName = getFunctionName(regions);
if (funcName == null || !funcName.toLowerCase().equals("rgb")) { //$NON-NLS-1$
return null;
}
String accepts[] = {CSSRegionContexts.CSS_DECLARATION_VALUE_NUMBER, CSSRegionContexts.CSS_DECLARATION_VALUE_PERCENTAGE};
ITextRegionList valueRegions = getFunctionParameters(regions, accepts);
if (valueRegions.size() != 3) {
return null;
}
RGBColorImpl value = getRGBColor();
if (value == null) {
return null;
}
for (int i = 0; i < 3; i++) {
ITextRegion region = valueRegions.get(i);
CSSPrimitiveValueImpl childValue = null;
switch (i) {
case 0 :
childValue = (CSSPrimitiveValueImpl) value.getRed();
break;
case 1 :
childValue = (CSSPrimitiveValueImpl) value.getGreen();
break;
case 2 :
childValue = (CSSPrimitiveValueImpl) value.getBlue();
break;
default :
break;
}
if (childValue == null) {
return null;
}
setFloatValue(childValue, getText(region), region.getType());
if (!fTempStructuredDocument) {
childValue.setRangeRegion(fParentRegion, region, region);
}
}
return value;
}
/**
*
*/
private CSSPrimitiveValueImpl createStringValue(String text, String type) {
short valueType = getStringValueType(text, type);
CSSPrimitiveValueImpl value = getCSSPrimitiveValue(valueType);
if (value != null) {
if (valueType == CSSPrimitiveValue.CSS_URI) {
text = CSSUtil.extractUriContents(text);
}
else if (valueType == CSSPrimitiveValue.CSS_STRING) {
text = CSSUtil.extractStringContents(text);
}
value.setValue(text);
}
return value;
}
/**
*
*/
private CSSPrimitiveValueImpl createStringValue(ITextRegionList regions) {
String type = CSSRegionContexts.CSS_DECLARATION_VALUE_IDENT;
if (regions.size() == 1) {
ITextRegion region = regions.get(0);
type = region.getType();
}
return createStringValue(makeString(regions), type);
}
/**
*
*/
private CounterImpl getCounter() {
CounterImpl node;
if (fUpdateContext != null && fUpdateContext.isActive()) {
node = fUpdateContext.getCounter();
}
else {
node = (CounterImpl) fDocument.createCSSPrimitiveValue(CSSPrimitiveValue.CSS_COUNTER);
}
return node;
}
/**
*
*/
private CSSPrimitiveValueImpl getCSSPrimitiveValue(short type) {
CSSPrimitiveValueImpl node;
if (fUpdateContext != null && fUpdateContext.isActive()) {
node = fUpdateContext.getCSSPrimitiveValue(type);
}
else {
node = (CSSPrimitiveValueImpl) fDocument.createCSSPrimitiveValue(type);
}
return node;
}
/**
*
*/
private CSSStyleDeclItemImpl getCSSStyleDeclItem(String propertyName) {
CSSStyleDeclItemImpl node;
if (fUpdateContext != null && fUpdateContext.isActive()) {
node = fUpdateContext.getCSSStyleDeclItem(propertyName);
}
else {
node = (CSSStyleDeclItemImpl) fDocument.createCSSStyleDeclItem(propertyName);
}
return node;
}
/**
*
*/
static short getFloatValueType(String ident) {
ident = ident.toLowerCase();
short valueType;
if (ident.length() == 0) {
valueType = CSSPrimitiveValue.CSS_NUMBER;
}
else if (ident.equals("%")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_PERCENTAGE;
}
else if (ident.equalsIgnoreCase("em")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_EMS;
}
else if (ident.equalsIgnoreCase("ex")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_EXS;
}
else if (ident.equalsIgnoreCase("px")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_PX;
}
else if (ident.equalsIgnoreCase("cm")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_CM;
}
else if (ident.equalsIgnoreCase("mm")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_MM;
}
else if (ident.equalsIgnoreCase("in")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_IN;
}
else if (ident.equalsIgnoreCase("pt")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_PT;
}
else if (ident.equalsIgnoreCase("pc")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_PC;
}
else if (ident.equalsIgnoreCase("deg")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_DEG;
}
else if (ident.equalsIgnoreCase("rad")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_RAD;
}
else if (ident.equalsIgnoreCase("grad")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_GRAD;
}
else if (ident.equalsIgnoreCase("ms")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_MS;
}
else if (ident.equalsIgnoreCase("s")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_S;
}
else if (ident.equalsIgnoreCase("hz")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_HZ;
}
else if (ident.equalsIgnoreCase("khz")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_KHZ;
}
else {
valueType = CSSPrimitiveValue.CSS_DIMENSION;
}
return valueType;
}
/**
*
*/
static short getFloatValueType(String value, String ident) {
ident = ident.toLowerCase();
short valueType;
if (ident.length() == 0) {
if (0 <= value.indexOf('.')) {
valueType = CSSPrimitiveValue.CSS_NUMBER;
}
else {
valueType = ICSSPrimitiveValue.CSS_INTEGER;
}
}
else if (ident.equals("%")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_PERCENTAGE;
}
else if (ident.equalsIgnoreCase("em")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_EMS;
}
else if (ident.equalsIgnoreCase("ex")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_EXS;
}
else if (ident.equalsIgnoreCase("px")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_PX;
}
else if (ident.equalsIgnoreCase("cm")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_CM;
}
else if (ident.equalsIgnoreCase("mm")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_MM;
}
else if (ident.equalsIgnoreCase("in")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_IN;
}
else if (ident.equalsIgnoreCase("pt")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_PT;
}
else if (ident.equalsIgnoreCase("pc")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_PC;
}
else if (ident.equalsIgnoreCase("deg")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_DEG;
}
else if (ident.equalsIgnoreCase("rad")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_RAD;
}
else if (ident.equalsIgnoreCase("grad")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_GRAD;
}
else if (ident.equalsIgnoreCase("ms")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_MS;
}
else if (ident.equalsIgnoreCase("s")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_S;
}
else if (ident.equalsIgnoreCase("hz")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_HZ;
}
else if (ident.equalsIgnoreCase("khz")) { //$NON-NLS-1$
valueType = CSSPrimitiveValue.CSS_KHZ;
}
else {
valueType = CSSPrimitiveValue.CSS_DIMENSION;
}
return valueType;
}
/**
*
*/
private String getFunctionName(ITextRegionList regions) {
if (regions == null || regions.size() < 2) {
return null;
}
ITextRegion firstRegion = regions.get(0);
if (firstRegion.getType() != CSSRegionContexts.CSS_DECLARATION_VALUE_FUNCTION) {
return null;
}
ITextRegion lastRegion = regions.get(regions.size() - 1);
if (lastRegion.getType() != CSSRegionContexts.CSS_DECLARATION_VALUE_PARENTHESIS_CLOSE) {
return null;
}
String text = getText(firstRegion);
return text.substring(0, text.length() - 1);
}
/**
* this method has no validation check, then regions must be passed
* getFunctionName()...
*/
private ITextRegionList getFunctionParameters(ITextRegionList regions, String[] accepts) {
ITextRegionList newRegions = new TextRegionListImpl();
int nAccepts = (accepts != null) ? accepts.length : 0;
Iterator i = regions.iterator();
i.next(); // skip FUNCTION
while (i.hasNext()) {
ITextRegion region = (ITextRegion) i.next();
if (region == null) {
continue;
}
String type = region.getType();
if (isBlank(type)) {
continue;
}
if (nAccepts == 0) {
newRegions.add(region);
}
else {
for (int iAccept = 0; iAccept < nAccepts; iAccept++) {
if (type == accepts[iAccept]) {
newRegions.add(region);
break;
}
}
}
}
return newRegions;
}
/**
*
*/
// private String getPropertyName(IStructuredDocumentRegion flatNode) {
// Vector nodeRegions = new Vector(flatNode.getRegions());
// return getPropertyName(nodeRegions);
// }
/**
*
*/
private String getPropertyName(ITextRegionList nodeRegions) {
ITextRegionList nameRegions = new TextRegionListImpl();
String name = null;
while (!nodeRegions.isEmpty()) {
ITextRegion region = nodeRegions.remove(0);
if (region == null) {
continue;
}
String type = region.getType();
if (type == CSSRegionContexts.CSS_DECLARATION_SEPARATOR) {
CSSUtil.stripSurroundingSpace(nameRegions);
name = makeString(nameRegions);
break;
}
else {
nameRegions.add(region);
}
}
return name;
}
/**
*
*/
private RectImpl getRect() {
RectImpl node;
if (fUpdateContext != null && fUpdateContext.isActive()) {
node = fUpdateContext.getRect();
}
else {
node = (RectImpl) fDocument.createCSSPrimitiveValue(CSSPrimitiveValue.CSS_RECT);
}
return node;
}
/**
*
*/
private RGBColorImpl getRGBColor() {
RGBColorImpl node;
if (fUpdateContext != null && fUpdateContext.isActive()) {
node = fUpdateContext.getRGBColor();
}
else {
node = (RGBColorImpl) fDocument.createCSSPrimitiveValue(CSSPrimitiveValue.CSS_RGBCOLOR);
}
return node;
}
/**
*
*/
private short getStringValueType(String text, String type) {
short valueType;
if (text.toLowerCase().equals("inherit")) { //$NON-NLS-1$
valueType = ICSSPrimitiveValue.CSS_INHERIT_PRIMITIVE;
}
else if (type == CSSRegionContexts.CSS_DECLARATION_VALUE_URI) {
valueType = CSSPrimitiveValue.CSS_URI;
}
else if (type == CSSRegionContexts.CSS_DECLARATION_VALUE_STRING) {
valueType = CSSPrimitiveValue.CSS_STRING;
}
else if (type == CSSRegionContexts.CSS_DECLARATION_VALUE_HASH) {
valueType = ICSSPrimitiveValue.CSS_HASH;
}
else if (type == CSSRegionContexts.CSS_DECLARATION_VALUE_OPERATOR && text.equals(",")) { //$NON-NLS-1$
valueType = ICSSPrimitiveValue.CSS_COMMA;
}
else if (type == CSSRegionContexts.CSS_DECLARATION_VALUE_OPERATOR && text.equals("/")) { //$NON-NLS-1$
valueType = ICSSPrimitiveValue.CSS_SLASH;
}
else if (type == CSSRegionContexts.CSS_DECLARATION_VALUE_UNICODE_RANGE) {
valueType = ICSSPrimitiveValue.CSS_URANGE;
}
else {
valueType = CSSPrimitiveValue.CSS_IDENT;
}
return valueType;
}
/**
*
*/
private String makeString(ITextRegionList regions) {
StringBuffer buf = new StringBuffer();
boolean bSpace = false;
for (Iterator i = regions.iterator(); i.hasNext();) {
ITextRegion region = (ITextRegion) i.next();
String type = region.getType();
if (!bSpace && isBlank(type)) {
buf.append(" "); //$NON-NLS-1$
bSpace = true;
}
else {
buf.append(getText(region));
bSpace = false;
}
}
return buf.toString();
}
/**
*
*/
void setStructuredDocumentTemporary(boolean bTemp) {
fTempStructuredDocument = bTemp;
}
/**
*
*/
private void setFloatValue(CSSPrimitiveValueImpl value, String text, String type) {
FloatInfo info = new FloatInfo(text);
value.setFloatValue(info.getValueType(), info.getValue());
}
/**
*
*/
private void setStringValue(CSSPrimitiveValueImpl value, String text, String type) {
short valueType = getStringValueType(text, type);
value.setStringValue(valueType, text);
}
/**
* @param item
* org.eclipse.wst.css.core.model.interfaces.ICSSStyleDeclItem
* @param nodeRegions
* java.util.Vector
*/
private void setupImportantAttribute(ICSSStyleDeclItem item, ITextRegionList nodeRegions) {
if (item == null || nodeRegions == null || nodeRegions.isEmpty()) {
return;
}
ITextRegion region = nodeRegions.get(nodeRegions.size() - 1);
if (region != null && region.getType() == CSSRegionContexts.CSS_DECLARATION_VALUE_IMPORTANT) {
item.setPriority(getText(region));
CSSAttrImpl attr = ((CSSStyleDeclItemImpl) item).getAttributeNode(ICSSStyleDeclItem.IMPORTANT);
attr.setRangeRegion(fParentRegion, region, region);
nodeRegions.remove(region);
}
}
/**
*
*/
void setUpdateContext(CSSModelUpdateContext updateContext) {
fUpdateContext = updateContext;
}
/**
*
*/
public static boolean hasColonSeparator(IStructuredDocumentRegion flatNode) {
if (flatNode == null) {
return false;
}
ITextRegionList regions = flatNode.getRegions();
if (regions == null || regions.size() == 0) {
return false;
}
for (Iterator i = regions.iterator(); i.hasNext();) {
ITextRegion region = (ITextRegion) i.next();
if (region == null) {
continue;
}
if (region.getType() == CSSRegionContexts.CSS_DECLARATION_SEPARATOR) {
return true;
}
}
return false;
}
/**
*
*/
CSSStyleDeclItemImpl setupDeclarationItem(IStructuredDocumentRegion flatNode) {
if (flatNode == null) {
return null;
}
if (!hasColonSeparator(flatNode)) {
return null;
}
fParentRegion = flatNode;
ITextRegionList nodeRegions = new TextRegionListImpl(flatNode.getRegions()); // make
// copy
CSSStyleDeclItemImpl newItem = createDeclarationItem(nodeRegions);
if (newItem == null) {
return null;
}
if (!fTempStructuredDocument && flatNode != null) {
newItem.setRangeStructuredDocumentRegion(flatNode, flatNode);
}
CSSUtil.stripSurroundingSpace(nodeRegions);
setupImportantAttribute(newItem, nodeRegions);
// Now, nodeRegions just has regions for value.
setupValues(newItem, nodeRegions);
return newItem;
}
void setupValues(ICSSStyleDeclItem item, IStructuredDocumentRegion parentRegion, ITextRegionList nodeRegions) {
fParentRegion = parentRegion;
setupValues(item, nodeRegions);
}
/**
* nodeRegions must be broken. If you need after, make copy of them.
*/
private void setupValues(ICSSStyleDeclItem item, ITextRegionList nodeRegions) {
if (item == null) {
return;
}
ICSSPrimitiveValue value;
ITextRegionList regionBuf = new TextRegionListImpl();
String propertyName = item.getPropertyName().toLowerCase();
boolean bFont = (propertyName.equals(PropCMProperty.P_FONT));
// (short-hand) font
int status = (propertyName.equals(PropCMProperty.P_VOICE_FAMILY) || propertyName.equals(PropCMProperty.P_FONT_FAMILY)) ? S_COMMA_SEPARATION : S_NORMAL;
while (!nodeRegions.isEmpty()) {
value = null;
ITextRegion region = nodeRegions.remove(0);
if (region == null) {
continue;
}
String type = region.getType();
// if (type == CSSRegionContexts.CSS_DECLARATION_DELIMITER || type
// == CSSRegionContexts.CSS_RBRACE) {
// break;
// }
switch (status) {
case S_NORMAL :
if (type == CSSRegionContexts.CSS_DECLARATION_VALUE_FUNCTION) {
regionBuf.add(region);
status = S_FUNCTION;
}
else if (bFont && type == CSSRegionContexts.CSS_DECLARATION_VALUE_OPERATOR && fParentRegion.getText(region).equals("/")) { //$NON-NLS-1$
value = createPrimitiveValue(region);
status = S_FONT_SLASH;
}
else if (!isBlank(type)) {
value = createPrimitiveValue(region);
}
break;
case S_FUNCTION :
if (type == CSSRegionContexts.CSS_DECLARATION_VALUE_PARENTHESIS_CLOSE) {
regionBuf.add(region);
value = createPrimitiveValue(regionBuf);
regionBuf.clear();
status = S_NORMAL;
}
else if (!isBlank(type)) {
regionBuf.add(region);
}
break;
case S_FONT_SLASH :
if (type == CSSRegionContexts.CSS_DECLARATION_VALUE_DIMENSION) {
value = createPrimitiveValue(region);
status = S_COMMA_SEPARATION;
}
else if (!isBlank(type)) {
value = createPrimitiveValue(region);
}
break;
case S_COMMA_SEPARATION :
if (type == CSSRegionContexts.CSS_DECLARATION_VALUE_OPERATOR && fParentRegion.getText(region).equals(",")) { //$NON-NLS-1$
value = createPrimitiveValue(regionBuf);
regionBuf.clear();
if (value != null) {
if (fUpdateContext == null || !fUpdateContext.isActive()) {
item.appendValue(value);
}
}
value = createPrimitiveValue(region);
}
else {
regionBuf.add(region);
}
break;
default :
break;
}
if (value != null) {
if (fUpdateContext == null || !fUpdateContext.isActive()) {
item.appendValue(value);
}
}
}
if (!regionBuf.isEmpty()) {
value = createPrimitiveValue(regionBuf);
if (fUpdateContext == null || !fUpdateContext.isActive()) {
item.appendValue(value);
}
}
}
private String getText(ITextRegion region) {
return (fParentRegion != null) ? fParentRegion.getText(region) : ""; //$NON-NLS-1$
}
private static boolean isBlank(String type) {
return (type == CSSRegionContexts.CSS_S || type == CSSRegionContexts.CSS_COMMENT || type == CSSRegionContexts.CSS_DECLARATION_VALUE_S);
}
}