@@ -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(
336331function 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 - F 0 - 9 ] { 1 , 6 } ) \x20 (? ! [ a - f A - F 0 - 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- }
0 commit comments