GithubHelp home page GithubHelp logo

csstree / stylelint-validator Goto Github PK

View Code? Open in Web Editor NEW
92.0 92.0 10.0 591 KB

Stylelint plugin to validate CSS syntax

License: MIT License

JavaScript 100.00%
css csstree less lint plugin stylelint stylelint-plugin syntax syntax-checker validator w3c

stylelint-validator's Introduction

CSSTree logo

CSSTree

NPM version Build Status Coverage Status NPM Downloads Twitter

CSSTree is a tool set for CSS: fast detailed parser (CSS → AST), walker (AST traversal), generator (AST → CSS) and lexer (validation and matching) based on specs and browser implementations. The main goal is to be efficient and W3C spec compliant, with focus on CSS analyzing and source-to-source transforming tasks.

Features

  • Detailed parsing with an adjustable level of detail

    By default CSSTree parses CSS as detailed as possible, i.e. each single logical part is representing with its own AST node (see AST format for all possible node types). The parsing detail level can be changed through parser options, for example, you can disable parsing of selectors or declaration values for component parts.

  • Tolerant to errors by design

    Parser behaves as spec says: "When errors occur in CSS, the parser attempts to recover gracefully, throwing away only the minimum amount of content before returning to parsing as normal". The only thing the parser departs from the specification is that it doesn't throw away bad content, but wraps it in a special node type (Raw) that allows processing it later.

  • Fast and efficient

    CSSTree is created with focus on performance and effective memory consumption. Therefore it's one of the fastest CSS parsers at the moment.

  • Syntax validation

    The build-in lexer can test CSS against syntaxes defined by W3C. CSSTree uses mdn/data as a basis for lexer's dictionaries and extends it with vendor specific and legacy syntaxes. Lexer can only check the declaration values currently, but this feature will be extended to other parts of the CSS in the future.

Projects using CSSTree

  • Svelte – Cybernetically enhanced web apps
  • SVGO – Node.js tool for optimizing SVG files
  • CSSO – CSS minifier with structural optimizations
  • NativeScript – NativeScript empowers you to access native APIs from JavaScript directly
  • react-native-svg – SVG library for React Native, React Native Web, and plain React web projects
  • penthouse – Critical Path CSS Generator
  • Bit – Bit is the platform for collaborating on components
  • and more...

Documentation

Tools

Related projects

Usage

Install with npm:

npm install css-tree

Basic usage:

import * as csstree from 'css-tree';

// parse CSS to AST
const ast = csstree.parse('.example { world: "!" }');

// traverse AST and modify it
csstree.walk(ast, (node) => {
    if (node.type === 'ClassSelector' && node.name === 'example') {
        node.name = 'hello';
    }
});

// generate CSS from AST
console.log(csstree.generate(ast));
// .hello{world:"!"}

Syntax matching:

// parse CSS to AST as a declaration value
const ast = csstree.parse('red 1px solid', { context: 'value' });

// match to syntax of `border` property
const matchResult = csstree.lexer.matchProperty('border', ast);

// check first value node is a <color>
console.log(matchResult.isType(ast.children.first, 'color'));
// true

// get a type list matched to a node
console.log(matchResult.getTrace(ast.children.first));
// [ { type: 'Property', name: 'border' },
//   { type: 'Type', name: 'color' },
//   { type: 'Type', name: 'named-color' },
//   { type: 'Keyword', name: 'red' } ]

Exports

Is it possible to import just a needed part of library like a parser or a walker. That's might useful for loading time or bundle size optimisations.

import * as tokenizer from 'css-tree/tokenizer';
import * as parser from 'css-tree/parser';
import * as walker from 'css-tree/walker';
import * as lexer from 'css-tree/lexer';
import * as definitionSyntax from 'css-tree/definition-syntax';
import * as data from 'css-tree/definition-syntax-data';
import * as dataPatch from 'css-tree/definition-syntax-data-patch';
import * as utils from 'css-tree/utils';

Using in a browser

Bundles are available for use in a browser:

  • dist/csstree.js – minified IIFE with csstree as global
<script src="node_modules/css-tree/dist/csstree.js"></script>
<script>
  csstree.parse('.example { color: green }');
</script>
  • dist/csstree.esm.js – minified ES module
<script type="module">
  import { parse } from 'node_modules/css-tree/dist/csstree.esm.js'
  parse('.example { color: green }');
</script>

One of CDN services like unpkg or jsDelivr can be used. By default (for short path) a ESM version is exposing. For IIFE version a full path to a bundle should be specified:

