From 3d92babadf92126eee69bb2612398b615510b647 Mon Sep 17 00:00:00 2001 From: Brad Werth Date: Tue, 23 Aug 2016 13:34:51 -0700 Subject: [PATCH] Bug 1289200 - Adds GridAreas to grid css dev tools API. r=bz, mats --- dom/grid/Grid.cpp | 43 ++++++- dom/grid/Grid.h | 3 + dom/grid/GridArea.cpp | 86 +++++++++++++ dom/grid/GridArea.h | 63 +++++++++ dom/grid/GridLine.cpp | 15 ++- dom/grid/GridLine.h | 10 +- dom/grid/GridLines.cpp | 13 +- dom/grid/GridTrack.cpp | 6 +- dom/grid/GridTrack.h | 9 +- dom/grid/GridTracks.cpp | 4 +- dom/grid/moz.build | 2 + dom/grid/test/chrome.ini | 2 + dom/grid/test/chrome/test_grid_areas.html | 96 ++++++++++++++ dom/grid/test/chrome/test_grid_implicit.html | 129 +++++++++++++++++++ dom/webidl/Grid.webidl | 77 +++++++++-- layout/generic/nsGridContainerFrame.cpp | 10 ++ layout/generic/nsGridContainerFrame.h | 20 ++- 17 files changed, 558 insertions(+), 30 deletions(-) create mode 100644 dom/grid/GridArea.cpp create mode 100644 dom/grid/GridArea.h create mode 100644 dom/grid/test/chrome/test_grid_areas.html create mode 100644 dom/grid/test/chrome/test_grid_implicit.html diff --git a/dom/grid/Grid.cpp b/dom/grid/Grid.cpp index 09144c2173e7..54c7e3714ced 100644 --- a/dom/grid/Grid.cpp +++ b/dom/grid/Grid.cpp @@ -6,6 +6,7 @@ #include "Grid.h" +#include "GridArea.h" #include "GridDimension.h" #include "mozilla/dom/GridBinding.h" #include "nsGridContainerFrame.h" @@ -13,7 +14,7 @@ namespace mozilla { namespace dom { -NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Grid, mParent, mRows, mCols) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Grid, mParent, mRows, mCols, mAreas) NS_IMPL_CYCLE_COLLECTING_ADDREF(Grid) NS_IMPL_CYCLE_COLLECTING_RELEASE(Grid) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Grid) @@ -43,6 +44,40 @@ Grid::Grid(nsISupports* aParent, aFrame->GetComputedTemplateColumnLines(); mCols->SetTrackInfo(columnTrackInfo); mCols->SetLineInfo(columnTrackInfo, columnLineInfo); + + // Add implicit areas first. + nsGridContainerFrame::ImplicitNamedAreas* implicitAreas = + aFrame->GetImplicitNamedAreas(); + if (implicitAreas) { + for (auto iter = implicitAreas->Iter(); !iter.Done(); iter.Next()) { + nsStringHashKey* entry = iter.Get(); + + GridArea* area = new GridArea(this, + nsString(entry->GetKey()), + GridDeclaration::Implicit, + 0, + 0, + 0, + 0); + mAreas.AppendElement(area); + } + } + + // Add explicit areas next. + nsGridContainerFrame::ExplicitNamedAreas* explicitAreas = + aFrame->GetExplicitNamedAreas(); + if (explicitAreas) { + for (auto areaInfo : *explicitAreas) { + GridArea* area = new GridArea(this, + areaInfo.mName, + GridDeclaration::Explicit, + areaInfo.mRowStart, + areaInfo.mRowEnd, + areaInfo.mColumnStart, + areaInfo.mColumnEnd); + mAreas.AppendElement(area); + } + } } Grid::~Grid() @@ -67,5 +102,11 @@ Grid::Cols() const return mCols; } +void +Grid::GetAreas(nsTArray>& aAreas) const +{ + aAreas = mAreas; +} + } // namespace dom } // namespace mozilla diff --git a/dom/grid/Grid.h b/dom/grid/Grid.h index 069fc89fac0c..426f33ec216c 100644 --- a/dom/grid/Grid.h +++ b/dom/grid/Grid.h @@ -7,6 +7,7 @@ #ifndef mozilla_dom_Grid_h #define mozilla_dom_Grid_h +#include "GridArea.h" #include "mozilla/dom/Element.h" #include "nsGridContainerFrame.h" #include "nsISupports.h" @@ -38,11 +39,13 @@ public: GridDimension* Rows() const; GridDimension* Cols() const; + void GetAreas(nsTArray>& aAreas) const; protected: nsCOMPtr mParent; RefPtr mRows; RefPtr mCols; + nsTArray> mAreas; }; } // namespace dom diff --git a/dom/grid/GridArea.cpp b/dom/grid/GridArea.cpp new file mode 100644 index 000000000000..d8a7eca76d44 --- /dev/null +++ b/dom/grid/GridArea.cpp @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "GridArea.h" +#include "mozilla/dom/GridBinding.h" +#include "Grid.h" + +namespace mozilla { +namespace dom { + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(GridArea, mParent) +NS_IMPL_CYCLE_COLLECTING_ADDREF(GridArea) +NS_IMPL_CYCLE_COLLECTING_RELEASE(GridArea) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GridArea) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +GridArea::GridArea(Grid* aParent, + const nsString& aName, + GridDeclaration aType, + uint32_t aRowStart, + uint32_t aRowEnd, + uint32_t aColumnStart, + uint32_t aColumnEnd) + : mParent(aParent) + , mName(aName) + , mType(aType) + , mRowStart(aRowStart) + , mRowEnd(aRowEnd) + , mColumnStart(aColumnStart) + , mColumnEnd(aColumnEnd) +{ +} + +GridArea::~GridArea() +{ +} + +JSObject* +GridArea::WrapObject(JSContext* aCx, JS::Handle aGivenProto) +{ + return GridAreaBinding::Wrap(aCx, this, aGivenProto); +} + +void +GridArea::GetName(nsString& aName) const +{ + aName = mName; +} + +GridDeclaration +GridArea::Type() const +{ + return mType; +} + +uint32_t +GridArea::RowStart() const +{ + return mRowStart; +} + +uint32_t +GridArea::RowEnd() const +{ + return mRowEnd; +} + +uint32_t +GridArea::ColumnStart() const +{ + return mColumnStart; +} + +uint32_t +GridArea::ColumnEnd() const +{ + return mColumnEnd; +} + +} // namespace dom +} // namespace mozilla diff --git a/dom/grid/GridArea.h b/dom/grid/GridArea.h new file mode 100644 index 000000000000..19b610ca2201 --- /dev/null +++ b/dom/grid/GridArea.h @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_GridArea_h +#define mozilla_dom_GridArea_h + +#include "mozilla/dom/GridBinding.h" +#include "nsWrapperCache.h" + +namespace mozilla { +namespace dom { + +class Grid; + +class GridArea : public nsISupports + , public nsWrapperCache +{ +public: + explicit GridArea(Grid *aParent, + const nsString& aName, + GridDeclaration aType, + uint32_t aRowStart, + uint32_t aRowEnd, + uint32_t aColumnStart, + uint32_t aColumnEnd); + +protected: + virtual ~GridArea(); + +public: + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(GridArea) + + virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; + Grid* GetParentObject() + { + return mParent; + } + + void GetName(nsString& aName) const; + GridDeclaration Type() const; + uint32_t RowStart() const; + uint32_t RowEnd() const; + uint32_t ColumnStart() const; + uint32_t ColumnEnd() const; + +protected: + RefPtr mParent; + const nsString mName; + const GridDeclaration mType; + const uint32_t mRowStart; + const uint32_t mRowEnd; + const uint32_t mColumnStart; + const uint32_t mColumnEnd; +}; + +} // namespace dom +} // namespace mozilla + +#endif /* mozilla_dom_GridTrack_h */ diff --git a/dom/grid/GridLine.cpp b/dom/grid/GridLine.cpp index 93fab743e15b..8e1e5ed7ced8 100644 --- a/dom/grid/GridLine.cpp +++ b/dom/grid/GridLine.cpp @@ -24,6 +24,7 @@ GridLine::GridLine(GridLines *aParent) : mParent(aParent) , mStart(0.0) , mBreadth(0.0) + , mType(GridDeclaration::Implicit) , mNumber(0) { MOZ_ASSERT(aParent, "Should never be instantiated with a null GridLines"); @@ -57,6 +58,12 @@ GridLine::Breadth() const return mBreadth; } +GridDeclaration +GridLine::Type() const +{ + return mType; +} + uint32_t GridLine::Number() const { @@ -64,15 +71,17 @@ GridLine::Number() const } void -GridLine::SetLineValues(double aStart, +GridLine::SetLineValues(const nsTArray& aNames, + double aStart, double aBreadth, uint32_t aNumber, - const nsTArray& aNames) + GridDeclaration aType) { + mNames = aNames; mStart = aStart; mBreadth = aBreadth; mNumber = aNumber; - mNames = aNames; + mType = aType; } } // namespace dom diff --git a/dom/grid/GridLine.h b/dom/grid/GridLine.h index db4f0be61090..858f9d5e0322 100644 --- a/dom/grid/GridLine.h +++ b/dom/grid/GridLine.h @@ -7,6 +7,7 @@ #ifndef mozilla_dom_GridLine_h #define mozilla_dom_GridLine_h +#include "mozilla/dom/GridBinding.h" #include "nsString.h" #include "nsTArray.h" #include "nsWrapperCache.h" @@ -39,19 +40,22 @@ public: double Start() const; double Breadth() const; + GridDeclaration Type() const; uint32_t Number() const; - void SetLineValues(double aStart, + void SetLineValues(const nsTArray& aNames, + double aStart, double aBreadth, uint32_t aNumber, - const nsTArray& aNames); + GridDeclaration aType); protected: RefPtr mParent; + nsTArray mNames; double mStart; double mBreadth; + GridDeclaration mType; uint32_t mNumber; - nsTArray mNames; }; } // namespace dom diff --git a/dom/grid/GridLines.cpp b/dom/grid/GridLines.cpp index fecd7b2b940b..f275fae5e5f8 100644 --- a/dom/grid/GridLines.cpp +++ b/dom/grid/GridLines.cpp @@ -97,11 +97,22 @@ GridLines::SetLineInfo(const ComputedGridTrackInfo* aTrackInfo, } line->SetLineValues( + lineNames, nsPresContext::AppUnitsToDoubleCSSPixels(endOfLastTrack), nsPresContext::AppUnitsToDoubleCSSPixels(startOfNextTrack - endOfLastTrack), i + 1, - lineNames + ( + // Implicit if there are no explicit tracks, or if the index + // is before the first explicit track, or after + // a track beyond the last explicit track. + (aTrackInfo->mNumExplicitTracks == 0) || + (i < aTrackInfo->mNumLeadingImplicitTracks) || + (i > aTrackInfo->mNumLeadingImplicitTracks + + aTrackInfo->mNumExplicitTracks) ? + GridDeclaration::Implicit : + GridDeclaration::Explicit + ) ); if (i < aTrackInfo->mEndFragmentTrack) { diff --git a/dom/grid/GridTrack.cpp b/dom/grid/GridTrack.cpp index eca0e205ca21..328af7d5c17e 100644 --- a/dom/grid/GridTrack.cpp +++ b/dom/grid/GridTrack.cpp @@ -24,7 +24,7 @@ GridTrack::GridTrack(GridTracks* aParent) : mParent(aParent) , mStart(0.0) , mBreadth(0.0) - , mType(GridTrackType::Implicit) + , mType(GridDeclaration::Implicit) , mState(GridTrackState::Static) { MOZ_ASSERT(aParent, "Should never be instantiated with a null GridTracks"); @@ -52,7 +52,7 @@ GridTrack::Breadth() const return mBreadth; } -GridTrackType +GridDeclaration GridTrack::Type() const { return mType; @@ -67,7 +67,7 @@ GridTrack::State() const void GridTrack::SetTrackValues(double aStart, double aBreadth, - GridTrackType aType, + GridDeclaration aType, GridTrackState aState) { mStart = aStart; diff --git a/dom/grid/GridTrack.h b/dom/grid/GridTrack.h index abc33f882cc6..d1825c5ad971 100644 --- a/dom/grid/GridTrack.h +++ b/dom/grid/GridTrack.h @@ -36,16 +36,19 @@ public: double Start() const; double Breadth() const; - GridTrackType Type() const; + GridDeclaration Type() const; GridTrackState State() const; - void SetTrackValues(double aStart, double aBreadth, GridTrackType aType, GridTrackState aState); + void SetTrackValues(double aStart, + double aBreadth, + GridDeclaration aType, + GridTrackState aState); protected: RefPtr mParent; double mStart; double mBreadth; - GridTrackType mType; + GridDeclaration mType; GridTrackState mState; }; diff --git a/dom/grid/GridTracks.cpp b/dom/grid/GridTracks.cpp index 099d926ed169..e66650881d07 100644 --- a/dom/grid/GridTracks.cpp +++ b/dom/grid/GridTracks.cpp @@ -86,8 +86,8 @@ GridTracks::SetTrackInfo(const ComputedGridTrackInfo* aTrackInfo) (i < aTrackInfo->mNumLeadingImplicitTracks) || (i >= aTrackInfo->mNumLeadingImplicitTracks + aTrackInfo->mNumExplicitTracks) ? - GridTrackType::Implicit : - GridTrackType::Explicit + GridDeclaration::Implicit : + GridDeclaration::Explicit ), GridTrackState(aTrackInfo->mStates[i]) ); diff --git a/dom/grid/moz.build b/dom/grid/moz.build index d65eb80f4642..96d5c31510be 100644 --- a/dom/grid/moz.build +++ b/dom/grid/moz.build @@ -8,6 +8,7 @@ MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini'] EXPORTS.mozilla.dom += [ 'Grid.h', + 'GridArea.h', 'GridDimension.h', 'GridLine.h', 'GridLines.h', @@ -17,6 +18,7 @@ EXPORTS.mozilla.dom += [ UNIFIED_SOURCES += [ 'Grid.cpp', + 'GridArea.cpp', 'GridDimension.cpp', 'GridLine.cpp', 'GridLines.cpp', diff --git a/dom/grid/test/chrome.ini b/dom/grid/test/chrome.ini index b9edcdb0f8c6..a1b5fcc1a387 100644 --- a/dom/grid/test/chrome.ini +++ b/dom/grid/test/chrome.ini @@ -1,4 +1,6 @@ +[chrome/test_grid_areas.html] [chrome/test_grid_fragmentation.html] +[chrome/test_grid_implicit.html] [chrome/test_grid_lines.html] [chrome/test_grid_object.html] [chrome/test_grid_track_state.html] diff --git a/dom/grid/test/chrome/test_grid_areas.html b/dom/grid/test/chrome/test_grid_areas.html new file mode 100644 index 000000000000..25795ac7ccfb --- /dev/null +++ b/dom/grid/test/chrome/test_grid_areas.html @@ -0,0 +1,96 @@ + + + + + + + + + + + + +
+
A
+
B
+
C
+
+ + + diff --git a/dom/grid/test/chrome/test_grid_implicit.html b/dom/grid/test/chrome/test_grid_implicit.html new file mode 100644 index 000000000000..3d329a252fa5 --- /dev/null +++ b/dom/grid/test/chrome/test_grid_implicit.html @@ -0,0 +1,129 @@ + + + + + + + + + + + + +
+
A
+
B
+
C
+
D
+
+ + + diff --git a/dom/webidl/Grid.webidl b/dom/webidl/Grid.webidl index 875e86734f3d..d3ca6cd3e8f3 100644 --- a/dom/webidl/Grid.webidl +++ b/dom/webidl/Grid.webidl @@ -1,13 +1,31 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* These objects support visualization of a css-grid by the dev tools. */ + +/** + * Explicit and implicit types apply to tracks, lines, and areas. + * https://drafts.csswg.org/css-grid/#explicit-grids + * https://drafts.csswg.org/css-grid/#implicit-grids + */ +enum GridDeclaration { "explicit", "implicit" }; + +/** + * Tracks expanded from auto-fill or auto-fit have repeat state, other tracks + * are static. + */ +enum GridTrackState { "static", "repeat" }; + [ChromeOnly] interface Grid { readonly attribute GridDimension rows; readonly attribute GridDimension cols; + [Cached, Constant] + readonly attribute sequence areas; }; [ChromeOnly] @@ -21,34 +39,77 @@ interface GridDimension interface GridLines { readonly attribute unsigned long length; + + /** + * This accessor method allows array-like access to lines. + * @param index A 0-indexed value. + */ getter GridLine? item(unsigned long index); }; [ChromeOnly] interface GridLine { - readonly attribute double start; - readonly attribute double breadth; - readonly attribute unsigned long number; - [Cached, Pure] + /** + * Names include both explicit names and implicit names, which will be + * assigned if the line contributes to a named area. + * https://drafts.csswg.org/css-grid/#implicit-named-lines + */ + [Cached, Constant] readonly attribute sequence names; + + readonly attribute double start; + + /** + * Breadth is the gap between the start of this line and the start of the + * next track in flow direction. It primarily is set by use of the -gap + * properties. + * https://drafts.csswg.org/css-grid/#gutters + */ + readonly attribute double breadth; + + readonly attribute GridDeclaration type; + + /** + * Number is the 1-indexed index of the line in flow order. + */ + readonly attribute unsigned long number; }; [ChromeOnly] interface GridTracks { readonly attribute unsigned long length; + + /** + * This accessor method allows array-like access to tracks. + * @param index A 0-indexed value. + */ getter GridTrack? item(unsigned long index); }; -enum GridTrackType { "explicit", "implicit" }; -enum GridTrackState { "static", "repeat" }; - [ChromeOnly] interface GridTrack { readonly attribute double start; readonly attribute double breadth; - readonly attribute GridTrackType type; + readonly attribute GridDeclaration type; readonly attribute GridTrackState state; }; + +[ChromeOnly] +interface GridArea +{ + readonly attribute DOMString name; + readonly attribute GridDeclaration type; + + /** + * These values are 1-indexed line numbers bounding the area. + * FIXME: Bug 1297189 - Implicit grid areas need boundary line numbers + * exposed to dev tools + */ + readonly attribute unsigned long rowStart; + readonly attribute unsigned long rowEnd; + readonly attribute unsigned long columnStart; + readonly attribute unsigned long columnEnd; +}; diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 0efc9540536e..7cefcf097a5b 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -5764,6 +5764,16 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, ComputedGridLineInfo* rowLineInfo = new ComputedGridLineInfo( Move(rowLineNames)); Properties().Set(GridRowLineInfo(), rowLineInfo); + + // Generate area info for explicit areas. Implicit areas are handled + // elsewhere. + if (gridReflowInput.mGridStyle->mGridTemplateAreas) { + nsTArray* areas = new nsTArray( + gridReflowInput.mGridStyle->mGridTemplateAreas->mNamedAreas); + Properties().Set(ExplicitNamedAreasProperty(), areas); + } else { + Properties().Delete(ExplicitNamedAreasProperty()); + } } if (!prevInFlow) { diff --git a/layout/generic/nsGridContainerFrame.h b/layout/generic/nsGridContainerFrame.h index 10bd8088ea6c..f3d16bbc374c 100644 --- a/layout/generic/nsGridContainerFrame.h +++ b/layout/generic/nsGridContainerFrame.h @@ -151,6 +151,20 @@ public: return info; } + typedef nsTHashtable ImplicitNamedAreas; + NS_DECLARE_FRAME_PROPERTY_DELETABLE(ImplicitNamedAreasProperty, + ImplicitNamedAreas) + ImplicitNamedAreas* GetImplicitNamedAreas() const { + return Properties().Get(ImplicitNamedAreasProperty()); + } + + typedef nsTArray ExplicitNamedAreas; + NS_DECLARE_FRAME_PROPERTY_DELETABLE(ExplicitNamedAreasProperty, + ExplicitNamedAreas) + ExplicitNamedAreas* GetExplicitNamedAreas() const { + return Properties().Get(ExplicitNamedAreasProperty()); + } + /** * Return a containing grid frame, and ensure it has computed grid info * @return nullptr if aFrame has no grid container, or frame was destroyed @@ -195,14 +209,8 @@ protected: * grid-template-columns / grid-template-rows are stored in this frame * property when needed, as a ImplicitNamedAreas* value. */ - typedef nsTHashtable ImplicitNamedAreas; - NS_DECLARE_FRAME_PROPERTY_DELETABLE(ImplicitNamedAreasProperty, - ImplicitNamedAreas) void InitImplicitNamedAreas(const nsStylePosition* aStyle); void AddImplicitNamedAreas(const nsTArray>& aLineNameLists); - ImplicitNamedAreas* GetImplicitNamedAreas() const { - return Properties().Get(ImplicitNamedAreasProperty()); - } /** * Reflow and place our children.