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

@import rule parsing breaks if the argument of url contains a semi-colon (e.g. Nunito Google font) #137

Open
dfdeagle47 opened this issue Jun 2, 2020 · 0 comments

Comments

@dfdeagle47
Copy link

Context

My CSS contains a CSS rule to import the Nunito Google font. The website provides the following rule

@import url("https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200;1,200&display=swap");

However, the parsing fails with this lib.

Sample test files

import-complex/ast.json

{
  "type": "stylesheet",
  "stylesheet": {
    "rules": [
      {
        "type": "import",
        "import": "@import url(\"https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200;1,200&display=swap\");",
        "position": {
          "start": {
            "line": 1,
            "column": 1
          },
          "end": {
            "line": 1,
            "column": 99
          },
          "source": "input.css"
        }
      }
    ]
  }
}

import-complex/compressed.css

@import url("https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200;1,200&display=swap");

import-complex/input.css

@import url("https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200;1,200&display=swap");

import-complex/output.css

@import url("https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200;1,200&display=swap");

Cause

The parsing fails due to how the "at" rules are defined (see here). In particular, the regex used to delimit rules is as follows:

var re = new RegExp('^@' + name + '\\s*([^;]+);');

Basically, it will match any rules which begin with @import (because name === 'import' in my case) and will stop when it encounters the first semi-colon ;.

This is problematic for the use case above because there are semi-colons contained in the URL. Note that this syntax is valid, as any string is a valid argument for the url function (see here).

Solution?

A "clean" solution would be to tweak the regex to properly handle this use case: if the semi-colon is contained inside simple/double quotes, we should not stop. However, this will make the regex more complex (with potential side-effects?) and harder to maintain. It might not be worth the effort because it's a pretty specific use case.

Even if the regex is left untouched, it's possible to work-around the issue above by using the URL-encoded version of the semi-colon character ;, namely %3B (see here), so the css rule becomes

@import url("https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200%3B1,200&display=swap");

I believe this work around is satisfactory given the drawbacks linked to updating the regexp. It might be useful to document this workaround in the Readme.md so anyone can find it.

Misc

I encountered this issue with the @import rule, but it probably affects any "@ rule".

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

No branches or pull requests

1 participant