Skip to content

Commit

Permalink
fix: add more checks for validity of an ID attribute
Browse files Browse the repository at this point in the history
refs #11
  • Loading branch information
fczbkk committed Dec 16, 2015
1 parent a2e5c30 commit 3bc5c55
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 21 deletions.
37 changes: 18 additions & 19 deletions src/css-selector-generator.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class CssSelectorGenerator
# escapes special characters in class and ID selectors
sanitizeItem: (item) ->
characters = (item.split '').map (character) ->
# colon is valid character in an attribute, but has to be escaped before
# being used in a selector, because it would clash with the CSS syntax
if character is ':'
"\\#{':'.charCodeAt(0).toString(16).toUpperCase()} "
else if /[ !"#$%&'()*+,./;<=>?@\[\\\]^`{|}~]/.test character
Expand All @@ -42,29 +44,26 @@ class CssSelectorGenerator
return characters.join ''


validateId: (id) ->
# ID must exist
return false unless id?

# ID can not start with number
return false if /^\d/.exec id

# ID must be unique
return document.querySelectorAll("##{id}").length is 1

getIdSelector: (element) ->
id = element.getAttribute 'id'

if id?
id = @sanitizeItem id
# ID must... exist, not to be empty and not to contain whitespace
if (
# ...exist
id? and
# ...not be empty
(id isnt '') and
# ...not contain whitespace
not (/\s/.exec id) and
# ...not start with a number
not (/^\d/.exec id)
)
sanitized_id = "##{@sanitizeItem id}"
# ID must match single element
if document.querySelectorAll(sanitized_id).length is 1
return sanitized_id

id =
if @validateId id
id = "##{id}"
else
id = null

id
null

getClassSelectors: (element) ->
result = []
Expand Down
22 changes: 20 additions & 2 deletions test/src/css-selector-generator.spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,29 @@ describe 'CSS Selector Generator', ->
expect(document.querySelector selector).toEqual root.firstChild

it 'should ignore ID attribute begining with a number', ->
expect(x.validateId '111aaa').toBe false
root.innerHTML = '<div id="111aaa"></div>'
selector = x.getIdSelector root.firstChild
expect(selector).toBe null

it 'should ignore non-unique ID attribute', ->
root.innerHTML = '<div id="aaa"></div><div id="aaa"></div>'
expect(x.validateId 'aaa').toBe false
selector = x.getIdSelector root.firstChild
expect(selector).toBe null

it 'should ignore empty ID attribute', ->
root.innerHTML = '<div id=""></div>'
selector = x.getIdSelector root.firstChild
expect(selector).toBe null

it 'should ignore ID attribute containing only whitespace', ->
root.innerHTML = '<div id=" "></div>'
selector = x.getIdSelector root.firstChild
expect(selector).toBe null

it 'should ignore ID attribute with whitespace', ->
root.innerHTML = '<div id="aaa bbb"></div>'
selector = x.getIdSelector root.firstChild
expect(selector).toBe null

describe 'class', ->

Expand Down

0 comments on commit 3bc5c55

Please sign in to comment.