Bug 877890: In CSS flexbox and XUL box model, sort placeholders using their out-of-flow frame's order/ordinal value. r=bz

This commit is contained in:
Daniel Holbert 2013-05-31 22:14:03 -07:00
parent dd8f55a449
commit ee5c8dc647
8 changed files with 146 additions and 7 deletions

View File

@ -12,6 +12,7 @@
#include "nsCSSAnonBoxes.h"
#include "nsDisplayList.h"
#include "nsLayoutUtils.h"
#include "nsPlaceholderFrame.h"
#include "nsPresContext.h"
#include "nsStyleContext.h"
#include "prlog.h"
@ -538,11 +539,17 @@ IsOrderLEQWithDOMFallback(nsIFrame* aFrame1,
return true;
}
int32_t order1 = aFrame1->StylePosition()->mOrder;
int32_t order2 = aFrame2->StylePosition()->mOrder;
// If we've got a placeholder frame, use its out-of-flow frame's 'order' val.
{
nsIFrame* aRealFrame1 = nsPlaceholderFrame::GetRealFrameFor(aFrame1);
nsIFrame* aRealFrame2 = nsPlaceholderFrame::GetRealFrameFor(aFrame2);
if (order1 != order2) {
return order1 < order2;
int32_t order1 = aRealFrame1->StylePosition()->mOrder;
int32_t order2 = aRealFrame2->StylePosition()->mOrder;
if (order1 != order2) {
return order1 < order2;
}
}
// The "order" values are equal, so we need to fall back on DOM comparison.
@ -603,8 +610,12 @@ IsOrderLEQ(nsIFrame* aFrame1,
MOZ_ASSERT(aFrame1->IsFlexItem() && aFrame2->IsFlexItem(),
"this method only intended for comparing flex items");
int32_t order1 = aFrame1->StylePosition()->mOrder;
int32_t order2 = aFrame2->StylePosition()->mOrder;
// If we've got a placeholder frame, use its out-of-flow frame's 'order' val.
nsIFrame* aRealFrame1 = nsPlaceholderFrame::GetRealFrameFor(aFrame1);
nsIFrame* aRealFrame2 = nsPlaceholderFrame::GetRealFrameFor(aFrame2);
int32_t order1 = aRealFrame1->StylePosition()->mOrder;
int32_t order2 = aRealFrame2->StylePosition()->mOrder;
return order1 <= order2;
}

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<style>
#container { display: -moz-box; }
#highOrdinal {
background: lime;
height: 100px; width: 100px;
}
</style>
</head>
<body>
<div id="container">
<div id="highOrdinal"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!-- Testcase for whether we honor "-moz-box-ordinal-group" on
absolutely-positioned elements within a -moz-box. Specifically,
we test whether it affects their paint-order (as it should, since
it reorders the frame tree).
-->
<html>
<head>
<style>
#container { display: -moz-box; }
#lowOrdinal {
position: absolute;
-moz-box-ordinal-group: 5;
background: red;
height: 100px; width: 100px;
}
#highOrdinal {
position: absolute;
-moz-box-ordinal-group: 10;
background: lime;
height: 100px; width: 100px;
}
#noOrdinal {
position: absolute;
background: orange;
height: 100px; width: 100px;
}
</style>
</head>
<body>
<div id="container">
<div id="highOrdinal"></div>
<div id="lowOrdinal"></div>
<div id="noOrdinal"></div>
</div>
</body>
</html>

View File

@ -1,3 +1,4 @@
== box-ordinal-with-out-of-flow-1.html box-ordinal-with-out-of-flow-1-ref.html
== dynamic-1-remove-to-none-grouped.xul dynamic-1-ref.xul
== dynamic-1-add-to-one-grouped.xul dynamic-1-ref.xul
== dynamic-1-remove-to-one-grouped-1.xul dynamic-1-ref.xul

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<style>
#container { display: flex; }
#highOrdinal {
background: lime;
height: 100px; width: 100px;
}
</style>
</head>
<body>
<div id="container">
<div id="highOrdinal"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,39 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!-- Testcase for whether we honor "order" on absolutely-positioned elements
within a flex container. Specifically, we test whether it affects their
paint-order (as it should, since it reorders the frame tree). -->
<html>
<head>
<style>
#container { display: flex; }
#lowOrdinal {
position: absolute;
order: 5;
background: red;
height: 100px; width: 100px;
}
#highOrdinal {
position: absolute;
order: 10;
background: lime;
height: 100px; width: 100px;
}
#noOrdinal {
position: absolute;
background: orange;
height: 100px; width: 100px;
}
</style>
</head>
<body>
<div id="container">
<div id="highOrdinal"></div>
<div id="lowOrdinal"></div>
<div id="noOrdinal"></div>
</div>
</body>
</html>

View File

@ -138,6 +138,7 @@ fails == flexbox-minSize-vert-1.xhtml flexbox-minSize-vert-1-ref.xhtml # bug 85
# Tests for the order in which we paint flex items
== flexbox-paint-ordering-1.xhtml flexbox-paint-ordering-1-ref.xhtml
== flexbox-paint-ordering-2.xhtml flexbox-paint-ordering-2-ref.xhtml
fails == flexbox-paint-ordering-3.html flexbox-paint-ordering-3-ref.html # bug 874718
# Tests for handling of absolutely/fixed/relatively-positioned flex items.
== flexbox-position-absolute-1.xhtml flexbox-position-absolute-1-ref.xhtml

View File

@ -35,6 +35,7 @@
#include "nsBoxFrame.h"
#include "mozilla/dom/Touch.h"
#include "nsStyleContext.h"
#include "nsPlaceholderFrame.h"
#include "nsPresContext.h"
#include "nsCOMPtr.h"
#include "nsINameSpaceManager.h"
@ -1889,7 +1890,10 @@ bool
IsBoxOrdinalLEQ(nsIFrame* aFrame1,
nsIFrame* aFrame2)
{
return aFrame1->GetOrdinal() <= aFrame2->GetOrdinal();
// If we've got a placeholder frame, use its out-of-flow frame's ordinal val.
nsIFrame* aRealFrame1 = nsPlaceholderFrame::GetRealFrameFor(aFrame1);
nsIFrame* aRealFrame2 = nsPlaceholderFrame::GetRealFrameFor(aFrame2);
return aRealFrame1->GetOrdinal() <= aRealFrame2->GetOrdinal();
}
void