mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Bug 339548. Part 14: hide windowed plugins in CSS transforms and SVG foreignObject contexts; we can't display them properly, so let's not display them at all. r=dbaron
This commit is contained in:
parent
933f110f1a
commit
0ed9805957
@ -71,7 +71,8 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
|
||||
mEventDelivery(aIsForEvents),
|
||||
mIsAtRootOfPseudoStackingContext(PR_FALSE),
|
||||
mPaintAllFrames(PR_FALSE),
|
||||
mAccurateVisibleRegions(PR_FALSE) {
|
||||
mAccurateVisibleRegions(PR_FALSE),
|
||||
mInTransform(PR_FALSE) {
|
||||
PL_InitArenaPool(&mPool, "displayListArena", 1024, sizeof(void*)-1);
|
||||
|
||||
nsPresContext* pc = aReferenceFrame->PresContext();
|
||||
|
@ -263,7 +263,19 @@ public:
|
||||
* Notify the display list builder that we're leaving a presshell.
|
||||
*/
|
||||
void LeavePresShell(nsIFrame* aReferenceFrame, const nsRect& aDirtyRect);
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if we're currently building a display list that's
|
||||
* directly or indirectly under an nsDisplayTransform or SVG
|
||||
* foreignObject.
|
||||
*/
|
||||
PRBool IsInTransform() { return mInTransform; }
|
||||
/**
|
||||
* Indicate whether or not we're directly or indirectly under and
|
||||
* nsDisplayTransform or SVG foreignObject.
|
||||
*/
|
||||
void SetInTransform(PRBool aInTransform) { mInTransform = aInTransform; }
|
||||
|
||||
/**
|
||||
* Mark aFrames and its (next) siblings to be displayed if they
|
||||
* intersect aDirtyRect (which is relative to aDirtyFrame). If the
|
||||
@ -301,6 +313,25 @@ public:
|
||||
nsDisplayListBuilder* mBuilder;
|
||||
PRPackedBool mOldValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* A helper class to temporarily set the value of mInTransform.
|
||||
*/
|
||||
class AutoInTransformSetter;
|
||||
friend class AutoInTransformSetter;
|
||||
class AutoInTransformSetter {
|
||||
public:
|
||||
AutoInTransformSetter(nsDisplayListBuilder* aBuilder, PRBool aInTransform)
|
||||
: mBuilder(aBuilder), mOldValue(aBuilder->mInTransform) {
|
||||
aBuilder->mInTransform = aInTransform;
|
||||
}
|
||||
~AutoInTransformSetter() {
|
||||
mBuilder->mInTransform = mOldValue;
|
||||
}
|
||||
private:
|
||||
nsDisplayListBuilder* mBuilder;
|
||||
PRPackedBool mOldValue;
|
||||
};
|
||||
|
||||
// Helpers for tables
|
||||
nsDisplayTableItem* GetCurrentTableItem() { return mCurrentTableItem; }
|
||||
@ -337,6 +368,9 @@ private:
|
||||
PRPackedBool mIsAtRootOfPseudoStackingContext;
|
||||
PRPackedBool mPaintAllFrames;
|
||||
PRPackedBool mAccurateVisibleRegions;
|
||||
// True when we're building a display list that's directly or indirectly
|
||||
// under an nsDisplayTransform
|
||||
PRPackedBool mInTransform;
|
||||
};
|
||||
|
||||
class nsDisplayItem;
|
||||
|
@ -1048,14 +1048,17 @@ GetNextPage(nsIFrame* aPageContentFrame)
|
||||
|
||||
nsresult
|
||||
nsLayoutUtils::PaintFrame(nsIRenderingContext* aRenderingContext, nsIFrame* aFrame,
|
||||
const nsRegion& aDirtyRegion, nscolor aBackstop)
|
||||
const nsRegion& aDirtyRegion, nscolor aBackstop,
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
nsAutoDisableGetUsedXAssertions disableAssert;
|
||||
|
||||
nsDisplayListBuilder builder(aFrame, PR_FALSE, PR_TRUE);
|
||||
nsDisplayList list;
|
||||
nsRect dirtyRect = aDirtyRegion.GetBounds();
|
||||
|
||||
if (aFlags & PAINT_IN_TRANSFORM) {
|
||||
builder.SetInTransform(PR_TRUE);
|
||||
}
|
||||
nsresult rv;
|
||||
|
||||
builder.EnterPresShell(aFrame, dirtyRect);
|
||||
|
@ -476,6 +476,7 @@ public:
|
||||
static nsRect RoundGfxRectToAppRect(const gfxRect &aRect, float aFactor);
|
||||
|
||||
|
||||
enum { PAINT_IN_TRANSFORM = 0x01 };
|
||||
/**
|
||||
* Given aFrame, the root frame of a stacking context, paint it and its
|
||||
* descendants to aRenderingContext.
|
||||
@ -486,9 +487,12 @@ public:
|
||||
* of aFrame
|
||||
* @param aBackstop paint the dirty area with this color before drawing
|
||||
* the actual content; pass NS_RGBA(0,0,0,0) to draw no background
|
||||
* @param aFlags if PAINT_IN_TRANSFORM is set, then we assume
|
||||
* this is inside a transform or SVG foreignObject.
|
||||
*/
|
||||
static nsresult PaintFrame(nsIRenderingContext* aRenderingContext, nsIFrame* aFrame,
|
||||
const nsRegion& aDirtyRegion, nscolor aBackstop);
|
||||
const nsRegion& aDirtyRegion, nscolor aBackstop,
|
||||
PRUint32 aFlags = 0);
|
||||
|
||||
/**
|
||||
* @param aRootFrame the root frame of the tree to be displayed
|
||||
|
@ -1253,13 +1253,16 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||
ApplyAbsPosClipping(aBuilder, disp, this, &absPosClip);
|
||||
nsRect dirtyRect = aDirtyRect;
|
||||
|
||||
PRBool inTransform = aBuilder->IsInTransform();
|
||||
/* If we're being transformed, we need to invert the matrix transform so that we don't
|
||||
* grab points in the wrong coordinate system!
|
||||
*/
|
||||
if ((mState & NS_FRAME_MAY_BE_TRANSFORMED_OR_HAVE_RENDERING_OBSERVERS) &&
|
||||
disp->HasTransform())
|
||||
disp->HasTransform()) {
|
||||
dirtyRect = nsDisplayTransform::UntransformRect(dirtyRect, this, nsPoint(0, 0));
|
||||
|
||||
inTransform = PR_TRUE;
|
||||
}
|
||||
|
||||
if (applyAbsPosClipping) {
|
||||
dirtyRect.IntersectRect(dirtyRect,
|
||||
absPosClip - aBuilder->ToReferenceFrame(this));
|
||||
@ -1277,6 +1280,8 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||
nsresult rv;
|
||||
{
|
||||
nsDisplayListBuilder::AutoIsRootSetter rootSetter(aBuilder, PR_TRUE);
|
||||
nsDisplayListBuilder::AutoInTransformSetter
|
||||
inTransformSetter(aBuilder, inTransform);
|
||||
rv = BuildDisplayList(aBuilder, dirtyRect, set);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -1233,12 +1233,19 @@ nsObjectFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
return NS_OK;
|
||||
|
||||
DO_GLOBAL_REFLOW_COUNT_DSP("nsObjectFrame");
|
||||
|
||||
|
||||
#ifndef XP_MACOSX
|
||||
if (mWidget && aBuilder->IsInTransform()) {
|
||||
// Windowed plugins should not be rendered inside a transform.
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
// determine if we are printing
|
||||
if (type == nsPresContext::eContext_Print)
|
||||
return aLists.Content()->AppendNewToTop(new (aBuilder)
|
||||
nsDisplayGeneric(this, PaintPrintPlugin, "PrintPlugin"));
|
||||
|
||||
|
||||
return aLists.Content()->AppendNewToTop(new (aBuilder)
|
||||
nsDisplayPlugin(this));
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ _TEST_FILES = \
|
||||
frame_selection_underline.css \
|
||||
plugin_clipping_helper.xhtml \
|
||||
plugin_clipping_helper2.xhtml \
|
||||
plugin_clipping_helper_transformed.xhtml \
|
||||
plugin_clipping_lib.js \
|
||||
test_backspace_delete.xul \
|
||||
test_bug263683.html \
|
||||
@ -86,6 +87,7 @@ _TEST_FILES = \
|
||||
test_movement_by_words.html \
|
||||
test_plugin_clipping.xhtml \
|
||||
test_plugin_clipping2.xhtml \
|
||||
test_plugin_clipping_transformed.xhtml \
|
||||
test_plugin_position.xhtml \
|
||||
test_selection_underline.html \
|
||||
$(NULL)
|
||||
|
@ -40,7 +40,6 @@ function runTests() {
|
||||
var zbox = document.getElementById("zbox");
|
||||
var sbox = document.getElementById("sbox");
|
||||
var p1 = document.getElementById("p1");
|
||||
var d1 = document.getElementById("d1");
|
||||
var d2 = document.getElementById("d2");
|
||||
|
||||
checkClipRegion("p1", [[0, 0, 200, 100]]);
|
||||
|
42
layout/generic/test/plugin_clipping_helper_transformed.xhtml
Normal file
42
layout/generic/test/plugin_clipping_helper_transformed.xhtml
Normal file
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" title="Test Plugin Clipping: Plugins in Transforms">
|
||||
<head>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<style>
|
||||
embed { width:300px; height:200px; display:block; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Use a XUL element here so we can get its boxObject.screenX/Y -->
|
||||
<hbox style="height:10px; position:absolute; left:0; top:0; z-index:-100;" id="h1"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<hbox style="width:100px;"></hbox><hbox id="h2"/>
|
||||
</hbox>
|
||||
|
||||
<div style="width:200px; position:absolute; top:0; left:0; -moz-transform:rotate(90deg)">
|
||||
<embed id="p1" type="application/x-test" wmode="window"></embed>
|
||||
</div>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="width:200px; position:absolute; top:200px; left:0;">
|
||||
<foreignObject width="200" height="200">
|
||||
<embed xmlns="http://www.w3.org/1999/xhtml" id="p2" type="application/x-test" wmode="window"></embed>
|
||||
</foreignObject>
|
||||
</svg>
|
||||
|
||||
<script src="plugin_clipping_lib.js"></script>
|
||||
<script class="testbody" type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
function runTests() {
|
||||
// p1 and p2 are both in a transformed context so they should be hidden.
|
||||
checkClipRegionNoBounds("p1", []);
|
||||
checkClipRegionNoBounds("p2", []);
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
22
layout/generic/test/test_plugin_clipping_transformed.xhtml
Normal file
22
layout/generic/test/test_plugin_clipping_transformed.xhtml
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" title="Test Plugin Clipping: Plugins in Transforms">
|
||||
<head>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
<![CDATA[
|
||||
if (navigator.platform.indexOf("Mac") == 0) {
|
||||
todo(false, "Mac plugins do not run in windowed mode");
|
||||
} else {
|
||||
window.open("plugin_clipping_helper_transformed.xhtml", "", "width=620,height=320");
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -237,7 +237,8 @@ nsSVGForeignObjectFrame::PaintSVG(nsSVGRenderState *aContext,
|
||||
gfx->Multiply(matrix);
|
||||
|
||||
nsresult rv = nsLayoutUtils::PaintFrame(ctx, kid, nsRegion(kid->GetRect()),
|
||||
NS_RGBA(0,0,0,0));
|
||||
NS_RGBA(0,0,0,0),
|
||||
nsLayoutUtils::PAINT_IN_TRANSFORM);
|
||||
|
||||
gfx->Restore();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user