Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for 'fr' units #251

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/css/Parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -1876,8 +1876,8 @@ Parser.prototype = function() {
/*
* term
* : unary_operator?
* [ NUMBER S* | PERCENTAGE S* | LENGTH S* | ANGLE S* |
* TIME S* | FREQ S* | function | ie_function ]
* [ NUMBER S* | PERCENTAGE S* | DIMENSION S* | LENGTH S* |
* ANGLE S* | TIME S* | FREQ S* | function | ie_function ]
* | STRING S* | IDENT S* | URI S* | UNICODERANGE S* | hexcolor
* ;
*/
Expand Down Expand Up @@ -1922,9 +1922,9 @@ Parser.prototype = function() {
this._readWhitespace();

// see if there's a simple match
} else if (tokenStream.match([Tokens.NUMBER, Tokens.PERCENTAGE, Tokens.LENGTH,
Tokens.ANGLE, Tokens.TIME,
Tokens.FREQ, Tokens.STRING, Tokens.IDENT, Tokens.URI, Tokens.UNICODE_RANGE])) {
} else if (tokenStream.match([Tokens.NUMBER, Tokens.PERCENTAGE, Tokens.DIMENSION,
Tokens.LENGTH, Tokens.ANGLE, Tokens.TIME, Tokens.FREQ, Tokens.STRING,
Tokens.IDENT, Tokens.URI, Tokens.UNICODE_RANGE])) {

value = tokenStream.token().value;
if (unary === null) {
Expand Down
2 changes: 1 addition & 1 deletion src/css/PropertyValuePart.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function PropertyValuePart(text, line, col, optionalHint) {
break;

case "fr":
this.type = "grid";
this.type = "flex";
break;

case "deg":
Expand Down
56 changes: 30 additions & 26 deletions src/css/TokenStream.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ function isNameChar(c) {
return c != null && (isNameStart(c) || /[0-9\-\\]/.test(c));
}

function isIdentStart(c) {
return c != null && (isNameStart(c) || /-\\/.test(c));
}

function mix(receiver, supplier) {
for (var prop in supplier) {
if (Object.prototype.hasOwnProperty.call(supplier, prop)) {
Expand Down Expand Up @@ -170,7 +166,7 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
*/
case ".":
if (isDigit(reader.peek())) {
token = this.numberToken(c, startLine, startCol);
token = this.numericToken(c, startLine, startCol);
} else {
token = this.charToken(c, startLine, startCol);
}
Expand All @@ -187,7 +183,7 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
*/
case "-":
if (wouldStartUnsignedNumber(reader.peekCount(2))) {
token = this.numberToken(c, startLine, startCol);
token = this.numericToken(c, startLine, startCol);
break;
} else if (reader.peekCount(2) === "->") {
token = this.htmlCommentEndToken(c, startLine, startCol);
Expand All @@ -203,7 +199,7 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
*/
case "+":
if (wouldStartUnsignedNumber(reader.peekCount(2))) {
token = this.numberToken(c, startLine, startCol);
token = this.numericToken(c, startLine, startCol);
} else {
token = this.charToken(c, startLine, startCol);
}
Expand Down Expand Up @@ -290,16 +286,7 @@ TokenStream.prototype = mix(new TokenStreamBase(), {

/**
* Produces a token based on the given character and location in the
* stream, when no other case applies.
* Potential tokens:
* - NUMBER
* - DIMENSION
* - LENGTH
* - FREQ
* - TIME
* - EMS
* - EXS
* - ANGLE
* stream, when no other case applies. Many potential tokens.
* @param {String} c The character for the token.
* @param {int} startLine The beginning line for the character.
* @param {int} startCol The beginning column for the character.
Expand All @@ -311,7 +298,7 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
token = null;

if (isDigit(c)) {
token = this.numberToken(c, startLine, startCol);
token = this.numericToken(c, startLine, startCol);
} else

/*
Expand Down Expand Up @@ -679,27 +666,44 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
},

/**
* Produces a number token based on the given character
* and location in the stream. This may return a token of
* NUMBER, EMS, EXS, LENGTH, ANGLE, TIME, FREQ, DIMENSION,
* or PERCENTAGE.
* Consume and return a numeric token, as described in the CSS spec:
* https://drafts.csswg.org/css-syntax-3/#consume-numeric-token.
* This may return a token of NUMBER, PERCENTAGE, or DIMENSION (or for now,
* one of LENGTH, ANGLE, TIME, FREQ, FLEX, or RESOLUTION when appropriate).
* @deprecated Use `numericToken` instead.
* @param {String} first The first character for the token.
* @param {int} startLine The beginning line for the character.
* @param {int} startCol The beginning column for the character.
* @return {Object} A token object.
* @method numberToken
*/
numberToken: function(first, startLine, startCol) {
return this.numericToken(first, startLine, startCol);
},

/**
* Consume and return a numeric token, as described in the CSS spec:
* https://drafts.csswg.org/css-syntax-3/#consume-numeric-token.
* This may return a token of NUMBER, PERCENTAGE, or DIMENSION (or for now,
* one of LENGTH, ANGLE, TIME, FREQ, FLEX, or RESOLUTION when appropriate).
* @param {String} first The first character for the token.
* @param {int} startLine The beginning line for the character.
* @param {int} startCol The beginning column for the character.
* @return {Object} A token object.
* @method numericToken
*/
numericToken: function(first, startLine, startCol) {
var reader = this._reader,
value = this.readNumber(first),
ident,
tt = Tokens.NUMBER,
c = reader.peek();
tt = Tokens.NUMBER;

if (isIdentStart(c)) {
if (wouldStartIdent(reader.peekCount(2))) {
ident = this.readName(reader.read());
value += ident;

// NOTE: As long as these dimension subtypes exist, these lists must
// be kept in sync with those in PropertyValuePart.js.
if (/^em$|^ex$|^px$|^gd$|^rem$|^vw$|^vh$|^vmax$|^vmin$|^ch$|^cm$|^mm$|^in$|^pt$|^pc$/i.test(ident)) {
tt = Tokens.LENGTH;
} else if (/^deg|^rad$|^grad$|^turn$/i.test(ident)) {
Expand All @@ -714,7 +718,7 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
tt = Tokens.DIMENSION;
}

} else if (c === "%") {
} else if (reader.peek() === "%") {
value += reader.read();
tt = Tokens.PERCENTAGE;
}
Expand Down
19 changes: 11 additions & 8 deletions src/css/Tokens.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,10 @@ var Tokens = module.exports = [
// important symbol
{ name: "IMPORTANT_SYM" },

// measurements
{ name: "LENGTH" },
{ name: "ANGLE" },
{ name: "TIME" },
{ name: "FREQ" },
{ name: "DIMENSION" },
{ name: "PERCENTAGE" },
{ name: "NUMBER" },
// numeric
{ name: "NUMBER" }, // https://www.w3.org/TR/css-syntax-3/#number-token-diagram
{ name: "DIMENSION" }, // https://www.w3.org/TR/css-syntax-3/#dimension-token-diagram
{ name: "PERCENTAGE" }, // https://www.w3.org/TR/css-syntax-3/#percentage-token-diagram

// functions
{ name: "URI" },
Expand Down Expand Up @@ -109,6 +105,13 @@ var Tokens = module.exports = [
* The following token names are not defined in any CSS specification but are used by the lexer.
*/

// TODO: Drop these as tokens, so they exist only as PropertyValueParts?
// subtypes of dimension: These are not tokens in CSS3 grammar.
{ name: "LENGTH" }, // https://www.w3.org/TR/css3-values/#lengths
{ name: "ANGLE" }, // https://www.w3.org/TR/css3-values/#angles
{ name: "TIME" }, // https://www.w3.org/TR/css3-values/#time
{ name: "FREQ" }, // https://www.w3.org/TR/css3-values/#frequency

// not a real token, but useful for stupid IE filters
{ name: "IE_FUNCTION" },

Expand Down
26 changes: 26 additions & 0 deletions tests/css/Parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -1037,6 +1037,32 @@ var YUITest = require("yuitest"),
Assert.areEqual("ch", result.parts[0].units);
},

testDimensionValueFr: function() {
var parser = new Parser();
var result = parser.parsePropertyValue("2fr");

Assert.isInstanceOf(parserlib.css.PropertyValue, result);
Assert.areEqual(1, result.parts.length);
Assert.areEqual("flex", result.parts[0].type);
Assert.areEqual(2, result.parts[0].value);
Assert.areEqual("fr", result.parts[0].units);
},

testDimensionValuePxAndFr: function() {
var parser = new Parser();
var result = parser.parsePropertyValue("100px 1fr");

Assert.isInstanceOf(parserlib.css.PropertyValue, result);
Assert.areEqual(2, result.parts.length);
Assert.areEqual("length", result.parts[0].type);
Assert.areEqual(100, result.parts[0].value);
Assert.areEqual("px", result.parts[0].units);
Assert.isInstanceOf(parserlib.css.PropertyValue, result);
Assert.areEqual("flex", result.parts[1].type);
Assert.areEqual(1, result.parts[1].value);
Assert.areEqual("fr", result.parts[1].units);
},

testViewportRelativeHeightValue: function() {
var parser = new Parser();
var result = parser.parsePropertyValue("50vh");
Expand Down
12 changes: 9 additions & 3 deletions tests/css/TokenStream.js
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ var YUITest = require("yuitest"),
}));

suite.add(new CSSTokenTestCase({
name : "Tests for Numbers",
name : "Tests for Numbers, Dimensions, and Percentages",

patterns: {

Expand All @@ -322,7 +322,6 @@ var YUITest = require("yuitest"),
"50.0PX" : [CSSTokens.LENGTH],
".6Px" : [CSSTokens.LENGTH],


"7cm" : [CSSTokens.LENGTH],
"7CM" : [CSSTokens.LENGTH],
"7cM" : [CSSTokens.LENGTH],
Expand Down Expand Up @@ -363,7 +362,6 @@ var YUITest = require("yuitest"),
"50.0CH" : [CSSTokens.LENGTH],
".5cH" : [CSSTokens.LENGTH],


"5deg" : [CSSTokens.ANGLE],
"50.0DEG" : [CSSTokens.ANGLE],
".5Deg" : [CSSTokens.ANGLE],
Expand Down Expand Up @@ -395,6 +393,10 @@ var YUITest = require("yuitest"),
"50.0KHZ" : [CSSTokens.FREQ],
".5kHz" : [CSSTokens.FREQ],

"1fr" : [CSSTokens.DIMENSION],
"0fr" : [CSSTokens.DIMENSION],
".25fr" : [CSSTokens.DIMENSION],

"5ncz" : [CSSTokens.DIMENSION],
"50.0NCZ" : [CSSTokens.DIMENSION],
".5nCz" : [CSSTokens.DIMENSION],
Expand Down Expand Up @@ -506,6 +508,10 @@ var YUITest = require("yuitest"),
"background: red;" : [CSSTokens.IDENT, CSSTokens.COLON, CSSTokens.S, CSSTokens.IDENT, CSSTokens.SEMICOLON],
"background-color: red;" : [CSSTokens.IDENT, CSSTokens.COLON, CSSTokens.S, CSSTokens.IDENT, CSSTokens.SEMICOLON],

//multiple value parts
"margin: 0 auto 10px;" : [CSSTokens.IDENT, CSSTokens.COLON, CSSTokens.S, CSSTokens.NUMBER, CSSTokens.S, CSSTokens.IDENT, CSSTokens.S, CSSTokens.LENGTH, CSSTokens.SEMICOLON],
"grid-template-columns: 100px 1fr max-content minmax(min-content, 1fr);" : [CSSTokens.IDENT, CSSTokens.COLON, CSSTokens.S, CSSTokens.LENGTH, CSSTokens.S, CSSTokens.DIMENSION, CSSTokens.S, CSSTokens.IDENT, CSSTokens.S, CSSTokens.FUNCTION, CSSTokens.IDENT, CSSTokens.COMMA, CSSTokens.S, CSSTokens.DIMENSION, CSSTokens.RPAREN, CSSTokens.SEMICOLON],

"filter: progid:DXImageTransform.Microsoft.Wave(strength=100);": [CSSTokens.IDENT, CSSTokens.COLON, CSSTokens.S, CSSTokens.IE_FUNCTION, CSSTokens.IDENT, CSSTokens.EQUALS, CSSTokens.NUMBER, CSSTokens.RPAREN, CSSTokens.SEMICOLON]

}
Expand Down
19 changes: 15 additions & 4 deletions tests/css/Validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ var YUITest = require("yuitest"),
underscoreHack: true
});
parser.parse(".foo { " + this.property + ":" + value + "}");
Assert.pass();
};


Expand Down Expand Up @@ -187,11 +188,12 @@ var YUITest = require("yuitest"),

invalid: {
"1px" : "Expected ([ none | <single-animation-name> ]#) but found '1px'.",
"--invalid" : "Expected ([ none | <single-animation-name> ]#) but found '--invalid'."
"--invalid" : "Expected ([ none | <single-animation-name> ]#) but found '--invalid'.",
"-0num": "Expected ([ none | <single-animation-name> ]#) but found '-0num'.",
},

error: {
"-0num": "Unexpected token '-0num' at line 1, col 23."
"@foo": "Unexpected token '@foo' at line 1, col 23."
}
}));

Expand Down Expand Up @@ -981,14 +983,14 @@ var YUITest = require("yuitest"),

invalid: {
"--Futura, sans-serif" : "Expected ([ <generic-family> | <family-name> ]#) but found '--Futura , sans-serif'.",
"47Futura, sans-serif" : "Expected ([ <generic-family> | <family-name> ]#) but found '47Futura , sans-serif'.",
"-7Futura, sans-serif" : "Expected ([ <generic-family> | <family-name> ]#) but found '-7Futura , sans-serif'.",
"Red/Black, sans-serif" : "Expected end of value but found '/'.",
"'Lucida' Grande, sans-serif" : "Expected end of value but found 'Grande'.",
"Hawaii 5-0, sans-serif" : "Expected end of value but found '5'."
},

error: {
"47Futura, sans-serif" : "Unexpected token '47Futura' at line 1, col 20.",
"-7Futura, sans-serif" : "Unexpected token '-7Futura' at line 1, col 20.",
"Ahem!, sans-serif" : "Expected RBRACE at line 1, col 24.",
"test@foo, sans-serif" : "Expected RBRACE at line 1, col 24.",
"#POUND, sans-serif" : "Expected a hex color but found '#POUND' at line 1, col 20."
Expand Down Expand Up @@ -1061,6 +1063,15 @@ var YUITest = require("yuitest"),
]
}));

suite.add(new ValidationTestCase({
property: "grid-template-columns",

valid: [
"100px 1fr", "fit-content(40%)", "repeat(3, 200px)",
"100px 1fr max-content minmax(min-content, 1fr)"
]
}));

suite.add(new ValidationTestCase({
property: "image-rendering",

Expand Down