Skip to content

Commit df88b72

Browse files
committed
Replace cssesc with CSS.escape
1 parent 81377fc commit df88b72

File tree

3 files changed

+6
-97
lines changed

3 files changed

+6
-97
lines changed

finder.ts

Lines changed: 3 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ function id(input: Element): Knot | null {
188188
const elementId = input.getAttribute('id')
189189
if (elementId && config.idName(elementId)) {
190190
return {
191-
name: '#' + cssesc(elementId, {isIdentifier: true}),
191+
name: '#' + CSS.escape(elementId),
192192
penalty: 0,
193193
}
194194
}
@@ -201,12 +201,7 @@ function attr(input: Element): Knot[] {
201201
)
202202
return attrs.map(
203203
(attr): Knot => ({
204-
name:
205-
'[' +
206-
cssesc(attr.name, {isIdentifier: true}) +
207-
'="' +
208-
cssesc(attr.value) +
209-
'"]',
204+
name: `[${CSS.escape(attr.name)}="${CSS.escape(attr.value)}"]`,
210205
penalty: 0.5,
211206
})
212207
)
@@ -216,7 +211,7 @@ function classNames(input: Element): Knot[] {
216211
const names = Array.from(input.classList).filter(config.className)
217212
return names.map(
218213
(name): Knot => ({
219-
name: '.' + cssesc(name, {isIdentifier: true}),
214+
name: '.' + CSS.escape(name),
220215
penalty: 1,
221216
})
222217
)
@@ -336,92 +331,3 @@ function* optimize(
336331
function same(path: Path, input: Element) {
337332
return rootDocument.querySelector(selector(path)) === input
338333
}
339-
340-
const regexAnySingleEscape = /[ -,\.\/:-@\[-\^`\{-~]/
341-
const regexSingleEscape = /[ -,\.\/:-@\[\]\^`\{-~]/
342-
const regexExcessiveSpaces =
343-
/(^|\\+)?(\\[A-F0-9]{1,6})\x20(?![a-fA-F0-9\x20])/g
344-
345-
const defaultOptions = {
346-
escapeEverything: false,
347-
isIdentifier: false,
348-
quotes: 'single',
349-
wrap: false,
350-
}
351-
352-
function cssesc(string: string, opt: Partial<typeof defaultOptions> = {}) {
353-
const options = {...defaultOptions, ...opt}
354-
if (options.quotes != 'single' && options.quotes != 'double') {
355-
options.quotes = 'single'
356-
}
357-
const quote = options.quotes == 'double' ? '"' : '\''
358-
const isIdentifier = options.isIdentifier
359-
const firstChar = string.charAt(0)
360-
let output = ''
361-
let counter = 0
362-
const length = string.length
363-
while (counter < length) {
364-
const character = string.charAt(counter++)
365-
let codePoint = character.charCodeAt(0)
366-
let value: string | undefined = void 0
367-
// If it’s not a printable ASCII character…
368-
if (codePoint < 0x20 || codePoint > 0x7e) {
369-
if (codePoint >= 0xd800 && codePoint <= 0xdbff && counter < length) {
370-
// It’s a high surrogate, and there is a next character.
371-
const extra = string.charCodeAt(counter++)
372-
if ((extra & 0xfc00) == 0xdc00) {
373-
// next character is low surrogate
374-
codePoint = ((codePoint & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000
375-
} else {
376-
// It’s an unmatched surrogate; only append this code unit, in case
377-
// the next code unit is the high surrogate of a surrogate pair.
378-
counter--
379-
}
380-
}
381-
value = '\\' + codePoint.toString(16).toUpperCase() + ' '
382-
} else {
383-
if (options.escapeEverything) {
384-
if (regexAnySingleEscape.test(character)) {
385-
value = '\\' + character
386-
} else {
387-
value = '\\' + codePoint.toString(16).toUpperCase() + ' '
388-
}
389-
} else if (/[\t\n\f\r\x0B]/.test(character)) {
390-
value = '\\' + codePoint.toString(16).toUpperCase() + ' '
391-
} else if (
392-
character == '\\' ||
393-
(!isIdentifier &&
394-
((character == '"' && quote == character) ||
395-
(character == '\'' && quote == character))) ||
396-
(isIdentifier && regexSingleEscape.test(character))
397-
) {
398-
value = '\\' + character
399-
} else {
400-
value = character
401-
}
402-
}
403-
output += value
404-
}
405-
if (isIdentifier) {
406-
if (/^-[-\d]/.test(output)) {
407-
output = '\\-' + output.slice(1)
408-
} else if (/\d/.test(firstChar)) {
409-
output = '\\3' + firstChar + ' ' + output.slice(1)
410-
}
411-
}
412-
// Remove spaces after `\HEX` escapes that are not followed by a hex digit,
413-
// since they’re redundant. Note that this is only possible if the escape
414-
// sequence isn’t preceded by an odd number of backslashes.
415-
output = output.replace(regexExcessiveSpaces, function ($0, $1, $2) {
416-
if ($1 && $1.length % 2) {
417-
// It’s not safe to remove the space, so don’t.
418-
return $0
419-
}
420-
// Strip the space.
421-
return ($1 || '') + $2
422-
})
423-
if (!isIdentifier && options.wrap) {
424-
return quote + output + quote
425-
}
426-
return output
427-
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"release": "release-it --access public"
1616
},
1717
"devDependencies": {
18+
"css.escape": "^1.5.1",
1819
"jsdom": "^21.1.0",
1920
"release-it": "^15.7.0",
2021
"typescript": "4.9.5",

tests/test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { fileURLToPath } from 'node:url'
66
import { dirname } from 'node:path'
77
import { finder } from '../finder.js'
88

9+
import 'css.escape'
10+
911
const __filename = fileURLToPath(import.meta.url)
1012
const __dirname = dirname(__filename)
1113

0 commit comments

Comments
 (0)