<!-- ESM -->
<script type="module">
  import * as csstree from 'https://cdn.jsdelivr.net/npm/css-tree';
  import * as csstree from 'https://unpkg.com/css-tree';
</script>

<!-- IIFE with an export to global -->
<script src="https://cdn.jsdelivr.net/npm/css-tree/dist/csstree.js"></script>
<script src="https://unpkg.com/css-tree/dist/csstree.js"></script>

Top level API

API map

License

MIT

stylelint-validator's People

Contributors

lahmatiy avatar limonte avatar ntwb avatar zabute avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

stylelint-validator's Issues

Support for React Native styles

When using styled-components in React Native, I can write CSS like:

const MyView = styled.View`
    aspect-ratio: 2;
    margin-horizontal: 10px;
    padding-vertical: 20px;
`;

But when seeing these properties, the csstree/validator will report error:

 21:3  ✖  Unknown property `aspect-ratio`  csstree/validator

To overcome this, I can disable checking of these properties:

    "csstree/validator": {
      "ignore": [
        "aspect-ratio",
        "margin-horizontal",
        "padding-vertical",
      ]
    }

But now I won't get any linting errors when I make a mistake in the values of those properties. Some of these properties I can simply avoid (like I can write margin: 0 10px instead of margin-horizontal: 10px), but for others there's no equivalent in standard CSS.

It would be great if these react-native extensions were supported by stylelint-validator. Even greater would be having a native mode switch (e.g. only allowing display: none|flex;).

Omit prelude requirement for SCSS `@else`

Problem

Snippet: https://github.com/csstree/stylelint-validator/blob/v2.0.0/lib/syntax-extension/sass/index.js

is causing the error

At-rule '@else' should contain a prelude (csstree/validator)

with code

  @if ($value == 0) {
    @return 0;
  } @else if ($value == 1) {
    @return 10;
  } @else {
    @return $delta;
  }
}

Analysis

