Diff
Modified: trunk/LayoutTests/ChangeLog (208629 => 208630)
--- trunk/LayoutTests/ChangeLog 2016-11-12 00:40:52 UTC (rev 208629)
+++ trunk/LayoutTests/ChangeLog 2016-11-12 00:48:46 UTC (rev 208630)
@@ -1,3 +1,21 @@
+2016-11-11 Ryosuke Niwa <rn...@webkit.org>
+
+ Hovering over a slotted Text node clears hover state
+ https://bugs.webkit.org/show_bug.cgi?id=164002
+ <rdar://problem/29040471>
+
+ Reviewed by Simon Fraser.
+
+ Added two reference tests for activating and hovering over a Text node.
+ The text node should activate :hover and :activate rules in the shadow tree respectively.
+
+ * fast/shadow-dom/activate-over-slotted-content-expected.html: Added.
+ * fast/shadow-dom/activate-over-slotted-content.html: Added.
+ * fast/shadow-dom/hover-over-slotted-content-expected.html: Added.
+ * fast/shadow-dom/hover-over-slotted-content.html: Added.
+ * platform/ios-simulator/TestExpectations: Skip the newly added tests since iOS doesn't
+ support :hover or :activate via mouse down.
+
2016-11-11 Brent Fulgham <bfulg...@apple.com>
Neutered ArrayBuffers are not properly serialized
Added: trunk/LayoutTests/fast/shadow-dom/activate-over-slotted-content-expected.html (0 => 208630)
--- trunk/LayoutTests/fast/shadow-dom/activate-over-slotted-content-expected.html (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/activate-over-slotted-content-expected.html 2016-11-12 00:48:46 UTC (rev 208630)
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<html>
+<body>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <div style="width: 100px; height: 100px; background: green;"></div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/shadow-dom/activate-over-slotted-content.html (0 => 208630)
--- trunk/LayoutTests/fast/shadow-dom/activate-over-slotted-content.html (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/activate-over-slotted-content.html 2016-11-12 00:48:46 UTC (rev 208630)
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+my-host {
+ display: block;
+ width: 100px;
+ height: 100px;
+ background: purple;
+}
+</style>
+</head>
+<body>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<my-host>Mouse down over this text</my-host>
+
+<script>
+const host = document.querySelector('my-host');
+host.attachShadow({mode: 'closed'}).innerHTML = `
+<a><span><slot></slot></span></a>
+<style>
+a {
+ display: block;
+ width: 80px;
+ height: 80px;
+ padding: 10px;
+ background: red;
+}
+a:active {
+ background: green;
+ color: green;
+}
+span {
+ background: green;
+}
+</style>`;
+
+if (window.eventSender) {
+ eventSender.mouseMoveTo(host.offsetLeft + 15, host.offsetTop + 15);
+ eventSender.mouseDown();
+}
+
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/shadow-dom/hover-over-slotted-content-expected.html (0 => 208630)
--- trunk/LayoutTests/fast/shadow-dom/hover-over-slotted-content-expected.html (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/hover-over-slotted-content-expected.html 2016-11-12 00:48:46 UTC (rev 208630)
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<html>
+<body>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <div style="width: 100px; height: 100px; background: green;"></div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/shadow-dom/hover-over-slotted-content.html (0 => 208630)
--- trunk/LayoutTests/fast/shadow-dom/hover-over-slotted-content.html (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/hover-over-slotted-content.html 2016-11-12 00:48:46 UTC (rev 208630)
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+my-host {
+ display: block;
+ width: 100px;
+ height: 100px;
+ background: purple;
+}
+</style>
+</head>
+<body>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<my-host>Hover over this text</my-host>
+
+<script>
+const host = document.querySelector('my-host');
+host.attachShadow({mode: 'closed'}).innerHTML = `
+<div id="container"><span><slot></slot></span></div>
+<style>
+#container {
+ width: 80px;
+ height: 80px;
+ padding: 10px;
+ background: red;
+}
+#container:hover {
+ background: green;
+ color: green;
+}
+span {
+ background: green;
+}
+</style>`;
+
+if (window.eventSender)
+ eventSender.mouseMoveTo(host.offsetLeft + 15, host.offsetTop + 15);
+
+</script>
+</body>
+</html>
Modified: trunk/LayoutTests/platform/ios-simulator/TestExpectations (208629 => 208630)
--- trunk/LayoutTests/platform/ios-simulator/TestExpectations 2016-11-12 00:40:52 UTC (rev 208629)
+++ trunk/LayoutTests/platform/ios-simulator/TestExpectations 2016-11-12 00:48:46 UTC (rev 208630)
@@ -341,6 +341,8 @@
webkit.org/b/155233 fast/events/max-tabindex-focus.html [ Skip ]
fast/shadow-dom/shadow-host-removal-crash.html [ Skip ]
fast/shadow-dom/input-element-in-shadow.html [ Skip ]
+fast/shadow-dom/activate-over-slotted-content.html [ Skip ]
+fast/shadow-dom/hover-over-slotted-content.html [ Skip ]
fast/events/keyboardevent-key.html [ Skip ]
fast/events/keyboardevent-code.html [ Skip ]
Modified: trunk/Source/WebCore/ChangeLog (208629 => 208630)
--- trunk/Source/WebCore/ChangeLog 2016-11-12 00:40:52 UTC (rev 208629)
+++ trunk/Source/WebCore/ChangeLog 2016-11-12 00:48:46 UTC (rev 208630)
@@ -1,3 +1,39 @@
+2016-11-11 Ryosuke Niwa <rn...@webkit.org>
+
+ Hovering over a slotted Text node clears hover state
+ https://bugs.webkit.org/show_bug.cgi?id=164002
+ <rdar://problem/29040471>
+
+ Reviewed by Simon Fraser.
+
+ The bug was caused by HitTestResult::innerElement returning the parent element of a Text node without
+ taking the shadow root or slots into account. For hit testing, we always want to use the "flat tree"
+ or "composed tree" (imprecisely but close enough in this case).
+
+ Fixed the bug by making HitTestResult::innerElement use parentNodeInComposedTree. Also renamed it to
+ HitTestResult::targetElement to be consistent with HitTestResult::targetNode.
+
+ Tests: fast/shadow-dom/activate-over-slotted-content.html
+ fast/shadow-dom/hover-over-slotted-content.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::prepareMouseEvent):
+ * html/MediaElementSession.cpp:
+ (WebCore::isMainContentForPurposesOfAutoplay):
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::eventMayStartDrag):
+ (WebCore::EventHandler::hitTestResultAtPoint):
+ (WebCore::EventHandler::handleWheelEvent):
+ (WebCore::EventHandler::sendContextMenuEventForKey):
+ (WebCore::EventHandler::hoverTimerFired):
+ (WebCore::EventHandler::handleDrag):
+ (WebCore::EventHandler::handleTouchEvent):
+ * rendering/HitTestResult.cpp:
+ (WebCore::HitTestResult::targetElement): Renamed from innerElement.
+ Now finds the parent element in the composed tree.
+ * rendering/HitTestResult.h:
+ (WebCore::HitTestResult::innerNode):
+
2016-11-11 Brent Fulgham <bfulg...@apple.com>
Unreviewed build fix after r208628
Modified: trunk/Source/WebCore/dom/Document.cpp (208629 => 208630)
--- trunk/Source/WebCore/dom/Document.cpp 2016-11-12 00:40:52 UTC (rev 208629)
+++ trunk/Source/WebCore/dom/Document.cpp 2016-11-12 00:48:46 UTC (rev 208630)
@@ -3277,7 +3277,7 @@
renderView()->hitTest(request, result);
if (!request.readOnly())
- updateHoverActiveState(request, result.innerElement());
+ updateHoverActiveState(request, result.targetElement());
return MouseEventWithHitTestResults(event, result);
}
Modified: trunk/Source/WebCore/html/MediaElementSession.cpp (208629 => 208630)
--- trunk/Source/WebCore/html/MediaElementSession.cpp 2016-11-12 00:40:52 UTC (rev 208629)
+++ trunk/Source/WebCore/html/MediaElementSession.cpp 2016-11-12 00:48:46 UTC (rev 208630)
@@ -676,7 +676,7 @@
// Elements which are obscured by other elements cannot be main content.
mainRenderView.hitTest(request, result);
result.setToNonUserAgentShadowAncestor();
- Element* hitElement = result.innerElement();
+ Element* hitElement = result.targetElement();
if (hitElement != &element)
return false;
Modified: trunk/Source/WebCore/page/EventHandler.cpp (208629 => 208630)
--- trunk/Source/WebCore/page/EventHandler.cpp 2016-11-12 00:40:52 UTC (rev 208629)
+++ trunk/Source/WebCore/page/EventHandler.cpp 2016-11-12 00:48:46 UTC (rev 208630)
@@ -892,7 +892,8 @@
HitTestResult result(view->windowToContents(event.position()));
renderView->hitTest(request, result);
DragState state;
- return result.innerElement() && page->dragController().draggableElement(&m_frame, result.innerElement(), result.roundedPointInInnerNodeFrame(), state);
+ Element* targetElement = result.targetElement();
+ return targetElement && page->dragController().draggableElement(&m_frame, targetElement, result.roundedPointInInnerNodeFrame(), state);
}
void EventHandler::updateSelectionForMouseDrag()
@@ -1159,7 +1160,7 @@
HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent);
renderView->hitTest(request, result);
if (!request.readOnly())
- m_frame.document()->updateHoverActiveState(request, result.innerElement());
+ m_frame.document()->updateHoverActiveState(request, result.targetElement());
if (request.disallowsUserAgentShadowContent())
result.setToNonUserAgentShadowAncestor();
@@ -2689,7 +2690,7 @@
HitTestResult result(view->windowToContents(event.position()));
renderView->hitTest(request, result);
- RefPtr<Element> element = result.innerElement();
+ RefPtr<Element> element = result.targetElement();
RefPtr<ContainerNode> scrollableContainer;
WeakPtr<ScrollableArea> scrollableArea;
bool isOverWidget = result.isOverWidget();
@@ -2875,7 +2876,7 @@
// Use the focused node as the target for hover and active.
HitTestResult result(position);
result.setInnerNode(targetNode);
- doc->updateHoverActiveState(HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent, result.innerElement());
+ doc->updateHoverActiveState(HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent, result.targetElement());
// The contextmenu event is a mouse event even when invoked using the keyboard.
// This is required for web compatibility.
@@ -2997,7 +2998,7 @@
HitTestRequest request(HitTestRequest::Move | HitTestRequest::DisallowUserAgentShadowContent);
HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
renderView->hitTest(request, result);
- m_frame.document()->updateHoverActiveState(request, result.innerElement());
+ m_frame.document()->updateHoverActiveState(request, result.targetElement());
}
}
}
@@ -3442,7 +3443,7 @@
HitTestResult result(m_mouseDownPos);
m_frame.contentRenderer()->hitTest(request, result);
if (m_frame.page())
- dragState().source = m_frame.page()->dragController().draggableElement(&m_frame, result.innerElement(), m_mouseDownPos, dragState());
+ dragState().source = m_frame.page()->dragController().draggableElement(&m_frame, result.targetElement(), m_mouseDownPos, dragState());
if (!dragState().source)
m_mouseDownMayStartDrag = false; // no element is draggable
@@ -3915,14 +3916,13 @@
} else
continue;
- // FIXME: This code should use Element* instead of Node*.
- Node* node = result.innerElement();
- ASSERT(node);
+ Element* element = result.targetElement();
+ ASSERT(element);
- if (node && InspectorInstrumentation::handleTouchEvent(m_frame, *node))
+ if (element && InspectorInstrumentation::handleTouchEvent(m_frame, *element))
return true;
- Document& doc = node->document();
+ Document& doc = element->document();
// Record the originating touch document even if it does not have a touch listener.
if (freshTouchEvents) {
m_originatingTouchPointDocument = &doc;
@@ -3930,8 +3930,8 @@
}
if (!doc.hasTouchEventHandlers())
continue;
- m_originatingTouchPointTargets.set(touchPointTargetKey, node);
- touchTarget = node;
+ m_originatingTouchPointTargets.set(touchPointTargetKey, element);
+ touchTarget = element;
} else if (pointState == PlatformTouchPoint::TouchReleased || pointState == PlatformTouchPoint::TouchCancelled) {
// No need to perform a hit-test since we only need to unset :hover and :active states.
if (!shouldGesturesTriggerActive() && allTouchReleased)
Modified: trunk/Source/WebCore/rendering/HitTestResult.cpp (208629 => 208630)
--- trunk/Source/WebCore/rendering/HitTestResult.cpp 2016-11-12 00:40:52 UTC (rev 208629)
+++ trunk/Source/WebCore/rendering/HitTestResult.cpp 2016-11-12 00:48:46 UTC (rev 208630)
@@ -764,14 +764,13 @@
return node;
}
-Element* HitTestResult::innerElement() const
+Element* HitTestResult::targetElement() const
{
- Node* node = m_innerNode.get();
- if (!node)
- return nullptr;
- if (is<Element>(*node))
- return downcast<Element>(node);
- return node->parentElement();
+ for (Node* node = m_innerNode.get(); node; node = node->parentInComposedTree()) {
+ if (is<Element>(*node))
+ return downcast<Element>(node);
+ }
+ return nullptr;
}
Element* HitTestResult::innerNonSharedElement() const
Modified: trunk/Source/WebCore/rendering/HitTestResult.h (208629 => 208630)
--- trunk/Source/WebCore/rendering/HitTestResult.h 2016-11-12 00:40:52 UTC (rev 208629)
+++ trunk/Source/WebCore/rendering/HitTestResult.h 2016-11-12 00:48:46 UTC (rev 208630)
@@ -59,7 +59,6 @@
WEBCORE_EXPORT HitTestResult& operator=(const HitTestResult&);
Node* innerNode() const { return m_innerNode.get(); }
- WEBCORE_EXPORT Element* innerElement() const;
Node* innerNonSharedNode() const { return m_innerNonSharedNode.get(); }
WEBCORE_EXPORT Element* innerNonSharedElement() const;
Element* URLElement() const { return m_innerURLElement.get(); }
@@ -151,6 +150,7 @@
Vector<String> dictationAlternatives() const;
Node* targetNode() const;
+ WEBCORE_EXPORT Element* targetElement() const;
private:
NodeSet& mutableRectBasedTestResult(); // See above.
Modified: trunk/Source/WebKit/mac/ChangeLog (208629 => 208630)
--- trunk/Source/WebKit/mac/ChangeLog 2016-11-12 00:40:52 UTC (rev 208629)
+++ trunk/Source/WebKit/mac/ChangeLog 2016-11-12 00:48:46 UTC (rev 208630)
@@ -1,3 +1,14 @@
+2016-11-11 Ryosuke Niwa <rn...@webkit.org>
+
+ Hovering over a slotted Text node clears hover state
+ https://bugs.webkit.org/show_bug.cgi?id=164002
+ <rdar://problem/29040471>
+
+ Reviewed by Simon Fraser.
+
+ * WebView/WebImmediateActionController.mm:
+ (-[WebImmediateActionController performHitTestAtPoint:]):
+
2016-11-11 Wenson Hsieh <wenson_hs...@apple.com>
[WK2] autocorrect and autocapitalize attributes do not work in contenteditable elements
Modified: trunk/Source/WebKit/mac/WebView/WebImmediateActionController.mm (208629 => 208630)
--- trunk/Source/WebKit/mac/WebView/WebImmediateActionController.mm 2016-11-12 00:40:52 UTC (rev 208629)
+++ trunk/Source/WebKit/mac/WebView/WebImmediateActionController.mm 2016-11-12 00:48:46 UTC (rev 208630)
@@ -150,7 +150,7 @@
_hitTestResult = coreFrame->eventHandler().hitTestResultAtPoint(IntPoint(viewPoint));
coreFrame->eventHandler().setImmediateActionStage(ImmediateActionStage::PerformedHitTest);
- if (Element* element = _hitTestResult.innerElement())
+ if (Element* element = _hitTestResult.targetElement())
_contentPreventsDefault = element->dispatchMouseForceWillBegin();
}
Modified: trunk/Source/WebKit2/ChangeLog (208629 => 208630)
--- trunk/Source/WebKit2/ChangeLog 2016-11-12 00:40:52 UTC (rev 208629)
+++ trunk/Source/WebKit2/ChangeLog 2016-11-12 00:48:46 UTC (rev 208630)
@@ -1,3 +1,16 @@
+2016-11-11 Ryosuke Niwa <rn...@webkit.org>
+
+ Hovering over a slotted Text node clears hover state
+ https://bugs.webkit.org/show_bug.cgi?id=164002
+ <rdar://problem/29040471>
+
+ Reviewed by Simon Fraser.
+
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::determinePrimarySnapshottedPlugIn):
+ * WebProcess/WebPage/mac/WebPageMac.mm:
+ (WebKit::WebPage::performImmediateActionHitTestAtLocation):
+
2016-11-11 Wenson Hsieh <wenson_hs...@apple.com>
[WK2] autocorrect and autocapitalize attributes do not work in contenteditable elements
Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (208629 => 208630)
--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp 2016-11-12 00:40:52 UTC (rev 208629)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp 2016-11-12 00:48:46 UTC (rev 208630)
@@ -5281,7 +5281,7 @@
HitTestResult hitTestResult(plugInRectRelativeToTopDocument.center());
mainRenderView.hitTest(request, hitTestResult);
- Element* element = hitTestResult.innerElement();
+ Element* element = hitTestResult.targetElement();
if (!element)
continue;
Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm (208629 => 208630)
--- trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm 2016-11-12 00:40:52 UTC (rev 208629)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm 2016-11-12 00:48:46 UTC (rev 208630)
@@ -1001,7 +1001,7 @@
HitTestResult hitTestResult = mainFrame.eventHandler().hitTestResultAtPoint(locationInContentCoordinates);
bool immediateActionHitTestPreventsDefault = false;
- Element* element = hitTestResult.innerElement();
+ Element* element = hitTestResult.targetElement();
mainFrame.eventHandler().setImmediateActionStage(ImmediateActionStage::PerformedHitTest);
if (element)