in AjaxMinDll/Css/CssScanner.cs [1019:1147]
private CssToken ScanNum()
{
CssToken token = null;
string num = GetNum();
if (num != null)
{
if (m_currentChar == '%')
{
NextChar();
// let's always keep the percentage on the number, even if it's
// zero -- some things require it (like the rgb function)
token = new CssToken(
TokenType.Percentage,
num + '%',
m_context
);
// and make sure the "raw number" we keep has it as well
m_rawNumber += '%';
}
else
{
string dimen = GetIdent();
if (dimen == null)
{
// if there is no identifier, it's a num.
token = new CssToken(TokenType.Number, num, m_context);
}
else
{
// add the dimension to the raw number
m_rawNumber += dimen;
// classify the dimension type
TokenType tokenType = TokenType.Dimension;
switch (dimen.ToUpperInvariant())
{
case "EM": // font-size of the element
case "EX": // x-height of the element's font
case "CH": // width of the zero glyph in the element's font
case "REM": // font-size of the root element
case "VW": // viewport's width
case "VH": // viewport's height
case "VM": // viewport width or height, whichever is smaller of the two (use VMIN)
case "VMIN": // minimum of the viewport's height and width
case "VMAX": // maximum of the viewport's height and width
case "FR": // fraction of available space
case "GR": // grid unit
case "GD": // text grid unit
tokenType = TokenType.RelativeLength;
break;
case "CM": // centimeters
case "MM": // millimeters
case "IN": // inches (1in == 2.54cm)
case "PX": // pixels (1px == 1/96in)
case "PT": // points (1pt == 1/72in)
case "PC": // picas (1pc == 12pt)
tokenType = TokenType.AbsoluteLength;
break;
case "DEG": // degrees (360deg == 1 full circle)
case "GRAD": // gradians (400grad == 1 full circle)
case "RAD": // radians (2*pi radians == 1 full circle)
case "TURN": // turns (1turn == 1 full circle)
tokenType = TokenType.Angle;
break;
case "MS": // milliseconds
case "S": // seconds
tokenType = TokenType.Time;
break;
case "DPI": // dots per inch
case "DPCM": // dots per centimeter
case "DPPX": // dots per pixel
tokenType = TokenType.Resolution;
break;
case "HZ": // hertz
case "KHZ": // kilohertz
tokenType = TokenType.Frequency;
break;
case "DB": // decibel
case "ST": // semitones
tokenType = TokenType.Speech;
break;
}
// if the number is zero, it really doesn't matter what the dimensions are so we can remove it
// EXCEPT for Angles, Times, Frequencies, and Resolutions - they should not get their units
// stripped, since we can only do that for LENGTHS as per the specs.
// And percentages, since 0% is the same as 0. (true?)
// ALSO, if we don't recognize the dimension, leave it -- it could be a browser hack or some
// other intentional construct.
if (num == "0"
&& tokenType != TokenType.Dimension
&& tokenType != TokenType.Angle
&& tokenType != TokenType.Time
&& tokenType != TokenType.Frequency
&& tokenType != TokenType.Resolution)
{
token = new CssToken(TokenType.Number, num, m_context);
}
else
{
token = new CssToken(tokenType, num + dimen, m_context);
}
}
}
}
else if (m_currentChar == '.')
{
token = new CssToken(TokenType.Character, '.', m_context);
NextChar();
}
else
{
// this function is only called when the first character is
// a digit or a period. So this block should never execute, since
// a digit will produce a num, and if it doesn't, the previous block
// picks up the period.
ReportError(1, CssErrorCode.UnexpectedNumberCharacter, m_currentChar);
}
return token;
}