Bug 1009776 - part 1, [css-grid] Implement line-based placement. r=dholbert
This commit is contained in:
@@ -15,6 +15,107 @@
|
|||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search for the aNth occurrence of aName in aNameList (forward), starting at
|
||||||
|
* the zero-based aFromIndex, and return the 1-based index (line number).
|
||||||
|
* Also take into account there is an unconditional match at aImplicitLine
|
||||||
|
* unless it's zero.
|
||||||
|
* Return the last match if aNth occurrences can't be found, or zero if no
|
||||||
|
* occurrence can be found.
|
||||||
|
*/
|
||||||
|
static uint32_t
|
||||||
|
FindLine(const nsString& aName, uint32_t aNth,
|
||||||
|
uint32_t aFromIndex, uint32_t aImplicitLine,
|
||||||
|
const nsTArray<nsTArray<nsString>>& aNameList)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aNth != 0);
|
||||||
|
const uint32_t len = aNameList.Length();
|
||||||
|
uint32_t lastFound = 0;
|
||||||
|
uint32_t line;
|
||||||
|
uint32_t i = aFromIndex;
|
||||||
|
for (; i < len; i = line) {
|
||||||
|
line = i + 1;
|
||||||
|
if (line == aImplicitLine || aNameList[i].Contains(aName)) {
|
||||||
|
lastFound = line;
|
||||||
|
if (--aNth == 0) {
|
||||||
|
return lastFound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (aImplicitLine > i) {
|
||||||
|
// aImplicitLine is after the lines we searched above so it's last.
|
||||||
|
// (grid-template-areas has more tracks than grid-template-[rows|columns])
|
||||||
|
lastFound = aImplicitLine;
|
||||||
|
}
|
||||||
|
return lastFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see FindLine, this function does the same but searches in reverse.
|
||||||
|
*/
|
||||||
|
static uint32_t
|
||||||
|
RFindLine(const nsString& aName, uint32_t aNth,
|
||||||
|
uint32_t aFromIndex, uint32_t aImplicitLine,
|
||||||
|
const nsTArray<nsTArray<nsString>>& aNameList)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aNth != 0);
|
||||||
|
const uint32_t len = aNameList.Length();
|
||||||
|
uint32_t lastFound = 0;
|
||||||
|
// The implicit line may be beyond the length of aNameList so we match this
|
||||||
|
// line first if it's within the 0..aFromIndex range.
|
||||||
|
if (aImplicitLine > len && aImplicitLine < aFromIndex) {
|
||||||
|
lastFound = aImplicitLine;
|
||||||
|
if (--aNth == 0) {
|
||||||
|
return lastFound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint32_t i = aFromIndex == 0 ? len : std::min(aFromIndex, len);
|
||||||
|
for (; i; --i) {
|
||||||
|
if (i == aImplicitLine || aNameList[i - 1].Contains(aName)) {
|
||||||
|
lastFound = i;
|
||||||
|
if (--aNth == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lastFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
FindNamedLine(const nsString& aName, int32_t aNth,
|
||||||
|
uint32_t aFromIndex, uint32_t aImplicitLine,
|
||||||
|
const nsTArray<nsTArray<nsString>>& aNameList)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aNth != 0);
|
||||||
|
if (aNth > 0) {
|
||||||
|
return ::FindLine(aName, aNth, aFromIndex, aImplicitLine, aNameList);
|
||||||
|
}
|
||||||
|
return ::RFindLine(aName, -aNth, aFromIndex, aImplicitLine, aNameList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A convenience method to lookup a name in 'grid-template-areas'.
|
||||||
|
* @param aStyle the StylePosition() for the grid container
|
||||||
|
* @return null if not found
|
||||||
|
*/
|
||||||
|
static const css::GridNamedArea*
|
||||||
|
FindNamedArea(const nsSubstring& aName, const nsStylePosition* aStyle)
|
||||||
|
{
|
||||||
|
if (!aStyle->mGridTemplateAreas) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
const nsTArray<css::GridNamedArea>& areas =
|
||||||
|
aStyle->mGridTemplateAreas->mNamedAreas;
|
||||||
|
size_t len = areas.Length();
|
||||||
|
for (size_t i = 0; i < len; ++i) {
|
||||||
|
const css::GridNamedArea& area = areas[i];
|
||||||
|
if (area.mName == aName) {
|
||||||
|
return &area;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Return true if aString ends in aSuffix and has at least one character before
|
// Return true if aString ends in aSuffix and has at least one character before
|
||||||
// the suffix. Assign aIndex to where the suffix starts.
|
// the suffix. Assign aIndex to where the suffix starts.
|
||||||
static bool
|
static bool
|
||||||
@@ -116,6 +217,230 @@ nsGridContainerFrame::InitImplicitNamedAreas(const nsStylePosition* aStyle)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
nsGridContainerFrame::ResolveLine(
|
||||||
|
const nsStyleGridLine& aLine,
|
||||||
|
int32_t aNth,
|
||||||
|
uint32_t aFromIndex,
|
||||||
|
const nsTArray<nsTArray<nsString>>& aLineNameList,
|
||||||
|
uint32_t GridNamedArea::* aAreaStart,
|
||||||
|
uint32_t GridNamedArea::* aAreaEnd,
|
||||||
|
uint32_t aExplicitGridEnd,
|
||||||
|
LineRangeSide aSide,
|
||||||
|
const nsStylePosition* aStyle)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(!aLine.IsAuto());
|
||||||
|
uint32_t line = 0;
|
||||||
|
if (aLine.mLineName.IsEmpty()) {
|
||||||
|
MOZ_ASSERT(aNth != 0, "css-grid 9.2: <integer> must not be zero.");
|
||||||
|
line = std::max(int32_t(aFromIndex) + aNth, 1);
|
||||||
|
} else {
|
||||||
|
if (aNth == 0) {
|
||||||
|
// <integer> was omitted; treat it as 1.
|
||||||
|
aNth = 1;
|
||||||
|
}
|
||||||
|
bool isNameOnly = !aLine.mHasSpan && aLine.mInteger == 0;
|
||||||
|
if (isNameOnly) {
|
||||||
|
const GridNamedArea* area = ::FindNamedArea(aLine.mLineName, aStyle);
|
||||||
|
if (area || HasImplicitNamedArea(aLine.mLineName)) {
|
||||||
|
// The given name is a named area - look for explicit lines named
|
||||||
|
// <name>-start/-end depending on which side we're resolving.
|
||||||
|
// http://dev.w3.org/csswg/css-grid/#grid-placement-slot
|
||||||
|
uint32_t implicitLine = 0;
|
||||||
|
nsAutoString lineName(aLine.mLineName);
|
||||||
|
if (aSide == eLineRangeSideStart) {
|
||||||
|
lineName.AppendLiteral("-start");
|
||||||
|
implicitLine = area ? area->*aAreaStart : 0;
|
||||||
|
} else {
|
||||||
|
lineName.AppendLiteral("-end");
|
||||||
|
implicitLine = area ? area->*aAreaEnd : 0;
|
||||||
|
}
|
||||||
|
// XXX must Implicit Named Areas have all four lines?
|
||||||
|
// http://dev.w3.org/csswg/css-grid/#implicit-named-areas
|
||||||
|
line = ::FindNamedLine(lineName, aNth, aFromIndex, implicitLine,
|
||||||
|
aLineNameList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line == 0) {
|
||||||
|
// If mLineName ends in -start/-end, try the prefix as a named area.
|
||||||
|
uint32_t implicitLine = 0;
|
||||||
|
uint32_t index;
|
||||||
|
auto GridNamedArea::* areaEdge = aAreaStart;
|
||||||
|
bool found = ::IsNameWithStartSuffix(aLine.mLineName, &index);
|
||||||
|
if (!found) {
|
||||||
|
found = ::IsNameWithEndSuffix(aLine.mLineName, &index);
|
||||||
|
areaEdge = aAreaEnd;
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
const GridNamedArea* area =
|
||||||
|
::FindNamedArea(nsDependentSubstring(aLine.mLineName, 0, index),
|
||||||
|
aStyle);
|
||||||
|
if (area) {
|
||||||
|
implicitLine = area->*areaEdge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
line = ::FindNamedLine(aLine.mLineName, aNth, aFromIndex, implicitLine,
|
||||||
|
aLineNameList);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line == 0) {
|
||||||
|
// No line matching <custom-ident> exists.
|
||||||
|
if (aLine.mHasSpan) {
|
||||||
|
// http://dev.w3.org/csswg/css-grid/#grid-placement-span-int
|
||||||
|
// Treat 'span <custom-ident> N' as 'span N'.
|
||||||
|
line = std::max(int32_t(aFromIndex) + aNth, 1);
|
||||||
|
} else {
|
||||||
|
// http://dev.w3.org/csswg/css-grid/#grid-placement-int
|
||||||
|
// Treat '<custom-ident> N' as first/last line depending on N's sign.
|
||||||
|
// XXX this is wrong due to a spec change, see bug 1009776 comment 17.
|
||||||
|
// XXX we want to possibly expand the implicit grid here.
|
||||||
|
line = aNth >= 0 ? 1 : aExplicitGridEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// The only case which can result in "auto" (line == 0) is a plain
|
||||||
|
// <custom-ident> (without <integer> or 'span') which wasn't found.
|
||||||
|
MOZ_ASSERT(line != 0 || (!aLine.mHasSpan && aLine.mInteger == 0),
|
||||||
|
"Given a <integer> or 'span' the result should never be auto");
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsGridContainerFrame::LinePair
|
||||||
|
nsGridContainerFrame::ResolveLineRangeHelper(
|
||||||
|
const nsStyleGridLine& aStart,
|
||||||
|
const nsStyleGridLine& aEnd,
|
||||||
|
const nsTArray<nsTArray<nsString>>& aLineNameList,
|
||||||
|
uint32_t GridNamedArea::* aAreaStart,
|
||||||
|
uint32_t GridNamedArea::* aAreaEnd,
|
||||||
|
uint32_t aExplicitGridEnd,
|
||||||
|
const nsStylePosition* aStyle)
|
||||||
|
{
|
||||||
|
if (aStart.mHasSpan) {
|
||||||
|
if (aEnd.mHasSpan || aEnd.IsAuto()) {
|
||||||
|
// http://dev.w3.org/csswg/css-grid/#grid-placement-errors
|
||||||
|
if (aStart.mLineName.IsEmpty()) {
|
||||||
|
// span <integer> / span *
|
||||||
|
// span <integer> / auto
|
||||||
|
return LinePair(0, aStart.mInteger);
|
||||||
|
}
|
||||||
|
// span <custom-ident> / span *
|
||||||
|
// span <custom-ident> / auto
|
||||||
|
return LinePair(0, 1); // XXX subgrid explicit size instead of 1?
|
||||||
|
}
|
||||||
|
|
||||||
|
auto end = ResolveLine(aEnd, aEnd.mInteger, 0, aLineNameList, aAreaStart,
|
||||||
|
aAreaEnd, aExplicitGridEnd, eLineRangeSideEnd,
|
||||||
|
aStyle);
|
||||||
|
if (end == 0) {
|
||||||
|
// span * / <custom-ident> that can't be found
|
||||||
|
return LinePair(0, aStart.mInteger);
|
||||||
|
}
|
||||||
|
int32_t span = aStart.mInteger == 0 ? 1 : aStart.mInteger;
|
||||||
|
auto start = ResolveLine(aStart, -span, end, aLineNameList, aAreaStart,
|
||||||
|
aAreaEnd, aExplicitGridEnd, eLineRangeSideStart,
|
||||||
|
aStyle);
|
||||||
|
MOZ_ASSERT(start > 0, "A start span can never resolve to 'auto'");
|
||||||
|
return LinePair(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t start = 0;
|
||||||
|
if (!aStart.IsAuto()) {
|
||||||
|
start = ResolveLine(aStart, aStart.mInteger, 0, aLineNameList, aAreaStart,
|
||||||
|
aAreaEnd, aExplicitGridEnd, eLineRangeSideStart,
|
||||||
|
aStyle);
|
||||||
|
}
|
||||||
|
if (aEnd.IsAuto()) {
|
||||||
|
// * (except span) / auto
|
||||||
|
return LinePair(start, 1); // XXX subgrid explicit size instead of 1?
|
||||||
|
}
|
||||||
|
if (start == 0 && aEnd.mHasSpan) {
|
||||||
|
if (aEnd.mLineName.IsEmpty()) {
|
||||||
|
// auto (or not found <custom-ident>) / span <integer>
|
||||||
|
MOZ_ASSERT(aEnd.mInteger != 0);
|
||||||
|
return LinePair(0, aEnd.mInteger);
|
||||||
|
}
|
||||||
|
// http://dev.w3.org/csswg/css-grid/#grid-placement-errors
|
||||||
|
// auto (or not found <custom-ident>) / span <custom-ident>
|
||||||
|
return LinePair(0, 1); // XXX subgrid explicit size instead of 1?
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t from = aEnd.mHasSpan ? start : 0;
|
||||||
|
auto end = ResolveLine(aEnd, aEnd.mInteger, from, aLineNameList, aAreaStart,
|
||||||
|
aAreaEnd, aExplicitGridEnd, eLineRangeSideEnd, aStyle);
|
||||||
|
if (end == 0) {
|
||||||
|
// * (except span) / not found <custom-ident>
|
||||||
|
end = 1; // XXX subgrid explicit size instead of 1?
|
||||||
|
} else if (start == 0) {
|
||||||
|
// auto (or not found <custom-ident>) / definite line
|
||||||
|
start = std::max(1U, end - 1);
|
||||||
|
}
|
||||||
|
return LinePair(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsGridContainerFrame::LineRange
|
||||||
|
nsGridContainerFrame::ResolveLineRange(
|
||||||
|
const nsStyleGridLine& aStart,
|
||||||
|
const nsStyleGridLine& aEnd,
|
||||||
|
const nsTArray<nsTArray<nsString>>& aLineNameList,
|
||||||
|
uint32_t GridNamedArea::* aAreaStart,
|
||||||
|
uint32_t GridNamedArea::* aAreaEnd,
|
||||||
|
uint32_t aExplicitGridEnd,
|
||||||
|
const nsStylePosition* aStyle)
|
||||||
|
{
|
||||||
|
LinePair r = ResolveLineRangeHelper(aStart, aEnd, aLineNameList, aAreaStart,
|
||||||
|
aAreaEnd, aExplicitGridEnd, aStyle);
|
||||||
|
MOZ_ASSERT(r.second != 0);
|
||||||
|
|
||||||
|
// http://dev.w3.org/csswg/css-grid/#grid-placement-errors
|
||||||
|
if (r.second <= r.first) {
|
||||||
|
r.second = r.first + 1;
|
||||||
|
}
|
||||||
|
return LineRange(r.first, r.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsGridContainerFrame::GridArea
|
||||||
|
nsGridContainerFrame::PlaceDefinite(nsIFrame* aChild,
|
||||||
|
const nsStylePosition* aStyle)
|
||||||
|
{
|
||||||
|
const nsStylePosition* itemStyle = aChild->StylePosition();
|
||||||
|
return GridArea(
|
||||||
|
ResolveLineRange(itemStyle->mGridColumnStart, itemStyle->mGridColumnEnd,
|
||||||
|
aStyle->mGridTemplateColumns.mLineNameLists,
|
||||||
|
&GridNamedArea::mColumnStart, &GridNamedArea::mColumnEnd,
|
||||||
|
mExplicitGridColEnd, aStyle),
|
||||||
|
ResolveLineRange(itemStyle->mGridRowStart, itemStyle->mGridRowEnd,
|
||||||
|
aStyle->mGridTemplateRows.mLineNameLists,
|
||||||
|
&GridNamedArea::mRowStart, &GridNamedArea::mRowEnd,
|
||||||
|
mExplicitGridRowEnd, aStyle));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsGridContainerFrame::InitializeGridBounds(const nsStylePosition* aStyle)
|
||||||
|
{
|
||||||
|
// http://dev.w3.org/csswg/css-grid/#grid-definition
|
||||||
|
uint32_t colEnd = aStyle->mGridTemplateColumns.mLineNameLists.Length();
|
||||||
|
uint32_t rowEnd = aStyle->mGridTemplateRows.mLineNameLists.Length();
|
||||||
|
auto areas = aStyle->mGridTemplateAreas.get();
|
||||||
|
mExplicitGridColEnd = std::max(colEnd, areas ? areas->mNColumns + 1 : 1);
|
||||||
|
mExplicitGridRowEnd = std::max(rowEnd, areas ? areas->NRows() + 1 : 1);
|
||||||
|
mGridColEnd = mExplicitGridColEnd;
|
||||||
|
mGridRowEnd = mExplicitGridRowEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsGridContainerFrame::PlaceGridItems(const nsStylePosition* aStyle)
|
||||||
|
{
|
||||||
|
InitializeGridBounds(aStyle);
|
||||||
|
|
||||||
|
// http://dev.w3.org/csswg/css-grid/#auto-placement-algo
|
||||||
|
// Step 1, place definite positions.
|
||||||
|
for (nsFrameList::Enumerator e(PrincipalChildList()); !e.AtEnd(); e.Next()) {
|
||||||
|
nsIFrame* child = e.get();
|
||||||
|
PlaceDefinite(child, aStyle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
|
nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
|
||||||
nsHTMLReflowMetrics& aDesiredSize,
|
nsHTMLReflowMetrics& aDesiredSize,
|
||||||
@@ -148,6 +473,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
|
|
||||||
const nsStylePosition* stylePos = aReflowState.mStylePosition;
|
const nsStylePosition* stylePos = aReflowState.mStylePosition;
|
||||||
InitImplicitNamedAreas(stylePos);
|
InitImplicitNamedAreas(stylePos);
|
||||||
|
PlaceGridItems(stylePos);
|
||||||
|
|
||||||
aStatus = NS_FRAME_COMPLETE;
|
aStatus = NS_FRAME_COMPLETE;
|
||||||
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
||||||
|
|||||||
@@ -39,10 +39,136 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
typedef mozilla::css::GridNamedArea GridNamedArea;
|
||||||
friend nsContainerFrame* NS_NewGridContainerFrame(nsIPresShell* aPresShell,
|
friend nsContainerFrame* NS_NewGridContainerFrame(nsIPresShell* aPresShell,
|
||||||
nsStyleContext* aContext);
|
nsStyleContext* aContext);
|
||||||
explicit nsGridContainerFrame(nsStyleContext* aContext) : nsContainerFrame(aContext) {}
|
explicit nsGridContainerFrame(nsStyleContext* aContext) : nsContainerFrame(aContext) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A LineRange can be definite or auto - when it's definite it represents
|
||||||
|
* a consecutive set of tracks between a starting line and an ending line
|
||||||
|
* (both 1-based) where mStart < mEnd. Before it's definite it can also
|
||||||
|
* represent an auto position with a span, where mStart == 0 and mEnd is
|
||||||
|
* the (non-zero positive) span.
|
||||||
|
* In both states the invariant mEnd > mStart holds.
|
||||||
|
*/
|
||||||
|
struct LineRange {
|
||||||
|
LineRange(uint32_t aStart, uint32_t aEnd)
|
||||||
|
: mStart(aStart), mEnd(aEnd) {}
|
||||||
|
bool IsAuto() const { return mStart == 0; }
|
||||||
|
bool IsDefinite() const { return mStart != 0; }
|
||||||
|
uint32_t Extent() const { return mEnd - mStart; }
|
||||||
|
|
||||||
|
uint32_t mStart; // the start line, or zero for 'auto'
|
||||||
|
uint32_t mEnd; // the end line, or the span length for 'auto'
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A GridArea is the area in the grid for a grid item.
|
||||||
|
* The area is represented by two LineRanges, both of which can be auto
|
||||||
|
* (@see LineRange) in intermediate steps while the item is being placed.
|
||||||
|
* @see PlaceGridItems
|
||||||
|
*/
|
||||||
|
struct GridArea {
|
||||||
|
GridArea(const LineRange& aCols, const LineRange& aRows)
|
||||||
|
: mCols(aCols), mRows(aRows) {}
|
||||||
|
bool IsDefinite() const { return mCols.IsDefinite() && mRows.IsDefinite(); }
|
||||||
|
LineRange mCols;
|
||||||
|
LineRange mRows;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LineRangeSide {
|
||||||
|
eLineRangeSideStart, eLineRangeSideEnd
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Return a line number for (non-auto) aLine, per:
|
||||||
|
* http://dev.w3.org/csswg/css-grid/#line-placement
|
||||||
|
* @param aLine style data for the line (must be non-auto)
|
||||||
|
* @param aNth a number of lines to find from aFromIndex, negative if the
|
||||||
|
* search should be in reverse order. In the case aLine has
|
||||||
|
* a specified line name, it's permitted to pass in zero which
|
||||||
|
* will be treated as one.
|
||||||
|
* @param aFromIndex the zero-based index to start counting from
|
||||||
|
* @param aLineNameList the explicit named lines
|
||||||
|
* @param aAreaStart a pointer to GridNamedArea::mColumnStart/mRowStart
|
||||||
|
* @param aAreaEnd a pointer to GridNamedArea::mColumnEnd/mRowEnd
|
||||||
|
* @param aExplicitGridEnd the last line in the explicit grid
|
||||||
|
* @param aEdge indicates whether we are resolving a start or end line
|
||||||
|
* @param aStyle the StylePosition() for the grid container
|
||||||
|
* @return a definite line number, or zero in case aLine is a <custom-ident>
|
||||||
|
* that can't be found.
|
||||||
|
*/
|
||||||
|
uint32_t ResolveLine(const nsStyleGridLine& aLine,
|
||||||
|
int32_t aNth,
|
||||||
|
uint32_t aFromIndex,
|
||||||
|
const nsTArray<nsTArray<nsString>>& aLineNameList,
|
||||||
|
uint32_t GridNamedArea::* aAreaStart,
|
||||||
|
uint32_t GridNamedArea::* aAreaEnd,
|
||||||
|
uint32_t aExplicitGridEnd,
|
||||||
|
LineRangeSide aEdge,
|
||||||
|
const nsStylePosition* aStyle);
|
||||||
|
/**
|
||||||
|
* Return a LineRange based on the given style data. Non-auto lines
|
||||||
|
* are resolved to a definite line number per:
|
||||||
|
* http://dev.w3.org/csswg/css-grid/#line-placement
|
||||||
|
* with placement errors corrected per:
|
||||||
|
* http://dev.w3.org/csswg/css-grid/#grid-placement-errors
|
||||||
|
* @param aStyle the StylePosition() for the grid container
|
||||||
|
* @param aStart style data for the start line
|
||||||
|
* @param aEnd style data for the end line
|
||||||
|
* @param aLineNameList the explicit named lines
|
||||||
|
* @param aAreaStart a pointer to GridNamedArea::mColumnStart/mRowStart
|
||||||
|
* @param aAreaEnd a pointer to GridNamedArea::mColumnEnd/mRowEnd
|
||||||
|
* @param aExplicitGridEnd the last line in the explicit grid
|
||||||
|
* @param aStyle the StylePosition() for the grid container
|
||||||
|
*/
|
||||||
|
LineRange ResolveLineRange(const nsStyleGridLine& aStart,
|
||||||
|
const nsStyleGridLine& aEnd,
|
||||||
|
const nsTArray<nsTArray<nsString>>& aLineNameList,
|
||||||
|
uint32_t GridNamedArea::* aAreaStart,
|
||||||
|
uint32_t GridNamedArea::* aAreaEnd,
|
||||||
|
uint32_t aExplicitGridEnd,
|
||||||
|
const nsStylePosition* aStyle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a GridArea with non-auto lines placed at a definite line number
|
||||||
|
* and with placement errors resolved. One or both positions may still be
|
||||||
|
* 'auto'.
|
||||||
|
* @param aChild the grid item
|
||||||
|
* @param aStyle the StylePosition() for the grid container
|
||||||
|
*/
|
||||||
|
GridArea PlaceDefinite(nsIFrame* aChild, const nsStylePosition* aStyle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign definite grid areas for all child frames and place them into
|
||||||
|
* the grid.
|
||||||
|
* @param aStyle the StylePosition() for the grid container
|
||||||
|
*/
|
||||||
|
void PlaceGridItems(const nsStylePosition* aStyle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the end lines of the Explicit Grid (mExplicitGridCol[Row]End).
|
||||||
|
* This is determined by the larger of the number of rows/columns defined
|
||||||
|
* by 'grid-template-areas' and the 'grid-template-rows'/'-columns', plus one.
|
||||||
|
* Also initialize the Implicit Grid (mGridCol[Row]End) to the same values.
|
||||||
|
* @param aStyle the StylePosition() for the grid container
|
||||||
|
*/
|
||||||
|
void InitializeGridBounds(const nsStylePosition* aStyle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for ResolveLineRange.
|
||||||
|
* @see ResolveLineRange
|
||||||
|
* @return a pair (start,end) of lines
|
||||||
|
*/
|
||||||
|
typedef std::pair<uint32_t, uint32_t> LinePair;
|
||||||
|
LinePair ResolveLineRangeHelper(const nsStyleGridLine& aStart,
|
||||||
|
const nsStyleGridLine& aEnd,
|
||||||
|
const nsTArray<nsTArray<nsString>>& aLineNameList,
|
||||||
|
uint32_t GridNamedArea::* aAreaStart,
|
||||||
|
uint32_t GridNamedArea::* aAreaEnd,
|
||||||
|
uint32_t aExplicitGridEnd,
|
||||||
|
const nsStylePosition* aStyle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* XXX temporary - move the ImplicitNamedAreas stuff to the style system.
|
* XXX temporary - move the ImplicitNamedAreas stuff to the style system.
|
||||||
* The implicit area names that come from x-start .. x-end lines in
|
* The implicit area names that come from x-start .. x-end lines in
|
||||||
@@ -57,10 +183,29 @@ protected:
|
|||||||
ImplicitNamedAreas* GetImplicitNamedAreas() const {
|
ImplicitNamedAreas* GetImplicitNamedAreas() const {
|
||||||
return static_cast<ImplicitNamedAreas*>(Properties().Get(ImplicitNamedAreasProperty()));
|
return static_cast<ImplicitNamedAreas*>(Properties().Get(ImplicitNamedAreasProperty()));
|
||||||
}
|
}
|
||||||
|
bool HasImplicitNamedArea(const nsString& aName) const {
|
||||||
|
ImplicitNamedAreas* areas = GetImplicitNamedAreas();
|
||||||
|
return areas && areas->Contains(aName);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void SanityCheckAnonymousGridItems() const;
|
void SanityCheckAnonymousGridItems() const;
|
||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The last column grid line (1-based) in the explicit grid.
|
||||||
|
* (i.e. the number of explicit columns + 1)
|
||||||
|
*/
|
||||||
|
uint32_t mExplicitGridColEnd;
|
||||||
|
/**
|
||||||
|
* The last row grid line (1-based) in the explicit grid.
|
||||||
|
* (i.e. the number of explicit rows + 1)
|
||||||
|
*/
|
||||||
|
uint32_t mExplicitGridRowEnd;
|
||||||
|
// Same for the implicit grid
|
||||||
|
uint32_t mGridColEnd; // always >= mExplicitGridColEnd
|
||||||
|
uint32_t mGridRowEnd; // always >= mExplicitGridRowEnd
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* nsGridContainerFrame_h___ */
|
#endif /* nsGridContainerFrame_h___ */
|
||||||
|
|||||||
Reference in New Issue
Block a user