StyleValue.h 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
  4. * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
  5. *
  6. * SPDX-License-Identifier: BSD-2-Clause
  7. */
  8. #pragma once
  9. #include <AK/NonnullOwnPtr.h>
  10. #include <AK/NonnullOwnPtrVector.h>
  11. #include <AK/NonnullRefPtrVector.h>
  12. #include <AK/RefCounted.h>
  13. #include <AK/RefPtr.h>
  14. #include <AK/String.h>
  15. #include <AK/StringView.h>
  16. #include <AK/URL.h>
  17. #include <AK/Variant.h>
  18. #include <AK/Vector.h>
  19. #include <AK/WeakPtr.h>
  20. #include <LibGfx/Bitmap.h>
  21. #include <LibGfx/Color.h>
  22. #include <LibWeb/CSS/Length.h>
  23. #include <LibWeb/CSS/Parser/StyleComponentValueRule.h>
  24. #include <LibWeb/CSS/PropertyID.h>
  25. #include <LibWeb/CSS/ValueID.h>
  26. #include <LibWeb/Forward.h>
  27. #include <LibWeb/Loader/ImageResource.h>
  28. namespace Web::CSS {
  29. enum class AlignItems {
  30. FlexStart,
  31. FlexEnd,
  32. Center,
  33. Baseline,
  34. Stretch,
  35. };
  36. enum class Clear {
  37. None,
  38. Left,
  39. Right,
  40. Both,
  41. };
  42. enum class Cursor {
  43. Auto,
  44. Default,
  45. None,
  46. ContextMenu,
  47. Help,
  48. Pointer,
  49. Progress,
  50. Wait,
  51. Cell,
  52. Crosshair,
  53. Text,
  54. VerticalText,
  55. Alias,
  56. Copy,
  57. Move,
  58. NoDrop,
  59. NotAllowed,
  60. Grab,
  61. Grabbing,
  62. EResize,
  63. NResize,
  64. NeResize,
  65. NwResize,
  66. SResize,
  67. SeResize,
  68. SwResize,
  69. WResize,
  70. EwResize,
  71. NsResize,
  72. NeswResize,
  73. NwseResize,
  74. ColResize,
  75. RowResize,
  76. AllScroll,
  77. ZoomIn,
  78. ZoomOut,
  79. };
  80. enum class Display {
  81. None,
  82. Block,
  83. Inline,
  84. InlineBlock,
  85. ListItem,
  86. Table,
  87. TableRow,
  88. TableCell,
  89. TableHeaderGroup,
  90. TableRowGroup,
  91. TableFooterGroup,
  92. TableColumn,
  93. TableColumnGroup,
  94. TableCaption,
  95. Flex,
  96. };
  97. enum class FlexBasis {
  98. Content,
  99. Length,
  100. Auto,
  101. };
  102. enum class FlexDirection {
  103. Row,
  104. RowReverse,
  105. Column,
  106. ColumnReverse,
  107. };
  108. enum class FlexWrap {
  109. Nowrap,
  110. Wrap,
  111. WrapReverse
  112. };
  113. enum class Float {
  114. None,
  115. Left,
  116. Right,
  117. };
  118. enum class JustifyContent {
  119. FlexStart,
  120. FlexEnd,
  121. Center,
  122. SpaceBetween,
  123. SpaceAround,
  124. };
  125. enum class LineStyle {
  126. None,
  127. Hidden,
  128. Dotted,
  129. Dashed,
  130. Solid,
  131. Double,
  132. Groove,
  133. Ridge,
  134. Inset,
  135. Outset,
  136. };
  137. enum class ListStyleType {
  138. None,
  139. Disc,
  140. Circle,
  141. Square,
  142. Decimal,
  143. DecimalLeadingZero,
  144. LowerAlpha,
  145. LowerLatin,
  146. LowerRoman,
  147. UpperAlpha,
  148. UpperLatin,
  149. UpperRoman,
  150. };
  151. enum class Overflow : u8 {
  152. Auto,
  153. Clip,
  154. Hidden,
  155. Scroll,
  156. Visible,
  157. };
  158. enum class Position {
  159. Static,
  160. Relative,
  161. Absolute,
  162. Fixed,
  163. Sticky,
  164. };
  165. enum class Repeat : u8 {
  166. NoRepeat,
  167. Repeat,
  168. Round,
  169. Space,
  170. };
  171. enum class TextAlign {
  172. Left,
  173. Center,
  174. Right,
  175. Justify,
  176. LibwebCenter,
  177. };
  178. enum class TextDecorationLine {
  179. None,
  180. Underline,
  181. Overline,
  182. LineThrough,
  183. Blink,
  184. };
  185. enum class TextTransform {
  186. None,
  187. Capitalize,
  188. Uppercase,
  189. Lowercase,
  190. FullWidth,
  191. FullSizeKana,
  192. };
  193. enum class TransformFunction {
  194. TranslateY,
  195. };
  196. enum class WhiteSpace {
  197. Normal,
  198. Pre,
  199. Nowrap,
  200. PreLine,
  201. PreWrap,
  202. };
  203. class StyleValue : public RefCounted<StyleValue> {
  204. public:
  205. virtual ~StyleValue();
  206. enum class Type {
  207. Background,
  208. BackgroundRepeat,
  209. Border,
  210. BorderRadius,
  211. BoxShadow,
  212. Calculated,
  213. Color,
  214. CombinedBorderRadius,
  215. CustomProperty,
  216. Flex,
  217. FlexFlow,
  218. Font,
  219. Identifier,
  220. Image,
  221. Inherit,
  222. Initial,
  223. Invalid,
  224. Length,
  225. ListStyle,
  226. Numeric,
  227. Overflow,
  228. String,
  229. TextDecoration,
  230. Transformation,
  231. Unset,
  232. ValueList,
  233. };
  234. Type type() const { return m_type; }
  235. bool is_background() const { return type() == Type::Background; }
  236. bool is_background_repeat() const { return type() == Type::BackgroundRepeat; }
  237. bool is_border() const { return type() == Type::Border; }
  238. bool is_border_radius() const { return type() == Type::BorderRadius; }
  239. bool is_box_shadow() const { return type() == Type::BoxShadow; }
  240. bool is_calculated() const { return type() == Type::Calculated; }
  241. bool is_color() const { return type() == Type::Color; }
  242. bool is_custom_property() const { return type() == Type::CustomProperty; }
  243. bool is_flex() const { return type() == Type::Flex; }
  244. bool is_flex_flow() const { return type() == Type::FlexFlow; }
  245. bool is_font() const { return type() == Type::Font; }
  246. bool is_identifier() const { return type() == Type::Identifier; }
  247. bool is_image() const { return type() == Type::Image; }
  248. bool is_inherit() const { return type() == Type::Inherit; }
  249. bool is_initial() const { return type() == Type::Initial; }
  250. bool is_length() const { return type() == Type::Length; }
  251. bool is_list_style() const { return type() == Type::ListStyle; }
  252. bool is_numeric() const { return type() == Type::Numeric; }
  253. bool is_overflow() const { return type() == Type::Overflow; }
  254. bool is_string() const { return type() == Type::String; }
  255. bool is_text_decoration() const { return type() == Type::TextDecoration; }
  256. bool is_transformation() const { return type() == Type::Transformation; }
  257. bool is_unset() const { return type() == Type::Unset; }
  258. bool is_value_list() const { return type() == Type::ValueList; }
  259. bool is_builtin() const { return is_inherit() || is_initial() || is_unset(); }
  260. BackgroundRepeatStyleValue const& as_background_repeat() const;
  261. BackgroundStyleValue const& as_background() const;
  262. BorderRadiusStyleValue const& as_border_radius() const;
  263. BorderStyleValue const& as_border() const;
  264. BoxShadowStyleValue const& as_box_shadow() const;
  265. CalculatedStyleValue const& as_calculated() const;
  266. ColorStyleValue const& as_color() const;
  267. CustomStyleValue const& as_custom_property() const;
  268. FlexFlowStyleValue const& as_flex_flow() const;
  269. FlexStyleValue const& as_flex() const;
  270. FontStyleValue const& as_font() const;
  271. IdentifierStyleValue const& as_identifier() const;
  272. ImageStyleValue const& as_image() const;
  273. InheritStyleValue const& as_inherit() const;
  274. InitialStyleValue const& as_initial() const;
  275. LengthStyleValue const& as_length() const;
  276. ListStyleStyleValue const& as_list_style() const;
  277. NumericStyleValue const& as_numeric() const;
  278. OverflowStyleValue const& as_overflow() const;
  279. StringStyleValue const& as_string() const;
  280. TextDecorationStyleValue const& as_text_decoration() const;
  281. TransformationStyleValue const& as_transformation() const;
  282. UnsetStyleValue const& as_unset() const;
  283. StyleValueList const& as_value_list() const;
  284. BackgroundRepeatStyleValue& as_background_repeat() { return const_cast<BackgroundRepeatStyleValue&>(const_cast<StyleValue const&>(*this).as_background_repeat()); }
  285. BackgroundStyleValue& as_background() { return const_cast<BackgroundStyleValue&>(const_cast<StyleValue const&>(*this).as_background()); }
  286. BorderRadiusStyleValue& as_border_radius() { return const_cast<BorderRadiusStyleValue&>(const_cast<StyleValue const&>(*this).as_border_radius()); }
  287. BorderStyleValue& as_border() { return const_cast<BorderStyleValue&>(const_cast<StyleValue const&>(*this).as_border()); }
  288. BoxShadowStyleValue& as_box_shadow() { return const_cast<BoxShadowStyleValue&>(const_cast<StyleValue const&>(*this).as_box_shadow()); }
  289. CalculatedStyleValue& as_calculated() { return const_cast<CalculatedStyleValue&>(const_cast<StyleValue const&>(*this).as_calculated()); }
  290. ColorStyleValue& as_color() { return const_cast<ColorStyleValue&>(const_cast<StyleValue const&>(*this).as_color()); }
  291. CustomStyleValue& as_custom_property() { return const_cast<CustomStyleValue&>(const_cast<StyleValue const&>(*this).as_custom_property()); }
  292. FlexFlowStyleValue& as_flex_flow() { return const_cast<FlexFlowStyleValue&>(const_cast<StyleValue const&>(*this).as_flex_flow()); }
  293. FlexStyleValue& as_flex() { return const_cast<FlexStyleValue&>(const_cast<StyleValue const&>(*this).as_flex()); }
  294. FontStyleValue& as_font() { return const_cast<FontStyleValue&>(const_cast<StyleValue const&>(*this).as_font()); }
  295. IdentifierStyleValue& as_identifier() { return const_cast<IdentifierStyleValue&>(const_cast<StyleValue const&>(*this).as_identifier()); }
  296. ImageStyleValue& as_image() { return const_cast<ImageStyleValue&>(const_cast<StyleValue const&>(*this).as_image()); }
  297. InheritStyleValue& as_inherit() { return const_cast<InheritStyleValue&>(const_cast<StyleValue const&>(*this).as_inherit()); }
  298. InitialStyleValue& as_initial() { return const_cast<InitialStyleValue&>(const_cast<StyleValue const&>(*this).as_initial()); }
  299. LengthStyleValue& as_length() { return const_cast<LengthStyleValue&>(const_cast<StyleValue const&>(*this).as_length()); }
  300. ListStyleStyleValue& as_list_style() { return const_cast<ListStyleStyleValue&>(const_cast<StyleValue const&>(*this).as_list_style()); }
  301. NumericStyleValue& as_numeric() { return const_cast<NumericStyleValue&>(const_cast<StyleValue const&>(*this).as_numeric()); }
  302. OverflowStyleValue& as_overflow() { return const_cast<OverflowStyleValue&>(const_cast<StyleValue const&>(*this).as_overflow()); }
  303. StringStyleValue& as_string() { return const_cast<StringStyleValue&>(const_cast<StyleValue const&>(*this).as_string()); }
  304. TextDecorationStyleValue& as_text_decoration() { return const_cast<TextDecorationStyleValue&>(const_cast<StyleValue const&>(*this).as_text_decoration()); }
  305. TransformationStyleValue& as_transformation() { return const_cast<TransformationStyleValue&>(const_cast<StyleValue const&>(*this).as_transformation()); }
  306. UnsetStyleValue& as_unset() { return const_cast<UnsetStyleValue&>(const_cast<StyleValue const&>(*this).as_unset()); }
  307. StyleValueList& as_value_list() { return const_cast<StyleValueList&>(const_cast<StyleValue const&>(*this).as_value_list()); }
  308. virtual bool has_auto() const { return false; }
  309. virtual bool has_color() const { return false; }
  310. virtual bool has_identifier() const { return false; }
  311. virtual bool has_length() const { return false; }
  312. virtual bool has_number() const { return false; }
  313. virtual Color to_color(Layout::NodeWithStyle const&) const { return {}; }
  314. virtual CSS::ValueID to_identifier() const { return ValueID::Invalid; }
  315. virtual Length to_length() const { return {}; }
  316. virtual float to_number() const { return {}; }
  317. virtual String to_string() const = 0;
  318. bool operator==(const StyleValue& other) const { return equals(other); }
  319. bool operator!=(const StyleValue& other) const { return !(*this == other); }
  320. virtual bool equals(const StyleValue& other) const
  321. {
  322. if (type() != other.type())
  323. return false;
  324. return to_string() == other.to_string();
  325. }
  326. protected:
  327. explicit StyleValue(Type);
  328. private:
  329. Type m_type { Type::Invalid };
  330. };
  331. class BackgroundStyleValue final : public StyleValue {
  332. public:
  333. static NonnullRefPtr<BackgroundStyleValue> create(
  334. NonnullRefPtr<StyleValue> color,
  335. NonnullRefPtr<StyleValue> image,
  336. NonnullRefPtr<StyleValue> repeat_x,
  337. NonnullRefPtr<StyleValue> repeat_y)
  338. {
  339. return adopt_ref(*new BackgroundStyleValue(color, image, repeat_x, repeat_y));
  340. }
  341. virtual ~BackgroundStyleValue() override { }
  342. NonnullRefPtr<StyleValue> color() const { return m_color; }
  343. NonnullRefPtr<StyleValue> image() const { return m_image; }
  344. NonnullRefPtr<StyleValue> repeat_x() const { return m_repeat_x; }
  345. NonnullRefPtr<StyleValue> repeat_y() const { return m_repeat_y; }
  346. virtual String to_string() const override
  347. {
  348. return String::formatted("{} {} {} {}", m_color->to_string(), m_image->to_string(), m_repeat_x->to_string(), m_repeat_y->to_string());
  349. }
  350. private:
  351. BackgroundStyleValue(
  352. NonnullRefPtr<StyleValue> color,
  353. NonnullRefPtr<StyleValue> image,
  354. NonnullRefPtr<StyleValue> repeat_x,
  355. NonnullRefPtr<StyleValue> repeat_y)
  356. : StyleValue(Type::Background)
  357. , m_color(color)
  358. , m_image(image)
  359. , m_repeat_x(repeat_x)
  360. , m_repeat_y(repeat_y)
  361. {
  362. }
  363. NonnullRefPtr<StyleValue> m_color;
  364. NonnullRefPtr<StyleValue> m_image;
  365. // FIXME: background-position
  366. // FIXME: background-size
  367. NonnullRefPtr<StyleValue> m_repeat_x;
  368. NonnullRefPtr<StyleValue> m_repeat_y;
  369. // FIXME: background-attachment
  370. // FIXME: background-clip
  371. // FIXME: background-origin
  372. };
  373. class BackgroundRepeatStyleValue final : public StyleValue {
  374. public:
  375. static NonnullRefPtr<BackgroundRepeatStyleValue> create(NonnullRefPtr<StyleValue> repeat_x, NonnullRefPtr<StyleValue> repeat_y)
  376. {
  377. return adopt_ref(*new BackgroundRepeatStyleValue(repeat_x, repeat_y));
  378. }
  379. virtual ~BackgroundRepeatStyleValue() override { }
  380. NonnullRefPtr<StyleValue> repeat_x() const { return m_repeat_x; }
  381. NonnullRefPtr<StyleValue> repeat_y() const { return m_repeat_y; }
  382. virtual String to_string() const override
  383. {
  384. return String::formatted("{} {}", m_repeat_x->to_string(), m_repeat_y->to_string());
  385. }
  386. private:
  387. BackgroundRepeatStyleValue(NonnullRefPtr<StyleValue> repeat_x, NonnullRefPtr<StyleValue> repeat_y)
  388. : StyleValue(Type::BackgroundRepeat)
  389. , m_repeat_x(repeat_x)
  390. , m_repeat_y(repeat_y)
  391. {
  392. }
  393. NonnullRefPtr<StyleValue> m_repeat_x;
  394. NonnullRefPtr<StyleValue> m_repeat_y;
  395. };
  396. class BorderStyleValue final : public StyleValue {
  397. public:
  398. static NonnullRefPtr<BorderStyleValue> create(
  399. NonnullRefPtr<StyleValue> border_width,
  400. NonnullRefPtr<StyleValue> border_style,
  401. NonnullRefPtr<StyleValue> border_color)
  402. {
  403. return adopt_ref(*new BorderStyleValue(border_width, border_style, border_color));
  404. }
  405. virtual ~BorderStyleValue() override { }
  406. NonnullRefPtr<StyleValue> border_width() const { return m_border_width; }
  407. NonnullRefPtr<StyleValue> border_style() const { return m_border_style; }
  408. NonnullRefPtr<StyleValue> border_color() const { return m_border_color; }
  409. virtual String to_string() const override
  410. {
  411. return String::formatted("Border border_width: {}, border_style: {}, border_color: {}", m_border_width->to_string(), m_border_style->to_string(), m_border_color->to_string());
  412. }
  413. private:
  414. BorderStyleValue(
  415. NonnullRefPtr<StyleValue> border_width,
  416. NonnullRefPtr<StyleValue> border_style,
  417. NonnullRefPtr<StyleValue> border_color)
  418. : StyleValue(Type::Border)
  419. , m_border_width(border_width)
  420. , m_border_style(border_style)
  421. , m_border_color(border_color)
  422. {
  423. }
  424. NonnullRefPtr<StyleValue> m_border_width;
  425. NonnullRefPtr<StyleValue> m_border_style;
  426. NonnullRefPtr<StyleValue> m_border_color;
  427. };
  428. class BorderRadiusStyleValue final : public StyleValue {
  429. public:
  430. static NonnullRefPtr<BorderRadiusStyleValue> create(Length const& horizontal_radius, Length const& vertical_radius)
  431. {
  432. return adopt_ref(*new BorderRadiusStyleValue(horizontal_radius, vertical_radius));
  433. }
  434. virtual ~BorderRadiusStyleValue() override { }
  435. Length const& horizontal_radius() const { return m_horizontal_radius; }
  436. Length const& vertical_radius() const { return m_vertical_radius; }
  437. bool is_elliptical() const { return m_is_elliptical; }
  438. // FIXME: Remove this once we support elliptical border-radius in Layout/Node.
  439. virtual Length to_length() const override { return horizontal_radius(); }
  440. virtual String to_string() const override
  441. {
  442. return String::formatted("{} / {}", m_horizontal_radius.to_string(), m_vertical_radius.to_string());
  443. }
  444. virtual bool equals(StyleValue const& other) const override
  445. {
  446. if (type() != other.type())
  447. return false;
  448. auto& other_value = static_cast<BorderRadiusStyleValue const&>(other);
  449. return m_is_elliptical == other_value.m_is_elliptical
  450. && m_horizontal_radius == other_value.m_horizontal_radius
  451. && m_vertical_radius == other_value.m_vertical_radius;
  452. }
  453. private:
  454. BorderRadiusStyleValue(Length const& horizontal_radius, Length const& vertical_radius)
  455. : StyleValue(Type::BorderRadius)
  456. , m_horizontal_radius(horizontal_radius)
  457. , m_vertical_radius(vertical_radius)
  458. {
  459. m_is_elliptical = (m_horizontal_radius != m_vertical_radius);
  460. }
  461. bool m_is_elliptical;
  462. Length m_horizontal_radius;
  463. Length m_vertical_radius;
  464. };
  465. class BoxShadowStyleValue : public StyleValue {
  466. public:
  467. static NonnullRefPtr<BoxShadowStyleValue> create(Length const& offset_x, Length const& offset_y, Length const& blur_radius, Color const& color)
  468. {
  469. return adopt_ref(*new BoxShadowStyleValue(offset_x, offset_y, blur_radius, color));
  470. }
  471. virtual ~BoxShadowStyleValue() override { }
  472. Length const& offset_x() const { return m_offset_x; }
  473. Length const& offset_y() const { return m_offset_y; }
  474. Length const& blur_radius() const { return m_blur_radius; }
  475. Color const& color() const { return m_color; }
  476. String to_string() const override { return String::formatted("BoxShadow offset_x: {}, offset_y: {}, blur_radius: {}, color: {}",
  477. m_offset_x.to_string(), m_offset_y.to_string(), m_blur_radius.to_string(), m_color.to_string()); }
  478. private:
  479. explicit BoxShadowStyleValue(Length const& offset_x, Length const& offset_y, Length const& blur_radius, Color const& color)
  480. : StyleValue(Type::BoxShadow)
  481. , m_offset_x(offset_x)
  482. , m_offset_y(offset_y)
  483. , m_blur_radius(blur_radius)
  484. , m_color(color)
  485. {
  486. }
  487. Length m_offset_x;
  488. Length m_offset_y;
  489. Length m_blur_radius;
  490. Color m_color;
  491. };
  492. class CalculatedStyleValue : public StyleValue {
  493. public:
  494. struct CalcSum;
  495. struct CalcSumPartWithOperator;
  496. struct CalcProduct;
  497. struct CalcProductPartWithOperator;
  498. struct CalcNumberSum;
  499. struct CalcNumberSumPartWithOperator;
  500. struct CalcNumberProduct;
  501. struct CalcNumberProductPartWithOperator;
  502. using CalcNumberValue = Variant<float, NonnullOwnPtr<CalcNumberSum>>;
  503. using CalcValue = Variant<float, CSS::Length, NonnullOwnPtr<CalcSum>>;
  504. // This represents that: https://drafts.csswg.org/css-values-3/#calc-syntax
  505. struct CalcSum {
  506. CalcSum(NonnullOwnPtr<CalcProduct> first_calc_product, NonnullOwnPtrVector<CalcSumPartWithOperator> additional)
  507. : first_calc_product(move(first_calc_product))
  508. , zero_or_more_additional_calc_products(move(additional)) {};
  509. NonnullOwnPtr<CalcProduct> first_calc_product;
  510. NonnullOwnPtrVector<CalcSumPartWithOperator> zero_or_more_additional_calc_products;
  511. };
  512. struct CalcNumberSum {
  513. CalcNumberSum(NonnullOwnPtr<CalcNumberProduct> first_calc_number_product, NonnullOwnPtrVector<CalcNumberSumPartWithOperator> additional)
  514. : first_calc_number_product(move(first_calc_number_product))
  515. , zero_or_more_additional_calc_number_products(move(additional)) {};
  516. NonnullOwnPtr<CalcNumberProduct> first_calc_number_product;
  517. NonnullOwnPtrVector<CalcNumberSumPartWithOperator> zero_or_more_additional_calc_number_products;
  518. };
  519. struct CalcProduct {
  520. CalcValue first_calc_value;
  521. NonnullOwnPtrVector<CalcProductPartWithOperator> zero_or_more_additional_calc_values;
  522. };
  523. struct CalcSumPartWithOperator {
  524. enum Operation {
  525. Add,
  526. Subtract,
  527. };
  528. CalcSumPartWithOperator(Operation op, NonnullOwnPtr<CalcProduct> calc_product)
  529. : op(op)
  530. , calc_product(move(calc_product)) {};
  531. Operation op;
  532. NonnullOwnPtr<CalcProduct> calc_product;
  533. };
  534. struct CalcProductPartWithOperator {
  535. enum {
  536. Multiply,
  537. Divide,
  538. } op;
  539. Variant<CalcValue, CalcNumberValue> value;
  540. };
  541. struct CalcNumberProduct {
  542. CalcNumberValue first_calc_number_value;
  543. NonnullOwnPtrVector<CalcNumberProductPartWithOperator> zero_or_more_additional_calc_number_values;
  544. };
  545. struct CalcNumberProductPartWithOperator {
  546. enum {
  547. Multiply,
  548. Divide,
  549. } op;
  550. CalcNumberValue value;
  551. };
  552. struct CalcNumberSumPartWithOperator {
  553. enum Operation {
  554. Add,
  555. Subtract,
  556. };
  557. CalcNumberSumPartWithOperator(Operation op, NonnullOwnPtr<CalcNumberProduct> calc_number_product)
  558. : op(op)
  559. , calc_number_product(move(calc_number_product)) {};
  560. Operation op;
  561. NonnullOwnPtr<CalcNumberProduct> calc_number_product;
  562. };
  563. static NonnullRefPtr<CalculatedStyleValue> create(String const& expression_string, NonnullOwnPtr<CalcSum> calc_sum)
  564. {
  565. return adopt_ref(*new CalculatedStyleValue(expression_string, move(calc_sum)));
  566. }
  567. String to_string() const override { return m_expression_string; }
  568. NonnullOwnPtr<CalcSum> const& expression() const { return m_expression; }
  569. private:
  570. explicit CalculatedStyleValue(String const& expression_string, NonnullOwnPtr<CalcSum> calc_sum)
  571. : StyleValue(Type::Calculated)
  572. , m_expression_string(expression_string)
  573. , m_expression(move(calc_sum))
  574. {
  575. }
  576. String m_expression_string;
  577. NonnullOwnPtr<CalcSum> m_expression;
  578. };
  579. class ColorStyleValue : public StyleValue {
  580. public:
  581. static NonnullRefPtr<ColorStyleValue> create(Color color)
  582. {
  583. return adopt_ref(*new ColorStyleValue(color));
  584. }
  585. virtual ~ColorStyleValue() override { }
  586. Color color() const { return m_color; }
  587. virtual String to_string() const override { return m_color.to_string(); }
  588. virtual bool has_color() const override { return true; }
  589. virtual Color to_color(Layout::NodeWithStyle const&) const override { return m_color; }
  590. virtual bool equals(const StyleValue& other) const override
  591. {
  592. if (type() != other.type())
  593. return false;
  594. return m_color == static_cast<const ColorStyleValue&>(other).m_color;
  595. }
  596. private:
  597. explicit ColorStyleValue(Color color)
  598. : StyleValue(Type::Color)
  599. , m_color(color)
  600. {
  601. }
  602. Color m_color;
  603. };
  604. class CombinedBorderRadiusStyleValue final : public StyleValue {
  605. public:
  606. static NonnullRefPtr<CombinedBorderRadiusStyleValue> create(NonnullRefPtr<BorderRadiusStyleValue> top_left, NonnullRefPtr<BorderRadiusStyleValue> top_right, NonnullRefPtr<BorderRadiusStyleValue> bottom_right, NonnullRefPtr<BorderRadiusStyleValue> bottom_left)
  607. {
  608. return adopt_ref(*new CombinedBorderRadiusStyleValue(top_left, top_right, bottom_right, bottom_left));
  609. }
  610. virtual ~CombinedBorderRadiusStyleValue() override { }
  611. NonnullRefPtr<BorderRadiusStyleValue> top_left() const { return m_top_left; }
  612. NonnullRefPtr<BorderRadiusStyleValue> top_right() const { return m_top_right; }
  613. NonnullRefPtr<BorderRadiusStyleValue> bottom_right() const { return m_bottom_right; }
  614. NonnullRefPtr<BorderRadiusStyleValue> bottom_left() const { return m_bottom_left; }
  615. virtual String to_string() const override
  616. {
  617. return String::formatted("{} {} {} {} / {} {} {} {}", m_top_left->horizontal_radius().to_string(), m_top_right->horizontal_radius().to_string(), m_bottom_right->horizontal_radius().to_string(), m_bottom_left->horizontal_radius().to_string(), m_top_left->vertical_radius().to_string(), m_top_right->vertical_radius().to_string(), m_bottom_right->vertical_radius().to_string(), m_bottom_left->vertical_radius().to_string());
  618. }
  619. private:
  620. CombinedBorderRadiusStyleValue(NonnullRefPtr<BorderRadiusStyleValue> top_left, NonnullRefPtr<BorderRadiusStyleValue> top_right, NonnullRefPtr<BorderRadiusStyleValue> bottom_right, NonnullRefPtr<BorderRadiusStyleValue> bottom_left)
  621. : StyleValue(Type::CombinedBorderRadius)
  622. , m_top_left(top_left)
  623. , m_top_right(top_right)
  624. , m_bottom_right(bottom_right)
  625. , m_bottom_left(bottom_left)
  626. {
  627. }
  628. NonnullRefPtr<BorderRadiusStyleValue> m_top_left;
  629. NonnullRefPtr<BorderRadiusStyleValue> m_top_right;
  630. NonnullRefPtr<BorderRadiusStyleValue> m_bottom_right;
  631. NonnullRefPtr<BorderRadiusStyleValue> m_bottom_left;
  632. };
  633. // FIXME: Allow for fallback
  634. class CustomStyleValue : public StyleValue {
  635. public:
  636. static NonnullRefPtr<CustomStyleValue> create(const String& custom_property_name)
  637. {
  638. return adopt_ref(*new CustomStyleValue(custom_property_name));
  639. }
  640. String custom_property_name() const { return m_custom_property_name; }
  641. String to_string() const override { return m_custom_property_name; }
  642. private:
  643. explicit CustomStyleValue(const String& custom_property_name)
  644. : StyleValue(Type::CustomProperty)
  645. , m_custom_property_name(custom_property_name)
  646. {
  647. }
  648. String m_custom_property_name {};
  649. };
  650. class FlexStyleValue final : public StyleValue {
  651. public:
  652. static NonnullRefPtr<FlexStyleValue> create(
  653. NonnullRefPtr<StyleValue> grow,
  654. NonnullRefPtr<StyleValue> shrink,
  655. NonnullRefPtr<StyleValue> basis)
  656. {
  657. return adopt_ref(*new FlexStyleValue(grow, shrink, basis));
  658. }
  659. virtual ~FlexStyleValue() override { }
  660. NonnullRefPtr<StyleValue> grow() const { return m_grow; }
  661. NonnullRefPtr<StyleValue> shrink() const { return m_shrink; }
  662. NonnullRefPtr<StyleValue> basis() const { return m_basis; }
  663. virtual String to_string() const override
  664. {
  665. return String::formatted("Flex grow: {}, shrink: {}, basis: {}", m_grow->to_string(), m_shrink->to_string(), m_basis->to_string());
  666. }
  667. private:
  668. FlexStyleValue(
  669. NonnullRefPtr<StyleValue> grow,
  670. NonnullRefPtr<StyleValue> shrink,
  671. NonnullRefPtr<StyleValue> basis)
  672. : StyleValue(Type::Flex)
  673. , m_grow(grow)
  674. , m_shrink(shrink)
  675. , m_basis(basis)
  676. {
  677. }
  678. NonnullRefPtr<StyleValue> m_grow;
  679. NonnullRefPtr<StyleValue> m_shrink;
  680. NonnullRefPtr<StyleValue> m_basis;
  681. };
  682. class FlexFlowStyleValue final : public StyleValue {
  683. public:
  684. static NonnullRefPtr<FlexFlowStyleValue> create(NonnullRefPtr<StyleValue> flex_direction, NonnullRefPtr<StyleValue> flex_wrap)
  685. {
  686. return adopt_ref(*new FlexFlowStyleValue(flex_direction, flex_wrap));
  687. }
  688. virtual ~FlexFlowStyleValue() override { }
  689. NonnullRefPtr<StyleValue> flex_direction() const { return m_flex_direction; }
  690. NonnullRefPtr<StyleValue> flex_wrap() const { return m_flex_wrap; }
  691. virtual String to_string() const override
  692. {
  693. return String::formatted("FlexFlow flex_direction: {}, flex_wrap: {}", m_flex_direction->to_string(), m_flex_wrap->to_string());
  694. }
  695. private:
  696. FlexFlowStyleValue(NonnullRefPtr<StyleValue> flex_direction, NonnullRefPtr<StyleValue> flex_wrap)
  697. : StyleValue(Type::FlexFlow)
  698. , m_flex_direction(flex_direction)
  699. , m_flex_wrap(flex_wrap)
  700. {
  701. }
  702. NonnullRefPtr<StyleValue> m_flex_direction;
  703. NonnullRefPtr<StyleValue> m_flex_wrap;
  704. };
  705. class FontStyleValue final : public StyleValue {
  706. public:
  707. static NonnullRefPtr<FontStyleValue> create(NonnullRefPtr<StyleValue> font_style, NonnullRefPtr<StyleValue> font_weight, NonnullRefPtr<StyleValue> font_size, NonnullRefPtr<StyleValue> line_height, NonnullRefPtr<StyleValue> font_families) { return adopt_ref(*new FontStyleValue(font_style, font_weight, font_size, line_height, font_families)); }
  708. virtual ~FontStyleValue() override { }
  709. NonnullRefPtr<StyleValue> font_style() const { return m_font_style; }
  710. NonnullRefPtr<StyleValue> font_weight() const { return m_font_weight; }
  711. NonnullRefPtr<StyleValue> font_size() const { return m_font_size; }
  712. NonnullRefPtr<StyleValue> line_height() const { return m_line_height; }
  713. NonnullRefPtr<StyleValue> font_families() const { return m_font_families; }
  714. virtual String to_string() const override
  715. {
  716. return String::formatted("Font style: {}, weight: {}, size: {}, line_height: {}, families: {}",
  717. m_font_style->to_string(), m_font_weight->to_string(), m_font_size->to_string(), m_line_height->to_string(), m_font_families->to_string());
  718. }
  719. private:
  720. FontStyleValue(NonnullRefPtr<StyleValue> font_style, NonnullRefPtr<StyleValue> font_weight, NonnullRefPtr<StyleValue> font_size, NonnullRefPtr<StyleValue> line_height, NonnullRefPtr<StyleValue> font_families)
  721. : StyleValue(Type::Font)
  722. , m_font_style(font_style)
  723. , m_font_weight(font_weight)
  724. , m_font_size(font_size)
  725. , m_line_height(line_height)
  726. , m_font_families(font_families)
  727. {
  728. }
  729. NonnullRefPtr<StyleValue> m_font_style;
  730. NonnullRefPtr<StyleValue> m_font_weight;
  731. NonnullRefPtr<StyleValue> m_font_size;
  732. NonnullRefPtr<StyleValue> m_line_height;
  733. NonnullRefPtr<StyleValue> m_font_families;
  734. // FIXME: Implement font-stretch and font-variant.
  735. };
  736. class IdentifierStyleValue final : public StyleValue {
  737. public:
  738. static NonnullRefPtr<IdentifierStyleValue> create(CSS::ValueID id)
  739. {
  740. return adopt_ref(*new IdentifierStyleValue(id));
  741. }
  742. virtual ~IdentifierStyleValue() override { }
  743. CSS::ValueID id() const { return m_id; }
  744. virtual bool has_auto() const override { return m_id == ValueID::Auto; }
  745. virtual bool has_identifier() const override { return true; }
  746. virtual CSS::ValueID to_identifier() const override { return m_id; }
  747. virtual bool has_color() const override;
  748. virtual Color to_color(Layout::NodeWithStyle const& node) const override;
  749. virtual String to_string() const override;
  750. virtual bool equals(const StyleValue& other) const override
  751. {
  752. if (type() != other.type())
  753. return false;
  754. return m_id == static_cast<const IdentifierStyleValue&>(other).m_id;
  755. }
  756. private:
  757. explicit IdentifierStyleValue(CSS::ValueID id)
  758. : StyleValue(Type::Identifier)
  759. , m_id(id)
  760. {
  761. }
  762. CSS::ValueID m_id { CSS::ValueID::Invalid };
  763. };
  764. class ImageStyleValue final
  765. : public StyleValue
  766. , public ImageResourceClient {
  767. public:
  768. static NonnullRefPtr<ImageStyleValue> create(const AK::URL& url, DOM::Document& document) { return adopt_ref(*new ImageStyleValue(url, document)); }
  769. virtual ~ImageStyleValue() override { }
  770. String to_string() const override { return String::formatted("Image({})", m_url.to_string()); }
  771. const Gfx::Bitmap* bitmap() const { return m_bitmap; }
  772. private:
  773. ImageStyleValue(const AK::URL&, DOM::Document&);
  774. // ^ResourceClient
  775. virtual void resource_did_load() override;
  776. AK::URL m_url;
  777. WeakPtr<DOM::Document> m_document;
  778. RefPtr<Gfx::Bitmap> m_bitmap;
  779. };
  780. class InheritStyleValue final : public StyleValue {
  781. public:
  782. static NonnullRefPtr<InheritStyleValue> the()
  783. {
  784. static NonnullRefPtr<InheritStyleValue> instance = adopt_ref(*new InheritStyleValue);
  785. return instance;
  786. }
  787. virtual ~InheritStyleValue() override { }
  788. String to_string() const override { return "inherit"; }
  789. private:
  790. InheritStyleValue()
  791. : StyleValue(Type::Inherit)
  792. {
  793. }
  794. };
  795. class InitialStyleValue final : public StyleValue {
  796. public:
  797. static NonnullRefPtr<InitialStyleValue> the()
  798. {
  799. static NonnullRefPtr<InitialStyleValue> instance = adopt_ref(*new InitialStyleValue);
  800. return instance;
  801. }
  802. virtual ~InitialStyleValue() override { }
  803. String to_string() const override { return "initial"; }
  804. private:
  805. InitialStyleValue()
  806. : StyleValue(Type::Initial)
  807. {
  808. }
  809. };
  810. class LengthStyleValue : public StyleValue {
  811. public:
  812. static NonnullRefPtr<LengthStyleValue> create(const Length& length)
  813. {
  814. return adopt_ref(*new LengthStyleValue(length));
  815. }
  816. virtual ~LengthStyleValue() override { }
  817. Length const& length() const { return m_length; }
  818. virtual bool has_auto() const override { return m_length.is_auto(); }
  819. virtual bool has_length() const override { return true; }
  820. virtual String to_string() const override { return m_length.to_string(); }
  821. virtual Length to_length() const override { return m_length; }
  822. virtual bool equals(const StyleValue& other) const override
  823. {
  824. if (type() != other.type())
  825. return false;
  826. return m_length == static_cast<const LengthStyleValue&>(other).m_length;
  827. }
  828. private:
  829. explicit LengthStyleValue(const Length& length)
  830. : StyleValue(Type::Length)
  831. , m_length(length)
  832. {
  833. }
  834. Length m_length;
  835. };
  836. class ListStyleStyleValue final : public StyleValue {
  837. public:
  838. static NonnullRefPtr<ListStyleStyleValue> create(
  839. NonnullRefPtr<StyleValue> position,
  840. NonnullRefPtr<StyleValue> image,
  841. NonnullRefPtr<StyleValue> style_type)
  842. {
  843. return adopt_ref(*new ListStyleStyleValue(position, image, style_type));
  844. }
  845. virtual ~ListStyleStyleValue() override { }
  846. NonnullRefPtr<StyleValue> position() const { return m_position; }
  847. NonnullRefPtr<StyleValue> image() const { return m_image; }
  848. NonnullRefPtr<StyleValue> style_type() const { return m_style_type; }
  849. virtual String to_string() const override
  850. {
  851. return String::formatted("ListStyle position: {}, image: {}, style_type: {}", m_position->to_string(), m_image->to_string(), m_style_type->to_string());
  852. }
  853. private:
  854. ListStyleStyleValue(
  855. NonnullRefPtr<StyleValue> position,
  856. NonnullRefPtr<StyleValue> image,
  857. NonnullRefPtr<StyleValue> style_type)
  858. : StyleValue(Type::ListStyle)
  859. , m_position(position)
  860. , m_image(image)
  861. , m_style_type(style_type)
  862. {
  863. }
  864. NonnullRefPtr<StyleValue> m_position;
  865. NonnullRefPtr<StyleValue> m_image;
  866. NonnullRefPtr<StyleValue> m_style_type;
  867. };
  868. class NumericStyleValue : public StyleValue {
  869. public:
  870. static NonnullRefPtr<NumericStyleValue> create(float value)
  871. {
  872. return adopt_ref(*new NumericStyleValue(value));
  873. }
  874. virtual bool has_length() const override { return m_value == 0; }
  875. virtual Length to_length() const override { return Length(0, Length::Type::Px); }
  876. virtual bool has_number() const override { return true; }
  877. virtual float to_number() const override { return m_value; }
  878. float value() const { return m_value; }
  879. // FIXME: Store integer values separately
  880. i64 int_value() const { return roundf(m_value); }
  881. String to_string() const override { return String::formatted("{}", m_value); }
  882. virtual bool equals(StyleValue const& other) const override
  883. {
  884. if (type() != other.type())
  885. return false;
  886. return m_value == static_cast<NumericStyleValue const&>(other).m_value;
  887. }
  888. private:
  889. explicit NumericStyleValue(float value)
  890. : StyleValue(Type::Numeric)
  891. , m_value(value)
  892. {
  893. }
  894. float m_value { 0 };
  895. };
  896. class OverflowStyleValue final : public StyleValue {
  897. public:
  898. static NonnullRefPtr<OverflowStyleValue> create(NonnullRefPtr<StyleValue> overflow_x, NonnullRefPtr<StyleValue> overflow_y)
  899. {
  900. return adopt_ref(*new OverflowStyleValue(overflow_x, overflow_y));
  901. }
  902. virtual ~OverflowStyleValue() override { }
  903. NonnullRefPtr<StyleValue> overflow_x() const { return m_overflow_x; }
  904. NonnullRefPtr<StyleValue> overflow_y() const { return m_overflow_y; }
  905. virtual String to_string() const override
  906. {
  907. return String::formatted("{} {}", m_overflow_x->to_string(), m_overflow_y->to_string());
  908. }
  909. private:
  910. OverflowStyleValue(NonnullRefPtr<StyleValue> overflow_x, NonnullRefPtr<StyleValue> overflow_y)
  911. : StyleValue(Type::Overflow)
  912. , m_overflow_x(overflow_x)
  913. , m_overflow_y(overflow_y)
  914. {
  915. }
  916. NonnullRefPtr<StyleValue> m_overflow_x;
  917. NonnullRefPtr<StyleValue> m_overflow_y;
  918. };
  919. class StringStyleValue : public StyleValue {
  920. public:
  921. static NonnullRefPtr<StringStyleValue> create(const String& string)
  922. {
  923. return adopt_ref(*new StringStyleValue(string));
  924. }
  925. virtual ~StringStyleValue() override { }
  926. String to_string() const override { return m_string; }
  927. private:
  928. explicit StringStyleValue(const String& string)
  929. : StyleValue(Type::String)
  930. , m_string(string)
  931. {
  932. }
  933. String m_string;
  934. };
  935. class TextDecorationStyleValue final : public StyleValue {
  936. public:
  937. static NonnullRefPtr<TextDecorationStyleValue> create(
  938. NonnullRefPtr<StyleValue> line,
  939. NonnullRefPtr<StyleValue> style,
  940. NonnullRefPtr<StyleValue> color)
  941. {
  942. return adopt_ref(*new TextDecorationStyleValue(line, style, color));
  943. }
  944. virtual ~TextDecorationStyleValue() override { }
  945. NonnullRefPtr<StyleValue> line() const { return m_line; }
  946. NonnullRefPtr<StyleValue> style() const { return m_style; }
  947. NonnullRefPtr<StyleValue> color() const { return m_color; }
  948. virtual String to_string() const override
  949. {
  950. return String::formatted("TextDecoration line: {}, style: {}, color: {}", m_line->to_string(), m_style->to_string(), m_color->to_string());
  951. }
  952. private:
  953. TextDecorationStyleValue(
  954. NonnullRefPtr<StyleValue> line,
  955. NonnullRefPtr<StyleValue> style,
  956. NonnullRefPtr<StyleValue> color)
  957. : StyleValue(Type::TextDecoration)
  958. , m_line(line)
  959. , m_style(style)
  960. , m_color(color)
  961. {
  962. }
  963. NonnullRefPtr<StyleValue> m_line;
  964. NonnullRefPtr<StyleValue> m_style;
  965. NonnullRefPtr<StyleValue> m_color;
  966. };
  967. class TransformationStyleValue final : public StyleValue {
  968. public:
  969. static NonnullRefPtr<TransformationStyleValue> create(CSS::TransformFunction transform_function, NonnullRefPtrVector<StyleValue>&& values)
  970. {
  971. return adopt_ref(*new TransformationStyleValue(transform_function, move(values)));
  972. }
  973. virtual ~TransformationStyleValue() override { }
  974. CSS::TransformFunction transform_function() const { return m_transform_function; }
  975. NonnullRefPtrVector<StyleValue> values() const { return m_values; }
  976. virtual String to_string() const override
  977. {
  978. return String::formatted("TransformationStyleValue");
  979. }
  980. private:
  981. TransformationStyleValue(CSS::TransformFunction transform_function, NonnullRefPtrVector<StyleValue>&& values)
  982. : StyleValue(Type::Transformation)
  983. , m_transform_function(transform_function)
  984. , m_values(move(values))
  985. {
  986. }
  987. CSS::TransformFunction m_transform_function;
  988. NonnullRefPtrVector<StyleValue> m_values;
  989. };
  990. class UnsetStyleValue final : public StyleValue {
  991. public:
  992. static NonnullRefPtr<UnsetStyleValue> the()
  993. {
  994. static NonnullRefPtr<UnsetStyleValue> instance = adopt_ref(*new UnsetStyleValue);
  995. return instance;
  996. }
  997. virtual ~UnsetStyleValue() override { }
  998. String to_string() const override { return "unset"; }
  999. private:
  1000. UnsetStyleValue()
  1001. : StyleValue(Type::Unset)
  1002. {
  1003. }
  1004. };
  1005. class StyleValueList final : public StyleValue {
  1006. public:
  1007. static NonnullRefPtr<StyleValueList> create(NonnullRefPtrVector<StyleValue>&& values) { return adopt_ref(*new StyleValueList(move(values))); }
  1008. NonnullRefPtrVector<StyleValue> const& values() const { return m_values; }
  1009. virtual String to_string() const
  1010. {
  1011. StringBuilder builder;
  1012. builder.appendff("List[{}](", m_values.size());
  1013. for (size_t i = 0; i < m_values.size(); ++i) {
  1014. if (i)
  1015. builder.append(',');
  1016. builder.append(m_values[i].to_string());
  1017. }
  1018. builder.append(')');
  1019. return builder.to_string();
  1020. }
  1021. private:
  1022. StyleValueList(NonnullRefPtrVector<StyleValue>&& values)
  1023. : StyleValue(Type::ValueList)
  1024. , m_values(move(values))
  1025. {
  1026. }
  1027. NonnullRefPtrVector<StyleValue> m_values;
  1028. };
  1029. }