mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 01:48:05 +00:00
Bug 796452. Add mozpasspointerevents attribute for IFRAMEs in chrome windows. r=mats
This commit is contained in:
parent
1c668a4d54
commit
9a45cc9183
@ -570,6 +570,7 @@ GK_ATOM(mousethrough, "mousethrough")
|
||||
GK_ATOM(mouseup, "mouseup")
|
||||
GK_ATOM(mozfullscreenchange, "mozfullscreenchange")
|
||||
GK_ATOM(mozfullscreenerror, "mozfullscreenerror")
|
||||
GK_ATOM(mozpasspointerevents, "mozpasspointerevents")
|
||||
GK_ATOM(mozpointerlockchange, "mozpointerlockchange")
|
||||
GK_ATOM(mozpointerlockerror, "mozpointerlockerror")
|
||||
GK_ATOM(moz_opaque, "moz-opaque")
|
||||
|
@ -1277,7 +1277,7 @@ void nsDisplayList::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
nsIFrame *f = outFrames.ElementAt(j);
|
||||
// Handle the XUL 'mousethrough' feature and 'pointer-events'.
|
||||
if (!GetMouseThrough(f) &&
|
||||
f->GetStyleVisibility()->mPointerEvents != NS_STYLE_POINTER_EVENTS_NONE) {
|
||||
f->GetStyleVisibility()->GetEffectivePointerEvents(f) != NS_STYLE_POINTER_EVENTS_NONE) {
|
||||
writeFrames->AppendElement(f);
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ MOCHITEST_CHROME_FILES = \
|
||||
test_dialog_with_positioning.html \
|
||||
dialog_with_positioning_window.xul \
|
||||
blue-32x32.png \
|
||||
test_passpointerevents.html \
|
||||
passpointerevents_window.html \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_DEBUG
|
||||
|
27
layout/base/tests/chrome/passpointerevents_window.html
Normal file
27
layout/base/tests/chrome/passpointerevents_window.html
Normal file
@ -0,0 +1,27 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test that mozpasspointerevents works</title>
|
||||
</head>
|
||||
<body onload="startTest()">
|
||||
<iframe id="f" style="border:none; width:200px; height:200px; pointer-events:none" mozpasspointerevents
|
||||
src="data:text/html,<html style='pointer-events:none'><div style='margin:100px; width:100px; height:100px; background:yellow; pointer-events:auto'>">
|
||||
</iframe>
|
||||
|
||||
<script type="application/javascript">
|
||||
var SimpleTest = window.opener.SimpleTest;
|
||||
var is = window.opener.is;
|
||||
|
||||
function startTest() {
|
||||
var f = document.getElementById("f");
|
||||
var fRect = f.getBoundingClientRect();
|
||||
var e1 = document.elementFromPoint(fRect.left + 10, fRect.top + 10);
|
||||
is(e1, document.body, "check point in transparent region of the iframe");
|
||||
var e2 = document.elementFromPoint(fRect.left + 110, fRect.top + 110);
|
||||
is(e2, f, "check point in opaque region of the iframe");
|
||||
window.close();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
21
layout/base/tests/chrome/test_passpointerevents.html
Normal file
21
layout/base/tests/chrome/test_passpointerevents.html
Normal file
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test that mozpasspointerevents works</title>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var root = getRootDirectory(window.location.href);
|
||||
window.openDialog(root + "passpointerevents_window.html", "passpointerevents",
|
||||
"chrome,width=400,height=400");
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -235,6 +235,23 @@ nsSubDocumentFrame::GetSubdocumentRootFrame()
|
||||
return subdocView ? subdocView->GetFrame() : nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
nsSubDocumentFrame::PassPointerEventsToChildren()
|
||||
{
|
||||
if (GetStyleVisibility()->mPointerEvents != NS_STYLE_POINTER_EVENTS_NONE) {
|
||||
return true;
|
||||
}
|
||||
// Limit use of mozpasspointerevents to chrome documents, because
|
||||
// this could be used by the parent document to discover which parts of the
|
||||
// subdocument are transparent to events (if subdocument uses
|
||||
// pointer-events:none on its root element, which is admittedly unlikely)
|
||||
if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::mozpasspointerevents) &&
|
||||
PresContext()->IsChrome()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsRect& aDirtyRect,
|
||||
@ -243,8 +260,9 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
if (!IsVisibleForPainting(aBuilder))
|
||||
return NS_OK;
|
||||
|
||||
if (aBuilder->IsForEventDelivery() &&
|
||||
GetStyleVisibility()->mPointerEvents == NS_STYLE_POINTER_EVENTS_NONE)
|
||||
// If mozpasspointerevents is set, then we should allow subdocument content
|
||||
// to handle events even if we're pointer-events:none.
|
||||
if (aBuilder->IsForEventDelivery() && !PassPointerEventsToChildren())
|
||||
return NS_OK;
|
||||
|
||||
nsresult rv = DisplayBorderBackgroundOutline(aBuilder, aLists);
|
||||
|
@ -136,6 +136,12 @@ protected:
|
||||
*/
|
||||
nsIFrame* ObtainIntrinsicSizeFrame();
|
||||
|
||||
/**
|
||||
* Return true if pointer event hit-testing should be allowed to target
|
||||
* content in the subdocument.
|
||||
*/
|
||||
bool PassPointerEventsToChildren();
|
||||
|
||||
nsRefPtr<nsFrameLoader> mFrameLoader;
|
||||
nsIView* mInnerView;
|
||||
bool mIsInline;
|
||||
|
@ -1375,7 +1375,7 @@ struct nsStyleVisibility {
|
||||
}
|
||||
|
||||
uint8_t mDirection; // [inherited] see nsStyleConsts.h NS_STYLE_DIRECTION_*
|
||||
uint8_t mVisible; // [inherited]
|
||||
uint8_t mVisible; // [inherited]
|
||||
uint8_t mPointerEvents; // [inherited] see nsStyleConsts.h
|
||||
|
||||
bool IsVisible() const {
|
||||
@ -1386,6 +1386,8 @@ struct nsStyleVisibility {
|
||||
return ((mVisible == NS_STYLE_VISIBILITY_VISIBLE) ||
|
||||
(mVisible == NS_STYLE_VISIBILITY_COLLAPSE));
|
||||
}
|
||||
|
||||
inline uint8_t GetEffectivePointerEvents(nsIFrame* aFrame) const;
|
||||
};
|
||||
|
||||
struct nsTimingFunction {
|
||||
|
@ -142,4 +142,20 @@ nsStyleDisplay::IsAbsolutelyPositioned(const nsIFrame* aFrame) const
|
||||
return IsAbsolutelyPositionedStyle() && !aFrame->IsSVGText();
|
||||
}
|
||||
|
||||
uint8_t
|
||||
nsStyleVisibility::GetEffectivePointerEvents(nsIFrame* aFrame) const
|
||||
{
|
||||
if (aFrame->GetContent() && !aFrame->GetContent()->GetParent()) {
|
||||
// The root element has a cluster of frames associated with it
|
||||
// (root scroll frame, canvas frame, the actual primary frame). Make
|
||||
// those take their pointer-events value from the root element's primary
|
||||
// frame.
|
||||
nsIFrame* f = aFrame->GetContent()->GetPrimaryFrame();
|
||||
if (f) {
|
||||
return f->GetStyleVisibility()->mPointerEvents;
|
||||
}
|
||||
}
|
||||
return mPointerEvents;
|
||||
}
|
||||
|
||||
#endif /* !defined(nsStyleStructInlines_h_) */
|
||||
|
Loading…
Reference in New Issue
Block a user