Skip to content

CSS selectors don't support escape sequence #7688

@rigor789

Description

@rigor789

Environment

Provide version numbers for the following components (information can be retrieved by running tns info in your project folder or by inspecting the package.json of the project):

  • CLI: 6.0.3
  • Cross-platform modules: 6.0.6
  • Android Runtime: 6.0.1
  • iOS Runtime: 6.0.2
  • Plugin(s): nativescript-tailwind, ... (N/A)

Describe the bug

Given we have a css selector like this:

.w-1\/2 {
  width: 50%;
}

This is fully supported in browsers, however in NativeScript when the css parser parses it, the selector is parsed as .w-1 completely ignoring the \/2 part.

In practice you would use these selectors as <Element class="w-1/2" />.

The issue with them parsing as just .w-1 is that if you already have a .w-1 class, it will override it's properties and lead to undesired results.

To Reproduce

Add the following css to any NativeScript app

.w-1 {
  width: 25;
}
.w-1\/2 {
  width: 50%;
}

And use this simple layout to see the issue

<StackLayout>
  <Label class="w-1" backgroundColor="red" />
  <Label class="w-1/2" backgroundColor="blue" />
</StackLayout>

Expected behavior

I would expect the red label to be width: 25 and the blue label to be width: 50%.

What is actually happening:

  • red is width: 50%
  • blue is width: auto (or whatever is default)

Sample project

https://play.nativescript.org/?template=play-vue&id=kMFahL

Additional context

I have tracked the issue down to the css parser, more specifically this part:

const simpleIdentifierSelectorRegEx = /(#|\.|:|\b)([_-\w][_-\w\d]*)/gy;
export function parseSimpleIdentifierSelector(text: string, start: number = 0): Parsed<TypeSelector | ClassSelector | IdSelector | PseudoClassSelector> {
simpleIdentifierSelectorRegEx.lastIndex = start;
const result = simpleIdentifierSelectorRegEx.exec(text);
if (!result) {
return null;
}
const end = simpleIdentifierSelectorRegEx.lastIndex;
const type = <"#" | "." | ":" | "">result[1];
const identifier: string = result[2];
const value = <TypeSelector | ClassSelector | IdSelector | PseudoClassSelector>{ type, identifier };
return { start, end, value };
}

I'm working on a PR to fix this issue.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions