Summary: | nested SVGs inside html table element fail to hit-test correctly | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Product: | WebKit | Reporter: | elliottcable <bugs.webkit.org> | ||||||||||||||
Component: | SVG | Assignee: | Nobody <webkit-unassigned> | ||||||||||||||
Status: | RESOLVED DUPLICATE | ||||||||||||||||
Severity: | Normal | CC: | bdakin, hyatt, mitz | ||||||||||||||
Priority: | P3 | ||||||||||||||||
Version: | 528+ (Nightly build) | ||||||||||||||||
Hardware: | Mac (Intel) | ||||||||||||||||
OS: | OS X 10.5 | ||||||||||||||||
Attachments: |
|
Description
elliottcable
2008-10-25 19:22:14 PDT
Created attachment 24679 [details]
A simple test case for the problem
This test case is pretty straight forward - it shows an example of an element with both a CSS :hover attribute, and a JavaScript onclick attribute. In FireFox, both 'work' as intended; in WebKit, neither does.
*** Bug 21890 has been marked as a duplicate of this bug. *** Confirming based on difference from Firefox. *** Bug 21891 has been marked as a duplicate of this bug. *** This is about embedding SVG content in HTML. The mouse events seem to be off in that case. Created attachment 24690 [details]
A reduction which shows this is not a problem with raw SVGs
Created attachment 24692 [details]
simpler test case (hovering the blue square should turn it green)
Ok, the bug is that this code in RenderSVGContainer::nodeAtPoint if (!viewport().isEmpty() && style()->overflowX() == OHIDDEN && style()->overflowY() == OHIDDEN) { // Check if we need to do anything at all. IntRect overflowBox = overflowRect(false); overflowBox.move(_tx, _ty); AffineTransform ctm = RenderObject::absoluteTransform(); ctm.translate(viewport().x(), viewport().y()); double localX, localY; ctm.inverse().map(_x - _tx, _y - _ty, &localX, &localY); if (!overflowBox.contains((int)localX, (int)localY)) return false; } Is getting back an overflowBox with a height of -1. I'm not sure why, but something is wrong with the overflowBox calculation here it seems. The inner <svg> (RenderSVGViewportContainer) seems to be asking the outer <td> (its containing block) for its height, that's returning a length object 0, which turns into -1 based on this calculation: // We need to stop here, since we don't want to increase the height of the table // artificially. We're going to rely on this cell getting expanded to some new // height, and then when we lay out again we'll use the calculation below. if (isTableCell() && (h.isAuto() || h.isPercent())) return overrideSize() - (borderLeft() + borderRight() + paddingLeft() + paddingRight()); It seems that this "second pass" is not happening correctly for SVG content. Maybe hyatt or beth have some clue what is supposed to be going on here. I think the inner <svg> (RenderSVGViewportContainer) shouldn't be asking its containing block for height, or if it does, that "containing block" should be the outer <svg>. I think that's the part which is wrong here. We end up asking the containing block via: void RenderSVGViewportContainer::layout() which calls "calcBounds()": void RenderSVGContainer::calcBounds() { m_width = calcReplacedWidth(); m_height = calcReplacedHeight(); m_absoluteBounds = absoluteClippedOverflowRect(); } int RenderSVGContainer::calcReplacedHeight() const { switch (style()->height().type()) { case Fixed: return max(0, style()->height().value()); case Percent: { RenderBlock* cb = containingBlock(); return style()->height().calcValue(cb->availableHeight()); } default: return 0; } } It seems that containing block call is likely wrong. Created attachment 24693 [details]
Testcase using an actual table instead of display: table;
Might be considered a more consice test case - display: table; isn't necessary, this happens with a real table element as well.
I think is actually entirely an SVG problem. SVG deals with "viewport elements", unfortunately we don't really expose such in the render tree. The DOM tree can be asked for things like the nearestViewportElement() via SVGElement. SVGLength knows how to look for the closest viewport element and resolve relative to that, but width and length are not defined as SVGLength elements in this context, they're pulled from the RenderStyle as Length objects. So I think this is just yet another side-effect of having a separate SVGLength class, and not very well exposting the whole "viewport" system in the render tree. This looks to be fixed by http://trac.webkit.org/changeset/42960 bug 25432. We should still land these as test cases in LayoutTests. Created attachment 29873 [details]
Add a couple table hit tests
5 files changed, 95 insertions(+), 0 deletions(-)
Comment on attachment 29873 [details] Add a couple table hit tests > + if (window.eventSender) { > + layoutTestController.dumpAsText(); > + eventSender.mouseMoveTo(50, 50); > + eventSender.mouseDown(); > + eventSender.mouseUp(); I think using document.elementFromPoint() is preferable, because then your test works outside of DRT. Created attachment 29874 [details]
Add a couple table hit tests
5 files changed, 81 insertions(+), 0 deletions(-)
Committing to http://svn.webkit.org/repository/webkit/trunk ... M LayoutTests/ChangeLog A LayoutTests/svg/hittest/svg-inside-display-table-expected.txt A LayoutTests/svg/hittest/svg-inside-display-table.xhtml A LayoutTests/svg/hittest/svg-inside-table-expected.txt A LayoutTests/svg/hittest/svg-inside-table.xhtml Committed r42977 *** This bug has been marked as a duplicate of 25432 *** |