As the else scss at-rule, doesn`t have a prelude, it looked like the simple solution would be:

// /lib/syntax-extension/sass/index.js#L56
syntaxConfig.atrules.else = {
    prelude: null
};
// /test/preprocessors.js#L80

// Add braces to ensure xxx is or is not seen as prelude
tr.ok('@else {}');
// Add missing else if
tr.ok('@else if {}');

But then the tr.ok('@else if {}'); assertion fails with At-rule '@else' should not contain a prelude (csstree/validator).

If we analyse the AST of the first code snippet (available here), the else if at-rule takes everything starting from if as prelude.

What should be the correct configuration for the else and else-if at-rule?

I've already forked the repo and tinkered with, without any success. Can you be of further assistance?

Invalid prelude for @media csstree/validator

As far as I know this is valid SCSS/SASS:

/// Custom breakpoints
/// @access public
/// @param {String} $breakpoint - Breakpoint
/// @param {String} $from - Defaults to "min-width" (mobile first)
///        can also take "max-width" to select elements under the provided size.
@mixin breakpoint($breakpoint, $from: 'min-width') {
  @media ($from: $breakpoint) {
    @content;
  }
}

But it results in an error:

src/styles/abstracts/_mixins.scss
25:11 ✖ Invalid prelude for @media csstree/validator

My config:
.stylelintrc.yml:

+  csstree/validator:
+    syntaxExtensions:
+      - sass

I have installed: [email protected]

First referenced in csstree/csstree#118 #issuecomment-993945845

Can't parse value from sass module namespace

I'm using scss module's @use syntax.

When I "@use" module, I have to access its variables with namespace, like this

image

When I do so with mixins or variables, like on screenshot - there's no problem.

But when I want to use that variable in selector property - linter throws error

image

Error:
image

App builds normally.

What can be done in order for the validator to recognize this?

Unknown property `font-display` v1.9.0

Hi! Thank you guys for creating this awesome plugin :)

I read in this issue that the 'css-tree' validates the font-display correctly. The VS Code plugin does work correctly, but the stylelint-csstree-validator plugin returns error: Unknown property font-display

I use the latest version: stylelint-csstree-validator: ^1.9.0

image

Could you help, please?

Can't parse value "(props) => (props.isHover ? 'block' : 'none')"

I'm using ReactJS and Material-UI.

I'm styling my components using makeStyles which implements css-in-js.

The validator gives an error for this type of value:

import { makeStyles } from '@material-ui/core/styles';

const useStyles = makeStyles(() => ({
  actions: {
    display: (props) => (props.isHover ? 'block' : 'none'),
  },
}));

The error:

35:4  ✖  Can't parse value "(props) => (props.isHover ? 'block' : 'none')"       csstree/validator

What can be done in order for the validator to recognize the function given as a value and evaluate its return value (block/none)?

Support for the CSS Color Module Level 4 (Editor's Draft)

It's very exciting to watch so many of the 1.0 roadmap items get ticked-off!

I was wondering if support for the CSS Color Module Level 4 (Editor's Draft) was under consideration, in particular, the color() function (playground here)?

Currently the following CSS:

a { 
  color: color(#eef6f8 alpha(50%));
  border-bottom: 2px solid color(#eef6f8 alpha(30%));
}

Produces the following warnings:

2:2  ✖  Invalid value for `color`   csstree/validator
3:2  ✖  The rest part of value can't to be matched on `border-bottom` syntax   csstree/validator

Support `attr` as a value

Hi there,

I am cleaning up our stylelint config and I came across what seems to be a missing feature in the stylelint validator. Namely, to write this

content: attr(title);

I need to have an ignoreValue pattern, (which I write attr.* for reference). I can not see from the docs that using attr is supported by the validator. Could you show me how I am wrong about that or point me in a direction to where I could add this support here?

Thanks

css modules properties

Thanks for working on this.

I've seen two other issues for handling Sass and less variables so I thought I might also add special css module properties are also throwing validation errors.

client/components/core/SignOutMenu.vue
4:3 ✖ Unknown property: composes csstree/validator

Any chance of supporting css modules features?

Ignoring value containing colon

Hi!

I'm trying to use ignoreValue to suppress a parsing error:

Can't parse value "alpha( opacity: 0 )"

The CSS property looks like this:

.class {
    filter: alpha( opacity: 0 );
}

I've tried combinations like

'ignoreValue': 'alpha'
'ignoreValue': 'alpha.*'
'ignoreValue': 'alpha\\(.*\\)'

to ignore the value, but can't seem to get the syntax right. Any advice on the correct syntax to ignore the filter: alpha( opacity: 0 ); property?

Thanks
– Andreas

Support stylelint@12

The module currently only support >=7.0.0 <12.0.0 which excludes the current 12.0.0.

Make @import rules require a semicolon

I created an issue in the stylelint repo, but they believed this repository would be a better candidate for this type of feature.

The problem is, if you forget to include a semicolon the import on the following line will not get exectued which is pretty annoying not to have a warning for when developing.

Allow ignoreProperties to accept RegExp

This is somewhat related to #19, but since v2 has been released, this likely concerns the new ignoreProperties configuration option.

The main use-case if for those using styled-components/emotion, where the use of stylelint-processor-styled-components will insert placeholders in the code, i.e. -styled-mixin0: $dummyValue. The $dummyValue value can be easily ignored by using a regex for ignoreValue config option. However, this isn't the same for the invalid property -styled-mixin0, because the processor appends an incremental number to the end of the property.

This means it is unnecessarily verbose to do this:

"csstree/validator": {
    "ignoreProperties": [
        "-styled-mixin0",
        "-styled-mixin1",
        "-styled-mixin2",
        "-styled-mixin3",
        "-styled-mixin4",
        "-styled-mixin5",
        "-styled-mixin6",
        "-styled-mixin7",
        "-styled-mixin8",
        "-styled-mixin9"
    ],
    "ignoreValue": "\\$dummyValue"
}

And this is not a safe way to fix the issue, since the number is arbitrary. What if we allow ignoreProperties to accept Array<string | RegExp>? By extension, we might want to extend the ignoreValue as well, so that it not only accepts string | RegExp but also Array<string | RegExp>.

I am happy to create a PR for this if necessary: but would love to hear your opinion on this.

Missing error on `appearance` property

I the SCSS I was validating someone used appearance property, which according to different sources (MDN, Can I Use) always requires moz- or webkit prefix.

I believe this is a bug, which would need fixing?

I might try to provide a PR after your confirmation, that this is an issue.

`width: fit-content` produces error `Invalid value for `width`

Clearly describe the bug
I expect this to pass without error or warning:

    width: fit-content;

or to be easily able to find how to make it pass (if it is somehow nonstandard/etc).

Which rule, if any, is the bug related to?
Not sure. I just installed stylelint.

What code is needed to reproduce the bug?

div {
  width: fit-content;
}

What stylelint configuration is needed to reproduce the bug?

{
  "plugins": [
    "stylelint-csstree-validator"
  ],
  "rules": {
    "csstree/validator": true
  }
}

Which version of stylelint are you using?
13.7.2

