Skip to content
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Head

* Adds `<clip-path>` validator.
* Adds `<mask-reference>` validator.
* Adds support for the non-standard -webkit-mask-position property.
* Adds support for the non-standard -webkit-mask-composite property.
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ valid, even though they are not to specification.

## Property support

We support 252 of 361 CSS properties (69.81%).
We support 254 of 361 CSS properties (70.36%).

* `-ms-overflow-style`
* `-moz-appearance`
Expand All @@ -56,6 +56,7 @@ We support 252 of 361 CSS properties (69.81%).
* `-webkit-border-before-color`
* `-webkit-border-before-style`
* `-webkit-border-before-width`
* `-webkit-clip-path`
* `-webkit-mask-attachment`
* `-webkit-mask-composite`
* `-webkit-mask-position`
Expand Down Expand Up @@ -141,6 +142,7 @@ We support 252 of 361 CSS properties (69.81%).
* `break-inside`
* `caption-side`
* `clear`
* `clip-path`
* `color`
* `column-count`
* `column-fill`
Expand Down
198 changes: 190 additions & 8 deletions packages/css-values/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,172 @@ function isBgSize(valueParserAST) {
return getArguments(valueParserAST).every(validateGroup$1);
}

var geometryBoxes = ['margin-box', 'fill-box', 'stroke-box', 'view-box'];

var nonStandardKeywords = ['content', 'padding', 'border'];

var isGeometryBox = (function (node) {
return isBox(node) || isKeyword(node, geometryBoxes) || isKeyword(node, nonStandardKeywords);
});

function isFillRule(node) {
return isKeyword(node, ['nonzero', 'evenodd']);
}

function isShapeRadius(node) {
return isLengthPercentage(node) || isKeyword(node, ['closest-side', 'farthest-side']);
}

function isInset(node) {
if (!isFunction(node, 'inset')) {
return false;
}
var valid = true;
walk(node.nodes, function (child, index) {
var even = isEven(index);
if (!even && !isSpace(child)) {
valid = false;
return false;
}
if (even && !isLengthPercentage(child)) {
valid = false;
return false;
}
});
return valid;
}

function isCircle(node) {
if (!isFunction(node, 'circle')) {
return false;
}
var valid = true;
var atIdx = 0;
var skip = false;
walk(node.nodes, function (child, index) {
if (skip) {
return false;
}
var even = isEven(index);
if (!even && !isSpace(child)) {
valid = false;
return false;
}
if (even) {
if (isAt(child)) {
skip = true;
atIdx = index;
return false;
}

if (!isShapeRadius(child)) {
valid = false;
return false;
}
}
});
if (skip && !isPositionNoRepeat({ nodes: node.nodes.slice(atIdx + 2) })) {
return false;
};
return valid;
}

function isEllipse(node) {
if (!isFunction(node, 'ellipse')) {
return false;
}
var valid = true;
var atIdx = 0;
var skip = false;
var expectShapeRadius = false;
walk(node.nodes, function (child, index) {
if (skip) {
return false;
}
if (index === 0) {
if (isShapeRadius(child)) {
expectShapeRadius = true;
}
};
if (index === 2 && expectShapeRadius) {
if (!isShapeRadius(child)) {
valid = false;
return false;
}
};
var even = isEven(index);
if (!even && !isSpace(child)) {
valid = false;
return false;
}
if (even) {
if (isAt(child)) {
skip = true;
atIdx = index;
return false;
}
};
});
if (skip && !isPositionNoRepeat({ nodes: node.nodes.slice(atIdx + 2) })) {
return false;
};
return valid;
}

function isPolygon(node) {
if (!isFunction(node, 'polygon')) {
return false;
}
var valid = true;
var commaIdx = void 0;
walk(node.nodes, function (child, index) {
if (index === node.nodes.length - 1) {
if (!isComma(node.nodes[index - 3])) {
valid = false;
return false;
};
};
if (index === 0) {
if (isFillRule(child)) {
commaIdx = 1;
return false;
}
if (isLengthPercentage(child)) {
commaIdx = 3;
return false;
}
valid = false;
return false;
};
if (index === commaIdx) {
commaIdx += 4;
if (!isComma(child)) {
valid = false;
return false;
};
} else {
var even = isEven(index);
if (even && !isLengthPercentage(child)) {
valid = false;
return false;
}
if (!even && !isSpace(child)) {
valid = false;
return false;
}
};
});
return valid;
}

var isBasicShape = (function (node) {
return isInset(node) || isCircle(node) || isEllipse(node) || isPolygon(node);
});

var isClipPathProperty = (function (node) {
return isUrl(node) || isBasicShape(node) || isGeometryBox(node);
});

var absoluteSizes = ['xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'];

