StyleValue.h 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154
  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. Invalid,
  208. Inherit,
  209. Initial,
  210. Unset,
  211. String,
  212. Length,
  213. Color,
  214. Identifier,
  215. Image,
  216. CustomProperty,
  217. Numeric,
  218. ValueList,
  219. Calculated,
  220. Background,
  221. BackgroundRepeat,
  222. Border,
  223. BorderRadius,
  224. CombinedBorderRadius,
  225. BoxShadow,
  226. Flex,
  227. FlexFlow,
  228. Font,
  229. ListStyle,
  230. Overflow,
  231. TextDecoration,
  232. Transformation,
  233. };
  234. Type type() const { return m_type; }
  235. bool is_inherit() const { return type() == Type::Inherit; }
  236. bool is_initial() const { return type() == Type::Initial; }
  237. bool is_unset() const { return type() == Type::Unset; }
  238. bool is_color() const;
  239. bool is_identifier() const { return type() == Type::Identifier || is_auto(); }
  240. bool is_image() const { return type() == Type::Image; }
  241. bool is_string() const { return type() == Type::String; }
  242. virtual bool is_length() const { return type() == Type::Length; }
  243. bool is_custom_property() const { return type() == Type::CustomProperty; }
  244. bool is_numeric() const { return type() == Type::Numeric; }
  245. bool is_value_list() const { return type() == Type::ValueList; }
  246. bool is_calculated() const { return type() == Type::Calculated; }
  247. bool is_background() const { return type() == Type::Background; }
  248. bool is_background_repeat() const { return type() == Type::BackgroundRepeat; }
  249. bool is_border() const { return type() == Type::Border; }
  250. bool is_border_radius() const { return type() == Type::BorderRadius; }
  251. bool is_box_shadow() const { return type() == Type::BoxShadow; }
  252. bool is_flex() const { return type() == Type::Flex; }
  253. bool is_flex_flow() const { return type() == Type::FlexFlow; }
  254. bool is_font() const { return type() == Type::Font; }
  255. bool is_list_style() const { return type() == Type::ListStyle; }
  256. bool is_overflow() const { return type() == Type::Overflow; }
  257. bool is_text_decoration() const { return type() == Type::TextDecoration; }
  258. bool is_transformation() const { return type() == Type::Transformation; }
  259. bool is_builtin() const { return is_inherit() || is_initial() || is_unset(); }
  260. bool is_builtin_or_dynamic() const
  261. {
  262. return is_builtin() || is_custom_property() || is_calculated();
  263. }
  264. float as_number() const;
  265. virtual String to_string() const = 0;
  266. virtual Length to_length() const { return {}; }
  267. virtual Color to_color(Layout::NodeWithStyle const&) const { return {}; }
  268. CSS::ValueID to_identifier() const;
  269. virtual bool is_auto() const { return false; }
  270. bool operator==(const StyleValue& other) const { return equals(other); }
  271. bool operator!=(const StyleValue& other) const { return !(*this == other); }
  272. virtual bool equals(const StyleValue& other) const
  273. {
  274. if (type() != other.type())
  275. return false;
  276. return to_string() == other.to_string();
  277. }
  278. protected:
  279. explicit StyleValue(Type);
  280. private:
  281. Type m_type { Type::Invalid };
  282. };
  283. // FIXME: Allow for fallback
  284. class CustomStyleValue : public StyleValue {
  285. public:
  286. static NonnullRefPtr<CustomStyleValue> create(const String& custom_property_name)
  287. {
  288. return adopt_ref(*new CustomStyleValue(custom_property_name));
  289. }
  290. String custom_property_name() const { return m_custom_property_name; }
  291. String to_string() const override { return m_custom_property_name; }
  292. private:
  293. explicit CustomStyleValue(const String& custom_property_name)
  294. : StyleValue(Type::CustomProperty)
  295. , m_custom_property_name(custom_property_name)
  296. {
  297. }
  298. String m_custom_property_name {};
  299. };
  300. class NumericStyleValue : public StyleValue {
  301. public:
  302. static NonnullRefPtr<NumericStyleValue> create(float value)
  303. {
  304. return adopt_ref(*new NumericStyleValue(value));
  305. }
  306. virtual bool is_length() const override { return m_value == 0; }
  307. virtual Length to_length() const override { return Length(0, Length::Type::Px); }
  308. float value() const { return m_value; }
  309. String to_string() const override { return String::formatted("{}", m_value); }
  310. virtual bool equals(StyleValue const& other) const override
  311. {
  312. if (type() != other.type())
  313. return false;
  314. return m_value == static_cast<NumericStyleValue const&>(other).m_value;
  315. }
  316. private:
  317. explicit NumericStyleValue(float value)
  318. : StyleValue(Type::Numeric)
  319. , m_value(value)
  320. {
  321. }
  322. float m_value { 0 };
  323. };
  324. class StringStyleValue : public StyleValue {
  325. public:
  326. static NonnullRefPtr<StringStyleValue> create(const String& string)
  327. {
  328. return adopt_ref(*new StringStyleValue(string));
  329. }
  330. virtual ~StringStyleValue() override { }
  331. String to_string() const override { return m_string; }
  332. private:
  333. explicit StringStyleValue(const String& string)
  334. : StyleValue(Type::String)
  335. , m_string(string)
  336. {
  337. }
  338. String m_string;
  339. };
  340. class BoxShadowStyleValue : public StyleValue {
  341. public:
  342. static NonnullRefPtr<BoxShadowStyleValue> create(Length const& offset_x, Length const& offset_y, Length const& blur_radius, Color const& color)
  343. {
  344. return adopt_ref(*new BoxShadowStyleValue(offset_x, offset_y, blur_radius, color));
  345. }
  346. virtual ~BoxShadowStyleValue() override { }
  347. Length const& offset_x() const { return m_offset_x; }
  348. Length const& offset_y() const { return m_offset_y; }
  349. Length const& blur_radius() const { return m_blur_radius; }
  350. Color const& color() const { return m_color; }
  351. String to_string() const override { return String::formatted("BoxShadow offset_x: {}, offset_y: {}, blur_radius: {}, color: {}",
  352. m_offset_x.to_string(), m_offset_y.to_string(), m_blur_radius.to_string(), m_color.to_string()); }
  353. private:
  354. explicit BoxShadowStyleValue(Length const& offset_x, Length const& offset_y, Length const& blur_radius, Color const& color)
  355. : StyleValue(Type::BoxShadow)
  356. , m_offset_x(offset_x)
  357. , m_offset_y(offset_y)
  358. , m_blur_radius(blur_radius)
  359. , m_color(color)
  360. {
  361. }
  362. Length m_offset_x;
  363. Length m_offset_y;
  364. Length m_blur_radius;
  365. Color m_color;
  366. };
  367. class LengthStyleValue : public StyleValue {
  368. public:
  369. static NonnullRefPtr<LengthStyleValue> create(const Length& length)
  370. {
  371. return adopt_ref(*new LengthStyleValue(length));
  372. }
  373. virtual ~LengthStyleValue() override { }
  374. virtual String to_string() const override { return m_length.to_string(); }
  375. virtual Length to_length() const override { return m_length; }
  376. const Length& length() const { return m_length; }
  377. virtual bool is_auto() const override { return m_length.is_auto(); }
  378. virtual bool equals(const StyleValue& other) const override
  379. {
  380. if (type() != other.type())
  381. return false;
  382. return m_length == static_cast<const LengthStyleValue&>(other).m_length;
  383. }
  384. private:
  385. explicit LengthStyleValue(const Length& length)
  386. : StyleValue(Type::Length)
  387. , m_length(length)
  388. {
  389. }
  390. Length m_length;
  391. };
  392. class CalculatedStyleValue : public StyleValue {
  393. public:
  394. struct CalcSum;
  395. struct CalcSumPartWithOperator;
  396. struct CalcProduct;
  397. struct CalcProductPartWithOperator;
  398. struct CalcNumberSum;
  399. struct CalcNumberSumPartWithOperator;
  400. struct CalcNumberProduct;
  401. struct CalcNumberProductPartWithOperator;
  402. using CalcNumberValue = Variant<float, NonnullOwnPtr<CalcNumberSum>>;
  403. using CalcValue = Variant<float, CSS::Length, NonnullOwnPtr<CalcSum>>;
  404. // This represents that: https://drafts.csswg.org/css-values-3/#calc-syntax
  405. struct CalcSum {
  406. CalcSum(NonnullOwnPtr<CalcProduct> first_calc_product, NonnullOwnPtrVector<CalcSumPartWithOperator> additional)
  407. : first_calc_product(move(first_calc_product))
  408. , zero_or_more_additional_calc_products(move(additional)) {};
  409. NonnullOwnPtr<CalcProduct> first_calc_product;
  410. NonnullOwnPtrVector<CalcSumPartWithOperator> zero_or_more_additional_calc_products;
  411. };
  412. struct CalcNumberSum {
  413. CalcNumberSum(NonnullOwnPtr<CalcNumberProduct> first_calc_number_product, NonnullOwnPtrVector<CalcNumberSumPartWithOperator> additional)
  414. : first_calc_number_product(move(first_calc_number_product))
  415. , zero_or_more_additional_calc_number_products(move(additional)) {};
  416. NonnullOwnPtr<CalcNumberProduct> first_calc_number_product;
  417. NonnullOwnPtrVector<CalcNumberSumPartWithOperator> zero_or_more_additional_calc_number_products;
  418. };
  419. struct CalcProduct {
  420. CalcValue first_calc_value;
  421. NonnullOwnPtrVector<CalcProductPartWithOperator> zero_or_more_additional_calc_values;
  422. };
  423. struct CalcSumPartWithOperator {
  424. enum Operation {
  425. Add,
  426. Subtract,
  427. };
  428. CalcSumPartWithOperator(Operation op, NonnullOwnPtr<CalcProduct> calc_product)
  429. : op(op)
  430. , calc_product(move(calc_product)) {};
  431. Operation op;
  432. NonnullOwnPtr<CalcProduct> calc_product;
  433. };
  434. struct CalcProductPartWithOperator {
  435. enum {
  436. Multiply,
  437. Divide,
  438. } op;
  439. Variant<CalcValue, CalcNumberValue> value;
  440. };
  441. struct CalcNumberProduct {
  442. CalcNumberValue first_calc_number_value;
  443. NonnullOwnPtrVector<CalcNumberProductPartWithOperator> zero_or_more_additional_calc_number_values;
  444. };
  445. struct CalcNumberProductPartWithOperator {
  446. enum {
  447. Multiply,
  448. Divide,
  449. } op;
  450. CalcNumberValue value;
  451. };
  452. struct CalcNumberSumPartWithOperator {
  453. enum Operation {
  454. Add,
  455. Subtract,
  456. };
  457. CalcNumberSumPartWithOperator(Operation op, NonnullOwnPtr<CalcNumberProduct> calc_number_product)
  458. : op(op)
  459. , calc_number_product(move(calc_number_product)) {};
  460. Operation op;
  461. NonnullOwnPtr<CalcNumberProduct> calc_number_product;
  462. };
  463. static NonnullRefPtr<CalculatedStyleValue> create(String const& expression_string, NonnullOwnPtr<CalcSum> calc_sum)
  464. {
  465. return adopt_ref(*new CalculatedStyleValue(expression_string, move(calc_sum)));
  466. }
  467. String to_string() const override { return m_expression_string; }
  468. NonnullOwnPtr<CalcSum> const& expression() const { return m_expression; }
  469. private:
  470. explicit CalculatedStyleValue(String const& expression_string, NonnullOwnPtr<CalcSum> calc_sum)
  471. : StyleValue(Type::Calculated)
  472. , m_expression_string(expression_string)
  473. , m_expression(move(calc_sum))
  474. {
  475. }
  476. String m_expression_string;
  477. NonnullOwnPtr<CalcSum> m_expression;
  478. };
  479. class InitialStyleValue final : public StyleValue {
  480. public:
  481. static NonnullRefPtr<InitialStyleValue> the()
  482. {
  483. static NonnullRefPtr<InitialStyleValue> instance = adopt_ref(*new InitialStyleValue);
  484. return instance;
  485. }
  486. virtual ~InitialStyleValue() override { }
  487. String to_string() const override { return "initial"; }
  488. private:
  489. InitialStyleValue()
  490. : StyleValue(Type::Initial)
  491. {
  492. }
  493. };
  494. class InheritStyleValue final : public StyleValue {
  495. public:
  496. static NonnullRefPtr<InheritStyleValue> the()
  497. {
  498. static NonnullRefPtr<InheritStyleValue> instance = adopt_ref(*new InheritStyleValue);
  499. return instance;
  500. }
  501. virtual ~InheritStyleValue() override { }
  502. String to_string() const override { return "inherit"; }
  503. private:
  504. InheritStyleValue()
  505. : StyleValue(Type::Inherit)
  506. {
  507. }
  508. };
  509. class UnsetStyleValue final : public StyleValue {
  510. public:
  511. static NonnullRefPtr<UnsetStyleValue> the()
  512. {
  513. static NonnullRefPtr<UnsetStyleValue> instance = adopt_ref(*new UnsetStyleValue);
  514. return instance;
  515. }
  516. virtual ~UnsetStyleValue() override { }
  517. String to_string() const override { return "unset"; }
  518. private:
  519. UnsetStyleValue()
  520. : StyleValue(Type::Unset)
  521. {
  522. }
  523. };
  524. class ColorStyleValue : public StyleValue {
  525. public:
  526. static NonnullRefPtr<ColorStyleValue> create(Color color)
  527. {
  528. return adopt_ref(*new ColorStyleValue(color));
  529. }
  530. virtual ~ColorStyleValue() override { }
  531. Color color() const { return m_color; }
  532. String to_string() const override { return m_color.to_string(); }
  533. Color to_color(Layout::NodeWithStyle const&) const override { return m_color; }
  534. virtual bool equals(const StyleValue& other) const override
  535. {
  536. if (type() != other.type())
  537. return false;
  538. return m_color == static_cast<const ColorStyleValue&>(other).m_color;
  539. }
  540. private:
  541. explicit ColorStyleValue(Color color)
  542. : StyleValue(Type::Color)
  543. , m_color(color)
  544. {
  545. }
  546. Color m_color;
  547. };
  548. class IdentifierStyleValue final : public StyleValue {
  549. public:
  550. static NonnullRefPtr<IdentifierStyleValue> create(CSS::ValueID id)
  551. {
  552. return adopt_ref(*new IdentifierStyleValue(id));
  553. }
  554. virtual ~IdentifierStyleValue() override { }
  555. CSS::ValueID id() const { return m_id; }
  556. virtual String to_string() const override;
  557. virtual Color to_color(Layout::NodeWithStyle const& node) const override;
  558. virtual bool equals(const StyleValue& other) const override
  559. {
  560. if (type() != other.type())
  561. return false;
  562. return m_id == static_cast<const IdentifierStyleValue&>(other).m_id;
  563. }
  564. private:
  565. explicit IdentifierStyleValue(CSS::ValueID id)
  566. : StyleValue(Type::Identifier)
  567. , m_id(id)
  568. {
  569. }
  570. CSS::ValueID m_id { CSS::ValueID::Invalid };
  571. };
  572. class ImageStyleValue final
  573. : public StyleValue
  574. , public ImageResourceClient {
  575. public:
  576. static NonnullRefPtr<ImageStyleValue> create(const AK::URL& url, DOM::Document& document) { return adopt_ref(*new ImageStyleValue(url, document)); }
  577. virtual ~ImageStyleValue() override { }
  578. String to_string() const override { return String::formatted("Image({})", m_url.to_string()); }
  579. const Gfx::Bitmap* bitmap() const { return m_bitmap; }
  580. private:
  581. ImageStyleValue(const AK::URL&, DOM::Document&);
  582. // ^ResourceClient
  583. virtual void resource_did_load() override;
  584. AK::URL m_url;
  585. WeakPtr<DOM::Document> m_document;
  586. RefPtr<Gfx::Bitmap> m_bitmap;
  587. };
  588. class BackgroundStyleValue final : public StyleValue {
  589. public:
  590. static NonnullRefPtr<BackgroundStyleValue> create(
  591. NonnullRefPtr<StyleValue> color,
  592. NonnullRefPtr<StyleValue> image,
  593. NonnullRefPtr<StyleValue> repeat_x,
  594. NonnullRefPtr<StyleValue> repeat_y)
  595. {
  596. return adopt_ref(*new BackgroundStyleValue(color, image, repeat_x, repeat_y));
  597. }
  598. virtual ~BackgroundStyleValue() override { }
  599. NonnullRefPtr<StyleValue> color() const { return m_color; }
  600. NonnullRefPtr<StyleValue> image() const { return m_image; }
  601. NonnullRefPtr<StyleValue> repeat_x() const { return m_repeat_x; }
  602. NonnullRefPtr<StyleValue> repeat_y() const { return m_repeat_y; }
  603. virtual String to_string() const override
  604. {
  605. return String::formatted("{} {} {} {}", m_color->to_string(), m_image->to_string(), m_repeat_x->to_string(), m_repeat_y->to_string());
  606. }
  607. private:
  608. BackgroundStyleValue(
  609. NonnullRefPtr<StyleValue> color,
  610. NonnullRefPtr<StyleValue> image,
  611. NonnullRefPtr<StyleValue> repeat_x,
  612. NonnullRefPtr<StyleValue> repeat_y)
  613. : StyleValue(Type::Background)
  614. , m_color(color)
  615. , m_image(image)
  616. , m_repeat_x(repeat_x)
  617. , m_repeat_y(repeat_y)
  618. {
  619. }
  620. NonnullRefPtr<StyleValue> m_color;
  621. NonnullRefPtr<StyleValue> m_image;
  622. // FIXME: background-position
  623. // FIXME: background-size
  624. NonnullRefPtr<StyleValue> m_repeat_x;
  625. NonnullRefPtr<StyleValue> m_repeat_y;
  626. // FIXME: background-attachment
  627. // FIXME: background-clip
  628. // FIXME: background-origin
  629. };
  630. class BackgroundRepeatStyleValue final : public StyleValue {
  631. public:
  632. static NonnullRefPtr<BackgroundRepeatStyleValue> create(NonnullRefPtr<StyleValue> repeat_x, NonnullRefPtr<StyleValue> repeat_y)
  633. {
  634. return adopt_ref(*new BackgroundRepeatStyleValue(repeat_x, repeat_y));
  635. }
  636. virtual ~BackgroundRepeatStyleValue() override { }
  637. NonnullRefPtr<StyleValue> repeat_x() const { return m_repeat_x; }
  638. NonnullRefPtr<StyleValue> repeat_y() const { return m_repeat_y; }
  639. virtual String to_string() const override
  640. {
  641. return String::formatted("{} {}", m_repeat_x->to_string(), m_repeat_y->to_string());
  642. }
  643. private:
  644. BackgroundRepeatStyleValue(NonnullRefPtr<StyleValue> repeat_x, NonnullRefPtr<StyleValue> repeat_y)
  645. : StyleValue(Type::BackgroundRepeat)
  646. , m_repeat_x(repeat_x)
  647. , m_repeat_y(repeat_y)
  648. {
  649. }
  650. NonnullRefPtr<StyleValue> m_repeat_x;
  651. NonnullRefPtr<StyleValue> m_repeat_y;
  652. };
  653. class BorderStyleValue final : public StyleValue {
  654. public:
  655. static NonnullRefPtr<BorderStyleValue> create(
  656. NonnullRefPtr<StyleValue> border_width,
  657. NonnullRefPtr<StyleValue> border_style,
  658. NonnullRefPtr<StyleValue> border_color)
  659. {
  660. return adopt_ref(*new BorderStyleValue(border_width, border_style, border_color));
  661. }
  662. virtual ~BorderStyleValue() override { }
  663. NonnullRefPtr<StyleValue> border_width() const { return m_border_width; }
  664. NonnullRefPtr<StyleValue> border_style() const { return m_border_style; }
  665. NonnullRefPtr<StyleValue> border_color() const { return m_border_color; }
  666. virtual String to_string() const override
  667. {
  668. 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());
  669. }
  670. private:
  671. BorderStyleValue(
  672. NonnullRefPtr<StyleValue> border_width,
  673. NonnullRefPtr<StyleValue> border_style,
  674. NonnullRefPtr<StyleValue> border_color)
  675. : StyleValue(Type::Border)
  676. , m_border_width(border_width)
  677. , m_border_style(border_style)
  678. , m_border_color(border_color)
  679. {
  680. }
  681. NonnullRefPtr<StyleValue> m_border_width;
  682. NonnullRefPtr<StyleValue> m_border_style;
  683. NonnullRefPtr<StyleValue> m_border_color;
  684. };
  685. class BorderRadiusStyleValue final : public StyleValue {
  686. public:
  687. static NonnullRefPtr<BorderRadiusStyleValue> create(Length const& horizontal_radius, Length const& vertical_radius)
  688. {
  689. return adopt_ref(*new BorderRadiusStyleValue(horizontal_radius, vertical_radius));
  690. }
  691. virtual ~BorderRadiusStyleValue() override { }
  692. Length const& horizontal_radius() const { return m_horizontal_radius; }
  693. Length const& vertical_radius() const { return m_vertical_radius; }
  694. bool is_elliptical() const { return m_is_elliptical; }
  695. // FIXME: Remove this once we support elliptical border-radius in Layout/Node.
  696. virtual Length to_length() const override { return horizontal_radius(); }
  697. virtual String to_string() const override
  698. {
  699. return String::formatted("{} / {}", m_horizontal_radius.to_string(), m_vertical_radius.to_string());
  700. }
  701. virtual bool equals(StyleValue const& other) const override
  702. {
  703. if (type() != other.type())
  704. return false;
  705. auto& other_value = static_cast<BorderRadiusStyleValue const&>(other);
  706. return m_is_elliptical == other_value.m_is_elliptical
  707. && m_horizontal_radius == other_value.m_horizontal_radius
  708. && m_vertical_radius == other_value.m_vertical_radius;
  709. }
  710. private:
  711. BorderRadiusStyleValue(Length const& horizontal_radius, Length const& vertical_radius)
  712. : StyleValue(Type::BorderRadius)
  713. , m_horizontal_radius(horizontal_radius)
  714. , m_vertical_radius(vertical_radius)
  715. {
  716. m_is_elliptical = (m_horizontal_radius != m_vertical_radius);
  717. }
  718. bool m_is_elliptical;
  719. Length m_horizontal_radius;
  720. Length m_vertical_radius;
  721. };
  722. class CombinedBorderRadiusStyleValue final : public StyleValue {
  723. public:
  724. static NonnullRefPtr<CombinedBorderRadiusStyleValue> create(NonnullRefPtr<BorderRadiusStyleValue> top_left, NonnullRefPtr<BorderRadiusStyleValue> top_right, NonnullRefPtr<BorderRadiusStyleValue> bottom_right, NonnullRefPtr<BorderRadiusStyleValue> bottom_left)
  725. {
  726. return adopt_ref(*new CombinedBorderRadiusStyleValue(top_left, top_right, bottom_right, bottom_left));
  727. }
  728. virtual ~CombinedBorderRadiusStyleValue() override { }
  729. NonnullRefPtr<BorderRadiusStyleValue> top_left() const { return m_top_left; }
  730. NonnullRefPtr<BorderRadiusStyleValue> top_right() const { return m_top_right; }
  731. NonnullRefPtr<BorderRadiusStyleValue> bottom_right() const { return m_bottom_right; }
  732. NonnullRefPtr<BorderRadiusStyleValue> bottom_left() const { return m_bottom_left; }
  733. virtual String to_string() const override
  734. {
  735. 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());
  736. }
  737. private:
  738. CombinedBorderRadiusStyleValue(NonnullRefPtr<BorderRadiusStyleValue> top_left, NonnullRefPtr<BorderRadiusStyleValue> top_right, NonnullRefPtr<BorderRadiusStyleValue> bottom_right, NonnullRefPtr<BorderRadiusStyleValue> bottom_left)
  739. : StyleValue(Type::CombinedBorderRadius)
  740. , m_top_left(top_left)
  741. , m_top_right(top_right)
  742. , m_bottom_right(bottom_right)
  743. , m_bottom_left(bottom_left)
  744. {
  745. }
  746. NonnullRefPtr<BorderRadiusStyleValue> m_top_left;
  747. NonnullRefPtr<BorderRadiusStyleValue> m_top_right;
  748. NonnullRefPtr<BorderRadiusStyleValue> m_bottom_right;
  749. NonnullRefPtr<BorderRadiusStyleValue> m_bottom_left;
  750. };
  751. class FlexStyleValue final : public StyleValue {
  752. public:
  753. static NonnullRefPtr<FlexStyleValue> create(
  754. NonnullRefPtr<StyleValue> grow,
  755. NonnullRefPtr<StyleValue> shrink,
  756. NonnullRefPtr<StyleValue> basis)
  757. {
  758. return adopt_ref(*new FlexStyleValue(grow, shrink, basis));
  759. }
  760. virtual ~FlexStyleValue() override { }
  761. NonnullRefPtr<StyleValue> grow() const { return m_grow; }
  762. NonnullRefPtr<StyleValue> shrink() const { return m_shrink; }
  763. NonnullRefPtr<StyleValue> basis() const { return m_basis; }
  764. virtual String to_string() const override
  765. {
  766. return String::formatted("Flex grow: {}, shrink: {}, basis: {}", m_grow->to_string(), m_shrink->to_string(), m_basis->to_string());
  767. }
  768. private:
  769. FlexStyleValue(
  770. NonnullRefPtr<StyleValue> grow,
  771. NonnullRefPtr<StyleValue> shrink,
  772. NonnullRefPtr<StyleValue> basis)
  773. : StyleValue(Type::Flex)
  774. , m_grow(grow)
  775. , m_shrink(shrink)
  776. , m_basis(basis)
  777. {
  778. }
  779. NonnullRefPtr<StyleValue> m_grow;
  780. NonnullRefPtr<StyleValue> m_shrink;
  781. NonnullRefPtr<StyleValue> m_basis;
  782. };
  783. class FlexFlowStyleValue final : public StyleValue {
  784. public:
  785. static NonnullRefPtr<FlexFlowStyleValue> create(NonnullRefPtr<StyleValue> flex_direction, NonnullRefPtr<StyleValue> flex_wrap)
  786. {
  787. return adopt_ref(*new FlexFlowStyleValue(flex_direction, flex_wrap));
  788. }
  789. virtual ~FlexFlowStyleValue() override { }
  790. NonnullRefPtr<StyleValue> flex_direction() const { return m_flex_direction; }
  791. NonnullRefPtr<StyleValue> flex_wrap() const { return m_flex_wrap; }
  792. virtual String to_string() const override
  793. {
  794. return String::formatted("FlexFlow flex_direction: {}, flex_wrap: {}", m_flex_direction->to_string(), m_flex_wrap->to_string());
  795. }
  796. private:
  797. FlexFlowStyleValue(NonnullRefPtr<StyleValue> flex_direction, NonnullRefPtr<StyleValue> flex_wrap)
  798. : StyleValue(Type::FlexFlow)
  799. , m_flex_direction(flex_direction)
  800. , m_flex_wrap(flex_wrap)
  801. {
  802. }
  803. NonnullRefPtr<StyleValue> m_flex_direction;
  804. NonnullRefPtr<StyleValue> m_flex_wrap;
  805. };
  806. class FontStyleValue final : public StyleValue {
  807. public:
  808. 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)); }
  809. virtual ~FontStyleValue() override { }
  810. NonnullRefPtr<StyleValue> font_style() const { return m_font_style; }
  811. NonnullRefPtr<StyleValue> font_weight() const { return m_font_weight; }
  812. NonnullRefPtr<StyleValue> font_size() const { return m_font_size; }
  813. NonnullRefPtr<StyleValue> line_height() const { return m_line_height; }
  814. NonnullRefPtr<StyleValue> font_families() const { return m_font_families; }
  815. virtual String to_string() const override
  816. {
  817. return String::formatted("Font style: {}, weight: {}, size: {}, line_height: {}, families: {}",
  818. 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());
  819. }
  820. private:
  821. FontStyleValue(NonnullRefPtr<StyleValue> font_style, NonnullRefPtr<StyleValue> font_weight, NonnullRefPtr<StyleValue> font_size, NonnullRefPtr<StyleValue> line_height, NonnullRefPtr<StyleValue> font_families)
  822. : StyleValue(Type::Font)
  823. , m_font_style(font_style)
  824. , m_font_weight(font_weight)
  825. , m_font_size(font_size)
  826. , m_line_height(line_height)
  827. , m_font_families(font_families)
  828. {
  829. }
  830. NonnullRefPtr<StyleValue> m_font_style;
  831. NonnullRefPtr<StyleValue> m_font_weight;
  832. NonnullRefPtr<StyleValue> m_font_size;
  833. NonnullRefPtr<StyleValue> m_line_height;
  834. NonnullRefPtr<StyleValue> m_font_families;
  835. // FIXME: Implement font-stretch and font-variant.
  836. };
  837. class ListStyleStyleValue final : public StyleValue {
  838. public:
  839. static NonnullRefPtr<ListStyleStyleValue> create(
  840. NonnullRefPtr<StyleValue> position,
  841. NonnullRefPtr<StyleValue> image,
  842. NonnullRefPtr<StyleValue> style_type)
  843. {
  844. return adopt_ref(*new ListStyleStyleValue(position, image, style_type));
  845. }
  846. virtual ~ListStyleStyleValue() override { }
  847. NonnullRefPtr<StyleValue> position() const { return m_position; }
  848. NonnullRefPtr<StyleValue> image() const { return m_image; }
  849. NonnullRefPtr<StyleValue> style_type() const { return m_style_type; }
  850. virtual String to_string() const override
  851. {
  852. return String::formatted("ListStyle position: {}, image: {}, style_type: {}", m_position->to_string(), m_image->to_string(), m_style_type->to_string());
  853. }
  854. private:
  855. ListStyleStyleValue(
  856. NonnullRefPtr<StyleValue> position,
  857. NonnullRefPtr<StyleValue> image,
  858. NonnullRefPtr<StyleValue> style_type)
  859. : StyleValue(Type::ListStyle)
  860. , m_position(position)
  861. , m_image(image)
  862. , m_style_type(style_type)
  863. {
  864. }
  865. NonnullRefPtr<StyleValue> m_position;
  866. NonnullRefPtr<StyleValue> m_image;
  867. NonnullRefPtr<StyleValue> m_style_type;
  868. };
  869. class OverflowStyleValue final : public StyleValue {
  870. public:
  871. static NonnullRefPtr<OverflowStyleValue> create(NonnullRefPtr<StyleValue> overflow_x, NonnullRefPtr<StyleValue> overflow_y)
  872. {
  873. return adopt_ref(*new OverflowStyleValue(overflow_x, overflow_y));
  874. }
  875. virtual ~OverflowStyleValue() override { }
  876. NonnullRefPtr<StyleValue> overflow_x() const { return m_overflow_x; }
  877. NonnullRefPtr<StyleValue> overflow_y() const { return m_overflow_y; }
  878. virtual String to_string() const override
  879. {
  880. return String::formatted("{} {}", m_overflow_x->to_string(), m_overflow_y->to_string());
  881. }
  882. private:
  883. OverflowStyleValue(NonnullRefPtr<StyleValue> overflow_x, NonnullRefPtr<StyleValue> overflow_y)
  884. : StyleValue(Type::Overflow)
  885. , m_overflow_x(overflow_x)
  886. , m_overflow_y(overflow_y)
  887. {
  888. }
  889. NonnullRefPtr<StyleValue> m_overflow_x;
  890. NonnullRefPtr<StyleValue> m_overflow_y;
  891. };
  892. class TextDecorationStyleValue final : public StyleValue {
  893. public:
  894. static NonnullRefPtr<TextDecorationStyleValue> create(
  895. NonnullRefPtr<StyleValue> line,
  896. NonnullRefPtr<StyleValue> style,
  897. NonnullRefPtr<StyleValue> color)
  898. {
  899. return adopt_ref(*new TextDecorationStyleValue(line, style, color));
  900. }
  901. virtual ~TextDecorationStyleValue() override { }
  902. NonnullRefPtr<StyleValue> line() const { return m_line; }
  903. NonnullRefPtr<StyleValue> style() const { return m_style; }
  904. NonnullRefPtr<StyleValue> color() const { return m_color; }
  905. virtual String to_string() const override
  906. {
  907. return String::formatted("TextDecoration line: {}, style: {}, color: {}", m_line->to_string(), m_style->to_string(), m_color->to_string());
  908. }
  909. private:
  910. TextDecorationStyleValue(
  911. NonnullRefPtr<StyleValue> line,
  912. NonnullRefPtr<StyleValue> style,
  913. NonnullRefPtr<StyleValue> color)
  914. : StyleValue(Type::TextDecoration)
  915. , m_line(line)
  916. , m_style(style)
  917. , m_color(color)
  918. {
  919. }
  920. NonnullRefPtr<StyleValue> m_line;
  921. NonnullRefPtr<StyleValue> m_style;
  922. NonnullRefPtr<StyleValue> m_color;
  923. };
  924. class TransformationStyleValue final : public StyleValue {
  925. public:
  926. static NonnullRefPtr<TransformationStyleValue> create(CSS::TransformFunction transform_function, NonnullRefPtrVector<StyleValue>&& values)
  927. {
  928. return adopt_ref(*new TransformationStyleValue(transform_function, move(values)));
  929. }
  930. virtual ~TransformationStyleValue() override { }
  931. CSS::TransformFunction transform_function() const { return m_transform_function; }
  932. NonnullRefPtrVector<StyleValue> values() const { return m_values; }
  933. virtual String to_string() const override
  934. {
  935. return String::formatted("TransformationStyleValue");
  936. }
  937. private:
  938. TransformationStyleValue(CSS::TransformFunction transform_function, NonnullRefPtrVector<StyleValue>&& values)
  939. : StyleValue(Type::Transformation)
  940. , m_transform_function(transform_function)
  941. , m_values(move(values))
  942. {
  943. }
  944. CSS::TransformFunction m_transform_function;
  945. NonnullRefPtrVector<StyleValue> m_values;
  946. };
  947. class StyleValueList final : public StyleValue {
  948. public:
  949. static NonnullRefPtr<StyleValueList> create(NonnullRefPtrVector<StyleValue>&& values) { return adopt_ref(*new StyleValueList(move(values))); }
  950. NonnullRefPtrVector<StyleValue> const& values() const { return m_values; }
  951. virtual String to_string() const
  952. {
  953. StringBuilder builder;
  954. builder.appendff("List[{}](", m_values.size());
  955. for (size_t i = 0; i < m_values.size(); ++i) {
  956. if (i)
  957. builder.append(',');
  958. builder.append(m_values[i].to_string());
  959. }
  960. builder.append(')');
  961. return builder.to_string();
  962. }
  963. private:
  964. StyleValueList(NonnullRefPtrVector<StyleValue>&& values)
  965. : StyleValue(Type::ValueList)
  966. , m_values(move(values))
  967. {
  968. }
  969. NonnullRefPtrVector<StyleValue> m_values;
  970. };
  971. inline CSS::ValueID StyleValue::to_identifier() const
  972. {
  973. if (type() == Type::Identifier)
  974. return static_cast<const IdentifierStyleValue&>(*this).id();
  975. if (is_auto())
  976. return CSS::ValueID::Auto;
  977. return CSS::ValueID::Invalid;
  978. }
  979. }