1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "GridTracks.h"
8 
9 #include "GridDimension.h"
10 #include "GridTrack.h"
11 #include "mozilla/dom/GridBinding.h"
12 #include "nsGridContainerFrame.h"
13 
14 namespace mozilla {
15 namespace dom {
16 
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(GridTracks,mParent,mTracks)17 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(GridTracks, mParent, mTracks)
18 NS_IMPL_CYCLE_COLLECTING_ADDREF(GridTracks)
19 NS_IMPL_CYCLE_COLLECTING_RELEASE(GridTracks)
20 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GridTracks)
21   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
22   NS_INTERFACE_MAP_ENTRY(nsISupports)
23 NS_INTERFACE_MAP_END
24 
25 GridTracks::GridTracks(GridDimension* aParent) : mParent(aParent) {
26   MOZ_ASSERT(aParent, "Should never be instantiated with a null GridDimension");
27 }
28 
29 GridTracks::~GridTracks() = default;
30 
WrapObject(JSContext * aCx,JS::Handle<JSObject * > aGivenProto)31 JSObject* GridTracks::WrapObject(JSContext* aCx,
32                                  JS::Handle<JSObject*> aGivenProto) {
33   return GridTracks_Binding::Wrap(aCx, this, aGivenProto);
34 }
35 
Length() const36 uint32_t GridTracks::Length() const { return mTracks.Length(); }
37 
Item(uint32_t aIndex)38 GridTrack* GridTracks::Item(uint32_t aIndex) {
39   return mTracks.SafeElementAt(aIndex);
40 }
41 
IndexedGetter(uint32_t aIndex,bool & aFound)42 GridTrack* GridTracks::IndexedGetter(uint32_t aIndex, bool& aFound) {
43   aFound = aIndex < mTracks.Length();
44   if (!aFound) {
45     return nullptr;
46   }
47   return mTracks[aIndex];
48 }
49 
SetTrackInfo(const ComputedGridTrackInfo * aTrackInfo)50 void GridTracks::SetTrackInfo(const ComputedGridTrackInfo* aTrackInfo) {
51   // rebuild the tracks based on aTrackInfo
52   mTracks.Clear();
53 
54   if (!aTrackInfo) {
55     return;
56   }
57 
58   nscoord lastTrackEdge = 0;
59   uint32_t repeatIndex = 0;
60   auto AppendRemovedAutoFits = [this, &aTrackInfo, &lastTrackEdge,
61                                 &repeatIndex]() {
62     uint32_t numRepeatTracks = aTrackInfo->mRemovedRepeatTracks.Length();
63     // Add in removed auto-fit tracks
64     while (repeatIndex < numRepeatTracks &&
65            aTrackInfo->mRemovedRepeatTracks[repeatIndex]) {
66       RefPtr<GridTrack> track = new GridTrack(this);
67       mTracks.AppendElement(track);
68       track->SetTrackValues(
69           nsPresContext::AppUnitsToDoubleCSSPixels(lastTrackEdge),
70           nsPresContext::AppUnitsToDoubleCSSPixels(0),
71           GridDeclaration::Explicit, GridTrackState::Removed);
72       repeatIndex++;
73     }
74     repeatIndex++;
75   };
76 
77   for (size_t i = aTrackInfo->mStartFragmentTrack;
78        i < aTrackInfo->mEndFragmentTrack; i++) {
79     if (i >= aTrackInfo->mRepeatFirstTrack) {
80       // Append removed auto-fit tracks, if appropriate. The
81       // AppendRemovedAutoFits function exits early once it has been called
82       // aTrackInfo->mRemovedRepeatTracks.Length() times -- a check we don't
83       // replicate here or at subsequent calling sites.
84       AppendRemovedAutoFits();
85     }
86 
87     RefPtr<GridTrack> track = new GridTrack(this);
88     mTracks.AppendElement(track);
89     track->SetTrackValues(
90         nsPresContext::AppUnitsToDoubleCSSPixels(aTrackInfo->mPositions[i]),
91         nsPresContext::AppUnitsToDoubleCSSPixels(aTrackInfo->mSizes[i]),
92         (
93             // Implicit if index is before the first explicit track, or after
94             // the last explicit track.
95             (i < aTrackInfo->mNumLeadingImplicitTracks) ||
96                     (i >= aTrackInfo->mNumLeadingImplicitTracks +
97                               aTrackInfo->mNumExplicitTracks)
98                 ? GridDeclaration::Implicit
99                 : GridDeclaration::Explicit),
100         GridTrackState(aTrackInfo->mStates[i]));
101 
102     lastTrackEdge = aTrackInfo->mPositions[i] + aTrackInfo->mSizes[i];
103   }
104 
105   // Append any trailing removed auto-fit tracks.
106   AppendRemovedAutoFits();
107 }
108 
109 }  // namespace dom
110 }  // namespace mozilla
111