var isAbsoluteSize = (function (node) {
Expand Down Expand Up @@ -978,14 +1144,6 @@ var isMaskingMode = (function (node) {
return isKeyword(node, maskingModes);
});

var geometryBoxes = ['margin-box', 'fill-box', 'stroke-box', 'view-box'];

var nonStandardKeywords = ['content', 'padding', 'border'];

var isGeometryBox = (function (node) {
return isBox(node) || isKeyword(node, geometryBoxes) || isKeyword(node, nonStandardKeywords);
});

function validateShadow(nodes) {
var hasColor = false;
var hasLength = 0;
Expand Down Expand Up @@ -1663,6 +1821,28 @@ var webkitColumnBreakInsideValidator = isKeywordFactory(["auto", "avoid", "avoid
var captionSideValidator = isKeywordFactory(["top", "bottom", "block-start", "block-end", "inline-start", "inline-end"]);
var clearValidator = isKeywordFactory(["none", "left", "right", "both", "inline-start", "inline-end"]);

var clipPathValidator = function clipPathValidator(valueParserAST) {
var node = valueParserAST.nodes[0];

if (valueParserAST.nodes.length !== 1) {
return invalidMessage("Expected a single value to be passed.");
}

var isKeywordResult = isKeyword(node, "none");

if (!!isKeywordResult !== false) {
return isKeywordResult;
}

var isClipPathPropertyResult = isClipPathProperty(node);

if (!!isClipPathPropertyResult !== false) {
return isClipPathPropertyResult;
}

return false;
};

var columnCountValidator = function columnCountValidator(valueParserAST) {
var node = valueParserAST.nodes[0];

Expand Down Expand Up @@ -2432,6 +2612,7 @@ var validators = {
"-webkit-box-orient": mozBoxOrientValidator,
"-webkit-box-pack": mozBoxPackValidator,
"-webkit-box-sizing": boxSizingValidator,
"-webkit-clip-path": clipPathValidator,
"-webkit-column-break-inside": webkitColumnBreakInsideValidator,
"-webkit-column-count": columnCountValidator,
"-webkit-column-fill": columnFillValidator,
Expand Down Expand Up @@ -2540,6 +2721,7 @@ var validators = {
"break-inside": webkitColumnBreakInsideValidator,
"caption-side": captionSideValidator,
"clear": clearValidator,
"clip-path": clipPathValidator,
"color": webkitBorderBeforeColorValidator,
"column-count": columnCountValidator,
"column-fill": columnFillValidator,
Expand Down
53 changes: 52 additions & 1 deletion packages/css-values/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1695,6 +1695,55 @@ test(validCI, clearValidator, "inline-start");
test(invalid, clearValidator, "inline-start inline-start");
test(validCI, clearValidator, "inline-end");
test(invalid, clearValidator, "inline-end inline-end");
var clipPathValidator = ["-webkit-clip-path", "clip-path"];
test(globals, clipPathValidator);
test(invalid, clipPathValidator, "0118-999-881-999-119-725-3");
test(valid, clipPathValidator, "url(https://ru.wikipedia.org/wiki/URI)");
test(valid, clipPathValidator, "url(data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAw)");
test(valid, clipPathValidator, "margin-box");
test(valid, clipPathValidator, "fill-box");
test(valid, clipPathValidator, "stroke-box");
test(valid, clipPathValidator, "view-box");
test(valid, clipPathValidator, "content");
test(valid, clipPathValidator, "padding");
test(valid, clipPathValidator, "border");
test(valid, clipPathValidator, "border-box");
test(valid, clipPathValidator, "padding-box");
test(valid, clipPathValidator, "content-box");
test(valid, clipPathValidator, "BORDER-BOX");
test(valid, clipPathValidator, "PADDING-BOX");
test(valid, clipPathValidator, "CONTENT-BOX");
test(valid, clipPathValidator, "view-box");
test(valid, clipPathValidator, "fill-box");
test(valid, clipPathValidator, "border-box");
test(valid, clipPathValidator, "inset(20% 50px)");
test(valid, clipPathValidator, "circle(closest-side at 20px 20px)");
test(valid, clipPathValidator, "circle(12%)");
test(valid, clipPathValidator, "ellipse(closest-side 20px at 20px 20px)");
test(valid, clipPathValidator, "polygon(30px 20px, 15px 10px, 12% 5px)");
test(valid, clipPathValidator, "polygon(evenodd, 30px 20px, 15px 10px, 12% 5px)");
test(invalid, clipPathValidator, "ur(https://ru.wikipedia.org/wiki/URI)");
test(invalid, clipPathValidator, "rock-box");
test(invalid, clipPathValidator, "view-box, fill-box, 1px");
test(invalid, clipPathValidator, "isnet(35px)");
test(invalid, clipPathValidator, "inset(98 12kHz)");
test(invalid, clipPathValidator, "inset(20%, 50px)");
test(invalid, clipPathValidator, "clrcke(15px at 20px 20px)");
test(invalid, clipPathValidator, "circle(12kHz at 20px 20px)");
test(invalid, clipPathValidator, "circle(farthest-side, at 20px)");
test(invalid, clipPathValidator, "circle(farthest-side at 20)");
test(invalid, clipPathValidator, "ellipse(closest-side, 20px at 20px 12em)");
test(invalid, clipPathValidator, "ellipse(closest-side 90deg at 20px 20px)");
test(invalid, clipPathValidator, "ellipse(90deg 20px at 65deg)");
test(invalid, clipPathValidator, "elcipse(closest-side 20px at 201)");
test(invalid, clipPathValidator, "monogon(30px 20px, 15px 10px, 12% 5px)");
test(invalid, clipPathValidator, "polygon(25kHz, 30px 20px, 15px 10px, 12% 5px)");
test(invalid, clipPathValidator, "polygon(15px 10px, yoyo 20px, 12% 5px)");
test(invalid, clipPathValidator, "polygon(closest-side, 10% 20px 6px, 15px 10px, 12% 5px)");
test(invalid, clipPathValidator, "polygon(30px 20px, 15px 10px, 12% 5px 78px)");
test(invalid, clipPathValidator, "url(https://ru.wikipedia.org/wiki/URI) url(https://ru.wikipedia.org/wiki/URI)");
test(validCI, clipPathValidator, "none");
test(invalid, clipPathValidator, "none none");
var columnCountValidator = ["-webkit-column-count", "-moz-column-count", "column-count"];
test(globals, columnCountValidator);
test(invalid, columnCountValidator, "0118-999-881-999-119-725-3");
Expand Down Expand Up @@ -2812,7 +2861,9 @@ test(valid, maskOriginValidator, "content-box");
test(valid, maskOriginValidator, "BORDER-BOX");
test(valid, maskOriginValidator, "PADDING-BOX");
test(valid, maskOriginValidator, "CONTENT-BOX");
test(valid, maskOriginValidator, "view-box, fill-box, border-box");
test(valid, maskOriginValidator, "view-box");
test(valid, maskOriginValidator, "fill-box");
test(valid, maskOriginValidator, "border-box");
test(invalid, maskOriginValidator, "rock-box");
test(invalid, maskOriginValidator, "view-box, fill-box, 1px");
test(valid, maskOriginValidator, "margin-box, margin-box");
Expand Down
2 changes: 2 additions & 0 deletions src/completed.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default [
'-webkit-border-before-color',
'-webkit-border-before-style',
'-webkit-border-before-width',
'-webkit-clip-path',
'-webkit-mask-attachment',
'-webkit-mask-composite',
'-webkit-mask-position',
Expand Down Expand Up @@ -103,6 +104,7 @@ export default [
'break-inside',
'caption-side',
'clear',
'clip-path',
'color',
'column-count',
'column-fill',
Expand Down
1 change: 1 addition & 0 deletions src/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const overrides = {
'text-indent': '[ <length> | <percentage> ] && hanging? && each-line?',
top: '<length-percentage> | auto',
'vertical-align': 'baseline | sub | super | text-top | text-bottom | middle | top | bottom | <length-percentage>',
'clip-path': '<clip-path-property> | none ',
// syntaxes
'feature-value-name': '<IDENT>',
'single-transition-property': 'all | <IDENT>',
Expand Down
28 changes: 28 additions & 0 deletions src/fixtures/basicShape.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export default {
valid: [
'inset(20% 50px)',
'circle(closest-side at 20px 20px)',
'circle(12%)',
'ellipse(closest-side 20px at 20px 20px)',
'polygon(30px 20px, 15px 10px, 12% 5px)',
'polygon(evenodd, 30px 20px, 15px 10px, 12% 5px)',
],
invalid: [
'isnet(35px)',
'inset(98 12kHz)',
'inset(20%, 50px)',
'clrcke(15px at 20px 20px)',
'circle(12kHz at 20px 20px)',
'circle(farthest-side, at 20px)',
'circle(farthest-side at 20)',
'ellipse(closest-side, 20px at 20px 12em)',
'ellipse(closest-side 90deg at 20px 20px)',
'ellipse(90deg 20px at 65deg)',
'elcipse(closest-side 20px at 201)',
'monogon(30px 20px, 15px 10px, 12% 5px)',
'polygon(25kHz, 30px 20px, 15px 10px, 12% 5px)',
'polygon(15px 10px, yoyo 20px, 12% 5px)',
'polygon(closest-side, 10% 20px 6px, 15px 10px, 12% 5px)',
'polygon(30px 20px, 15px 10px, 12% 5px 78px)',
],
};
Loading