GridTrackSize.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*
  2. * Copyright (c) 2022, Martin Falisse <mfalisse@outlook.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "GridTrackSize.h"
  7. #include <AK/String.h>
  8. #include <LibWeb/CSS/Size.h>
  9. namespace Web::CSS {
  10. GridSize::GridSize(Type type, LengthPercentage length_percentage)
  11. : m_value(move(length_percentage))
  12. {
  13. VERIFY(type == Type::FitContent);
  14. m_type = type;
  15. }
  16. GridSize::GridSize(LengthPercentage length_percentage)
  17. : m_type(Type::LengthPercentage)
  18. , m_value(move(length_percentage))
  19. {
  20. }
  21. GridSize::GridSize(Flex flex_factor)
  22. : m_type(Type::FlexibleLength)
  23. , m_value(move(flex_factor))
  24. {
  25. }
  26. GridSize::GridSize(Type type)
  27. : m_value { Empty() }
  28. {
  29. VERIFY(type == Type::MinContent || type == Type::MaxContent);
  30. m_type = type;
  31. }
  32. GridSize::GridSize()
  33. : m_type(Type::LengthPercentage)
  34. , m_value { Length::make_auto() }
  35. {
  36. }
  37. GridSize::~GridSize() = default;
  38. bool GridSize::is_auto(Layout::AvailableSize const& available_size) const
  39. {
  40. if (m_type == Type::LengthPercentage) {
  41. auto& length_percentage = m_value.get<LengthPercentage>();
  42. if (length_percentage.contains_percentage())
  43. return !available_size.is_definite();
  44. return length_percentage.is_auto();
  45. }
  46. return false;
  47. }
  48. bool GridSize::is_fixed(Layout::AvailableSize const& available_size) const
  49. {
  50. if (m_type == Type::LengthPercentage) {
  51. auto& length_percentage = m_value.get<LengthPercentage>();
  52. if (length_percentage.contains_percentage())
  53. return available_size.is_definite();
  54. return !length_percentage.is_auto();
  55. }
  56. return false;
  57. }
  58. bool GridSize::is_intrinsic(Layout::AvailableSize const& available_size) const
  59. {
  60. return is_auto(available_size) || is_max_content() || is_min_content() || is_fit_content();
  61. }
  62. GridSize GridSize::make_auto()
  63. {
  64. return GridSize(CSS::Length::make_auto());
  65. }
  66. Size GridSize::css_size() const
  67. {
  68. VERIFY(m_type == Type::LengthPercentage || m_type == Type::FitContent);
  69. auto& length_percentage = m_value.get<LengthPercentage>();
  70. if (length_percentage.is_auto())
  71. return CSS::Size::make_auto();
  72. if (length_percentage.is_length())
  73. return CSS::Size::make_length(length_percentage.length());
  74. if (length_percentage.is_calculated())
  75. return CSS::Size::make_calculated(length_percentage.calculated());
  76. return CSS::Size::make_percentage(length_percentage.percentage());
  77. }
  78. String GridSize::to_string() const
  79. {
  80. switch (m_type) {
  81. case Type::LengthPercentage:
  82. case Type::FitContent:
  83. return m_value.get<LengthPercentage>().to_string();
  84. case Type::FlexibleLength:
  85. return m_value.get<Flex>().to_string();
  86. case Type::MaxContent:
  87. return "max-content"_string;
  88. case Type::MinContent:
  89. return "min-content"_string;
  90. }
  91. VERIFY_NOT_REACHED();
  92. }
  93. GridMinMax::GridMinMax(GridSize min_grid_size, GridSize max_grid_size)
  94. : m_min_grid_size(min_grid_size)
  95. , m_max_grid_size(max_grid_size)
  96. {
  97. }
  98. String GridMinMax::to_string() const
  99. {
  100. StringBuilder builder;
  101. builder.append("minmax("sv);
  102. builder.appendff("{}", m_min_grid_size.to_string());
  103. builder.append(", "sv);
  104. builder.appendff("{}", m_max_grid_size.to_string());
  105. builder.append(")"sv);
  106. return MUST(builder.to_string());
  107. }
  108. GridFitContent::GridFitContent(GridSize max_grid_size)
  109. : m_max_grid_size(max_grid_size)
  110. {
  111. }
  112. GridFitContent::GridFitContent()
  113. : m_max_grid_size(GridSize::make_auto())
  114. {
  115. }
  116. String GridFitContent::to_string() const
  117. {
  118. return MUST(String::formatted("fit-content({})", m_max_grid_size.to_string()));
  119. }
  120. GridRepeat::GridRepeat(GridTrackSizeList grid_track_size_list, int repeat_count)
  121. : m_type(Type::Default)
  122. , m_grid_track_size_list(grid_track_size_list)
  123. , m_repeat_count(repeat_count)
  124. {
  125. }
  126. GridRepeat::GridRepeat(GridTrackSizeList grid_track_size_list, Type type)
  127. : m_type(type)
  128. , m_grid_track_size_list(grid_track_size_list)
  129. {
  130. }
  131. GridRepeat::GridRepeat()
  132. {
  133. }
  134. String GridRepeat::to_string() const
  135. {
  136. StringBuilder builder;
  137. builder.append("repeat("sv);
  138. switch (m_type) {
  139. case Type::AutoFit:
  140. builder.append("auto-fill"sv);
  141. break;
  142. case Type::AutoFill:
  143. builder.append("auto-fit"sv);
  144. break;
  145. case Type::Default:
  146. builder.appendff("{}", m_repeat_count);
  147. break;
  148. default:
  149. VERIFY_NOT_REACHED();
  150. }
  151. builder.append(", "sv);
  152. builder.appendff("{}", m_grid_track_size_list.to_string());
  153. builder.append(")"sv);
  154. return MUST(builder.to_string());
  155. }
  156. ExplicitGridTrack::ExplicitGridTrack(CSS::GridFitContent grid_fit_content)
  157. : m_type(Type::FitContent)
  158. , m_grid_fit_content(grid_fit_content)
  159. {
  160. }
  161. ExplicitGridTrack::ExplicitGridTrack(CSS::GridMinMax grid_minmax)
  162. : m_type(Type::MinMax)
  163. , m_grid_minmax(grid_minmax)
  164. {
  165. }
  166. ExplicitGridTrack::ExplicitGridTrack(CSS::GridRepeat grid_repeat)
  167. : m_type(Type::Repeat)
  168. , m_grid_repeat(grid_repeat)
  169. {
  170. }
  171. ExplicitGridTrack::ExplicitGridTrack(CSS::GridSize grid_size)
  172. : m_type(Type::Default)
  173. , m_grid_size(grid_size)
  174. {
  175. }
  176. String ExplicitGridTrack::to_string() const
  177. {
  178. switch (m_type) {
  179. case Type::FitContent:
  180. return m_grid_fit_content.to_string();
  181. case Type::MinMax:
  182. return m_grid_minmax.to_string();
  183. case Type::Repeat:
  184. return m_grid_repeat.to_string();
  185. case Type::Default:
  186. return m_grid_size.to_string();
  187. default:
  188. VERIFY_NOT_REACHED();
  189. }
  190. }
  191. String GridLineNames::to_string() const
  192. {
  193. StringBuilder builder;
  194. builder.append("["sv);
  195. builder.join(' ', names);
  196. builder.append("]"sv);
  197. return MUST(builder.to_string());
  198. }
  199. GridTrackSizeList::GridTrackSizeList(Vector<Variant<ExplicitGridTrack, GridLineNames>>&& list)
  200. : m_list(move(list))
  201. {
  202. }
  203. GridTrackSizeList::GridTrackSizeList()
  204. {
  205. }
  206. GridTrackSizeList GridTrackSizeList::make_none()
  207. {
  208. return GridTrackSizeList();
  209. }
  210. String GridTrackSizeList::to_string() const
  211. {
  212. StringBuilder builder;
  213. for (auto const& line_definition_or_name : m_list) {
  214. if (!builder.is_empty())
  215. builder.append(" "sv);
  216. if (line_definition_or_name.has<ExplicitGridTrack>()) {
  217. builder.append(line_definition_or_name.get<ExplicitGridTrack>().to_string());
  218. } else if (line_definition_or_name.has<GridLineNames>()) {
  219. auto const& line_names = line_definition_or_name.get<GridLineNames>();
  220. builder.append(line_names.to_string());
  221. }
  222. }
  223. return MUST(builder.to_string());
  224. }
  225. Vector<ExplicitGridTrack> GridTrackSizeList::track_list() const
  226. {
  227. Vector<ExplicitGridTrack> track_list;
  228. for (auto const& line_definition_or_name : m_list) {
  229. if (line_definition_or_name.has<ExplicitGridTrack>())
  230. track_list.append(line_definition_or_name.get<ExplicitGridTrack>());
  231. }
  232. return track_list;
  233. }
  234. bool GridTrackSizeList::operator==(GridTrackSizeList const& other) const
  235. {
  236. if (m_list.size() != other.m_list.size())
  237. return false;
  238. for (size_t i = 0; i < m_list.size(); ++i) {
  239. if (m_list[i] != other.m_list[i])
  240. return false;
  241. }
  242. return true;
  243. }
  244. }