Skip to main content

Bug Tracker

Side navigation

#10799 closed bug (fixed)

Opened November 15, 2011 10:57PM UTC

Closed July 03, 2012 06:09PM UTC

Inconsistent results with [name="name"] selectors (also breaks .has)

Reported by: rgibson@relware.com Owned by: rgibson@relware.com
Priority: low Milestone: 1.8
Component: selector Version: 1.7
Keywords: Cc:
Blocked by: Blocking:
Description

jQuery delivers inconsistent results with [name="name"] selectors because of optimization-driven dependence upon un-normalized results from document.getElementsByName (defined in DOM Level 2), whose behavior in Internet Explorer differs between "quirks" and "standards" modes (in "quirks" mode, the method will only return form controls: elements with tag names like INPUT/SELECT/etc.). Specifically, calls to jQuery with default/document scope will fail to include non-form controls on IE ''if and only if'' there is no DOCTYPE declaration and there are form controls that also match the selector.

Chrome, Firefox, and Safari do not limit the potential set of matching elements for document.getElementsByName regardless of DOCTYPE, and so do not exhibit this bug.

I've created demonstration pages for both no DOCTYPE and simple DOCTYPE cases. Expected behavior is for the following expressions to always return all elements with a matching name attribute, but observed behavior is that the simplest one returns only form controls when the browser is IE and there is no DOCTYPE declaration and there is at least one form control that matches the selector.

  • unscoped: $('*[name="named"]')
  • workaround: $('*:not([name!="named"])')
  • scoped: $('*[name="named"]', '#context')

Note that scoping to document.body would also avoid this bug because getElementsByName is only defined on the document level (see below for relevance), but unfortunately jQuery's has method is implemented with precisely the kind of unscoped call to jQuery that is problematic.

A possible fix would be something like jQuery.support.getByName (true if document.getElementsByName can return elements of any tag name) and corresponding tweaking of Sizzle.selectors.find.NAME (accessed in Sizzle.find as Expr.find[ type ] at line 4129 of the uncompressed jQuery-1.7.js) to always return null when getElementsByName is restricted. That is already the return value now when context is not a document, or when context is a document but getElementsByName returns an empty list, making this a very minor change.

Such a fix would add fewer than 100 bytes.

Attachments (0)
Change History (7)

Changed November 15, 2011 11:55PM UTC by rgibson@relware.com comment:1

Also note that the HTML5 Definition does not specify any "form control" exclusions, providing ample reason to implement a fix in jQuery.

Changed November 16, 2011 01:29AM UTC by timmywil comment:2

component: unfiledselector
milestone: None1.next
priority: undecidedlow
status: newopen

Confirmed, but we are not that concerned with quirksmode as it is not officially supported. We can look into this, but it is low priority.

reduced test case

Changed November 16, 2011 09:33PM UTC by anonymous comment:3

Changed November 16, 2011 11:26PM UTC by timmywil comment:4

That is probably too much code to add for this edge case.

Changed November 17, 2011 03:18PM UTC by rgibson@relware.com comment:5

The change is two new if-blocks, each with a single-line body and one requiring a new temporary element, along with six lines of explanatory comments.

Also, I found out while fixing this that my initial guess about quirks mode vs. standards mode was incomplete, and a deeper issue is whether or not searches are handled with querySelectorAll (which makes it a bit broader). As shown at http://jsbin.com/uyezin/4, other conditions for incorrect results on Internet Explorer are:

  • no scope (equivalent to document scope)
  • both form and non-form elements in the document with the same name
  • selector incompatible with querySelectorAll (e.g., includes a psuedo selector)

Remembering that this bug counterintuitively breaks expressions like $set.has("[name=*]:visible"), what must change in order for a patch to be accepted?

Changed July 03, 2012 02:37AM UTC by timmywil comment:6

milestone: 1.next1.8
owner: → rgibson@relware.com
status: openassigned

If you update the pull to fit with the rewrite, I'll probably land it.

Changed July 03, 2012 06:09PM UTC by timmywil comment:7

resolution: → fixed
status: assignedclosed

Sizzle: detects a buggy getElementsByName. Fixes #10799.

Changeset: b325f7161c32a9dc8dfb49e5009af1b7f04ae276