![JAR search and dependency download from the Maven repository](/logo.png)
com.inet.sass.parser.LexicalUnitImpl Maven / Gradle / Ivy
/*
* Copyright 2023 i-net software
* Copyright 2000-2014 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
/*
* Copyright (c) 1999 World Wide Web Consortium
* (Massachusetts Institute of Technology, Institut National de Recherche
* en Informatique et en Automatique, Keio University).
* All Rights Reserved. http://www.w3.org/Consortium/Legal/
*/
package com.inet.sass.parser;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import com.inet.sass.ScssContext;
import com.inet.sass.function.SCSSFunctionGenerator;
import com.inet.sass.handler.SCSSErrorHandler;
import com.inet.sass.tree.BlockNode;
import com.inet.sass.tree.FunctionCall;
import com.inet.sass.tree.FunctionDefNode;
import com.inet.sass.tree.Node;
import com.inet.sass.tree.Node.BuildStringStrategy;
import com.inet.sass.util.ColorUtil;
import com.inet.sass.util.StringUtil;
public class LexicalUnitImpl implements SCSSLexicalUnit, SassListItem {
public static final long PRECISION = 100000L;
private static final ThreadLocal CSS_FLOAT_FORMAT = new ThreadLocal() {
@Override
protected DecimalFormat initialValue() {
return new DecimalFormat("0.#####", DecimalFormatSymbols.getInstance(Locale.US) );
}
};
public static final LexicalUnitImpl WHITESPACE = new LexicalUnitImpl( null, 0, 0, SAC_IDENT, " " );
private short type;
private int line;
private int column;
private double f;
private String sdimension;
private StringInterpolationSequence s;
private String fname;
private ActualArgumentList params;
private String uri;
private String printState;
private boolean varNotResolved;
LexicalUnitImpl( String uri, int line, int column, short type ) {
this.uri = uri;
this.line = line;
this.column = column;
this.type = type;
}
LexicalUnitImpl( String uri, int line, int column, short type, double f ) {
this( uri, line, column, type );
this.f = f;
}
LexicalUnitImpl( String uri, int line, int column, short type, String sdimension, double f ) {
this( uri, line, column, type, f );
this.sdimension = sdimension;
}
LexicalUnitImpl( String uri, int line, int column, short type, String s ) {
this( uri, line, column, type, new StringInterpolationSequence( s ) );
}
LexicalUnitImpl( String uri, int line, int column, short type, StringInterpolationSequence s ) {
this( uri, line, column, type );
this.s = s;
}
LexicalUnitImpl( String uri, short type, int line, int column, String fname, ActualArgumentList params ) {
this( uri, line, column, type );
this.fname = fname;
this.params = params;
this.uri = uri;
}
/**
* {@inheritDoc}
*/
public int getLineNumber() {
return line;
}
/**
* {@inheritDoc}
*/
public int getColumnNumber() {
return column;
}
public short getItemType() {
return type;
}
private void setLexicalUnitType(short type) {
this.type = type;
}
public boolean isUnitlessNumber() {
switch (type) {
case LexicalUnitImpl.SAC_INTEGER:
case LexicalUnitImpl.SAC_REAL:
return true;
default:
return false;
}
}
public boolean isNumber() {
short type = getItemType();
switch (type) {
case SAC_INTEGER:
case SAC_REAL:
case SAC_EM:
case SAC_LEM:
case SAC_REM:
case SAC_EX:
case SAC_PIXEL:
case SAC_INCH:
case SAC_CENTIMETER:
case SAC_MILLIMETER:
case SAC_POINT:
case SAC_PICA:
case SAC_PERCENTAGE:
case SAC_DEGREE:
case SAC_GRADIAN:
case SAC_RADIAN:
case SAC_MILLISECOND:
case SAC_SECOND:
case SAC_HERTZ:
case SAC_KILOHERTZ:
case SAC_DIMENSION:
return true;
default:
return false;
}
}
public int getIntegerValue() {
return (int)f;
}
public double getDoubleValue() {
return f;
}
/**
* Returns the double value as a string unless the value is an integer. In
* that case returns the integer value as a string.
*
* @return a string representing the value, either with or without decimals
*/
public String getDoubleOrInteger() {
return CSS_FLOAT_FORMAT.get().format( f );
}
private void setDoubleValue( double f ) {
this.f = f;
}
public String getDimensionUnitText() {
switch (type) {
case SAC_INTEGER:
case SAC_REAL:
return "";
case SAC_PERCENTAGE:
return "%";
case SAC_EM:
return "em";
case SAC_LEM:
return "lem";
case SAC_REM:
return "rem";
case SAC_EX:
return "ex";
case SAC_PIXEL:
return "px";
case SAC_CENTIMETER:
return "cm";
case SAC_MILLIMETER:
return "mm";
case SAC_INCH:
return "in";
case SAC_POINT:
return "pt";
case SAC_PICA:
return "pc";
case SAC_DEGREE:
return "deg";
case SAC_RADIAN:
return "rad";
case SAC_GRADIAN:
return "grad";
case SAC_MILLISECOND:
return "ms";
case SAC_SECOND:
return "s";
case SAC_HERTZ:
return "Hz";
case SAC_KILOHERTZ:
return "kHz";
case SAC_DIMENSION:
return sdimension;
default:
throw new IllegalStateException("invalid dimension " + type);
}
}
public String getStringValue() {
return s == null ? null : s.toString();
}
private void setStringValue(String str) {
s = new StringInterpolationSequence(str);
}
public String getFunctionName() {
return fname;
}
public ActualArgumentList getParameterList() {
return params;
}
/**
* Get the URI, where a function is define
* @return the uri
*/
@Override
public String getUri() {
return uri;
}
/**
* Prints out the current state of the node tree. Will return SCSS before
* compile and CSS after.
*
* Result value could be null.
*
* @return State as a string
*/
public String printState() {
if (printState == null) {
if( varNotResolved ) {
// throw this exception only if there was already a failing try to resolve this variable
throw new ParseException( "Variable was not resolved: " + simpleAsString(), uri, line, column );
}
printState = buildString(Node.PRINT_STRATEGY);
}
return printState;
}
@Override
public String toString() {
String result = simpleAsString();
if (result == null) {
return "Lexical unit node [" + buildString(Node.TO_STRING_STRATEGY)
+ "]";
} else {
return result;
}
}
// A helper method for sass interpolation
@Override
public String unquotedString() {
String result = printState();
if (result.length() >= 2
&& ((result.charAt(0) == '"' && result
.charAt(result.length() - 1) == '"') || (result
.charAt(0) == '\'' && result
.charAt(result.length() - 1) == '\''))) {
result = result.substring(1, result.length() - 1);
}
return result;
}
public LexicalUnitImpl divide( LexicalUnitImpl denominator ) {
if( denominator.type != SAC_INTEGER && denominator.type != SAC_REAL && type != denominator.type ) {
// then this is not a numeric division
return new LexicalUnitImpl( uri, line, column, SAC_IDENT, printState()+'/'+denominator.printState() );
}
LexicalUnitImpl copy = copyWithValue( getDoubleValue() / denominator.getDoubleValue() );
if( type == denominator.type ) {
copy.setLexicalUnitType( SAC_REAL );
}
return copy;
}
public LexicalUnitImpl add(LexicalUnitImpl another) {
LexicalUnitImpl copy = copyWithValue(getDoubleValue()
+ another.getDoubleValue());
copy.setLexicalUnitType(checkAndGetUnit(another));
return copy;
}
public LexicalUnitImpl minus(LexicalUnitImpl another) {
LexicalUnitImpl copy = copyWithValue(getDoubleValue()
- another.getDoubleValue());
copy.setLexicalUnitType(checkAndGetUnit(another));
return copy;
}
public LexicalUnitImpl multiply(LexicalUnitImpl another) {
LexicalUnitImpl copy = copyWithValue(getDoubleValue()
* another.getDoubleValue());
copy.setLexicalUnitType(checkAndGetUnit(another));
return copy;
}
private ParseException createIncompatibleUnitsException( LexicalUnitImpl another ) {
String msg = "Incompatible units found in: '" + printState() + "' <> '" + another.printState() + "'\n" //
+ new ParseException( "", this ).getMessage() + '\n';
return new ParseException( msg, another );
}
public short checkAndGetUnit( LexicalUnitImpl another ) {
short thisType = this.type;
short otherType = another.type;
if( thisType == otherType ) {
return thisType;
}
switch( otherType ) {
case SAC_INTEGER:
case SAC_REAL:
return thisType == SAC_INTEGER ? otherType : thisType ;
case SAC_CENTIMETER:
case SAC_MILLIMETER:
case SAC_INCH:
switch( thisType ) {
case SAC_CENTIMETER:
case SAC_MILLIMETER:
case SAC_INCH:
return thisType;
}
}
switch( thisType ) {
case SAC_INTEGER:
case SAC_REAL:
return otherType;
}
throw createIncompatibleUnitsException( another );
}
public LexicalUnitImpl modulo(LexicalUnitImpl another) {
if( !checkLexicalUnitType( another, type, SAC_INTEGER, SAC_REAL ) ) {
throw createIncompatibleUnitsException( another );
}
return copyWithValue( (int)getIntegerValue() % (int)another.getIntegerValue() );
}
/**
* Returns a shallow copy of the {@link LexicalUnitImpl} with null as next
* lexical unit pointer. Parameters are not copied but a reference to the
* same parameter list is used.
*
* @return copy of this without next
*/
public LexicalUnitImpl copy() {
LexicalUnitImpl copy = new LexicalUnitImpl( uri, line, column, type );
copy.f = f;
copy.s = s;
copy.fname = fname;
copy.sdimension = sdimension;
copy.params = params;
return copy;
}
public LexicalUnitImpl copyWithValue( double value ) {
LexicalUnitImpl result = copy();
result.setDoubleValue( value );
return result;
}
public String getSdimension() {
return sdimension;
}
// here some useful function for creation
public static LexicalUnitImpl createVariable( String uri, int line, int column, String name ) {
return new LexicalUnitImpl( uri, line, column, SCSS_VARIABLE, name );
}
public static LexicalUnitImpl createNull( String uri, int line, int column ) {
return new LexicalUnitImpl( uri, line, column, SCSS_NULL, "null" );
}
public static LexicalUnitImpl createNumber( String uri, int line, int column, double v ) {
int i = (int)v;
if( v == i ) {
return new LexicalUnitImpl( uri, line, column, SAC_INTEGER, i );
} else {
return new LexicalUnitImpl( uri, line, column, SAC_REAL, v );
}
}
public static LexicalUnitImpl createInteger( String uri, int line, int column, int i ) {
return new LexicalUnitImpl( uri, line, column, SAC_INTEGER, i );
}
public static LexicalUnitImpl createPercentage( String uri, int line, int column, double v ) {
if( Math.round( v * 100 * PRECISION ) == (((int)v) * 100 * PRECISION) ) {
v = (int)v;
}
return new LexicalUnitImpl( uri, line, column, SAC_PERCENTAGE, v );
}
static LexicalUnitImpl createEMS( String uri, int line, int column, double v ) {
return new LexicalUnitImpl( uri, line, column, SAC_EM, v );
}
static LexicalUnitImpl createLEM( String uri, int line, int column, double v ) {
return new LexicalUnitImpl( uri, line, column, SCSSLexicalUnit.SAC_LEM, v );
}
static LexicalUnitImpl createREM( String uri, int line, int column, double v ) {
return new LexicalUnitImpl( uri, line, column, SCSSLexicalUnit.SAC_REM, v );
}
static LexicalUnitImpl createEXS( String uri, int line, int column, double v ) {
return new LexicalUnitImpl( uri, line, column, SAC_EX, v );
}
public static LexicalUnitImpl createPX( String uri, int line, int column, double v ) {
return new LexicalUnitImpl( uri, line, column, SAC_PIXEL, v );
}
public static LexicalUnitImpl createCM( String uri, int line, int column, double v ) {
return new LexicalUnitImpl( uri, line, column, SAC_CENTIMETER, v );
}
static LexicalUnitImpl createMM( String uri, int line, int column, double v ) {
return new LexicalUnitImpl( uri, line, column, SAC_MILLIMETER, v );
}
static LexicalUnitImpl createIN( String uri,int line, int column, double v) {
return new LexicalUnitImpl(uri, line, column, SAC_INCH, v);
}
static LexicalUnitImpl createPT( String uri, int line, int column, double v ) {
return new LexicalUnitImpl( uri, line, column, SAC_POINT, v );
}
static LexicalUnitImpl createPC( String uri, int line, int column, double v ) {
return new LexicalUnitImpl( uri, line, column, SAC_PICA, v );
}
public static LexicalUnitImpl createDEG( String uri, int line, int column, double v ) {
return new LexicalUnitImpl( uri, line, column, SAC_DEGREE, v );
}
static LexicalUnitImpl createRAD( String uri, int line, int column, double v ) {
return new LexicalUnitImpl( uri, line, column, SAC_RADIAN, v );
}
static LexicalUnitImpl createGRAD( String uri, int line, int column, double v ) {
return new LexicalUnitImpl( uri, line, column, SAC_GRADIAN, v );
}
static LexicalUnitImpl createMS( String uri, int line, int column, double v ) {
if( v < 0 ) {
throw new ParseException( "Time values may not be negative", uri, line, column );
}
return new LexicalUnitImpl( uri, line, column, SAC_MILLISECOND, v );
}
static LexicalUnitImpl createS( String uri, int line, int column, double v ) {
if( v < 0 ) {
throw new ParseException( "Time values may not be negative", uri, line, column );
}
return new LexicalUnitImpl( uri, line, column, SAC_SECOND, v );
}
static LexicalUnitImpl createHZ( String uri, int line, int column, double v ) {
if( v < 0 ) {
throw new ParseException( "Frequency values may not be negative", uri, line, column );
}
return new LexicalUnitImpl( uri, line, column, SAC_HERTZ, v );
}
static LexicalUnitImpl createKHZ( String uri, int line, int column, double v ) {
if( v < 0 ) {
throw new ParseException( "Frequency values may not be negative", uri, line, column );
}
return new LexicalUnitImpl( uri, line, column, SAC_KILOHERTZ, v );
}
static LexicalUnitImpl createDimen( String uri, int line, int column, double v, String s ) {
return new LexicalUnitImpl( uri, line, column, SAC_DIMENSION, s, v );
}
static LexicalUnitImpl createInherit( String uri, int line, int column ) {
return new LexicalUnitImpl( uri, line, column, SAC_INHERIT, "inherit" );
}
public static LexicalUnitImpl createRawIdent( String uri, int line, int column, String s ) {
return new LexicalUnitImpl( uri, line, column, SAC_IDENT, s );
}
public static LexicalUnitImpl createIdent( String uri, int line, int column, String s ) {
return createIdent( uri, line, column, new StringInterpolationSequence( s ) );
}
public static LexicalUnitImpl createIdent( String uri, int line, int column, StringInterpolationSequence s ) {
if( "null".equals( s.toString() ) ) {
return createNull( uri, line, column );
}
return new LexicalUnitImpl( uri, line, column, SAC_IDENT, s );
}
public static LexicalUnitImpl createString( String uri, int line, int column, String s ) {
return createString( uri, line, column, new StringInterpolationSequence( s ) );
}
public static LexicalUnitImpl createString( String uri, int line, int column, StringInterpolationSequence s ) {
return new LexicalUnitImpl( uri, line, column, SAC_STRING_VALUE, s );
}
public static LexicalUnitImpl createURL( String uri, int line, int column, StringInterpolationSequence s ) {
return new LexicalUnitImpl( uri, line, column, SAC_URI, s );
}
public static LexicalUnitImpl createRGBColor( String uri, int line, int column, ActualArgumentList params ) {
return new LexicalUnitImpl( uri, SAC_RGBCOLOR, line, column, "rgb", params );
}
public static LexicalUnitImpl createRect( String uri, int line, int column, ActualArgumentList params ) {
return new LexicalUnitImpl( uri, SAC_RECT_FUNCTION, line, column, "rect", params );
}
public static LexicalUnitImpl createFunction( String uri, int line, int column, String fname, ActualArgumentList params ) {
return new LexicalUnitImpl( uri, SAC_FUNCTION, line, column, fname, params );
}
public static LexicalUnitImpl createGetFunction( String uri, int line, int column, String fname ) {
return new LexicalUnitImpl( uri, SCSS_GET_FUNCTION, line, column, fname, null );
}
public static LexicalUnitImpl createParent( String uri, int line, int column ) {
return new LexicalUnitImpl( uri, line, column, SCSS_PARENT );
}
public static boolean checkLexicalUnitType(SassListItem item,
short... lexicalUnitTypes) {
if (!(item instanceof LexicalUnitImpl)) {
return false;
}
short itemType = ((LexicalUnitImpl)item).type;
for (short s : lexicalUnitTypes) {
if (itemType == s) {
return true;
}
}
return false;
}
public static LexicalUnitImpl createComma( String uri, int line, int column ) {
return new LexicalUnitImpl( uri, line, column, SAC_OPERATOR_COMMA );
}
public static LexicalUnitImpl createSlash( String uri, int line, int column ) {
return new LexicalUnitImpl( uri, line, column, SAC_OPERATOR_SLASH );
}
public static LexicalUnitImpl createAdd( String uri, int line, int column ) {
return new LexicalUnitImpl( uri, line, column, SAC_OPERATOR_PLUS );
}
public static LexicalUnitImpl createMinus( String uri, int line, int column ) {
return new LexicalUnitImpl( uri, line, column, SAC_OPERATOR_MINUS );
}
public static LexicalUnitImpl createMultiply( String uri, int line, int column ) {
return new LexicalUnitImpl( uri, line, column, SAC_OPERATOR_MULTIPLY );
}
public static LexicalUnitImpl createModulo( String uri, int line, int column ) {
return new LexicalUnitImpl( uri, line, column, SAC_OPERATOR_MOD );
}
public static LexicalUnitImpl createIdent( String s ) {
return new LexicalUnitImpl( null, 0, 0, SAC_IDENT, s );
}
public static LexicalUnitImpl createEquals( String uri, int line, int column) {
return new LexicalUnitImpl(uri,line, column, SCSS_OPERATOR_EQUALS);
}
public static LexicalUnitImpl createNotEqual( String uri, int line, int column ) {
return new LexicalUnitImpl( uri, line, column, SCSS_OPERATOR_NOT_EQUAL );
}
public static LexicalUnitImpl createGreaterThan( String uri, int line, int column ) {
return new LexicalUnitImpl( uri, line, column, SAC_OPERATOR_GT );
}
public static LexicalUnitImpl createGreaterThanOrEqualTo( String uri, int line, int column ) {
return new LexicalUnitImpl( uri, line, column, SAC_OPERATOR_GE );
}
public static LexicalUnitImpl createLessThan( String uri, int line, int column ) {
return new LexicalUnitImpl( uri, line, column, SAC_OPERATOR_LT );
}
public static LexicalUnitImpl createLessThanOrEqualTo( String uri, int line, int column ) {
return new LexicalUnitImpl( uri, line, column, SAC_OPERATOR_LE );
}
public static LexicalUnitImpl createAnd( String uri, int line, int column ) {
return new LexicalUnitImpl( uri, line, column, SCSS_OPERATOR_AND );
}
public static LexicalUnitImpl createOr( String uri, int line, int column ) {
return new LexicalUnitImpl( uri, line, column, SCSS_OPERATOR_OR );
}
public boolean containsInterpolation() {
return s != null && s.containsInterpolation();
}
@Override
public SassListItem evaluateFunctionsAndExpressions( ScssContext context, boolean evaluateArithmetics ) {
switch( type ) {
case SCSS_VARIABLE:
String stringValue = getStringValue();
Variable var = context.getVariable( stringValue );
if( var != null ) {
return var.getExpr().evaluateFunctionsAndExpressions( context, evaluateArithmetics );
}
varNotResolved = true;
break;
case SCSS_PARENT:
BlockNode parentBlock = context.getParentBlock();
return parentBlock != null ? new StringItem( parentBlock.getSelectors() ) : createNull( uri, line, column );
case SAC_FUNCTION:
case SAC_RGBCOLOR:
String functionName = fname;
if( "calc".equals( functionName ) ) {
return createFunction( uri, line, column, functionName, params.evaluateFunctionsAndExpressions( context, false ) );
}
SCSSFunctionGenerator generator = SCSSFunctionGenerator.getGenerator( functionName );
LexicalUnitImpl copy = this;
if( !"if".equals( functionName ) ) {
copy = createFunction( uri, line, column, functionName, params.evaluateFunctionsAndExpressions( context, true ) );
}
if( generator == null ) {
SassListItem result = copy.replaceCustomFunctions( context );
if( result != null ) {
return result;
}
}
if( generator == null ) {
// log unknown functions
switch( functionName.toLowerCase() ) {
case "brightness":
case "counters":
case "hsl":
case "hsla":
case "linear-gradient":
case "not ":
case "rgba":
case "rotate":
case "scale":
case "translate":
case "translatey":
case "translatex":
case "translatez":
case "url":
case "var":
// ignore well known CSS functions
break;
default:
SCSSErrorHandler.get().warning( "Unknown function: " + functionName );
}
return copy;
}
return generator.compute( context, copy );
default:
StringInterpolationSequence s = this.s;
if( s != null && s.containsInterpolation() ) {
StringInterpolationSequence sis = s.replaceVariables( context );
if( sis != s ) {
copy = copy();
copy.s = sis;
return copy;
}
}
}
return this;
}
private SassListItem replaceCustomFunctions(ScssContext context) {
FunctionDefNode functionDef = context
.getFunctionDefinition(getFunctionName());
if (functionDef != null) {
return FunctionCall.evaluate(context, functionDef, this);
}
return null;
}
private String simpleAsString() {
String text = null;
switch (type) {
case SCSS_VARIABLE:
text = "$" + s;
break;
case SCSS_NULL:
text = "";
break;
case SAC_OPERATOR_COMMA:
text = ",";
break;
case SAC_OPERATOR_PLUS:
text = "+";
break;
case SAC_OPERATOR_MINUS:
text = "-";
break;
case SAC_OPERATOR_MULTIPLY:
text = "*";
break;
case SAC_OPERATOR_SLASH:
text = "/";
break;
case SAC_OPERATOR_MOD:
text = "%";
break;
case SAC_OPERATOR_EXP:
text = "^";
break;
case SCSS_OPERATOR_EQUALS:
text = "==";
break;
case SCSS_OPERATOR_NOT_EQUAL:
text = "!=";
break;
case SCSS_OPERATOR_NOT:
text = "not";
break;
case SCSS_OPERATOR_AND:
text = "and";
break;
case SCSS_OPERATOR_OR:
text = "or";
break;
case SAC_OPERATOR_LT:
text = "<";
break;
case SAC_OPERATOR_GT:
text = ">";
break;
case SAC_OPERATOR_LE:
text = "<=";
break;
case SAC_OPERATOR_GE:
text = "=>";
break;
case SAC_OPERATOR_TILDE:
text = "~";
break;
case SAC_INHERIT:
text = "inherit";
break;
case SAC_INTEGER:
case SAC_REAL:
text = getDoubleOrInteger();
break;
case SAC_EM:
case SAC_LEM:
case SAC_REM:
case SAC_EX:
case SAC_PIXEL:
case SAC_INCH:
case SAC_CENTIMETER:
case SAC_MILLIMETER:
case SAC_POINT:
case SAC_PICA:
case SAC_PERCENTAGE:
case SAC_DEGREE:
case SAC_GRADIAN:
case SAC_RADIAN:
case SAC_MILLISECOND:
case SAC_SECOND:
case SAC_HERTZ:
case SAC_KILOHERTZ:
case SAC_DIMENSION:
text = getDoubleOrInteger() + getDimensionUnitText();
break;
}
return text;
}
@Override
public String buildString(BuildStringStrategy strategy) {
String text = simpleAsString();
if (text == null) {
switch (type) {
case SAC_URI:
text = "url(" + getStringValue() + ")";
break;
case SAC_RGBCOLOR:
int[] rgb = getRgb();
if (rgb != null) {
text = ColorUtil.rgbToColorString(rgb);
break;
}
//$FALL-THROUGH$ else fall through to the function branch
case SAC_COUNTER_FUNCTION:
case SAC_COUNTERS_FUNCTION:
case SAC_RECT_FUNCTION:
case SAC_FUNCTION:
if( ColorUtil.isColor( this ) ) {
text = ColorUtil.rgbToColorString( ColorUtil.colorToRgb( this ) );
break;
} else if( ColorUtil.isRgba( this ) || ColorUtil.isHsla( this ) ) {
double alpha = params.get( params.size() - 1 ).getContainedValue().getDoubleValue();
rgb = ColorUtil.colorToRgb( this );
if( rgb != null ) {
if( alpha == 0.0f && rgb[0] == 0 && rgb[1] == 0 && rgb[2] == 0 ) {
text = "transparent";
break;
} else if( alpha == 1.0f ) {
text = ColorUtil.rgbToColorString( rgb );
break;
} else if( params.size() == 2 || ColorUtil.isHsla( this ) ) {
String alphaText = alpha == 0.0f ? "0" : CSS_FLOAT_FORMAT.get().format( alpha );
text = "rgba(" + rgb[0] + ", " + rgb[1] + ", " + rgb[2] + ", " + alphaText + ")";
break;
}
}
}
text = fname + "(" + params.buildString( strategy ) + ")";
break;
case SCSS_GET_FUNCTION:
text = "get-function(" + fname + ")";
break;
case SAC_IDENT:
text = getStringValue();
break;
case SAC_STRING_VALUE:
// @@SEEME. not exact
text = "\"" + getStringValue() + "\"";
break;
case SAC_SUB_EXPRESSION:
text = strategy.build(getParameterList());
break;
case SCSS_PARENT:
text = "&";
break;
default:
text = "@unknown";
break;
}
}
return text;
}
private int[] getRgb() {
if (params.size() != 3
|| !checkLexicalUnitType(params.get(0), SAC_INTEGER)
|| !checkLexicalUnitType(params.get(1), SAC_INTEGER)
|| !checkLexicalUnitType(params.get(2), SAC_INTEGER)) {
return null;
}
int red = ((LexicalUnitImpl) params.get(0)).getIntegerValue();
int green = ((LexicalUnitImpl) params.get(1)).getIntegerValue();
int blue = ((LexicalUnitImpl) params.get(2)).getIntegerValue();
return new int[] { red, green, blue };
}
@Override
public boolean containsArithmeticalOperator() {
return false;
}
@Override
public LexicalUnitImpl updateUrl(String prefix) {
if (getItemType() == SAC_URI) {
LexicalUnitImpl copy = copy();
if( s.containsInterpolation() ) {
List items = new ArrayList<>();
items.add( new StringItem( prefix ) );
items.addAll( s.getItems() );
copy.s = new StringInterpolationSequence( items );
} else {
String path = getStringValue().replaceAll("^\"|\"$", "")
.replaceAll("^'|'$", "");
if (!path.startsWith("/") && !path.contains(":")) {
path = prefix + path;
path = StringUtil.cleanPath(path);
}
copy.setStringValue(path);
}
return copy;
} else if (containsInterpolation()) {
// s might contain URLs in its Interpolation objects
LexicalUnitImpl copy = copy();
copy.s = s.updateUrl(prefix);
return copy;
}
return this;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof LexicalUnitImpl)) {
return false;
}
LexicalUnitImpl other = (LexicalUnitImpl) o;
if (isNumber() && other.isNumber()) {
if (!isUnitlessNumber() && !other.isUnitlessNumber()) {
if (getItemType() != other.getItemType()) {
return false;
}
}
return getDoubleValue() == other.getDoubleValue()
&& getIntegerValue() == other.getIntegerValue();
} else if (getItemType() != other.getItemType()) {
return false;
} else {
return printState().equals(other.printState());
}
}
@Override
public int hashCode() {
return printState().hashCode();
}
@Override
public LexicalUnitImpl getContainedValue() {
return this;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy