Code Monkey home page Code Monkey logo

postcss-values-parser's Introduction



postcss-values-parser tests cover size

A CSS property value parser built upon PostCSS, following the same node and traversal patterns as PostCSS.

Install

Using npm:

npm install postcss-values-parser --save-dev

Please consider becoming a patron if you find this module useful.

Requirements

postcss-values-parser Node version v6.14.0+ and PostCSS v7.0.0+.

Benefits

  • Leverages PostCSS and its tokenizer under the hood
  • Doesn't strip characters; eg. parenthesis
  • Full AST traversal
  • Ability to walk the AST for every Node type
  • Convenience methods to stringify Nodes
  • Follows PostCSS patterns for whitespace between Nodes
  • Provides convenience properties for number units, colors, etc.

Usage

Using the parser is straightforward and minimalistic:

const { parse } = require('postcss-values-parser');

const root = parse('#fff');
const node = root.first;

// → Word {
//     raws: { before: '', after: '' },
//     value: '#fff',
//     type: 'word',
//     isHex: true,
//     isColor: true,
//     isVariable: false,
//     ...
//   }

Please see the Documentation for further information on using the module.

Meta

CONTRIBUTING

LICENSE (Mozilla Public License)

postcss-values-parser's People

Contributors

anderscan avatar andyogo avatar antonio-laguna avatar corysimmons avatar cyjake avatar evilebottnawi avatar fiftyfactorauthentication avatar greenkeeper[bot] avatar jonathantneal avatar jsnajdr avatar jwilsson avatar lydell avatar marcalexiei avatar nex3 avatar niksy avatar onigoetz avatar radeno avatar realityking avatar rzhw avatar salimbensiali avatar shellscape 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

postcss-values-parser's Issues

isColor does not detect capitalized color keywords

  • Webpack Version: N/A
  • Operating System (or Browser): Mac OS 10.14.3
  • Node Version: 10.15.2
  • postcss-values-parser Version: 3.0.0-beta.4

How Do We Reproduce?

const {parse} = require('postcss-values-parser')

;['Red', 'GREEN', 'whiteSmoke'].forEach(color => {
  parse(color, {loose: true}).walk(node => {
    console.log(node.isColor)
  })
})

Expected Behavior

Expected isColor to be true for all of these cases

Actual Behavior

isColor is false for all of these cases

Related issues and code

isColor does not detect capitalized RGB(A) and HSL(A) functions

  • Webpack Version: N/A
  • Operating System (or Browser): Mac OS 10.14.3
  • Node Version: 10.15.2
  • postcss-values-parser Version: 3.0.0 (🎉)

How Do We Reproduce?

const {parse} = require('postcss-values-parser')

const fixtures = [
  'RGBA(100, 200, 11, .5)',
  'RGB(100, 200, 11)',
  'Hsl(20, 10%, 5%)',
  'HSLA(20, 10%, 5%, 0.5)'
]

fixtures.forEach(color => {
  parse(color, {loose: true}).walk(node => {
    console.log(node.isColor)
  })
})

Expected Behavior

Expected isColor to be true for all of these cases

Actual Behavior

isColor is false for all of these cases

Related issues and code

  • Related to #67

I hope I've covered most cases by now 😬

atwords do not stringify correctly

This parser correctly identifies an atword, but it stringifies it without the @.

parseValue('@color').parse().toString(); // returns "color"
parseValue('foo @color').parse().toString(); // returns "foo color"
parseValue('foo @color bar').parse().toString(); // returns "foo color bar"

Support PostCSS insertBefore

  • Webpack Version: n/a
  • Operating System (or Browser): Ubuntu Linux 18.04
  • Node Version: 10.15.1
  • postcss-values-parser Version: 3.0.1

How Do We Reproduce?

const postcssValuesParser = require('postcss-values-parser');
const node = postcssValuesParser.parse('sans-serif');

node.insertBefore(node.nodes[0], '12px');

Expected Behavior

That the string 12px turns into a Numeric token and gets added at the start so that n.toString() would return 12px sans-serif.

Actual Behavior

{ CssSyntaxError: <css input>:1:1: Unknown word

> 1 | 12px
    | ^

    at Input.error (/home/andreas/work/postcss-values-parser/node_modules/postcss/lib/input.js:130:16)
    at Parser.unknownWord (/home/andreas/work/postcss-values-parser/node_modules/postcss/lib/parser.js:563:22)
    at Parser.other (/home/andreas/work/postcss-values-parser/node_modules/postcss/lib/parser.js:168:12)
    at Parser.parse (/home/andreas/work/postcss-values-parser/node_modules/postcss/lib/parser.js:77:16)
    at parse (/home/andreas/work/postcss-values-parser/node_modules/postcss/lib/parse.js:17:12)
    at Root.normalize (/home/andreas/work/postcss-values-parser/node_modules/postcss/lib/container.js:738:27)
    at Root.normalize (/home/andreas/work/postcss-values-parser/node_modules/postcss/lib/root.js:49:48)
    at Root.insertBefore (/home/andreas/work/postcss-values-parser/node_modules/postcss/lib/container.js:494:22)
  name: 'CssSyntaxError',
  reason: 'Unknown word',
  source: '12px',
  line: 1,
  column: 1,
  input: { line: 1, column: 1, source: '12px' } }

If I try with an entire valid CSS rule, eg. body { color: maroon }, it works -- so it seems like this hits the regular postcss parser rather than the postcss-values-parser one.

add isVar to func to mark CSS variables usage

Feature Use Case

// declaring a csutomproperty
element {
  --main-bg-color: brown;
}

// Using the custom property:
element {
  background-color: var(--main-bg-color);
}

https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties
https://drafts.csswg.org/css-variables/#defining-variables

Feature Proposal

I would propose to extend the Func node with isVar to mark var() calls related to using variables:
https://developer.mozilla.org/en-US/docs/Web/CSS/var
https://drafts.csswg.org/css-variables/#using-variables

Parser throws error on font shorthand

  • Node Version: 10.0.0
  • NPM Version: 6.5
  • postcss-values-parser Version: 3.0.0-beta.2

This issue is regarding a problem with:

  • Standard CSS
  • LESS
  • SCSS
  • SASS

If you have a large amount of code to share which demonstrates the problem you're experiencing, please provide a link to your
repository rather than pasting code. Otherwise, please paste relevant short snippets below.

// offending or problematic css
.font-family3 { font: normal normal 1em/1 'Source Sans Pro', serif; }
// actual error output, if error was thrown
CssSyntaxError {
    column: 15,
    input: {
      column: 15,
      line: 1,
      source: 'normal normal 1em/1 \'Source Sans Pro\', serif',
    },
    line: 1,
    reason: 'Unknown word',
    source: 'normal normal 1em/1 \'Source Sans Pro\', serif',
    message: '<css input>:1:15: Unknown word',
  }

Expected Behavior

Expected the font shorthand to be fully parsed in parts.

Actual Behavior

It throws an error

How can we reproduce the behavior?

const {parse} = require('postcss-values-parser')
parse("normal normal 1em/1 'Source Sans Pro', serif")

Support customisation for other DSLs like Sass, Less, ...

Feature Use Case

It would be great to tweak the parsers rules for other domain-specific-languages like Sass and Less, to allow for broader syntax support of these, but keep it out of the scope of this repo.

E.g. CSS has no support for negative var() statements, in contrast to Sass and Less, they allow to prefix variables with unary operators like -$var #84

Currently I refactor a stylelint plugin and I need to support not only CSS, but also Sass and Less syntax.

Feature Proposal

As supposed in #82 by @shellscape hooks could be a generic solution to this problem.
Would be great to make them plug-able as well.

Parse Error parsing dash in `calc(-0.5 * var(ei-table-cell-padding));`

  • Node Version: 4.3.2
  • NPM Version: 3.10.10
  • postcss-values-parser Version: 1.2.2

This issue is regarding a problem with:

  • Standard CSS
calc(-0.5 * var(ei-table-cell-padding))
{ [ParserError: Syntax Error at line: 1, column 6] name: 'ParserError' }

Expected Behavior

Not to error on the -

Actual Behavior

Errors

How can we reproduce the behavior?

Just parse this block of code

Stringifier Ignores Manually Added Func Child Nodes

  • Webpack Version: N/A
  • Operating System (or Browser): N/A
  • Node Version: N/A
  • postcss-values-parser Version: 3.0.1

How Do We Reproduce?

Insert a new node into an AST.

import valuesParser from 'postcss-values-parser';
import Punctuation from 'postcss-values-parser/lib/nodes/Punctuation';

const astValue = valuesParser.parse('rgb(100% 100% 100%)');

astValue.nodes[0].nodes.splice(1, 0, new Punctuation({ value: ',' }));
astValue.nodes[0].nodes.splice(2, 0, new Punctuation({ value: ',' }));

console.log({
	punctuation: valuesParser.nodeToString(astValue.nodes[0].nodes[1]),
	root: valuesParser.nodeToString(astValue)
});

Expected Behavior

Commas are added.

{
  punctuation: ',\n',
  root: 'rgb(100%, 100%, 100%)'
}

Actual Behavior

Commas are not added.

{
  punctuation: ',\n',
  root: 'rgb(100% 100% 100%)'
}

The color-mod function should not require loose mode

  • Node Version: 9.3.0
  • NPM Version: 5.6.0
  • postcss-values-parser Version: 1.3.1

This issue is regarding a problem with:

  • Standard CSS

Description

Parsing color-mod should probably work outside loose mode.

See https://drafts.csswg.org/css-color/#modifying-colors

test {
  color-mod(blue blackness(+ 20%));
}

Note that the space after the plus is required to distinguish between setting the blackness of blue to 20% versus adding 20% blackness to the existing blackness of blue.

Error

ParserError: Syntax Error at line: 1, column 26
    at Parser.error (/node_modules/postcss-values-parser/lib/parser.js:116:11)
    at Parser.operator (/node_modules/postcss-values-parser/lib/parser.js:172:18)
    at Parser.parseTokens (/node_modules/postcss-values-parser/lib/parser.js:234:14)
    at Parser.loop (/node_modules/postcss-values-parser/lib/parser.js:121:12)
    at Parser.parse (/node_modules/postcss-values-parser/lib/parser.js:50:17)
    at Object.<anonymous> (/test.js:4:44)
    at Module._compile (module.js:660:30)
    at Object.Module._extensions..js (module.js:671:10)
    at Module.load (module.js:573:32)
    at tryModuleLoad (module.js:513:12)

Expected Behavior

It should parse without error.

Actual Behavior

It throws an error.

How can we reproduce the behavior?

require('postcss-values-parser')('color-mod(blue blackness(+ 20%))').parse();

return false in Node#walk aborts the entire walk

Is there a clean way to stop a walk from descending any further, but to continue to the next sibling? In postcss-value-parser this is done by returning false, in here that would abandon the whole walk.

Consider a rule that is looking for offset values in background: url(foo.jpg) 3px 5px;. When I come across the FunctionNode for url I want to stop descending, but I still want to iterate over the siblings where the offsets are. My current approach is to set node.walk=null then return undefined, but this is very hacky.

Nested function calls have ) token in the wrong place

When parsing

a(b(c(d())))

The ) isn't placed in the proper place: the last three ) tokens are placed in the before-last function node instead of the corresponding opening.

Root {
  type: 'root',
  nodes:
   [ Value {
       type: 'value',
       nodes:
        [ FunctionNode {
            type: 'func',
            value: 'a',
            nodes:
             [ Parenthesis { type: 'paren', value: '(' },
               FunctionNode {
                 type: 'func',
                 value: 'b',
                 nodes:
                  [ Parenthesis { type: 'paren', value: '(' },
                    FunctionNode {
                      type: 'func',
                      value: 'c',
                      nodes:
                       [ Parenthesis { type: 'paren', value: '(' },
                         FunctionNode {
                           type: 'func',
                           value: 'd',
                           nodes:
                            [ Parenthesis { type: 'paren', value: '(' },
                              Parenthesis { type: 'paren', value: ')' } ] },
                         Parenthesis { type: 'paren', value: ')' },
                         Parenthesis { type: 'paren', value: ')' },
                         Parenthesis { type: 'paren', value: ')' } ] } ] } ] } ] } ] }

Program to reproduce:

const parser = require('postcss-values-parser')
const str = 'a(b(c(d())))';
const value = parser(str).parse();

log(clean(value));

function log(node) {
  console.log(require('util').inspect(node, false, null));
}

function clean(node) {
  if (Array.isArray(node)) {
    node.forEach(clean);
  } else if (node && typeof node === "object") {
    const type = node.type;
    const value = node.value;
    const nodes = node.nodes;
    for (let key in node) {
      if (key !== "parent") {
        clean(node[key]);
      }
      delete node[key];
    }
    if (type) node.type = type;
    if (value) node.value = value;
    if (nodes) node.nodes = nodes;
  }
  return node;
}

For context, I'm trying to use this to build a CSS pretty printer: prettier/prettier#1636

Depends on deprecated package "flatten"

Expected Behavior / Situation

Installation does not install a deprecated package.

Actual Behavior / Situation

Installation installs deprecated package "flatten."

warning postcss-values-parser > [email protected]: I wrote this module a very long time ago; you should use something else.

Modification Proposal

Remove dependency on flatten.

Error thrown on trailing !important following Function

Originally reported at lesshint/lesshint#367

  • Node Version: 6.10.3
  • NPM Version: 4.5.0
  • postcss-values-parser Version: 1.2.1

This issue is regarding a problem with:

  • Standard CSS
  • LESS
  • SCSS
  • SASS

If you have a large amount of code to share which demonstrates the problem you're experiencing, please provide a link to your
repository rather than pasting code. Otherwise, please paste relevant short snippets below.

.blah(fade(rgb(0, 0, 0), 10%)) !important;
/Users/jwilsson/value-test/node_modules/postcss-values-parser/lib/parser.js:114
    throw new ParserError(message + ` at line: ${token[2]}, column ${token[3]}`);
    ^

ParserError: Expected opening parenthesis at line: 1, column 30
    at Parser.error (/Users/jwilsson/value-test/node_modules/postcss-values-parser/lib/parser.js:114:11)
    at Parser.parenClose (/Users/jwilsson/value-test/node_modules/postcss-values-parser/lib/parser.js:355:12)
    at Parser.parseTokens (/Users/jwilsson/value-test/node_modules/postcss-values-parser/lib/parser.js:222:14)
    at Parser.loop (/Users/jwilsson/value-test/node_modules/postcss-values-parser/lib/parser.js:119:12)
    at Parser.parse (/Users/jwilsson/value-test/node_modules/postcss-values-parser/lib/parser.js:48:17)
    at Object.<anonymous> (/Users/jwilsson/value-test/index.js:2:66)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)

Expected Behavior

Not throw an error and return a AST.

Actual Behavior

It throws the above error.

How can we reproduce the behavior?

Create and run a .js-file with this code in it:

