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