Grid.cpp (4269B)
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 "Grid.h" 8 9 #include "GridArea.h" 10 #include "GridDimension.h" 11 #include "mozilla/dom/Element.h" 12 #include "mozilla/dom/GridBinding.h" 13 #include "nsGridContainerFrame.h" 14 #include "nsTHashSet.h" 15 16 namespace mozilla::dom { 17 18 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(Grid) 19 20 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Grid) 21 tmp->ForgetFrame(); 22 NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent, mRows, mCols, mAreas) 23 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER 24 NS_IMPL_CYCLE_COLLECTION_UNLINK_END 25 26 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Grid) 27 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent, mRows, mCols, mAreas) 28 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 29 30 NS_IMPL_CYCLE_COLLECTING_ADDREF(Grid) 31 NS_IMPL_CYCLE_COLLECTING_RELEASE(Grid) 32 33 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Grid) 34 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 35 NS_INTERFACE_MAP_ENTRY(nsISupports) 36 NS_INTERFACE_MAP_END 37 38 Grid::Grid(nsISupports* aParent, nsGridContainerFrame* aFrame) 39 : mParent(do_QueryInterface(aParent)), 40 mFrame(aFrame), 41 mRows(new GridDimension(this)), 42 mCols(new GridDimension(this)) { 43 MOZ_ASSERT(aFrame, 44 "Should never be instantiated with a null nsGridContainerFrame"); 45 46 aFrame->SetProperty(nsGridContainerFrame::GridFragmentInfo(), this); 47 48 // Construct areas first, because lines may need to reference them 49 // to extract additional names for boundary lines. 50 51 // Add implicit areas first. Track the names that we add here, because 52 // we will ignore future explicit areas with the same name. 53 nsTHashSet<RefPtr<nsAtom>> namesSeen; 54 nsGridContainerFrame::ImplicitNamedAreas* implicitAreas = 55 aFrame->GetImplicitNamedAreas(); 56 if (implicitAreas) { 57 for (auto iter = implicitAreas->iter(); !iter.done(); iter.next()) { 58 auto& areaInfo = iter.get().value(); 59 namesSeen.Insert(areaInfo.name.AsAtom()); 60 GridArea* area = 61 new GridArea(this, areaInfo.name.AsAtom(), GridDeclaration::Implicit, 62 areaInfo.rows.start, areaInfo.rows.end, 63 areaInfo.columns.start, areaInfo.columns.end); 64 mAreas.AppendElement(area); 65 } 66 } 67 68 // Add explicit areas next, as long as they don't have the same name 69 // as the implicit areas, because the implicit values override what was 70 // initially available in the explicit areas. 71 if (auto* explicitAreas = aFrame->GetExplicitNamedAreas()) { 72 for (auto& areaInfo : explicitAreas->AsSpan()) { 73 if (!namesSeen.Contains(areaInfo.name.AsAtom())) { 74 GridArea* area = new GridArea( 75 this, areaInfo.name.AsAtom(), GridDeclaration::Explicit, 76 areaInfo.rows.start, areaInfo.rows.end, areaInfo.columns.start, 77 areaInfo.columns.end); 78 mAreas.AppendElement(area); 79 } 80 } 81 } 82 83 // Now construct the tracks and lines. 84 const ComputedGridTrackInfo* rowTrackInfo = aFrame->GetComputedTemplateRows(); 85 const ComputedGridLineInfo* rowLineInfo = 86 aFrame->GetComputedTemplateRowLines(); 87 mRows->SetTrackInfo(rowTrackInfo); 88 mRows->SetLineInfo(rowTrackInfo, rowLineInfo, mAreas, true); 89 90 const ComputedGridTrackInfo* columnTrackInfo = 91 aFrame->GetComputedTemplateColumns(); 92 const ComputedGridLineInfo* columnLineInfo = 93 aFrame->GetComputedTemplateColumnLines(); 94 mCols->SetTrackInfo(columnTrackInfo); 95 mCols->SetLineInfo(columnTrackInfo, columnLineInfo, mAreas, false); 96 } 97 98 Grid::~Grid() = default; 99 100 JSObject* Grid::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) { 101 return Grid_Binding::Wrap(aCx, this, aGivenProto); 102 } 103 104 void Grid::ForgetFrame() { 105 if (mFrame.IsAlive()) { 106 mFrame->RemoveProperty(nsGridContainerFrame::GridFragmentInfo()); 107 mFrame.Clear(mFrame->PresContext()->GetPresShell()); 108 } 109 } 110 111 GridDimension* Grid::Rows() const { return mRows; } 112 113 GridDimension* Grid::Cols() const { return mCols; } 114 115 void Grid::GetAreas(nsTArray<RefPtr<GridArea>>& aAreas) const { 116 aAreas = mAreas.Clone(); 117 } 118 119 } // namespace mozilla::dom