const parser = require('postcss-values-parser');
const ast = parser('.blah(fade(rgb(0, 0, 0), 10%)) !important;').parse();

Missing files in 1.0.0

Looks like the *.js-files aren't included in the npm package. I guess adding lib to files in package.json should be enough.

Sorry for not catching it when reviewing!

next version errors

An issue to track bits that aren't passing with the next branch:

  • sass "maps" - ( a: ( b: c ) )

Functions registered with registerWalker do not work

  • Node Version: 9.8.0
  • NPM Version: 5.6.0
  • postcss-values-parser Version: 1.4.0

This issue is regarding a problem with:

  • Standard CSS
  • LESS
  • SCSS
  • SASS

See: #50

const source = '/*1*/ 5px /* 2 */';
const ast = new Parser(source).parse();

ast.first.walkComments(node => {
  console.log(node.value);
});

RunKit Example

spaces around url string in url() function

url( 'img/image.jpg' );

results in:

[
  'func'
  'paren'
  'word' -> " 'img/image.jpg' "
  'paren'
]

word should be a string with raws.before and raws.after containing the spaces.

SCSS Interpolation in strings

  • Node Version: 8.3.0
  • NPM Version: 5.3.0
  • postcss-values-parser Version: 1.3.0

This issue is regarding a problem with:

  • Standard CSS
  • LESS
  • SCSS
  • SASS
"a #{"1"} b #{2} c"

Actual Behavior

Parsed as:

StringNode {
  value: 'a #{'
}
NumberNode {
  value: '1'
}
StringNode {
  value: '} b #{2} c'
}

Expected Behavior

Proposal:

Similar to how Babylon parses template literals in JavaScript: astexplorer

Something like this:

InterpolationStringNode {
  expressions: [
    StringNode {
      value: '1'
    },
    NumberNode {
      value: '2'
    }
  ],
  quasis: [
    InterpolationStringElementNode {
      value: 'a '
    },
    InterpolationStringElementNode {
      value: ' b '
    },
    InterpolationStringElementNode {
      value: ' c'
    }
  ]
}

(The "expressions" and "quasis" names comes from Babylon’s AST. I made up "InterpolationStringNode". I don’t care about what they’re called.)

