CSS :hover regression in Firefox 13 when an element's class name is set by Javascript

RESOLVED FIXED in Firefox 14

Status

()

Core
CSS Parsing and Computation
RESOLVED FIXED
5 years ago
5 years ago

People

(Reporter: mjh563, Assigned: bz)

Tracking

13 Branch
mozilla15
Points:
---
Bug Flags:
in-testsuite ?

Firefox Tracking Flags

(firefox13+, firefox14+ verified, firefox15+ verified)

Details

(Whiteboard: [qa+])

Attachments

(2 attachments, 1 obsolete attachment)

(Reporter)

Description

5 years ago
Created attachment 627486 [details]
testcase

The attached testcase sets the class name of an element in window.onload, but in Firefox >= 13 the CSS rule that references that class name is not applied.

The testcase works as expected in Opera, Google Chrome and Firefox <= 12.
(Reporter)

Updated

5 years ago
Attachment #627486 - Attachment mime type: text/plain → text/html
(Reporter)

Comment 1

5 years ago
Created attachment 627487 [details]
New  testcase

Sorry, the previous attachment was wrong. 

In this testcase, the block should turn red when you hover the mouse over it. This works in Firefox 12 and other browsers, but not in Firefox 13.
Attachment #627486 - Attachment is obsolete: true
(Reporter)

Updated

5 years ago
Attachment #627487 - Attachment mime type: text/plain → text/html
Regression range from Linux m-c nightlies is (not surprisingly; I only downloaded 2 nightlies to test this):
http://hg.mozilla.org/mozilla-central/pushloghtml?fromchange=1ca7a94573f2&tochange=c71845b3b2a6
Confirmed as regression from https://hg.mozilla.org/mozilla-central/rev/4bd80687cb32 by local backout of the nsCSSFrameConstructor.cpp changes in it.
Blocks: 732667
Status: UNCONFIRMED → NEW
tracking-firefox13: --- → ?
tracking-firefox14: --- → ?
tracking-firefox15: --- → ?
Ever confirmed: true
OS: Linux → All
Hardware: x86 → All
Summary: CSS regression in Firefox 13 when an element's class name is set by Javascript → CSS :hover regression in Firefox 13 when an element's class name is set by Javascript
Taking.  Wish this had gotten reported earlier; at this point the chances of me being able to convince the beta drivers to take a fix for 13 might be slim.  :(
Assignee: nobody → bzbarsky
So the key issue here is that during initial CSS matching the node does not have class="test", so we short-circuit matching the ".test:hover" selector before matching the :hover part, and hence don't set the "affected by :hover" flag on the element.

Then when the class is changed, we do HasAttributeDependentStyle, but the ".test:hover" selector doesn't match because ":hover" doesn't match, so we don't do a restyle on the element.  During HasAttributeDependentStyle, mForStyling is false, so we don't set the "affected by :hover" flag again.

Finally, when we enter hover the "affected by :hover" flag is not set, so we don't think we need to restyle.

Nice testcase!
And even a naive change that fixed HasAttributeDependentStyle when matching :hover to flag the node would fail in general, I think, because we shortcut the matching in AttrEnumFunc altogether if the restyle hint for the current selector is subsumed by our pending restyle hint.  So we might not match the :hover during the restyle at all.
So the obvious options are:

1)  Back out bug 732667.
2)  Add a boolean flag to nsCSSSelector (maybe shrinking the number of bits mPseudoType
    to avoid changing the struct size) that indicates whether the selector includes
    :hover.  Set this as needed while building the rule cascade; check for this flag in
    SelectorMatches() after the namespace/tag checks, and set the bit on the DOM node
    accordingly.  Need to watch out for :not here.
3)  Restrict the optimization from bug 732667 to selectors that only include :hover with a
    tag name and nothing else.  It would still be good enough for github, and would not be
    subject to the issues here because tag names are immutable.

Everything else I've thought of so far is a slower version of #2.

I think #3 is the way to go, personally.  I'll write up a patch.
Created attachment 627838 [details] [diff] [review]
Don't apply the dynamic :hover reresolution skipping optimization to selectors which can match on mutable state other than :hover.

