jquery.suggestions: Handle CSS ellipsis better for IE
authorBartosz Dziewoński <matma.rex@gmail.com>
Sun, 25 May 2014 12:09:10 +0000 (14:09 +0200)
committerBartosz Dziewoński <matma.rex@gmail.com>
Wed, 28 May 2014 21:36:30 +0000 (23:36 +0200)
IE is not impressed by our puny hacks and still reports the width
"in context of" the position in the document, limited by the width
of ancestor elements.

Let's temporarily apply position: absolute; to the involved elements.
This pulls them out of normal document flow and lets us figure out the
real width at last.

Also wrote a proper comment on why we need this stuff.

Verified that this fixes:
* IE 8
* IE 11

Verified that it doesn't break:
* Firefox 3.6
* Firefox 29
* Opera 12
* Opera 22

It *does not* fix IE 6. I don't think that investigating why is a good
use of my time, so I didn't. I84fbae5a made the functionality usable
on IE 6, which feels good enough for me.

Bug: 65224
Change-Id: I4a7357543ca244585ade2061b92f5a6d1e439278

resources/src/jquery/jquery.suggestions.js

index a20a948..7a32076 100644 (file)
@@ -267,10 +267,22 @@ $.suggestions = {
                                                        }
 
                                                        // Widen results box if needed (new width is only calculated here, applied later).
-                                                       // We need this awful hack to calculate the actual pre-ellipsis width.
+
+                                                       // The monstrosity below accomplishes two things:
+                                                       // * Wraps the text contents in a DOM element, so that we can know its width. There is
+                                                       //   no way to directly access the width of a text node, and we can't use the parent
+                                                       //   node width as it has text-overflow: ellipsis; and overflow: hidden; applied to
+                                                       //   it, which trims it to a smaller width.
+                                                       // * Temporarily applies position: absolute; to the wrapper to pull it out of normal
+                                                       //   document flow. Otherwise the CSS text-overflow: ellipsis; and overflow: hidden;
+                                                       //   rules would cause some browsers (at least all versions of IE from 6 to 11) to
+                                                       //   still report the "trimmed" width. This should not be done in regular CSS
+                                                       //   stylesheets as we don't want this rule to apply to other <span> elements, like
+                                                       //   the ones generated by jquery.highlightText.
                                                        $spanForWidth = $result.wrapInner( '<span>' ).children();
-                                                       childrenWidth = $spanForWidth.outerWidth();
+                                                       childrenWidth = $spanForWidth.css( 'position', 'absolute' ).outerWidth();
                                                        $spanForWidth.contents().unwrap();
+
                                                        if ( childrenWidth > $result.width() && childrenWidth > expWidth ) {
                                                                // factor in any padding, margin, or border space on the parent
                                                                expWidth = childrenWidth + ( context.data.$container.width() - $result.width() );