How are you running stylelint: CLI, PostCSS plugin, Node.js API?

npx stylelint *.css

Does the bug relate to non-standard syntax (e.g. SCSS, Less etc.)?
No.

What did you expect to happen?
"No warnings to be flagged."

What actually happened (e.g. what warnings or errors did you get)?

✖  Invalid value for `width`   csstree/validator

(ref: stylelint/stylelint#5081)

Validating selectors and a plugin pack

Firstly, thanks again for this plugin. It's great!

Now, how stylelint validates CSS is currently influx:

Invalid code is best handled by emerging dedicated tools e.g. csstree - a language parser with syntax validation. As a stop-gap, while these tools mature, provide invalid code rules for the simplest of cases. (In the future, these tools can be wrapped as plugins to make use of features such as /* stylelint-* */ command comments, severity levels, and options validator.)

At stylelint, we currently direct users to this plugin when they request a rule to validate their declarations e.g. stylelint/stylelint#2816 & stylelint/stylelint#2777.

This plugin validates the property and value pairs of declarations, but I believe csstree can also validate selector lists (and at-rule validation is in the works). What do you think about creating a plugin pack, like stylelint-order and stylelint-scss, to house plugins for declaration and selector list (and at-rule in the future) validation?

In stylelint rules target things (rules, at-rules, selector lists, value lists etc...). We did this to help users find and locate only the rules they need. I think having a validation plugin pack that follows this convention would be beneficial to users. What do you think?

The plugin pack could keep the same name as this plugin (stylelint-csstree-validator) and it could, to be begin with, contain two plugins:

  • csstree-validator/declaration-no-invalid (what this plugin currently does)
  • csstree-validator/selector-list-no-invalid

(As an aside, there was a selector-no-empty rule in stylelint but it was removed in 8.0.0. as it was acting as a proxy for validation rather than preference).

I'd be eager to hear your thoughts on whether you think this is a good idea and whether it's aligned how you originally thought csstree and stylelint could work together.

Compatibility with stylelint 10?

Currently there's a peer dependency on stylelint < 10 which prevents usage with current versions of a growing number of projects.

Ignoring Less variables

I took this lovely plugin for a whirl today, it correctly discovered some issues where my team had written invalid syntax, however the majority of the errors it reported was the csstree/validator rule choking on Less variables, ex:

src/Component/Component.less
 28:13  ✖  Can't parse value "@link-hover-color"   csstree/validator
 54:9   ✖  Can't parse value "@icon-color"         csstree/validator

Any idea how to mute or ignore Less variables (I'm assuming the same goes for Sass variables).

Thanks!

sass interpolation

Slightly related to #4, I've found our codese problems coming from sass interpolation

.navbar-static-top .dropdown .dropdown-menu {
    max-height: calc(100vh - #{$navbar-height});
    overflow-y: auto;
}
>> theme/boost/scss/moodle/undo.scss
>>  138:5  ✖  Can't parse value "calc(100vh - #{$navbar-height})"   csstree/validator

Thanks for this project!

Support for regular expressions in ignore

Hi, thanks for creating this useful plugin!

Is there any chance of passing in a regular expression to the ignore option?

My reason for doing so is that stylelint-processor-styled-components outputs styled-components mixins as invalid properties e.g. -styled-mixin0, -styled-mixin1,-styled-mixin2 which then fails validation when using this plugin.

If I could do something like below that would be great

  "rules": {
    "csstree/validator": {
      "ignore": ["/-styled-mixin/"]
    }
  }

Support for CSS wide keyword "revert"

Hi,

I'm using stylelint-csstree-validator plugin, but on using the CSS property "display: revert",
I'm getting the error "Invalid value" for display.
But this property works in some browser.

Attached the screenshot of package.json file and the error that I'm getting

image

image

stylelint-tree-validation-error

Can anyone help regarding this?

Thanks

Stylelint 16 Support

Would like to use this plugin in version 16, and it probably requires an update to ESM. https://stylelint.io/migration-guide/to-16#deprecated-commonjs-api

Current error:

Error: Cannot find module '{redacted}/frontend/node_modules/stylelint/lib/utils/isStandardSyntaxAtRule.js'
    at createEsmNotFoundErr (node:internal/modules/cjs/loader:1098:15)
    at finalizeEsmResolution (node:internal/modules/cjs/loader:1091:15)
    at resolveExports (node:internal/modules/cjs/loader:567:14)
    at Module._findPath (node:internal/modules/cjs/loader:636:31)
    at Module._resolveFilename (node:internal/modules/cjs/loader:1063:27)
    at Module._load (node:internal/modules/cjs/loader:922:27)
    at Module.require (node:internal/modules/cjs/loader:1143:19)
    at require (node:internal/modules/cjs/helpers:119:18)
    at Object.<anonymous> ({redacted}/frontend/node_modules/stylelint-csstree-validator/cjs/index.cjs:4:32)
    at Module._compile (node:internal/modules/cjs/loader:1256:14)

Getting some weird output ok ?? 36 ok ?? 36 ok ?? 36

This issue is forwarded from stylelint/stylelint#4146

In stylelint/stylelint#4146 (comment) @hudochenkov narrowed down the issue is coming from stylelint-csstree-validator.


Clearly describe the bug

I'm getting some weird output when running stylelint src/**/*.scss:

ok
?? 36
ok
?? 36
ok
?? 36
ok
?? 36

Live demo: https://travis-ci.org/sweetalert2/sweetalert2/builds/554841887

What stylelint configuration is needed to reproduce the bug?

https://github.com/sweetalert2/stylelint-config/blob/master/index.js

Which version of stylelint are you using?

10.1.0

How are you running stylelint: CLI, PostCSS plugin, Node.js API?

stylelint src/**/*.scss

What did you expect to happen?

No weird output.

Steps to reproduce

  1. git clone https://github.com/sweetalert2/sweetalert2.git
  2. cd sweetalert2
  3. yarn install
  4. ./node_modules/.bin/stylelint src/**/*.scss

OS: Linux,
node version: 12.5.0

Sass variables definition

I've tried to use the plugin to lint Sass files (scss syntax) but the plugin is showing an error on each line where there is a variable definition i.e. $color01: #eee;

2:1  ✖  Unknown property: $color01        csstree/validator
3:1  ✖  Unknown property: $color02        csstree/validator
4:1  ✖  Unknown property: $color03        csstree/validator

It seems working fine for variables defined inside mixins.

This is the list of all plugins that I'm currently using:

"plugins": [
        "stylelint-scss",
        "stylelint-order",
        "stylelint-declaration-use-variable",
        "stylelint-csstree-validator"
    ]

Thank you!!

`inherit` should be accepted for `color`

According to the spec, inherit is a valid value for the color property but it's being rejected:

a { color: inherit } /* Invalid value for `color` */

I assume this is an issue for many if not all properties that can take <color>.

Cannot read properties of null (reading 'match')

Hi!

after update [email protected] to [email protected]:

> [email protected] test
> npx stylelint test.css

TypeError: Cannot read properties of null (reading 'match')
    at ~/stylelint-csstree-validator-bug.localhost/stylelint-csstree-validator-bug/test.css:1:2
    at matchSyntax (~/stylelint-csstree-validator-bug.localhost/stylelint-csstree-validator-bug/node_modules/css-tree/cjs/lexer/Lexer.cjs:82:51)
    at Lexer.matchAtrulePrelude (~/stylelint-csstree-validator-bug.localhost/stylelint-csstree-validator-bug/node_modules/css-tree/cjs/lexer/Lexer.cjs:289:16)
    at ~/stylelint-csstree-validator-bug.localhost/stylelint-csstree-validator-bug/node_modules/stylelint-csstree-validator/cjs/index.cjs:123:31
    at ~/stylelint-csstree-validator-bug.localhost/stylelint-csstree-validator-bug/node_modules/postcss/lib/container.js:119:18
    at ~/stylelint-csstree-validator-bug.localhost/stylelint-csstree-validator-bug/node_modules/postcss/lib/container.js:55:18
    at Root.each (~/stylelint-csstree-validator-bug.localhost/stylelint-csstree-validator-bug/node_modules/postcss/lib/container.js:41:16)
    at Root.walk (~/stylelint-csstree-validator-bug.localhost/stylelint-csstree-validator-bug/node_modules/postcss/lib/container.js:52:17)
    at Root.walkAtRules (~/stylelint-csstree-validator-bug.localhost/stylelint-csstree-validator-bug/node_modules/postcss/lib/container.js:117:19)
    at ~/stylelint-csstree-validator-bug.localhost/stylelint-csstree-validator-bug/node_modules/stylelint-csstree-validator/cjs/index.cjs:92:14
    at ~/stylelint-csstree-validator-bug.localhost/stylelint-csstree-validator-bug/node_modules/stylelint/lib/lintPostcssResult.js:113:8

npm i [email protected] --save-exact -- this fix command

https://github.com/dkrnl/stylelint-csstree-validator-bug -- test bug repo

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.