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::dom {
15 
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(GridTracks,mParent,mTracks)16 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(GridTracks, mParent, mTracks)
17 NS_IMPL_CYCLE_COLLECTING_ADDREF(GridTracks)
18 NS_IMPL_CYCLE_COLLECTING_RELEASE(GridTracks)
19 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GridTracks)
20   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
21   NS_INTERFACE_MAP_ENTRY(nsISupports)
22 NS_INTERFACE_MAP_END
23 
24 GridTracks::GridTracks(GridDimension* aParent) : mParent(aParent) {
25   MOZ_ASSERT(aParent, "Should never be instantiated with a null GridDimension");
26 }
27 
28 GridTracks::~GridTracks() = default;
29 
WrapObject(JSContext * aCx,JS::Handle<JSObject * > aGivenProto)30 JSObject* GridTracks::WrapObject(JSContext* aCx,
31                                  JS::Handle<JSObject*> aGivenProto) {
32   return GridTracks_Binding::Wrap(aCx, this, aGivenProto);
33 }
34 
Length() const35 uint32_t GridTracks::Length() const { return mTracks.Length(); }
36 
Item(uint32_t aIndex)37 GridTrack* GridTracks::Item(uint32_t aIndex) {
38   return mTracks.SafeElementAt(aIndex);
39 }
40 
IndexedGetter(uint32_t aIndex,bool & aFound)41 GridTrack* GridTracks::IndexedGetter(uint32_t aIndex, bool& aFound) {
42   aFound = aIndex < mTracks.Length();
43   if (!aFound) {
44     return nullptr;
45   }
46   return mTracks[aIndex];
47 }
48 
SetTrackInfo(const ComputedGridTrackInfo * aTrackInfo)49 void GridTracks::SetTrackInfo(const ComputedGridTrackInfo* aTrackInfo) {
50   // rebuild the tracks based on aTrackInfo
51   mTracks.Clear();
52 
53   if (!aTrackInfo) {
54     return;
55   }
56 
57   nscoord lastTrackEdge = 0;
58   uint32_t repeatIndex = 0;
59   auto AppendRemovedAutoFits = [this, &aTrackInfo, &lastTrackEdge,
60                                 &repeatIndex]() {
61     uint32_t numRepeatTracks = aTrackInfo->mRemovedRepeatTracks.Length();
62     // Add in removed auto-fit tracks
63     while (repeatIndex < numRepeatTracks &&
64            aTrackInfo->mRemovedRepeatTracks[repeatIndex]) {
65       RefPtr<GridTrack> track = new GridTrack(this);
66       mTracks.AppendElement(track);
67       track->SetTrackValues(
68           nsPresContext::AppUnitsToDoubleCSSPixels(lastTrackEdge),
69           nsPresContext::AppUnitsToDoubleCSSPixels(0),
70           GridDeclaration::Explicit, GridTrackState::Removed);
71       repeatIndex++;
72     }
73     repeatIndex++;
74   };
75 
76   for (size_t i = aTrackInfo->mStartFragmentTrack;
77        i < aTrackInfo->mEndFragmentTrack; i++) {
78     if (i >= aTrackInfo->mRepeatFirstTrack) {
79       // Append removed auto-fit tracks, if appropriate. The
80       // AppendRemovedAutoFits function exits early once it has been called
81       // aTrackInfo->mRemovedRepeatTracks.Length() times -- a check we don't
82       // replicate here or at subsequent calling sites.
83       AppendRemovedAutoFits();
84     }
85 
86     RefPtr<GridTrack> track = new GridTrack(this);
87     mTracks.AppendElement(track);
88     track->SetTrackValues(
89         nsPresContext::AppUnitsToDoubleCSSPixels(aTrackInfo->mPositions[i]),
90         nsPresContext::AppUnitsToDoubleCSSPixels(aTrackInfo->mSizes[i]),
91         (
92             // Implicit if index is before the first explicit track, or after
93             // the last explicit track.
94             (i < aTrackInfo->mNumLeadingImplicitTracks) ||
95                     (i >= aTrackInfo->mNumLeadingImplicitTracks +
96                               aTrackInfo->mNumExplicitTracks)
97                 ? GridDeclaration::Implicit
98                 : GridDeclaration::Explicit),
99         GridTrackState(aTrackInfo->mStates[i]));
100 
101     lastTrackEdge = aTrackInfo->mPositions[i] + aTrackInfo->mSizes[i];
102   }
103 
104   // Append any trailing removed auto-fit tracks.
105   AppendRemovedAutoFits();
106 }
107 
108 }  // namespace mozilla::dom
109