When you encounter #{ in a string

  1. Push the string so far to quasis
  2. Recursively parse with postcss-values-parser until the next unbalanced }. (Error handling, if no ending } is found throw TokenizeError: Unclosed interpolation or something.)
  3. Start to parse as a string again (until the end quote or the next #{).

Notes:

  • Interpolations can contain any expression, even another string with
    interpolations (recursively).
  • It is possible to escape interpolations: "\#{1}" is a single StringNode.

How can we reproduce the behavior?

const parse = require("postcss-values-parser")

const test = '"a #{"1"} b #{2} c"'
const ast = parse(test, {loose: true}).parse()

console.dir(ast, {colors: true, depth: null})

Related

Should parens be part of raws

Looking over the API, this example struck me as including unnecessary work.

let func = parser.func({ value: 'calc' });

func.append(parser.paren());
func.append(parser.paren({ value: ')' }));

func.toString();
// → calc()

Should parens be raws? Otherwise, a stringified function without parens would be re-parsed as a word, right?

This seems like unnecessary work on the part of devs. It would be like PostCSS requiring curly braces within at-rules and rules.

let rule = postcss.rule({ selector: 'body' });

rule.append(parser.brace());
rule.append(parser.brace({ value: '}' }));

rule.toString();
// → .body{}

By either including the whitespace around the parens or making them separate raws, would that preserve formatting? Sorry in advance if I misunderstand something.

Protocol-relative URL parsed as comment in url() function

  • Webpack Version: N/A
  • Operating System (or Browser): macOS 10.14.2
  • Node Version: 11.9.0
  • postcss-values-parser Version: 3.0.0-beta.3

How Do We Reproduce?

Run this code:

const { parse } = require('postcss-values-parser');

const root = parse('url(//example.com)');

console.log(root.first.first);

Expected Behavior

root.first.first to be a Word node or whichever is suitable (I don't have a strong opinion on it, it could be multiple nodes as well).

Actual Behavior

root.first.first is a Comment node.

String(node) should produce string or throw more helpful error

Expected Behavior / Situation

In postcss-values-parser v2, String(node) returns the string value of any Node. In postcss-values-parser v3, one must now use the nodeToString function to retrieve the string value. Worse yet, when a node is accidentally toString’d, an error is thrown!

I would prefers things work the same as they did in v2, as well as how they still do in PostCSS.

const ast = parse('#000 url(path/to/image.jpg)');

console.log(String(ast)); // "#000 url(path/to/image.jpg)"
console.log(String(ast.nodes[0])); // "#000"

And here is an example of the stringified behavior currently in PostCSS:

import postcss from 'postcss';

const ast = postcss.parse('selector { property-name: property-value; }');

console.log(String(ast.nodes[0].nodes[0])); // "property-name: property-value"

Actual Behavior / Situation

TypeError: this[node.type] is not a function

Modification Proposal

Remove the TypeError: this[node.type] is not a function error and default toString to work like nodeToString.

Should parentheses have child nodes?

  • Node Version: 9.3.0
  • NPM Version: 5.6.0
  • postcss-values-parser Version: 1.3.1

This issue is regarding a problem with:

  • Standard CSS

Description

I was expecting parentheses to group a portion of the following CSS value, but they do not:

5px / (2px + 3px)

The result, expressed as a simplified array, demonstrate the grouping as:

[
  '5px',
  '/',
  '(',
  '2px',
  '+',
  '3px',
  ')'
]

Whereas I would have expected:

[
  '5px',
  '/'
  [
    '2px',
    '3px'
  ]
]

So, would you categorize this as a feature request, or would you deliberately wish to not group nodes by parentheses? Or something else?

Expected Behavior

I was expecting a Parentheses container node.

Actual Behavior

The parenthesis is treated more like an operator.

How can we reproduce the behavior?

require('postcss-values-parser')('5px / (2px + 3px)').parse();

ParserError: url() function containing function

  • Node Version: 4.3.2
  • NPM Version: 3.10.10
  • postcss-values-parser Version: 1.2.2

This issue is regarding a problem with:

  • Standard CSS
url(var(audience-network-checkbox-image)) center no-repeat
test.css: SyntaxError: ParserError: Expected opening parenthesis at line: 1, column 41 (104:54)
  102 |
  103 | .audienceNetworkFilter/checkboxSelected .audienceNetworkFilter/checkbox {
> 104 |   background: url(var(audience-network-checkbox-image)) center no-repeat;
      |                                                       ^
  105 | }

Expected Behavior

Not to error on the )

Actual Behavior

Errors

How can we reproduce the behavior?

Just parse this block of code

Support double slash comments

  • Node Version: latest
  • NPM Version: latest
  • postcss-values-parser Version: latest

This issue is regarding a problem with:

  • Standard CSS
  • LESS
  • SCSS
  • SASS

If you have a large amount of code to share which demonstrates the problem you're experiencing, please provide a link to your
repository rather than pasting code. Otherwise, please paste relevant short snippets below.

.foo {
  prop: 1px // comment
    2px;
}

Expected Behavior

Double slash will be parsed as comments

Actual Behavior

Don't parsed.

How can we reproduce the behavior?

Try to parse example above.

What do you think it is possible. I think problem only in one place - url(http://domain.com). Any ideas how we can solve this?

missing operators *, / and %

First thanks for this awesome package, I just started using it.

  • Node Version: v6.12.3
  • NPM Version: 3.10.10
  • postcss-values-parser Version: 2.0.0

This issue is regarding a problem with:

If you have a large amount of code to share which demonstrates the problem you're experiencing, please provide a link to your
repository rather than pasting code. Otherwise, please paste relevant short snippets below.

// offending or problematic css
.foo { margin: 2 * 10 }; 
.foo { margin: 2 / 10 }; 
.foo { margin: 10 % modulo }; 

// and using just those operators does not throw
.foo { margin: * }; 
.foo { margin: / };
.foo { margin: % };

// But for + and - it does throw
.foo { margin: + }; 
.foo { margin: - };

Expected Behavior

* multiply, / divide and % modulo should be parsed as operators too.
And they should throw according to the same rules of + add and - subtract.

Actual Behavior

Not detected as operators and do not throw based on same rules like for add and subtract.

How can we reproduce the behavior?

See above CSS and this PR #59

Commas are included in AtWord nodes

Take the following input:

color: rgb(@a, @b, @c);

which will result in this AST:

[...]
AtWord {
  raws: { before: '', after: '' },
  value: 'a,', 
  source: { start: { line: 1, column: 5 }, end: { line: 1, column: 7 } },
  sourceIndex: 4,
  nodes: [],
  type: 'atword',
}
[...]

I would expect a Comma node after each AtWord node.

I found that using the same regex currently used for Word nodes for AtWord nodes too seems to solve it, it needs some more tests though.

But I don't know how we should handle it since it's not something that will happen while writing regular CSS, is it out of the scope for this and something we should handle in lesshint or include it here? @shellscape

Hyphen in prefixed values gets parsed as operator node when in loose mode

Originally reported at lesshint/lesshint#433

  • Node Version: 8.5.0
  • NPM Version: 5.4.2
  • postcss-values-parser Version: 1.3.0

This issue is regarding a problem with:

  • Standard CSS
  • LESS
  • SCSS
  • SASS

If you have a large amount of code to share which demonstrates the problem you're experiencing, please provide a link to your
repository rather than pasting code. Otherwise, please paste relevant short snippets below.

opacity -webkit-filter

Expected Behavior

An AST similar to this:

Word {
  value: 'opacity',
  ...
}
Word {
  value: '-webkit-filter'
  ...
}

Actual Behavior

This AST:

Word {
  value: 'opacity',
  ...
}
Operator {
  value: '-',
  ...
}
Word {
  value: 'webkit-filter',
  ...
}

How can we reproduce the behavior?

const parser = require('postcss-values-parser');
const ast = parser('opacity -webkit-filter', {
    loose: true,
}).parse();

ast.walk((node) => {
    console.log(node);
});

The issue is only present in loose mode. In the regular/strict mode it works as expected. It also seems to work as expected when the prefixed value is the first one, but when it's the second (or more) it starts emitting operator nodes.

Crash when there's lots of nested parentheses

Originally reported at lesshint/lesshint#256.

It seems that code with a lot of nested parentheses crashes.

For example, the following code will crash with the stack trace below.

.output((unit(extract(@pxValues, @idx)) / unit(@application-base-font-size)));
An unknown error occurred, please file an issue with this info:
Error: Expected opening parenthesis.
    at Parser.error (/Users/jonathan/lesshint/node_modules/postcss-values-parser/dist/parser.js:165:11)
    at Parser.parenClose (/Users/jonathan/lesshint/node_modules/postcss-values-parser/dist/parser.js:355:12)
    at Parser.parseTokens (/Users/jonathan/lesshint/node_modules/postcss-values-parser/dist/parser.js:224:14)
    at Parser.loop (/Users/jonathan/lesshint/node_modules/postcss-values-parser/dist/parser.js:170:12)
    at Parser.parse (/Users/jonathan/lesshint/node_modules/postcss-values-parser/dist/parser.js:99:17)
    at Object.spaceAroundCommaLinter [as lint] (/Users/jonathan/lesshint/lib/linters/space_around_comma.js:19:41)
    at /Users/jonathan/lesshint/lib/linter.js:134:32
    at Array.forEach (native)
    at checkNode (/Users/jonathan/lesshint/lib/linter.js:105:17)
    at /Users/jonathan/lesshint/lib/linter.js:204:9

Everything dropped after ()

  • Node Version: 4.3.2
  • NPM Version: 3.10.10
  • postcss-values-parser Version: 1.2.2

This issue is regarding a problem with:

  • Standard CSS
url() center center no-repeat black
{
  "raws": {
    "before": "",
    "after": ""
  },
  "nodes": [
    {
      "raws": {
        "before": "",
        "after": ""
      },
      "nodes": [
        {
          "raws": {
            "before": "",
            "after": ""
          },
          "value": "url", // <--------------------------------
          "source": {
            "start": {
              "line": 1,
              "column": 1
            },
            "end": {
              "line": 1,
              "column": 3
            }
          },
          "sourceIndex": 0,
          "nodes": [
            {
              "raws": {
                "before": "",
                "after": ""
              },
              "value": "(", // <--------------------------------
              "source": {
                "start": {
                  "line": 1,
                  "column": 4
                },
                "end": {
                  "line": 1,
                  "column": 3
                }
              },
              "sourceIndex": 3,
              "type": "paren",
              "parenType": ""
            },
            {
              "raws": {
                "before": "",
                "after": ""
              },
              "value": "black", // <--------------------------------
              "source": {
                "start": {
                  "line": 1,
                  "column": 31
                },
                "end": {
                  "line": 1,
                  "column": 35
                }
              },
              "sourceIndex": 30,
              "type": "word",
              "isHex": false,
              "isColor": false
            }
          ],
          "type": "func",
          "unbalanced": 1 // <--------------------------------
        }
      ],
      "type": "value",
      "unbalanced": 0
    }
  ],
  "type": "root"
}

Expected Behavior

It should give me the full ast so that I can print url() center center no-repeat black back

Actual Behavior

Right now, it only gives me url( black and unbalanced: 1

How can we reproduce the behavior?

Just parse this block of code

Node 11+ import support

  • Webpack Version: N/A
  • Operating System (or Browser): N/A
  • Node Version: v11.10.1 (and all versions yet supporting import/export)
  • postcss-values-parser Version: 3.0.1

How Do We Reproduce?

Import the parse function from an mjs file:

// test.mjs
import { parse } from 'postcss-values-parser';

Run the mjs file:

node --experimental-modules test.mjs

Expected Behavior

The parse function is imported.

Actual Behavior

Nothing is imported, because the package only exports CommonJS modules.exports, a technique allowable in Babel but not in Node.

A secondary mjs file would need to be created that correctly exported individual parts (like export function parse() { [code] }). This file would also need to be wired into package.json as module (beside main).

Issue on color-mod()

  • Node Version: 10
  • NPM Version: 6.4.1
  • postcss-values-parser Version: 1.5.0

This issue is regarding a problem with:

  • Standard CSS
  • LESS
  • SCSS
  • SASS
  • postcss-preset-env additional syntax

If you have a large amount of code to share which demonstrates the problem you're experiencing, please provide a link to your
repository rather than pasting code. Otherwise, please paste relevant short snippets below.

.foo {
  background: color-mod(var(--accent) s(+ 30%) l(+ 10%));
}
    ERROR in ./layout/pay-Pay.css (./node_modules/css-loader??ref--5-1!./node_modules/postcss-loader/src!./layout/pay-Pay.css)
    Module build failed (from ./node_modules/postcss-loader/src/index.js):
    ParserError: Syntax Error at line: 1, column 27
        at /home/ai/Dev/amplifr-front/layout/pay-Pay.css:18:5
        at Parser.error (/home/ai/Dev/amplifr-front/node_modules/postcss-values-parser/lib/parser.js:127:11)
        at Parser.operator (/home/ai/Dev/amplifr-front/node_modules/postcss-values-parser/lib/parser.js:183:18)
        at Parser.parseTokens (/home/ai/Dev/amplifr-front/node_modules/postcss-values-parser/lib/parser.js:245:14)
        at Parser.loop (/home/ai/Dev/amplifr-front/node_modules/postcss-values-parser/lib/parser.js:132:12)
        at Parser.parse (/home/ai/Dev/amplifr-front/node_modules/postcss-values-parser/lib/parser.js:51:17)
        at root.walkDecls.decl (/home/ai/Dev/amplifr-front/node_modules/postcss-custom-properties/index.cjs.js:191:51)
        at /home/ai/Dev/amplifr-front/node_modules/postcss/lib/container.js:198:18
        at /home/ai/Dev/amplifr-front/node_modules/postcss/lib/container.js:146:18
        at Rule.each (/home/ai/Dev/amplifr-front/node_modules/postcss/lib/container.js:110:16)
        at Rule.walk (/home/ai/Dev/amplifr-front/node_modules/postcss/lib/container.js:143:17)
        at /home/ai/Dev/amplifr-front/node_modules/postcss/lib/container.js:156:24
        at Rule.each (/home/ai/Dev/amplifr-front/node_modules/postcss/lib/container.js:110:16)
        at Rule.walk (/home/ai/Dev/amplifr-front/node_modules/postcss/lib/container.js:143:17)
        at /home/ai/Dev/amplifr-front/node_modules/postcss/lib/container.js:156:24
        at Root.each (/home/ai/Dev/amplifr-front/node_modules/postcss/lib/container.js:110:16)
        at Root.walk (/home/ai/Dev/amplifr-front/node_modules/postcss/lib/container.js:143:17)
        at Root.walkDecls (/home/ai/Dev/amplifr-front/node_modules/postcss/lib/container.js:196:19)
        at transformProperties (/home/ai/Dev/amplifr-front/node_modules/postcss-custom-properties/index.cjs.js:188:8)
        at /home/ai/Dev/amplifr-front/node_modules/postcss-custom-properties/index.cjs.js:541:9
        at Generator.next (<anonymous>)
        at asyncGeneratorStep (/home/ai/Dev/amplifr-front/node_modules/postcss-custom-properties/index.cjs.js:12:24)
        at _next (/home/ai/Dev/amplifr-front/node_modules/postcss-custom-properties/index.cjs.js:34:9)

Expected Behavior

I understand that color-mod was not official CSS syntax. But right now it is the most popular way (the only way for most of the users) to work with color in pure PostCSS environment.

/cc @jonathantneal

Prettier format url path with number incorrectly

  • Node Version:
  • NPM Version:
  • postcss-values-parser Version: 1.5.0

This issue is regarding a problem with:

  • Standard CSS
  • LESS
  • SCSS
  • SASS

If you have a large amount of code to share which demonstrates the problem you're experiencing, please provide a link to your
repository rather than pasting code. Otherwise, please paste relevant short snippets below.

// offending or problematic css
body {
  background: url(http://123.example.com);
}

Expected Behavior

body {
  background: url(http://123.example.com);
}

Actual Behavior

body {
  background: url(http://123example.com);
}

How can we reproduce the behavior?

Playground link

See also prettier/prettier#5654

Is this a PR or a v2

Fantastic work on this parser; I could foresee it becoming the defacto standard. I’m inviting you and other PostCSS developers and advocates to chime in on my prompt. Sincerely, I hope not to provoke any harsh feelings.

I see you opened an issue with postcss-value-parser which presented your concerns regarding helper methods and raws, as well as a motivation to seeing it “integrating this into the main parser [of PostCSS]”. Those are all good goals, and I think you’ve met them in this project. It’s unfortunate the discussion ended there and you closed the issue a week later, only because it’s possible @TrySound did not have a chance to review it.

Moving forward, what might we do to help coalesce the PostCSS ecosystem here? Since your plugins are not fundamentally attempting to do different things or things in different ways, would the ideal scenario be that postcss-values-parser be merged back into postcss-value-parser, or that postcss-value-parser be deprecated?

I also want to acknowledge that project ownership may be another factor. postcss-values-parser may have become in-house work that must remain in-house. Conversely, @TrySound may not be interested in these changes. All that is fair; I’d just like to know how you all think we should proceed here (and in related matters going forward), as interested users of the ecosystem?

Thanks for reviewing this!

Word.isColor doesn't support RGBA hex colors

  • Node Version: 6.11.1
  • NPM Version: 5.3.0
  • postcss-values-parser Version: 1.2.2

This issue is regarding a problem with:

  • Standard CSS
  • LESS
  • SCSS
  • SASS

For example:

color: #000000ff;

Expected Behavior

Word.isColor should be true.

Actual Behavior

Word.isColor is false.

How can we reproduce the behavior?

Run the parser on a RGBA hex color, for example the one above.

This should be a simple extension of the current isColor regex, to allow for colors with 8 chars. I'd be happy to do it.

All walk functions registered with registerWalker do not work

  • Node Version: 9.8.0
  • NPM Version: 5.6.0
  • postcss-values-parser Version: 1.4.0

This issue is regarding a problem with:

  • Standard CSS
  • LESS
  • SCSS
  • SASS

All walk functions (eg: walkFunctionNodes, walkComments) registered with registerWalker do not work.

SASS Interpolation Not Parsed in Loose Mode

  • Node Version: 7.6
  • NPM Version: 4.1.2
  • postcss-values-parser Version: latest

This issue is regarding a problem with:

  • Standard CSS
  • LESS
  • SCSS
  • SASS

If you have a large amount of code to share which demonstrates the problem you're experiencing, please provide a link to your
repository rather than pasting code. Otherwise, please paste relevant short snippets below.

a { margin: calc(100% - #{$margin * 2px}); }
// resulting node tree
func calc
  paren
  number 100, unit='%'
  operator '-'
  word '#{$margin'
  operator '*'
  number 2, unit='px}'
  paren

Expected Behavior

The parser should account for the SCSS bracket interpolation.

Actual Behavior

SCSS bracket interpolation isn't recognized and is instead part of surrounding word nodes. See tree output.

How can we reproduce the behavior?

Parse the references css with loose: true option.

parse negated variables

Feature Use Case

Support negated (and explicitly positive) variables like(non-standrad, only available in preprocessors like scss or less):

.foo { margin: -$x; }

// or

.foo { margin: +$x; }

Currently it throws:

parse: margin: -$y;

.../stylelint-declaration-strict-value/node_modules/postcss/lib/parser.js:559
    throw this.input.error('Unknown word', tokens[0][2], tokens[0][3]);
    ^
CssSyntaxError: <css input>:1:9: Unknown word
    at Input.error (.../stylelint-declaration-strict-value/node_modules/postcss/lib/input.js:127:16)
    at ValuesParser.unknownWord (.../stylelint-declaration-strict-value/node_modules/postcss/lib/parser.js:559:22)
    at ValuesParser.unknownWord (.../stylelint-declaration-strict-value/node_modules/postcss-values-parser/lib/ValuesParser.js:195:15)
    at ValuesParser.other (.../stylelint-declaration-strict-value/node_modules/postcss-values-parser/lib/ValuesParser.js:110:10)
    at ValuesParser.parse (.../stylelint-declaration-strict-value/node_modules/postcss-values-parser/lib/ValuesParser.js:135:16)
    at Object.parse (.../stylelint-declaration-strict-value/node_modules/postcss-values-parser/lib/index.js:21:12)
    at Object.<anonymous> (.../stylelint-declaration-strict-value/test-ast.js:8:31)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)

Feature Proposal

It should work similar to numeric node's isNumber test:

static test(what) {
return isNumber(what);
}

API walk* proxies don't work, and here’s how we fix them

Hey, I’ve been a long-time user and advocate of postcss-values-parser. I’d like to think I’ve helped push it as the defacto value parser in PostCSS.


I’ve also been avoiding a significant bug in the API, and I’m here to resolve it with you. The walk proxies don’t work. Here’s why:

Container.registerWalker creates new proxy methods that walk nodes by a specific type. This means that something like Container.registerWalker(FunctionNode) becomes walkType(type, callback), where type is FunctionNode. So far, so good.

But within the walkType function, we normalize the type:

type = type.name && type.prototype ? type.name : type;

So now our type would be the following string; FunctionNode. And do you remember how we verify the node type?

if (node.type === type) { // node.type will be "func" and type will be "FunctionNode"

How do we fix this?

The fastest solution would be to update the walkType function like so:

walkType (type, callback) {
  if (!type || !callback) {
    throw new Error('Parameters {type} and {callback} are required.');
  }

  const isTypeCallable = typeof type === 'function'

  return this.walk((node, index) => {
    if (isTypeCallable && node instanceof type || !isTypeCallable && node.type === type) {
      return callback.call(this, node, index);
    }
  });
}

Would this be an acceptable solution? If so, I would gladly write up the PR.

I also want to acknowledge that @corysimmons and @nuintun tried to tell us in #34, #50, and #52. I just avoided the bug for a long time.


  • Node Version: v10.0.0
  • NPM Version: 6.0.0
  • postcss-values-parser Version: 1.5.0

This issue is regarding a problem with:

  • Standard CSS
  • LESS
  • SCSS
  • SASS

Expected Behavior

The walk proxies walk nodes by their respective type

Actual Behavior

The walk proxies do not walk nodes by their respective type

How can we reproduce the behavior?

By testing the walk proxies

provide for a 'loose' mode

Operator parsing in CSS-like languages don't adhere to the strict spec and need a 'loose' mode, which will not throw TokenizeErrors

Flat parsing of "(foo,bar),(baz)"

This gets parsed as a completely flat AST. It seems to me like the parentheses groups should be represented as nodes. postcss-value-parser interprets them as functions with no names so it would make sense to be consistent with that. I am trying to rewrite stylelint to use this parser instead of value-parser, and this is a requirement for certain rules.

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.