-
Notifications
You must be signed in to change notification settings - Fork 358
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Carlos (Goodwine) <2022649+Goodwine@users.noreply.github.com>
- Loading branch information
Showing
21 changed files
with
2,453 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
// Copyright 2024 Google Inc. Use of this source code is governed by an | ||
// MIT-style license that can be found in the LICENSE file or at | ||
// https://opensource.org/licenses/MIT. | ||
|
||
import 'package:charcode/charcode.dart'; | ||
import 'package:string_scanner/string_scanner.dart'; | ||
|
||
import 'character.dart'; | ||
|
||
extension StringExtension on String { | ||
/// Returns a minimally-escaped CSS identifiers whose contents evaluates to | ||
/// [text]. | ||
/// | ||
/// Throws a [FormatException] if [text] cannot be represented as a CSS | ||
/// identifier (such as the empty string). | ||
String toCssIdentifier() { | ||
var buffer = StringBuffer(); | ||
var scanner = SpanScanner(this); | ||
|
||
void writeEscape(int character) { | ||
buffer.writeCharCode($backslash); | ||
buffer.write(character.toRadixString(16)); | ||
if (scanner.peekChar() case int(isHex: true)) { | ||
buffer.writeCharCode($space); | ||
} | ||
} | ||
|
||
void consumeSurrogatePair(int character) { | ||
if (scanner.peekChar(1) case null || int(isLowSurrogate: false)) { | ||
scanner.error( | ||
"An individual surrogates can't be represented as a CSS " | ||
"identifier.", | ||
length: 1); | ||
} else if (character.isPrivateUseHighSurrogate) { | ||
writeEscape(combineSurrogates(scanner.readChar(), scanner.readChar())); | ||
} else { | ||
buffer.writeCharCode(scanner.readChar()); | ||
buffer.writeCharCode(scanner.readChar()); | ||
} | ||
} | ||
|
||
var doubleDash = false; | ||
if (scanner.scanChar($dash)) { | ||
if (scanner.isDone) return '\\2d'; | ||
|
||
buffer.writeCharCode($dash); | ||
|
||
if (scanner.scanChar($dash)) { | ||
buffer.writeCharCode($dash); | ||
doubleDash = true; | ||
} | ||
} | ||
|
||
if (!doubleDash) { | ||
switch (scanner.peekChar()) { | ||
case null: | ||
scanner.error( | ||
"The empty string can't be represented as a CSS identifier."); | ||
|
||
case 0: | ||
scanner.error("The U+0000 can't be represented as a CSS identifier."); | ||
|
||
case int character when character.isHighSurrogate: | ||
consumeSurrogatePair(character); | ||
|
||
case int(isLowSurrogate: true): | ||
scanner.error( | ||
"An individual surrogate can't be represented as a CSS " | ||
"identifier.", | ||
length: 1); | ||
|
||
case int(isNameStart: true, isPrivateUseBMP: false): | ||
buffer.writeCharCode(scanner.readChar()); | ||
|
||
case _: | ||
writeEscape(scanner.readChar()); | ||
} | ||
} | ||
|
||
loop: | ||
while (true) { | ||
switch (scanner.peekChar()) { | ||
case null: | ||
break loop; | ||
|
||
case 0: | ||
scanner.error("The U+0000 can't be represented as a CSS identifier."); | ||
|
||
case int character when character.isHighSurrogate: | ||
consumeSurrogatePair(character); | ||
|
||
case int(isLowSurrogate: true): | ||
scanner.error( | ||
"An individual surrogate can't be represented as a CSS " | ||
"identifier.", | ||
length: 1); | ||
|
||
case int(isName: true, isPrivateUseBMP: false): | ||
buffer.writeCharCode(scanner.readChar()); | ||
|
||
case _: | ||
writeEscape(scanner.readChar()); | ||
} | ||
} | ||
|
||
return buffer.toString(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
pkg/sass-parser/lib/src/__snapshots__/configured-variable.test.ts.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`a configured variable toJSON 1`] = ` | ||
{ | ||
"expression": <"qux">, | ||
"guarded": false, | ||
"inputs": [ | ||
{ | ||
"css": "@use "foo" with ($baz: "qux")", | ||
"hasBOM": false, | ||
"id": "<input css _____>", | ||
}, | ||
], | ||
"raws": {}, | ||
"sassType": "configured-variable", | ||
"source": <1:18-1:29 in 0>, | ||
"variableName": "baz", | ||
} | ||
`; |
Oops, something went wrong.