I tried to add a test for this to test_hover, but couldn't get it to fail even without this patch....
Attachment #627838 - Flags: review?(dbaron)
Whiteboard: [need review]
Comment on attachment 627838 [details] [diff] [review]
Don't apply the dynamic :hover reresolution skipping optimization to selectors which can match on mutable state other than :hover.

r=dbaron

I guess AncestorFilter interactions are ok because any change to a class or ID on an ancestor will always trigger the full restyle when there's a selector that's relevant (because we're only looking at part of the selector).
Attachment #627838 - Flags: review?(dbaron) → review+
Yes, exactly.
http://hg.mozilla.org/integration/mozilla-inbound/rev/6aa5239fe656
Flags: in-testsuite?
Whiteboard: [need review]
Target Milestone: --- → mozilla15
Comment on attachment 627838 [details] [diff] [review]
Don't apply the dynamic :hover reresolution skipping optimization to selectors which can match on mutable state other than :hover.

[Approval Request Comment]
Bug caused by (feature/regressing bug #): bug 732667 
User impact if declined: Some elements that should respond to hover won't
Testing completed (on m-c, etc.): Passes attached test and some other basic
   smoketesting.
Risk to taking this patch (and alternatives if risky): Risk should be low: the
   patch is making an optimization apply in fewer cases so it doesn't lead to
   incorrect behavior.  The main alternative is disabling the optimization
   altogether (i.e. backing out bug 732667).
String or UUID changes made by this patch: None
Attachment #627838 - Flags: approval-mozilla-beta?
Attachment #627838 - Flags: approval-mozilla-aurora?

Updated

5 years ago
tracking-firefox13: ? → +
tracking-firefox14: ? → +
tracking-firefox15: ? → +
Comment on attachment 627838 [details] [diff] [review]
Don't apply the dynamic :hover reresolution skipping optimization to selectors which can match on mutable state other than :hover.

[Triage Comment]
There isn't enough evidence that this is a common action in websites to warrant any additional risk between our final beta and RC. We haven't received feedback around site breakage caused by this bug. Please re-nominate if you disagree.

We will, however, release note this bug for FF13. Approving for Aurora 14.
Attachment #627838 - Flags: approval-mozilla-beta?
Attachment #627838 - Flags: approval-mozilla-beta-
Attachment #627838 - Flags: approval-mozilla-aurora?
Attachment #627838 - Flags: approval-mozilla-aurora+
https://hg.mozilla.org/mozilla-central/rev/6aa5239fe656
Status: NEW → RESOLVED
Last Resolved: 5 years ago
Resolution: --- → FIXED
http://hg.mozilla.org/releases/mozilla-aurora/rev/89176b6d643c
status-firefox14: --- → fixed

Comment 16

5 years ago
Hi

Im having this same issue, even in the test case this problem still exists. Using Mac firefox 13, tested in earlier versions of Firefox, this works fine but the problem persists in firefox 13.
(Reporter)

Comment 17

5 years ago
Yes, the fix didn't quite make it into version 13. It's fixed in 14 though, which is due to be released in mid-July (it's currently in beta).
Indeed.  See the Firefox 13 release notes...

Comment 19

5 years ago
Thanks for getting back to me so quickly guys :)
Verified using the test case attached in the Description that the CSS rule is applied. 

Verified using Firefox 14 beta 8 on Windows 7, Ubuntu 12.04 and Mac OS X 10.6:

Mozilla/5.0 (Windows NT 6.1; rv:14.0) Gecko/20100101 Firefox/14.0
Mozilla/5.0 (X11; Linux i686; rv:14.0) Gecko/20100101 Firefox/14.0
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:14.0) Gecko/20100101 Firefox/14.0
status-firefox14: fixed → verified
Whiteboard: [qa+]

Updated

5 years ago
status-firefox15: --- → fixed
Verified on Firefox 15 beta 3, using the test case attached in the Description that - the CSS rule is applied. 

Verified on Windows XP, Ubuntu 12.04 and Mac OS X 10.7:

Mozilla/5.0 (Windows NT 5.1; rv:15.0) Gecko/20100101 Firefox/15.0
Mozilla/5.0 (X11; Linux i686; rv:15.0) Gecko/20100101 Firefox/15.0
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:15.0) Gecko/20100101 Firefox/15.0
status-firefox15: fixed → verified
You need to log in before you can comment on or make changes to this bug.