Bug 1241932 - Expose decoded CSS grid track properties in a Chrome API. r=heycam, r=khuey
authorBrad Werth <bwerth@mozilla.com>
Wed, 06 Jul 2016 11:45:18 -0700
changeset 346085 3396152c5e11bb9c2a8af4ef1bd1c39be78d5e28
parent 346084 eecb6828cdb643dd4581e302e50d299861d98d79
child 346086 a96f09f90b2f5c670a6f7975b4b7045ea68dcd41
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam, khuey
bugs1241932
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1241932 - Expose decoded CSS grid track properties in a Chrome API. r=heycam, r=khuey
dom/base/Element.cpp
dom/base/Element.h
dom/bindings/moz.build
dom/grid/Grid.cpp
dom/grid/Grid.h
dom/grid/GridDimension.cpp
dom/grid/GridDimension.h
dom/grid/GridLine.cpp
dom/grid/GridLine.h
dom/grid/GridLines.cpp
dom/grid/GridLines.h
dom/grid/GridTrack.cpp
dom/grid/GridTrack.h
dom/grid/GridTracks.cpp
dom/grid/GridTracks.h
dom/grid/moz.build
dom/grid/test/chrome.ini
dom/grid/test/chrome/test_grid_object.html
dom/grid/test/chrome/test_grid_repeats.html
dom/grid/test/chrome/test_grid_state.html
dom/moz.build
dom/webidl/Element.webidl
dom/webidl/Grid.webidl
dom/webidl/moz.build
layout/generic/nsGridContainerFrame.cpp
layout/generic/nsGridContainerFrame.h
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -11,16 +11,17 @@
  */
 
 #include "mozilla/dom/ElementInlines.h"
 
 #include "AnimationCommon.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/dom/Animation.h"
 #include "mozilla/dom/Attr.h"
+#include "mozilla/dom/Grid.h"
 #include "nsDOMAttributeMap.h"
 #include "nsIAtom.h"
 #include "nsIContentInlines.h"
 #include "mozilla/dom/NodeInfo.h"
 #include "nsIDocumentInlines.h"
 #include "mozilla/dom/DocumentTimeline.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMDocument.h"
@@ -948,17 +949,16 @@ Element::GetClientRects()
 
   nsLayoutUtils::RectListBuilder builder(rectList);
   nsLayoutUtils::GetAllInFlowRects(frame,
           nsLayoutUtils::GetContainingBlockForClientRect(frame), &builder,
           nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
   return rectList.forget();
 }
 
-
 //----------------------------------------------------------------------
 
 void
 Element::AddToIdTable(nsIAtom* aId)
 {
   NS_ASSERTION(HasID(), "Node doesn't have an ID?");
   if (IsInShadowTree()) {
     ShadowRoot* containingShadow = GetContainingShadow();
@@ -3284,16 +3284,31 @@ Element::RequestFullscreen(JSContext* aC
 }
 
 void
 Element::MozRequestPointerLock()
 {
   OwnerDoc()->RequestPointerLock(this);
 }
 
+void
+Element::GetGridFragments(nsTArray<RefPtr<Grid>>& aResult)
+{
+  nsIFrame* frame = GetPrimaryFrame();
+  if (frame && (frame->GetType() == nsGkAtoms::gridContainerFrame)) {
+    // If primary frame is a nsGridContainerFrame, all the next frames
+    // in flow will also be nsGridContainerFrame.
+    for (; frame != nullptr; frame = frame->GetNextInFlow()) {
+      aResult.AppendElement(
+        new Grid(this, static_cast<nsGridContainerFrame*>(frame))
+      );
+    }
+  }
+}
+
 already_AddRefed<Animation>
 Element::Animate(JSContext* aContext,
                  JS::Handle<JSObject*> aKeyframes,
                  const UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions,
                  ErrorResult& aError)
 {
   Nullable<ElementOrCSSPseudoElement> target;
   target.SetValue().SetAsElement() = this;
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -135,16 +135,17 @@ class EventStateManager;
 namespace dom {
 
 class Animation;
 class Link;
 class UndoManager;
 class DOMRect;
 class DOMRectList;
 class DestinationInsertionPointList;
+class Grid;
 
 // IID for the dom::Element interface
 #define NS_ELEMENT_IID \
 { 0xc67ed254, 0xfd3b, 0x4b10, \
   { 0x96, 0xa2, 0xc5, 0x8b, 0x7b, 0x64, 0x97, 0xd1 } }
 
 class Element : public FragmentOrElement
 {
@@ -825,16 +826,18 @@ public:
   int32_t ScrollLeftMax()
   {
     nsIScrollableFrame* sf = GetScrollFrame();
     return sf ?
            nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollRange().XMost()) :
            0;
   }
 
+  void GetGridFragments(nsTArray<RefPtr<Grid>>& aResult);
+
   virtual already_AddRefed<UndoManager> GetUndoManager()
   {
     return nullptr;
   }
 
   virtual bool UndoScope()
   {
     return false;
--- a/dom/bindings/moz.build
+++ b/dom/bindings/moz.build
@@ -69,16 +69,17 @@ LOCAL_INCLUDES += [
     '/dom/workers',
     '/dom/xbl',
     '/dom/xml',
     '/dom/xslt/base',
     '/dom/xslt/xpath',
     '/dom/xul',
     '/js/xpconnect/src',
     '/js/xpconnect/wrappers',
+    '/layout/generic',
     '/layout/style',
     '/layout/xul/tree',
     '/media/mtransport',
     '/media/webrtc/',
     '/media/webrtc/signaling/src/common/time_profiling',
     '/media/webrtc/signaling/src/peerconnection',
 ]
 
new file mode 100644
--- /dev/null
+++ b/dom/grid/Grid.cpp
@@ -0,0 +1,65 @@
+/* -*- 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 "Grid.h"
+
+#include "GridDimension.h"
+#include "mozilla/dom/GridBinding.h"
+#include "nsGridContainerFrame.h"
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Grid, mParent, mRows, mCols)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(Grid)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(Grid)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Grid)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+Grid::Grid(nsISupports* aParent,
+           nsGridContainerFrame* aFrame)
+  : mParent(do_QueryInterface(aParent))
+  , mRows(new GridDimension(this))
+  , mCols(new GridDimension(this))
+{
+  MOZ_ASSERT(aFrame,
+    "Should never be instantiated with a null nsGridContainerFrame");
+
+  const ComputedGridTrackInfo* rowTrackInfo = aFrame->GetComputedTemplateRows();
+  mRows->SetTrackInfo(rowTrackInfo);
+  mRows->SetLineInfo(rowTrackInfo);
+
+  const ComputedGridTrackInfo* colTrackInfo = aFrame->GetComputedTemplateColumns();
+  mCols->SetTrackInfo(colTrackInfo);
+  mCols->SetLineInfo(colTrackInfo);
+}
+
+Grid::~Grid()
+{
+}
+
+JSObject*
+Grid::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+{
+  return GridBinding::Wrap(aCx, this, aGivenProto);
+}
+
+GridDimension*
+Grid::Rows() const
+{
+  return mRows;
+}
+
+GridDimension*
+Grid::Cols() const
+{
+  return mCols;
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/grid/Grid.h
@@ -0,0 +1,51 @@
+/* -*- 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_Grid_h
+#define mozilla_dom_Grid_h
+
+#include "mozilla/dom/Element.h"
+#include "nsGridContainerFrame.h"
+#include "nsISupports.h"
+#include "nsWrapperCache.h"
+
+namespace mozilla {
+namespace dom {
+
+class GridDimension;
+
+class Grid : public nsISupports
+           , public nsWrapperCache
+{
+public:
+  explicit Grid(nsISupports* aParent, nsGridContainerFrame* aFrame);
+
+protected:
+  virtual ~Grid();
+
+public:
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Grid)
+
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+  Element* GetParentObject()
+  {
+    return mParent;
+  }
+
+  GridDimension* Rows() const;
+  GridDimension* Cols() const;
+
+protected:
+  nsCOMPtr<Element> mParent;
+  RefPtr<GridDimension> mRows;
+  RefPtr<GridDimension> mCols;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif /* mozilla_dom_Grid_h */
new file mode 100644
--- /dev/null
+++ b/dom/grid/GridDimension.cpp
@@ -0,0 +1,69 @@
+/* -*- 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 "GridDimension.h"
+
+#include "Grid.h"
+#include "GridLines.h"
+#include "GridTracks.h"
+#include "mozilla/dom/GridBinding.h"
+#include "nsGridContainerFrame.h"
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(GridDimension, mParent, mLines, mTracks)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(GridDimension)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(GridDimension)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GridDimension)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+GridDimension::GridDimension(Grid* aParent)
+  : mParent(aParent)
+  , mLines(new GridLines(this))
+  , mTracks(new GridTracks(this))
+{
+  MOZ_ASSERT(aParent, "Should never be instantiated with a null Grid");
+}
+
+GridDimension::~GridDimension()
+{
+}
+
+JSObject*
+GridDimension::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+{
+  return GridDimensionBinding::Wrap(aCx, this, aGivenProto);
+}
+
+GridLines*
+GridDimension::Lines() const
+{
+  return mLines;
+}
+
+GridTracks*
+GridDimension::Tracks() const
+{
+  return mTracks;
+}
+
+void
+GridDimension::SetTrackInfo(const ComputedGridTrackInfo* aTrackInfo)
+{
+  mTracks->SetTrackInfo(aTrackInfo);
+}
+
+void
+GridDimension::SetLineInfo(const ComputedGridTrackInfo* aTrackInfo)
+{
+  mLines->SetLineInfo(aTrackInfo);
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/grid/GridDimension.h
@@ -0,0 +1,56 @@
+/* -*- 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_GridDimension_h
+#define mozilla_dom_GridDimension_h
+
+#include "nsWrapperCache.h"
+
+namespace mozilla {
+
+struct ComputedGridTrackInfo;
+
+namespace dom {
+
+class Grid;
+class GridLines;
+class GridTracks;
+
+class GridDimension : public nsISupports
+                    , public nsWrapperCache
+{
+public:
+  explicit GridDimension(Grid* aParent);
+
+protected:
+  virtual ~GridDimension();
+
+public:
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(GridDimension)
+
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+  Grid* GetParentObject()
+  {
+    return mParent;
+  }
+
+  GridLines* Lines() const;
+  GridTracks* Tracks() const;
+
+  void SetTrackInfo(const ComputedGridTrackInfo* aTrackInfo);
+  void SetLineInfo(const ComputedGridTrackInfo* aTrackInfo);
+
+protected:
+  RefPtr<Grid> mParent;
+  RefPtr<GridLines> mLines;
+  RefPtr<GridTracks> mTracks;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif /* mozilla_dom_GridDimension_h */
new file mode 100644
--- /dev/null
+++ b/dom/grid/GridLine.cpp
@@ -0,0 +1,79 @@
+/* -*- 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 "GridLine.h"
+
+#include "GridLines.h"
+#include "mozilla/dom/GridBinding.h"
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(GridLine, mParent)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(GridLine)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(GridLine)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GridLine)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+GridLine::GridLine(GridLines *aParent)
+  : mParent(aParent)
+  , mStart(0.0)
+  , mBreadth(0.0)
+  , mNumber(0)
+{
+  MOZ_ASSERT(aParent, "Should never be instantiated with a null GridLines");
+}
+
+GridLine::~GridLine()
+{
+}
+
+void
+GridLine::GetNames(nsTArray<nsString>& aNames) const
+{
+  aNames = mNames;
+}
+
+JSObject*
+GridLine::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+{
+  return GridLineBinding::Wrap(aCx, this, aGivenProto);
+}
+
+double
+GridLine::Start() const
+{
+  return mStart;
+}
+
+double
+GridLine::Breadth() const
+{
+  return mBreadth;
+}
+
+uint32_t
+GridLine::Number() const
+{
+  return mNumber;
+}
+
+void
+GridLine::SetLineValues(double aStart,
+                        double aBreadth,
+                        uint32_t aNumber,
+                        const nsTArray<nsString>& aNames)
+{
+  mStart = aStart;
+  mBreadth = aBreadth;
+  mNumber = aNumber;
+  mNames = aNames;
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/grid/GridLine.h
@@ -0,0 +1,60 @@
+/* -*- 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_GridLine_h
+#define mozilla_dom_GridLine_h
+
+#include "nsString.h"
+#include "nsTArray.h"
+#include "nsWrapperCache.h"
+
+namespace mozilla {
+namespace dom {
+
+class GridLines;
+
+class GridLine : public nsISupports
+               , public nsWrapperCache
+{
+public:
+  explicit GridLine(GridLines* aParent);
+
+protected:
+  virtual ~GridLine();
+
+public:
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(GridLine)
+
+  void GetNames(nsTArray<nsString>& aNames) const;
+
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+  GridLines* GetParentObject()
+  {
+    return mParent;
+  }
+
+  double Start() const;
+  double Breadth() const;
+  uint32_t Number() const;
+
+  void SetLineValues(double aStart,
+                     double aBreadth,
+                     uint32_t aNumber,
+                     const nsTArray<nsString>& aNames);
+
+protected:
+  RefPtr<GridLines> mParent;
+  double mStart;
+  double mBreadth;
+  uint32_t mNumber;
+  nsTArray<nsString> mNames;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif /* mozilla_dom_GridLine_h */
new file mode 100644
--- /dev/null
+++ b/dom/grid/GridLines.cpp
@@ -0,0 +1,108 @@
+/* -*- 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 "GridLines.h"
+
+#include "GridDimension.h"
+#include "GridLine.h"
+#include "mozilla/dom/GridBinding.h"
+#include "nsGridContainerFrame.h"
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(GridLines, mParent, mLines)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(GridLines)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(GridLines)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GridLines)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+GridLines::GridLines(GridDimension* aParent)
+  : mParent(aParent)
+{
+  MOZ_ASSERT(aParent,
+    "Should never be instantiated with a null GridDimension");
+}
+
+GridLines::~GridLines()
+{
+}
+
+JSObject*
+GridLines::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+{
+  return GridLinesBinding::Wrap(aCx, this, aGivenProto);
+}
+
+uint32_t
+GridLines::Length() const
+{
+  return mLines.Length();
+}
+
+GridLine*
+GridLines::Item(uint32_t aIndex)
+{
+  return mLines.SafeElementAt(aIndex);
+}
+
+GridLine*
+GridLines::IndexedGetter(uint32_t aIndex,
+                         bool& aFound)
+{
+  aFound = aIndex < mLines.Length();
+  if (!aFound) {
+    return nullptr;
+  }
+  return mLines[aIndex];
+}
+
+void
+GridLines::SetLineInfo(const ComputedGridTrackInfo* aTrackInfo)
+{
+  mLines.Clear();
+
+  if (!aTrackInfo) {
+    return;
+  }
+
+  uint32_t trackCount = aTrackInfo->mEndFragmentTrack -
+                        aTrackInfo->mStartFragmentTrack;
+
+  // If there is at least one track, line count is one more
+  // than the number of tracks.
+  if (trackCount > 0) {
+    double endOfLastTrack = 0.0;
+    double startOfNextTrack;
+
+    for (uint32_t i = aTrackInfo->mStartFragmentTrack;
+         i < aTrackInfo->mEndFragmentTrack + 1;
+         i++) {
+      startOfNextTrack = (i < aTrackInfo->mEndFragmentTrack) ?
+                         aTrackInfo->mPositions[i] :
+                         endOfLastTrack;
+
+      GridLine* line = new GridLine(this);
+      mLines.AppendElement(line);
+      line->SetLineValues(
+        nsPresContext::AppUnitsToDoubleCSSPixels(endOfLastTrack),
+        nsPresContext::AppUnitsToDoubleCSSPixels(startOfNextTrack -
+                                                 endOfLastTrack),
+        i + 1,
+        nsTArray<nsString>()
+      );
+
+      if (i < aTrackInfo->mEndFragmentTrack) {
+        endOfLastTrack = aTrackInfo->mPositions[i] + aTrackInfo->mSizes[i];
+      }
+    }
+  }
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/grid/GridLines.h
@@ -0,0 +1,52 @@
+/* -*- 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_GridLines_h
+#define mozilla_dom_GridLines_h
+
+#include "nsTArray.h"
+#include "nsWrapperCache.h"
+
+namespace mozilla {
+namespace dom {
+
+class GridDimension;
+class GridLine;
+
+class GridLines : public nsISupports
+                , public nsWrapperCache
+{
+public:
+  explicit GridLines(GridDimension* aParent);
+
+protected:
+  virtual ~GridLines();
+
+public:
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(GridLines)
+
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+  GridDimension* GetParentObject()
+  {
+    return mParent;
+  }
+
+  uint32_t Length() const;
+  GridLine* Item(uint32_t aIndex);
+  GridLine* IndexedGetter(uint32_t aIndex, bool& aFound);
+
+  void SetLineInfo(const ComputedGridTrackInfo* aTrackInfo);
+
+protected:
+  RefPtr<GridDimension> mParent;
+  nsTArray<RefPtr<GridLine>> mLines;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif /* mozilla_dom_GridLines_h */
new file mode 100644
--- /dev/null
+++ b/dom/grid/GridTrack.cpp
@@ -0,0 +1,80 @@
+/* -*- 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 "GridTrack.h"
+
+#include "GridTracks.h"
+#include "mozilla/dom/GridBinding.h"
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(GridTrack, mParent)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(GridTrack)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(GridTrack)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GridTrack)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+GridTrack::GridTrack(GridTracks* aParent)
+  : mParent(aParent)
+  , mStart(0.0)
+  , mBreadth(0.0)
+  , mType(GridTrackType::Implicit)
+  , mState(GridTrackState::Static)
+{
+  MOZ_ASSERT(aParent, "Should never be instantiated with a null GridTracks");
+}
+
+GridTrack::~GridTrack()
+{
+}
+
+JSObject*
+GridTrack::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+{
+  return GridTrackBinding::Wrap(aCx, this, aGivenProto);
+}
+
+double
+GridTrack::Start() const
+{
+  return mStart;
+}
+
+double
+GridTrack::Breadth() const
+{
+  return mBreadth;
+}
+
+GridTrackType
+GridTrack::Type() const
+{
+  return mType;
+}
+
+GridTrackState
+GridTrack::State() const
+{
+  return mState;
+}
+
+void
+GridTrack::SetTrackValues(double aStart,
+                          double aBreadth,
+                          GridTrackType aType,
+                          GridTrackState aState)
+{
+  mStart = aStart;
+  mBreadth = aBreadth;
+  mType = aType;
+  mState = aState;
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/grid/GridTrack.h
@@ -0,0 +1,55 @@
+/* -*- 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_GridTrack_h
+#define mozilla_dom_GridTrack_h
+
+#include "mozilla/dom/GridBinding.h"
+#include "nsWrapperCache.h"
+
+namespace mozilla {
+namespace dom {
+
+class GridTracks;
+
+class GridTrack : public nsISupports
+                , public nsWrapperCache
+{
+public:
+  explicit GridTrack(GridTracks *parent);
+
+protected:
+  virtual ~GridTrack();
+
+public:
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(GridTrack)
+
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+  GridTracks* GetParentObject()
+  {
+    return mParent;
+  }
+
+  double Start() const;
+  double Breadth() const;
+  GridTrackType Type() const;
+  GridTrackState State() const;
+
+  void SetTrackValues(double aStart, double aBreadth, GridTrackType aType, GridTrackState aState);
+
+protected:
+  RefPtr<GridTracks> mParent;
+  double mStart;
+  double mBreadth;
+  GridTrackType mType;
+  GridTrackState mState;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif /* mozilla_dom_GridTrack_h */
new file mode 100644
--- /dev/null
+++ b/dom/grid/GridTracks.cpp
@@ -0,0 +1,98 @@
+/* -*- 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 "GridTracks.h"
+
+#include "GridDimension.h"
+#include "GridTrack.h"
+#include "mozilla/dom/GridBinding.h"
+#include "nsGridContainerFrame.h"
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(GridTracks, mParent, mTracks)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(GridTracks)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(GridTracks)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GridTracks)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+GridTracks::GridTracks(GridDimension *aParent)
+  : mParent(aParent)
+{
+  MOZ_ASSERT(aParent,
+    "Should never be instantiated with a null GridDimension");
+}
+
+GridTracks::~GridTracks()
+{
+}
+
+JSObject*
+GridTracks::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+{
+  return GridTracksBinding::Wrap(aCx, this, aGivenProto);
+}
+
+uint32_t
+GridTracks::Length() const
+{
+  return mTracks.Length();
+}
+
+GridTrack*
+GridTracks::Item(uint32_t aIndex)
+{
+  return mTracks.SafeElementAt(aIndex);
+}
+
+GridTrack*
+GridTracks::IndexedGetter(uint32_t aIndex,
+                          bool& aFound)
+{
+  aFound = aIndex < mTracks.Length();
+  if (!aFound) {
+    return nullptr;
+  }
+  return mTracks[aIndex];
+}
+
+void
+GridTracks::SetTrackInfo(const ComputedGridTrackInfo* aTrackInfo)
+{
+  // rebuild the tracks based on aTrackInfo
+  mTracks.Clear();
+
+  if (!aTrackInfo) {
+    return;
+  }
+
+  for (size_t i = aTrackInfo->mStartFragmentTrack;
+       i < aTrackInfo->mEndFragmentTrack;
+       i++) {
+    GridTrack* track = new GridTrack(this);
+    mTracks.AppendElement(track);
+    track->SetTrackValues(
+      nsPresContext::AppUnitsToDoubleCSSPixels(aTrackInfo->mPositions[i]),
+      nsPresContext::AppUnitsToDoubleCSSPixels(aTrackInfo->mSizes[i]),
+      (
+        // Implicit if index is before the first explicit track, or after
+        // the last explicit track.
+        (i < aTrackInfo->mNumLeadingImplicitTracks) ||
+        (i >= aTrackInfo->mNumLeadingImplicitTracks +
+              aTrackInfo->mNumExplicitTracks) ?
+          GridTrackType::Implicit :
+          GridTrackType::Explicit
+      ),
+      GridTrackState(aTrackInfo->mStates[i])
+    );
+  }
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/grid/GridTracks.h
@@ -0,0 +1,55 @@
+/* -*- 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_GridTracks_h
+#define mozilla_dom_GridTracks_h
+
+#include "nsTArray.h"
+#include "nsWrapperCache.h"
+
+namespace mozilla {
+
+struct ComputedGridTrackInfo;
+
+namespace dom {
+
+class GridDimension;
+class GridTrack;
+
+class GridTracks : public nsISupports
+                 , public nsWrapperCache
+{
+public:
+  explicit GridTracks(GridDimension* aParent);
+
+protected:
+  virtual ~GridTracks();
+
+public:
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(GridTracks)
+
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+  GridDimension* GetParentObject()
+  {
+    return mParent;
+  }
+
+  uint32_t Length() const;
+  GridTrack* Item(uint32_t aIndex);
+  GridTrack* IndexedGetter(uint32_t aIndex, bool& aFound);
+
+  void SetTrackInfo(const mozilla::ComputedGridTrackInfo* aTrackInfo);
+
+protected:
+  RefPtr<GridDimension> mParent;
+  nsTArray<RefPtr<GridTrack>> mTracks;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif /* mozilla_dom_GridTracks_h */
new file mode 100644
--- /dev/null
+++ b/dom/grid/moz.build
@@ -0,0 +1,31 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
+
+EXPORTS.mozilla.dom += [
+    'Grid.h',
+    'GridDimension.h',
+    'GridLine.h',
+    'GridLines.h',
+    'GridTrack.h',
+    'GridTracks.h',
+]
+
+UNIFIED_SOURCES += [
+    'Grid.cpp',
+    'GridDimension.cpp',
+    'GridLine.cpp',
+    'GridLines.cpp',
+    'GridTrack.cpp',
+    'GridTracks.cpp',
+]
+
+LOCAL_INCLUDES += [
+    '/layout/generic',
+]
+
+FINAL_LIBRARY = 'xul'
new file mode 100644
--- /dev/null
+++ b/dom/grid/test/chrome.ini
@@ -0,0 +1,3 @@
+[chrome/test_grid_object.html]
+[chrome/test_grid_state.html]
+[chrome/test_grid_repeats.html]
new file mode 100644
--- /dev/null
+++ b/dom/grid/test/chrome/test_grid_object.html
@@ -0,0 +1,92 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8">
+<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+<style>
+body {
+	margin: 40px;
+}
+.wrapper {
+	display: grid;
+	width: 400px;
+	grid-gap: 10px;
+	grid-template-columns: 100px 1fr 1fr 100px;
+	background-color: #f00;
+}
+.box {
+	background-color: #444;
+	color: #fff;
+}
+</style>
+
+<script>
+'use strict';
+
+SimpleTest.waitForExplicitFinish();
+
+function runTests() {
+	var wrapper = document.getElementById("wrapper");
+	var boxA = document.getElementById("boxA");
+	var boxB = document.getElementById("boxB");
+	var boxC = document.getElementById("boxC");
+
+	// test function existence
+	is(typeof(wrapper.getGridFragments), "function",
+		"getGridFragments function exists."
+	);
+	
+	// test that display:grid elements have grids and display:block elements don't	
+	is(boxA.getGridFragments().length, 0, "No grid on display:block styled objects.");
+	is(wrapper.getGridFragments().length, 1,
+		"One grid on an un-fragmented display:grid styled object."
+	);
+	
+	var grid = wrapper.getGridFragments()[0];
+	
+	// test column and row track counts
+	is(grid.cols.tracks.length, 4,
+		"Grid.cols.tracks property has length that matches grid-template-columns."
+	);
+	is(grid.rows.tracks.length, 2,
+		"Grid.rows.tracks property has length that matches content."
+	);
+	
+	// test column track position
+	is(grid.cols.tracks[1].start, 110, "Grid column track 1 position is as expected.");
+	
+	// test column track width
+	is(grid.cols.tracks[0].breadth, boxA.offsetWidth,
+		"Grid column track width (fixed size) matches item width."
+	);
+	is(grid.cols.tracks[1].breadth, boxB.offsetWidth,
+		"Grid column track width (flexible size) matches item width."
+	);
+	is(grid.cols.tracks[1].breadth, grid.cols.tracks[2].breadth,
+		"Grid column track widths with equal proportion flexible size actually are same size."
+	);
+	
+	// test explicit / implicit tracks
+	is(grid.cols.tracks[0].type, "explicit", "Grid column track 0 is explicit.");
+	is(grid.rows.tracks[0].type, "implicit", "Grid row track 0 is implicit.");
+	
+	SimpleTest.finish();
+}
+</script>
+</head>
+<body onLoad="runTests();">
+
+	<div id="wrapper" class="wrapper">
+		<div id="boxA" class="box a">A</div>
+		<div id="boxB" class="box b">B</div>
+		<div id="boxC" class="box c">C</div>
+		<div class="box d">D</div>
+		<div class="box e">E</div>
+		<div class="box f">F</div>
+		<div class="box g">G</div>
+		<div class="box h">H</div>
+	</div>
+	
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/grid/test/chrome/test_grid_repeats.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8">
+<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+<style>
+body {
+	margin: 40px;
+}
+.wrapper {
+	display: grid;
+	width: 600px;
+	grid-gap: 10px;
+	grid-template-columns: repeat(2, 100px) repeat(auto-fill, 50px);
+	background-color: #f00;
+}
+.box {
+	background-color: #444;
+	color: #fff;
+}
+
+</style>
+
+<script>
+'use strict';
+
+SimpleTest.waitForExplicitFinish();
+
+function runTests() {
+	var wrapper = document.getElementById("wrapper");
+	var grid = wrapper.getGridFragments()[0];
+	
+	// test state of tracks
+	is(grid.cols.tracks[1].state, "static", "Grid column track 1 is marked as static.");
+	is(grid.cols.tracks[2].state, "repeat", "Grid column track 2 is marked as repeat.");
+	
+	SimpleTest.finish();
+}
+</script>
+</head>
+<body onLoad="runTests();">
+
+	<div id="wrapper" class="wrapper">
+		<div id="boxA" class="box a">A</div>
+		<div class="box b">B</div>
+		<div class="box c">C</div>
+		<div class="box d">D</div>
+		<div class="box e">E</div>
+	</div>
+	
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/grid/test/chrome/test_grid_state.html
@@ -0,0 +1,54 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8">
+<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+<style>
+body {
+	margin: 40px;
+}
+.wrapper {
+	display: grid;
+	width: 600px;
+	grid-gap: 0px;
+	grid-template-columns: 50px repeat(auto-fit, 100px);
+	background-color: #f00;
+}
+.box {
+	background-color: #444;
+	color: #fff;
+}
+.a {
+	grid-column: 3;
+}
+</style>
+
+<script>
+'use strict';
+
+SimpleTest.waitForExplicitFinish();
+
+function runTests() {
+	var wrapper = document.getElementById("wrapper");
+	var grid = wrapper.getGridFragments()[0];
+	
+	// test count after removal
+	is(grid.cols.tracks.length, 2, "Grid column track array compensates for removed auto-fit columns.");
+	
+	// test state of tracks
+	is(grid.cols.tracks[0].state, "static", "Grid column track 0 is marked as static.");
+	is(grid.cols.tracks[1].state, "repeat", "Grid column track 1 is marked as repeat.");
+	
+	SimpleTest.finish();
+}
+</script>
+</head>
+<body onLoad="runTests();">
+
+	<div id="wrapper" class="wrapper">
+		<div id="boxA" class="box a">A</div>
+	</div>
+	
+</body>
+</html>
--- a/dom/moz.build
+++ b/dom/moz.build
@@ -57,16 +57,17 @@ DIRS += [
     'events',
     'fetch',
     'filehandle',
     'filesystem',
     'flyweb',
     'fmradio',
     'gamepad',
     'geolocation',
+    'grid',
     'html',
     'icc',
     'inputport',
     'json',
     'jsurl',
     'asmjscache',
     'mathml',
     'media',
--- a/dom/webidl/Element.webidl
+++ b/dom/webidl/Element.webidl
@@ -150,16 +150,26 @@ interface Element : Node {
   Attr? setAttributeNodeNS(Attr newAttr);
 
   [ChromeOnly]
   /**
    * Scrolls the element by (dx, dy) CSS pixels without doing any
    * layout flushing.
    */
   boolean scrollByNoFlush(long dx, long dy);
+
+  // Support reporting of Grid properties
+
+  /**
+   * If this element has a display:grid or display:inline-grid style,
+   * this property returns an object with computed values for grid
+   * tracks and lines.
+   */
+  [ChromeOnly, Pure]
+  sequence<Grid> getGridFragments();
 };
 
 // http://dev.w3.org/csswg/cssom-view/
 enum ScrollLogicalPosition { "start", "end" };
 dictionary ScrollIntoViewOptions : ScrollOptions {
   ScrollLogicalPosition block = "start";
 };
 
new file mode 100644
--- /dev/null
+++ b/dom/webidl/Grid.webidl
@@ -0,0 +1,54 @@
+/* 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/.
+ */
+
+[ChromeOnly]
+interface Grid
+{
+  readonly attribute GridDimension rows;
+  readonly attribute GridDimension cols;
+};
+
+[ChromeOnly]
+interface GridDimension
+{
+  readonly attribute GridLines lines;
+  readonly attribute GridTracks tracks;
+};
+
+[ChromeOnly]
+interface GridLines
+{
+  readonly attribute unsigned long length;
+  getter GridLine? item(unsigned long index);
+};
+
+[ChromeOnly]
+interface GridLine
+{
+  readonly attribute double start;
+  readonly attribute double breadth;
+  readonly attribute unsigned long number;
+  [Cached, Pure]
+  readonly attribute sequence<DOMString> names;
+};
+
+[ChromeOnly]
+interface GridTracks
+{
+  readonly attribute unsigned long length;
+  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 GridTrackState state;
+};
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -171,16 +171,17 @@ WEBIDL_FILES = [
     'FontFaceSet.webidl',
     'FontFaceSource.webidl',
     'FormData.webidl',
     'Function.webidl',
     'GainNode.webidl',
     'Geolocation.webidl',
     'GeometryUtils.webidl',
     'GetUserMediaRequest.webidl',
+    'Grid.webidl',
     'HDMIInputPort.webidl',
     'Headers.webidl',
     'HeapSnapshot.webidl',
     'History.webidl',
     'HTMLAllCollection.webidl',
     'HTMLAnchorElement.webidl',
     'HTMLAppletElement.webidl',
     'HTMLAreaElement.webidl',
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -20,16 +20,17 @@
 #include "nsDisplayList.h"
 #include "nsHashKeys.h"
 #include "nsIFrameInlines.h"
 #include "nsPresContext.h"
 #include "nsRenderingContext.h"
 #include "nsReadableUtils.h"
 #include "nsRuleNode.h"
 #include "nsStyleContext.h"
+#include "mozilla/dom/GridBinding.h"
 
 using namespace mozilla;
 typedef nsAbsoluteContainingBlock::AbsPosReflowFlags AbsPosReflowFlags;
 typedef nsGridContainerFrame::TrackSize TrackSize;
 const uint32_t nsGridContainerFrame::kTranslatedMaxLine =
   uint32_t(nsStyleGridLine::kMaxLine - nsStyleGridLine::kMinLine);
 const uint32_t nsGridContainerFrame::kAutoLine = kTranslatedMaxLine + 3457U;
 typedef nsTHashtable< nsPtrHashKey<nsIFrame> > FrameHashtable;
@@ -5508,38 +5509,16 @@ nsGridContainerFrame::Reflow(nsPresConte
       computedMinSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
     }
     Grid grid;
     grid.PlaceGridItems(gridReflowState, computedMinSize, computedSize,
                         aReflowState.ComputedMaxSize());
 
     gridReflowState.CalculateTrackSizes(grid, computedSize,
                                         nsLayoutUtils::PREF_ISIZE);
-
-    // FIXME bug 1229180: Instead of doing this on every reflow, we should only
-    // set these properties if they are needed.
-    nsTArray<nscoord> colTrackSizes(gridReflowState.mCols.mSizes.Length());
-    for (const TrackSize& sz : gridReflowState.mCols.mSizes) {
-      colTrackSizes.AppendElement(sz.mBase);
-    }
-    ComputedGridTrackInfo* colInfo = new ComputedGridTrackInfo(
-      gridReflowState.mColFunctions.mExplicitGridOffset,
-      gridReflowState.mColFunctions.NumExplicitTracks(),
-      Move(colTrackSizes));
-    Properties().Set(GridColTrackInfo(), colInfo);
-    
-    nsTArray<nscoord> rowTrackSizes(gridReflowState.mRows.mSizes.Length());
-    for (const TrackSize& sz : gridReflowState.mRows.mSizes) {
-      rowTrackSizes.AppendElement(sz.mBase);
-    }
-    ComputedGridTrackInfo* rowInfo = new ComputedGridTrackInfo(
-      gridReflowState.mRowFunctions.mExplicitGridOffset,
-      gridReflowState.mRowFunctions.NumExplicitTracks(),
-      Move(rowTrackSizes));
-    Properties().Set(GridRowTrackInfo(), rowInfo);
   } else {
     consumedBSize = GetConsumedBSize();
     gridReflowState.InitializeForContinuation(this, consumedBSize);
   }
 
   nscoord bSize = 0;
   if (computedBSize == NS_AUTOHEIGHT) {
     const uint32_t numRows = gridReflowState.mRows.mSizes.Length();
@@ -5595,16 +5574,97 @@ nsGridContainerFrame::Reflow(nsPresConte
       NS_FRAME_SET_OVERFLOW_INCOMPLETE(aStatus);
       aStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
     }
     bSize = 0;
     desiredSize.BSize(wm) = bSize + bp.BStartEnd(wm);
     aDesiredSize.SetSize(wm, desiredSize);
   }
 
+  // Now that we know column and row sizes and positions, set
+  // the ComputedGridTrackInfo.
+
+  // FIXME bug 1229180: Instead of doing this on every reflow, we should only
+  // set these properties if they are needed.
+  uint32_t colTrackCount = gridReflowState.mCols.mSizes.Length();
+  nsTArray<nscoord> colTrackPositions(colTrackCount);
+  nsTArray<nscoord> colTrackSizes(colTrackCount);
+  nsTArray<uint32_t> colTrackStates(colTrackCount);
+  uint32_t col = 0;
+  for (const TrackSize& sz : gridReflowState.mCols.mSizes) {
+    colTrackPositions.AppendElement(sz.mPosition);
+    colTrackSizes.AppendElement(sz.mBase);
+    bool isRepeat = ((col >= gridReflowState.mColFunctions.mRepeatAutoStart) &&
+                     (col < gridReflowState.mColFunctions.mRepeatAutoEnd));
+    colTrackStates.AppendElement(
+        isRepeat ?
+        (uint32_t)mozilla::dom::GridTrackState::Repeat :
+        (uint32_t)mozilla::dom::GridTrackState::Static
+    );
+
+    col++;
+  }
+  ComputedGridTrackInfo* colInfo = new ComputedGridTrackInfo(
+    gridReflowState.mColFunctions.mExplicitGridOffset,
+    gridReflowState.mColFunctions.NumExplicitTracks(),
+    0,
+    col,
+    Move(colTrackPositions),
+    Move(colTrackSizes),
+    Move(colTrackStates));
+  Properties().Set(GridColTrackInfo(), colInfo);
+
+  uint32_t rowTrackCount = gridReflowState.mRows.mSizes.Length();
+  nsTArray<nscoord> rowTrackPositions(rowTrackCount);
+  nsTArray<nscoord> rowTrackSizes(rowTrackCount);
+  nsTArray<uint32_t> rowTrackStates(rowTrackCount);
+  uint32_t row = 0;
+  for (const TrackSize& sz : gridReflowState.mRows.mSizes) {
+    rowTrackPositions.AppendElement(sz.mPosition);
+    rowTrackSizes.AppendElement(sz.mBase);
+    bool isRepeat = ((row >= gridReflowState.mRowFunctions.mRepeatAutoStart) &&
+                     (row < gridReflowState.mRowFunctions.mRepeatAutoEnd));
+    rowTrackStates.AppendElement(
+      isRepeat ?
+      (uint32_t)mozilla::dom::GridTrackState::Repeat :
+      (uint32_t)mozilla::dom::GridTrackState::Static
+    );
+
+    row++;
+  }
+  // Row info has to accomodate fragmentation of the grid, which may happen in
+  // later calls to Reflow. For now, presume that no more fragmentation will
+  // occur.
+  ComputedGridTrackInfo* rowInfo = new ComputedGridTrackInfo(
+    gridReflowState.mRowFunctions.mExplicitGridOffset,
+    gridReflowState.mRowFunctions.NumExplicitTracks(),
+    gridReflowState.mStartRow,
+    row,
+    Move(rowTrackPositions),
+    Move(rowTrackSizes),
+    Move(rowTrackStates));
+  Properties().Set(GridRowTrackInfo(), rowInfo);
+
+  if (prevInFlow) {
+    // This frame is fragmenting rows from a previous frame, so patch up
+    // the prior GridRowTrackInfo with a new end row.
+
+    ComputedGridTrackInfo* priorRowInfo =
+      prevInFlow->Properties().Get(GridRowTrackInfo());
+    ComputedGridTrackInfo* revisedPriorRowInfo = new ComputedGridTrackInfo(
+      priorRowInfo->mNumLeadingImplicitTracks,
+      priorRowInfo->mNumExplicitTracks,
+      priorRowInfo->mStartFragmentTrack,
+      gridReflowState.mStartRow,
+      Move(priorRowInfo->mPositions),
+      Move(priorRowInfo->mSizes),
+      Move(priorRowInfo->mStates));
+    prevInFlow->Properties().Set(GridRowTrackInfo(), revisedPriorRowInfo);
+  }
+
   if (!prevInFlow) {
     SharedGridData* sharedGridData = Properties().Get(SharedGridData::Prop());
     if (!NS_FRAME_IS_FULLY_COMPLETE(aStatus)) {
       if (!sharedGridData) {
         sharedGridData = new SharedGridData;
         Properties().Set(SharedGridData::Prop(), sharedGridData);
       }
       sharedGridData->mCols.mSizes.Clear();
--- a/layout/generic/nsGridContainerFrame.h
+++ b/layout/generic/nsGridContainerFrame.h
@@ -25,24 +25,36 @@ nsContainerFrame* NS_NewGridContainerFra
 namespace mozilla {
 /**
  * The number of implicit / explicit tracks and their sizes.
  */
 struct ComputedGridTrackInfo
 {
   ComputedGridTrackInfo(uint32_t aNumLeadingImplicitTracks,
                         uint32_t aNumExplicitTracks,
-                        nsTArray<nscoord>&& aSizes)
+                        uint32_t aStartFragmentTrack,
+                        uint32_t aEndFragmentTrack,
+                        nsTArray<nscoord>&& aPositions,
+                        nsTArray<nscoord>&& aSizes,
+                        nsTArray<uint32_t>&& aStates)
     : mNumLeadingImplicitTracks(aNumLeadingImplicitTracks)
     , mNumExplicitTracks(aNumExplicitTracks)
+    , mStartFragmentTrack(aStartFragmentTrack)
+    , mEndFragmentTrack(aEndFragmentTrack)
+    , mPositions(aPositions)
     , mSizes(aSizes)
+    , mStates(aStates)
   {}
   uint32_t mNumLeadingImplicitTracks;
   uint32_t mNumExplicitTracks;
+  uint32_t mStartFragmentTrack;
+  uint32_t mEndFragmentTrack;
+  nsTArray<nscoord> mPositions;
   nsTArray<nscoord> mSizes;
+  nsTArray<uint32_t> mStates;
 };
 } // namespace mozilla
 
 class nsGridContainerFrame final : public nsContainerFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS
   NS_DECL_QUERYFRAME_TARGET(nsGridContainerFrame)