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

Fix TypeError for custom properties fallback in length-zero-no-unit #4860

Merged
merged 3 commits into from Aug 10, 2020

Conversation

shirotech
Copy link
Contributor

@shirotech shirotech commented Jul 12, 2020

e.g.

font: var(--Funnel-header-font, 600 16px/1.5 var(--font-header));

lineHeightNode is undefined, so we just need to check for it.

@jeddy3 jeddy3 changed the title fix: fails on custom properties fallback with another custom property Fix TypeError for custom properties fallback in length-zero-no-unit Jul 12, 2020
@jeddy3
Copy link
Member

jeddy3 commented Jul 12, 2020

@shirotech Thank you for the pull request.

Can you add a test case for this, please?

You'll also need to run npm run format for the linting check to pass.

You'll find more information about running tests and formatting code in the contributing guide.

@shirotech
Copy link
Contributor Author

shirotech commented Jul 12, 2020

Actually I found there is an option for ignore: ["custom-properties"] but it is not taking effect, the lint should skip if this option is found. I will need to look into fixing this properly and provide tests as well, thanks for looking at this. Having said that, if the option is not found it should also find another way to detect the lineHeightNode.

@jeddy3 what are your thoughts on quickly fixing it, for now, to at least not have any errors, and we can do a follow-up PR to address this properly for the "clean" way mentioned above?

if (decl.prop.toLowerCase() === 'font' && node.type === 'div' && node.value === '/') {
const lineHeightNode = parsedValue.nodes[nodeIndex + 1];
const lineHeightNode = nodes[nodeIndex + 1];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When descending into functions, the nodes array will be scoped to the current function args. This is the array that nodeIndex refers to. See the postcss-value-parser docs for details.

e.g., to parse the value font: var(--foo, normal normal 400 16px/0 cursive);, the value parser will run two loops.

The outer loop operates on the following nodes:

// parsedValue.nodes contains this array:
[
      { type: 'word', sourceIndex: 0, value: 'font' },
      { type: 'div', sourceIndex: 4, value: ':', before: '', after: ' ' },
      {
        type: 'function',
        sourceIndex: 6,
        value: 'var',
        before: '',
        after: '',
        nodes: [
          [Object], [Object],
          [Object], [Object],
          [Object], [Object],
          [Object], [Object],
          [Object], [Object],
          [Object], [Object],
          [Object]
        ]
      }

The inner loop (equivalent to parsedValue.nodes[2].nodes) runs on the following values:

[
      { type: 'word', sourceIndex: 10, value: '--foo' },
      { type: 'div', sourceIndex: 15, value: ',', before: '', after: ' ' },
      { type: 'word', sourceIndex: 17, value: 'normal' },
      { type: 'space', sourceIndex: 23, value: ' ' },
      { type: 'word', sourceIndex: 24, value: 'normal' },
      { type: 'space', sourceIndex: 30, value: ' ' },
      { type: 'word', sourceIndex: 31, value: '400' },
      { type: 'space', sourceIndex: 34, value: ' ' },
      { type: 'word', sourceIndex: 35, value: '16px' },
      { type: 'div', sourceIndex: 39, value: '/', before: '', after: '' },
      { type: 'word', sourceIndex: 40, value: '0' },
      { type: 'space', sourceIndex: 41, value: ' ' },
      { type: 'word', sourceIndex: 42, value: 'cursive' }
    ]

Using nodes here means we can pick the right node with nodes[nodeIndex+1].

@m-allanson
Copy link
Member

m-allanson commented Jul 22, 2020

I've updated this and added a couple of tests. It should be ok for review now.

@shirotech the ignore: ["custom-properties"] option will only run on custom property declarations like:

a { --x: 0px; }

It doesn't handle var functions like:

font: var(--foo, normal normal 400 16px/0 cursive);

I'd recommend opening a separate issue to talk about the custom-properties option.

Test should have a unit, as it should check that the unit-ed zero is ignored.
@shirotech
Copy link
Contributor Author

Thanks @m-allanson anything else do we need to get this merged? Very keen on re-enabling this rule.

Copy link
Member

@jeddy3 jeddy3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-allanson Thanks! LGTM now.

@jeddy3 jeddy3 mentioned this pull request Aug 9, 2020
6 tasks
Copy link
Member

@mattxwang mattxwang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On my end, LGTM! We should open another issue discussing the custom properties option if it hasn't been done already.

@jeddy3 jeddy3 merged commit 9e1edfa into stylelint:master Aug 10, 2020
@jeddy3
Copy link
Member

jeddy3 commented Aug 10, 2020

Changelog:

  • Fixed: length-zero-no-unit TypeError for custom properties fallback (#4860).

We should open another issue discussing the custom properties option if it hasn't been done already.

We can wait for a user to open one as I believe this pull request resolves the issue at hand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants