Last Comment Bug 797029 - jQuery defaultDisplay() can't figure out display of <body> element
: jQuery defaultDisplay() can't figure out display of <body> element
Product: Core
Classification: Components
Component: DOM: CSS Object Model (show other bugs)
: Trunk
: x86_64 Windows 7
: -- normal (vote)
: ---
Assigned To: Nobody; OK to take it and work on it
: Andrew Overholt [:overholt]
Depends on:
Blocks: 968240
  Show dependency treegraph
Reported: 2012-10-02 11:12 PDT by Vladimir Vukicevic [:vlad] [:vladv]
Modified: 2015-04-20 23:30 PDT (History)
3 users (show)
See Also:
Crash Signature:
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---

testcase (1.93 KB, text/html)
2012-10-02 12:16 PDT, Vladimir Vukicevic [:vlad] [:vladv]
no flags Details
using jquery 1.8.2 (420 bytes, text/html)
2012-10-04 09:18 PDT, Vladimir Vukicevic [:vlad] [:vladv]
no flags Details

Description Vladimir Vukicevic [:vlad] [:vladv] 2012-10-02 11:12:50 PDT
This may well be a jQuery bug, but Firefox and Chrome behave differently.  For various transitions, jQuery wants to figure out the default value of the 'display' style property.  It does this using a helper function that tries to do two things:

1 - first it creates an element of the given tag name, appends it to the body, and reads its display
2 - if it's none/blank, it creates an iframe with a document consisting of <html><body> and then creates an element with the given tag name, appends it to the iframe doc, and reads the display.

This is all great, except when the element in question is <body>.  It goes down the iframe path which results in |undefined| as the value.  It then tries to do things like set the display to that when doing a transition such as a fade in on the body, which then horks.

Chrome gives back 'block'.  Is the bug in jQuery (it really should be special-casing <body>!) or is it in Firefox (it should be doing... something... for two body elements?)
Comment 1 Vladimir Vukicevic [:vlad] [:vladv] 2012-10-02 11:59:27 PDT
Ah, the jQuery folks claim this is a Firefox bug:

Apparently display: none on <body> causes the <iframe> to display fallback content or somesuch.  I have no idea what should actually be happening here.
Comment 2 Boris Zbarsky [:bz] (still a bit busy) 2012-10-02 12:00:11 PDT
What code is jquery actually running in this case?  How is it creating the element?  How is it reading the display?
Comment 3 Boris Zbarsky [:bz] (still a bit busy) 2012-10-02 12:00:47 PDT
Ah, so they're doing getComputedStyle on things that are inside a display:none iframe?

Those don't have meaningful computed styles, and can't due to media queries.
Comment 4 Boris Zbarsky [:bz] (still a bit busy) 2012-10-02 12:03:12 PDT
Here's a question.  Why are they doing the iframe thing at all?  That part makes absolutely not sense to me.
Comment 5 Boris Zbarsky [:bz] (still a bit busy) 2012-10-02 12:10:32 PDT
Also, the jQuery ticket is about cases when "body { display: none; }".  Is that the case in the situation you were dealing with here?
Comment 6 Vladimir Vukicevic [:vlad] [:vladv] 2012-10-02 12:16:42 PDT
Created attachment 667104 [details]

Yes, I'm an idiot, I forgot to attach the testcase.  Attached now.

Note that the function is taken straight from the jQuery source; jQuery 1.8.2 gets back 'none' instead of undefined, but same problem continues.
Comment 7 Boris Zbarsky [:bz] (still a bit busy) 2012-10-02 12:43:59 PDT
Ok, yes.  So your <body> is "display: none" (why?), and then things are all bad.

There's just no sane way to make what jQuery is trying to do here work in Gecko without completely changing how the style system works.  And even then (if we did it the way WebKit does) it would return bogus answers if there were user or UA style sheets with media queries.

On the other hand, what we _can_ do is just create an API for asking "what is the style if you only look at UA and user sheets?" and jQuery could use that instead of the hackery, yes?

Alternately, if it wants to, it could append the iframe to <html>, not <body>.  It would certainly fix the people who use "display: none" on <body>, at least....
Comment 8 Vladimir Vukicevic [:vlad] [:vladv] 2012-10-02 14:03:00 PDT
Fair enough -- sounds like a weird edge case on both ends.  Appending to <html> is definitely interesting, and I should suggest this to them... I guess I'll modify the testcase to verify that it works and punt it over to them.

(This all came up because does this, and is broken in Firefox, and whoever owns it doesn't seem interested in fixing it and is instead blaming 'Firefox bugs' or something.  So I dug into it to figure out what the heck was actually doing it, and it was all because he wanted a fadeIn() effect on load.)
Comment 9 Rick Waldron [:rwaldron] 2012-10-04 08:13:23 PDT
I developed the approach that jQuery is using in response to user code that overrides the default display for any given nodeName. Neither Firefox nor jQuery should have to accept the added burden, when the user code could just as easily use a css class to achieve exactly the same desired behaviour.
Comment 10 Rick Waldron [:rwaldron] 2012-10-04 08:15:46 PDT
One more thing... Boris, jQuery would absolutely love this: 

> an API for asking "what is the style if you only look at UA and user sheets?" 

Comment 11 Rick Waldron [:rwaldron] 2012-10-04 09:07:06 PDT
This issue doesn't exist in jQuery 1.8.x
Comment 12 Vladimir Vukicevic [:vlad] [:vladv] 2012-10-04 09:17:45 PDT
(In reply to Rick Waldron from comment #11)
> This issue doesn't exist in jQuery 1.8.x

Hm, seems to from my testing -- only difference is that the defaultDisplay function in 1.8.2 returns 'none' instead of unknown, but it results in equally broken behaviour.  (e.g. loading 1.8.2 in the testcase attached here still has the text not showing up)
Comment 13 Vladimir Vukicevic [:vlad] [:vladv] 2012-10-04 09:18:04 PDT
Created attachment 668016 [details]
using jquery 1.8.2
Comment 14 Rick Waldron [:rwaldron] 2012-10-04 09:48:54 PDT
Indeed, there was a bug in the test case that I wrote for our core tests. Sorry about that.
Comment 15 Rick Waldron [:rwaldron] 2012-10-04 10:29:05 PDT
This issue is too edge case to warrant refactoring the entire default display algorithm, so we're going with a naive solution in which we pre-cache body:block in the elemdisplay table. 

Friends don't let friends override default displays.
Comment 16 Boris Zbarsky [:bz] (still a bit busy) 2012-10-12 10:15:42 PDT
> an API for asking "what is the style if you only look at UA and user sheets?" 

Bug 800983.
Comment 17 Vladimir Vukicevic [:vlad] [:vladv] 2012-10-12 10:32:14 PDT
Rick, thanks for jumping on this!  Closing this bug off, since a fix went into jQuery.
Comment 18 Rick Waldron [:rwaldron] 2012-10-12 11:06:04 PDT
Just for good record keeping:

Note You need to log in before you can comment on or make changes to this bug.