Skip to main content

Bug Tracker

Side navigation

#6448 closed bug (fixed)

Opened April 16, 2010 10:39AM UTC

Closed January 27, 2011 02:49PM UTC

Problem with selector having "]" and context

Reported by: maizy Owned by:
Priority: high Milestone: 1.5
Component: selector Version: 1.5b1
Keywords: scope ] Cc:
Blocked by: Blocking:
Description

I have html structure like that:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru">
<body>
<div id="wrap">

<!-- ... -->
    <button name="belongs[ok]">Ok</button>
<!-- ... -->

</div>
</body>
</html>

This selectors work fine:

$('button[name$="ok\\\\]"]').length === 1; //true
$('button[name*="ok"]').length === 1;  //true
$('div#wrap button[name$="ok\\\\]"]').length === 1; //true
$('button[name*="ok\\\\]"]', $('#wrap')).length === 1; //true
$('div#wrap').length === 1; //true

but that doesn't:

var res = $('button[name$="ok\\\\]"]', $('#wrap')).length;
res === 1;      //false
res === 0;      //true

jQuery 1.4.2.

Checked on Google Chrome 5.0.342.9 beta (Linux), FF 3.5.9 (Linux).

Attachments (0)
Change History (8)

Changed April 20, 2010 11:23AM UTC by rsinton comment:1

Some extra observations:

  • Also happens if the right square bracket occurs in the middle of the match, i.e.
    $('button[name$="ok\\\\]xyz "]', $('#wrap'))
    still fails against
    button name="belongs[ok]xyz">Ok</button>
  • Happens with other entities that need escaping
  • This ''does'' work:
    $('button[name$="ok\\]"]', $('#wrap') )
  • So does this:
    $('button[name$="ok\\\\]"]', $('#wrap').get[0] )

Changed April 20, 2010 11:34AM UTC by rsinton comment:2

Something else that works:

$('button[name$="ok\\\\]"]', $('#wrap')
matches against
<button name="belongs[ok\\]">Ok</button>
.

This looks like the double-backslash is causing a match on a literal backslash, instead of escaping the following special character, ''but'' this is only happening when a context parameter is supplied, ''and'' that context parameter is a jQuery object (not a raw DOM element). Very curious.

Changed April 21, 2010 12:29PM UTC by rsinton comment:3

Sorry, was confusing get[0] with get(0).

$('button[name$="ok\\\\]"]', $('#wrap').get(0) )

and

$('button[name$="ok\\\\]"]', $('#wrap') )

both fail.

So the ''apparent'' behaviour is as simple as: double backslashes are required for matching special chars when no context parameter is given, but single backslashes work when there is a context parameter supplied.

Changed April 21, 2010 01:23PM UTC by rsinton comment:4

Some work with a debugger makes me think that the issue lies in .filter(), which gets called internally when there is a context parameter.

As expected from that theory, this fails:

$('#wrap button').filter('[name$="ok\\\\]"]' )

but this works:

$('#wrap button').filter('[name$="ok\\]"]' )

Changed April 21, 2010 08:19PM UTC by rsinton comment:5

I doubt that it's really the correct place to do it, but confirmed that replacing

Sizzle.filter = function(expr, set, inplace, not){

with

Sizzle.filter = function(expr, set, inplace, not){
	expr = expr.replace(/\\\\/g, "");

makes the problem go away, by removing the single backslash that has already been unescaped down from the double one in the original selector.

Changed October 21, 2010 12:36AM UTC by snover comment:6

milestone: → 1.5
priority: → high
status: newopen

Changed October 21, 2010 12:36AM UTC by snover comment:7

blockedby: → 6093

Changed January 27, 2011 02:49PM UTC by jitter comment:8

resolution: → fixed
status: openclosed
version: 1.4.21.5b1

This test case shows it works now after the fix for #6093