Skip to content

Commit

Permalink
fix: better escaping of special characters, especially the colon
Browse files Browse the repository at this point in the history
  • Loading branch information
fczbkk committed Nov 14, 2015
1 parent 80d1029 commit 6cd0d36
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 9 deletions.
26 changes: 26 additions & 0 deletions src/css-selector-generator.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,32 @@ class CssSelectorGenerator

# escapes special characters in class and ID selectors
sanitizeItem: (item) ->
characters = (item.split '').map (character) ->
if character is ':'
"\\#{':'.charCodeAt(0).toString(16).toUpperCase()} "
else if /[ !"#$%&'()*+,./;<=>?@\[\\\]^`{|}~]/.test character
"\\#{character}"
else
escape character
.replace /\%/g, '\\'

return characters.join ''

console.log 'item', characters


###
// `\r` is already tokenized away at this point by the HTML parser.
// `:` can be escaped as `\:`, but that fails in IE < 8.
if (/[\t\n\v\f:]/.test(character)) {
value = '\\' + charCode.toString(16).toUpperCase() + ' ';
} else if (/[ !"#$%&'()*+,./;<=>?@\[\\\]^`{|}~]/.test(character)) {
value = '\\' + character;
} else {
value = character;
}
###

escape item
.replace /\%/g, '\\'
# special characters *+-./
Expand Down
20 changes: 11 additions & 9 deletions test/src/css-selector-generator.spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -108,19 +108,21 @@ describe 'CSS Selector Generator', ->
expect(x.getIdSelector elm).toBe '#linkZero'
expect(x.getIdSelector root).toBe null

it 'should sanitize ID selector', ->
expect(x.sanitizeItem 'aaa:bbb').toEqual 'aaa\\3Abbb'

it 'should escape special characters in ID selector', ->
expect(x.sanitizeItem 'aaa*bbb').toEqual 'aaa\*bbb'
expect(x.sanitizeItem 'aaa+bbb').toEqual 'aaa\+bbb'
expect(x.sanitizeItem 'aaa-bbb').toEqual 'aaa\-bbb'
expect(x.sanitizeItem 'aaa.bbb').toEqual 'aaa\.bbb'
expect(x.sanitizeItem 'aaa/bbb').toEqual 'aaa\/bbb'
special_characters = '*+-./;'
for special_character in special_characters.split ''
root.innerHTML = "<div id='aaa#{special_character}bbb'></div>"
selector = x.getIdSelector root.firstChild
expect(document.querySelector selector).toEqual root.firstChild

it 'should escape ID selector containing UTF8 characters', ->
expect(x.sanitizeItem 'aaa✓bbb').toEqual 'aaa\\u2713bbb'

it 'should match element with colon in its ID', ->
root.innerHTML = '<div id="aaa:bbb"></div>'
selector = x.getIdSelector root.firstChild
expect(document.querySelector selector).toEqual root.firstChild

it 'should ignore ID attribute begining with a number', ->
expect(x.validateId '111aaa').toBe false

Expand Down Expand Up @@ -154,7 +156,7 @@ describe 'CSS Selector Generator', ->
root.innerHTML = '<div class="aaa:bbb"></div>'
elm = root.firstChild
result = x.getClassSelectors elm
expect(result).toContain '.aaa\\3Abbb'
expect(result).toContain '.aaa\\3A bbb'

describe 'attribute', ->

Expand Down

0 comments on commit 6cd0d36

Please sign in to comment.