The [attr~=value] filter is not listed on the API page, but, if used, produces the same results as the [attr*=value] filter.
To match the CSS spec for the same notation, E[foo~="warning"] should match "any E element whose 'foo' attribute value is a list of space-separated values, one of which is exactly equal to 'warning'."
Under the current implementation, E[foo~="warning"] would match any E element whose 'foo' attribute contained the string 'warning', whether or not it was a separate word. E.g., it would match an E element with a 'foo' attribute whose value was 'stormwarning'.
Basically, [attr~=value] is supposed to implement .class-like behavior for arbitrary attributes.
All that's necessary to correct the problem is to replace line 347 of selector.js
(type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
with the following:
type == "*=" && z.indexOf(m[5]) >= 0 ||
type == "~=" && (" "+z+" ").indexOf(" " + m[5] +" ") >= 0 ) ^ not )
Note:
Ticket 2640 asks for the proper behavior as an enhancement, but behavior that produces different results than the CSS spec seems like a bug, to me.