Unable to add Taxonomies to custom post type taxonomies in 3.4.1

Description

This is reproducible in at least IE8 and FF 13.0.1, WordPress 3.4.1, and at least two separate domains.

Problem: We have a least two sites which have custom post types and taxonomies originally added by the Custom Post Type UI plugin, in which we are unable to add new taxonomies to. After disabling all plugins and putting the post type/taxonomy code directly into the functions.php file: we are still unable to add new taxonomies.

Reproduction: 1. Add a custom post type and a custom post type taxonomy. Add new custom post type "entry/post" from the admin menu or from the Dashboard sidebar. If is a hierarchical custom post type taxonomy, add a new custom post taxonomy. When the "Add New [Taxonomy]" button is pressed, the entered name in the taxonomy text field stays present, the add button seems to disappear from its location, and the add button is now displayed at the end of the custom post taxonomy list. The new taxonomy has not been added. (see image attached)

Add a custom post type and a custom post type taxonomy. Add new custom post type "entry/post" from the admin menu or from the Dashboard sidebar. If is a hierarchical custom post type taxonomy, which already has taxonomy present, check several taxonomies. You will notice that there is "lag" in selecting these current taxonomies (IE8 at least).

Although I have not been able to reproduce this, a client has mentioned that on an add custom post page where there is custom post taxonomy, the page is unusable and can eventually crash in IE8.

"event-city" starts with the word "even". WordPress uses some colon-separated class names. like: add:event-citychecklist. See the :even in there? The issue manifests if you replace "event-city" with "oddsfish".

On line 81 of wp-includes/js/wp-lists.dev.js has the following line:

if ( !e.is('[class^="add:' + list.id + ':"]') )

This test is failing when it shouldn't be.

Here's my theory: there was a bug introduced in jQuery 1.7.2 regarding attribute selector quoting. It's seeing :even or :odd in a quoted class selector and it's parsing that as the :even/:odd pseudo-classes that jQuery supports.

What's really frustrating is that I can't reproduce it more simply. I've been trying to make a simple proof of concept on jsfiddle.net

Because :checkbox is a jQuery extension and not part of the CSS specification, queries using :checkbox cannot take advantage of the performance boost provided by the native DOM querySelectorAll() method. For better performance in modern browsers, use [type="checkbox"] instead.

21106.2.patch​ fixes the stack overflow in IE and the lagging in both Firefox and IE. It should cover all the existing core usage of those class names. Tested in 3.4.1 (with jQuery 1.7.2) as well.

21106.3.patch​ binds all three non-form functions to both a and input elements, in case plugins might rely on that. Seems is a little bit slower, but perhaps safer. Not sure if that's necessary though.

SergeyBiryukov's comment suggests that this remaining issue has to do with jQuery 1.8.x, which is WP trunk only. The Sizzle selector engine was rebuilt in 1.8, so I would not be surprised if this did not affect 1.7. The original report does suggest this is a problem with 3.4.x. Does 21106.2.patch​ (or .3.patch) handle both?

I think so. In 3.4.1, the lagging (~3 seconds) only appears in IE when checking terms of a taxonomy starting with "even" (as described in the ticket). It would be good to fix that.

In trunk, the lagging appears in both IE and Firefox (~1 second in Firefox and IE 9, ~5 seconds in IE 8) when checking any category on a regular Edit Post screen as well. Additionally, a stack overflow error occurs in IE 8 when checking terms of a taxonomy starting with "even".

Upon more testing, it turned out that 21106.2.patch​ doesn't work as intended (the functions are not binded properly for some reason), so I've decided to simplify it.

21106.5.patch​ fixes the lagging in IE in 3.4.1. In trunk, it also fixes stack overflow in IE 8 and at least partially fixes the lagging (~0.2 seconds, almost unnoticeable, in FF, ~1 second in IE). We could look into further optimization in a new ticket.

The process() runs on load with no arg, then on adding elements with the element as arg. This isn't needed if the events are delegated (i.e. attached to $(document) so they will trigger when new elements are added with ajax). Also, on load $el = $(document) so doing $el.find(...) goes through the whole DOM.

For this to work it shouldn't use .find() and only attach the events to $(document) on load. There's no need to run it on each ajax response. All this can be seen in action on the Comments screen.

We hit a bug in jQuery. When a class name contains :event it cannot be used as selector in jQuery even when the : is escaped (it won't select any elements). This affects process() too.