AriaData.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  1. /*
  2. * Copyright (c) 2023, Jonah Shafran <jonahshafran@gmail.com>
  3. * Copyright (c) 2023, Shannon Booth <shannon@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <LibWeb/ARIA/AriaData.h>
  8. #include <LibWeb/Infra/CharacterTypes.h>
  9. namespace Web::ARIA {
  10. AriaData::AriaData(Web::ARIA::ARIAMixin const& source)
  11. {
  12. m_aria_active_descendant = source.aria_active_descendant();
  13. m_aria_atomic = AriaData::parse_optional_true_false(source.aria_atomic());
  14. m_aria_auto_complete = AriaData::parse_aria_autocomplete(source.aria_auto_complete());
  15. m_aria_busy = AriaData::parse_true_false(source.aria_busy());
  16. m_aria_checked = AriaData::parse_tristate(source.aria_checked());
  17. m_aria_col_count = AriaData::parse_integer(source.aria_col_count());
  18. m_aria_col_index = AriaData::parse_integer(source.aria_col_index());
  19. m_aria_col_span = AriaData::parse_integer(source.aria_col_span());
  20. m_aria_controls = source.parse_id_reference_list(source.aria_controls());
  21. m_aria_current = AriaData::parse_aria_current(source.aria_current());
  22. m_aria_described_by = source.parse_id_reference_list(source.aria_described_by());
  23. m_aria_details = source.parse_id_reference(source.aria_details());
  24. m_aria_disabled = AriaData::parse_true_false(source.aria_disabled());
  25. m_aria_drop_effect = AriaData::parse_aria_drop_effect(source.aria_drop_effect());
  26. m_aria_error_message = source.parse_id_reference(source.aria_error_message());
  27. m_aria_expanded = AriaData::parse_true_false_undefined(source.aria_expanded());
  28. m_aria_flow_to = source.parse_id_reference_list(source.aria_flow_to());
  29. m_aria_grabbed = AriaData::parse_true_false_undefined(source.aria_grabbed());
  30. m_aria_has_popup = AriaData::parse_aria_has_popup(source.aria_has_popup());
  31. m_aria_hidden = AriaData::parse_true_false_undefined(source.aria_hidden());
  32. m_aria_invalid = AriaData::parse_aria_invalid(source.aria_invalid());
  33. m_aria_key_shortcuts = source.aria_key_shortcuts().value_or(String {});
  34. m_aria_label = source.aria_label().value_or(String {});
  35. m_aria_labelled_by = source.parse_id_reference_list(source.aria_labelled_by());
  36. m_aria_level = AriaData::parse_integer(source.aria_level());
  37. m_aria_live = AriaData::parse_aria_live(source.aria_live());
  38. m_aria_modal = AriaData::parse_true_false(source.aria_modal());
  39. m_aria_multi_line = AriaData::parse_true_false(source.aria_multi_line());
  40. m_aria_multi_selectable = AriaData::parse_true_false(source.aria_multi_selectable());
  41. m_aria_orientation = AriaData::parse_aria_orientation(source.aria_orientation());
  42. m_aria_owns = source.parse_id_reference_list(source.aria_owns());
  43. m_aria_placeholder = source.aria_placeholder().value_or(String {});
  44. m_aria_pos_in_set = AriaData::parse_integer(source.aria_pos_in_set());
  45. m_aria_pressed = AriaData::parse_tristate(source.aria_pressed());
  46. m_aria_read_only = AriaData::parse_true_false(source.aria_read_only());
  47. m_aria_relevant = AriaData::parse_aria_relevant(source.aria_relevant());
  48. m_aria_required = AriaData::parse_true_false(source.aria_required());
  49. m_aria_role_description = source.aria_role_description().value_or(String {});
  50. m_aria_row_count = AriaData::parse_integer(source.aria_row_count());
  51. m_aria_row_index = AriaData::parse_integer(source.aria_row_index());
  52. m_aria_row_span = AriaData::parse_integer(source.aria_row_span());
  53. m_aria_selected = AriaData::parse_true_false_undefined(source.aria_selected());
  54. m_aria_set_size = AriaData::parse_integer(source.aria_set_size());
  55. m_aria_sort = AriaData::parse_aria_sort(source.aria_sort());
  56. m_aria_value_max = AriaData::parse_number(source.aria_value_max());
  57. m_aria_value_min = AriaData::parse_number(source.aria_value_min());
  58. m_aria_value_now = AriaData::parse_number(source.aria_value_now());
  59. m_aria_value_text = source.aria_value_text().value_or(String {});
  60. }
  61. bool AriaData::parse_true_false(Optional<String> const& value)
  62. {
  63. if (value == "true"sv)
  64. return true;
  65. if (value == "false"sv)
  66. return false;
  67. return false;
  68. }
  69. Tristate AriaData::parse_tristate(Optional<String> const& value)
  70. {
  71. if (value == "true"sv)
  72. return Tristate::True;
  73. if (value == "false"sv)
  74. return Tristate::False;
  75. if (value == "mixed"sv)
  76. return Tristate::Mixed;
  77. if (value == "undefined"sv)
  78. return Tristate::Undefined;
  79. return Tristate::Undefined;
  80. }
  81. Optional<bool> AriaData::parse_true_false_undefined(Optional<String> const& value)
  82. {
  83. if (value == "true"sv)
  84. return true;
  85. if (value == "false"sv)
  86. return false;
  87. if (value == "undefined"sv)
  88. return {};
  89. return {};
  90. }
  91. Optional<i32> AriaData::parse_integer(Optional<String> const& value)
  92. {
  93. if (!value.has_value())
  94. return {};
  95. return value->bytes_as_string_view().to_number<i32>();
  96. }
  97. Optional<f64> AriaData::parse_number(Optional<String> const& value)
  98. {
  99. if (!value.has_value())
  100. return {};
  101. return value->to_number<double>(TrimWhitespace::Yes);
  102. }
  103. Optional<String> AriaData::aria_active_descendant_or_default() const
  104. {
  105. return m_aria_active_descendant;
  106. }
  107. bool AriaData::aria_atomic_or_default(bool default_value) const
  108. {
  109. auto value = m_aria_atomic;
  110. if (!value.has_value())
  111. return default_value;
  112. return value.value();
  113. }
  114. AriaAutocomplete AriaData::aria_auto_complete_or_default() const
  115. {
  116. return m_aria_auto_complete;
  117. }
  118. bool AriaData::aria_busy_or_default() const
  119. {
  120. return m_aria_busy;
  121. }
  122. Tristate AriaData::aria_checked_or_default() const
  123. {
  124. return m_aria_checked;
  125. }
  126. Optional<i32> AriaData::aria_col_count_or_default() const
  127. {
  128. return m_aria_col_count;
  129. }
  130. Optional<i32> AriaData::aria_col_index_or_default() const
  131. {
  132. return m_aria_col_index;
  133. }
  134. Optional<i32> AriaData::aria_col_span_or_default() const
  135. {
  136. return m_aria_col_span;
  137. }
  138. Vector<String> AriaData::aria_controls_or_default() const
  139. {
  140. return m_aria_controls;
  141. }
  142. AriaCurrent AriaData::aria_current_or_default() const
  143. {
  144. return m_aria_current;
  145. }
  146. Vector<String> AriaData::aria_described_by_or_default() const
  147. {
  148. return m_aria_described_by;
  149. }
  150. Optional<String> AriaData::aria_details_or_default() const
  151. {
  152. return m_aria_details;
  153. }
  154. bool AriaData::aria_disabled_or_default() const
  155. {
  156. return m_aria_disabled;
  157. }
  158. Vector<AriaDropEffect> AriaData::aria_drop_effect_or_default() const
  159. {
  160. return m_aria_drop_effect;
  161. }
  162. Optional<String> AriaData::aria_error_message_or_default() const
  163. {
  164. return m_aria_error_message;
  165. }
  166. Optional<bool> AriaData::aria_expanded_or_default() const
  167. {
  168. return m_aria_expanded;
  169. }
  170. Vector<String> AriaData::aria_flow_to_or_default() const
  171. {
  172. return m_aria_flow_to;
  173. }
  174. Optional<bool> AriaData::aria_grabbed_or_default() const
  175. {
  176. return m_aria_grabbed;
  177. }
  178. AriaHasPopup AriaData::aria_has_popup_or_default() const
  179. {
  180. return m_aria_has_popup;
  181. }
  182. Optional<bool> AriaData::aria_hidden_or_default() const
  183. {
  184. return m_aria_hidden;
  185. }
  186. AriaInvalid AriaData::aria_invalid_or_default() const
  187. {
  188. return m_aria_invalid;
  189. }
  190. String AriaData::aria_key_shortcuts_or_default() const
  191. {
  192. return m_aria_key_shortcuts;
  193. }
  194. String AriaData::aria_label_or_default() const
  195. {
  196. return m_aria_label;
  197. }
  198. Vector<String> AriaData::aria_labelled_by_or_default() const
  199. {
  200. return m_aria_labelled_by;
  201. }
  202. Optional<i32> AriaData::aria_level_or_default() const
  203. {
  204. return m_aria_level;
  205. }
  206. AriaLive AriaData::aria_live_or_default(AriaLive default_value) const
  207. {
  208. auto value = m_aria_live;
  209. if (!value.has_value())
  210. return default_value;
  211. return value.value();
  212. }
  213. bool AriaData::aria_modal_or_default() const
  214. {
  215. return m_aria_modal;
  216. }
  217. bool AriaData::aria_multi_line_or_default() const
  218. {
  219. return m_aria_multi_line;
  220. }
  221. bool AriaData::aria_multi_selectable_or_default() const
  222. {
  223. return m_aria_multi_selectable;
  224. }
  225. AriaOrientation AriaData::aria_orientation_or_default(AriaOrientation default_value) const
  226. {
  227. auto value = m_aria_orientation;
  228. if (!value.has_value())
  229. return default_value;
  230. return value.value();
  231. }
  232. Vector<String> AriaData::aria_owns_or_default() const
  233. {
  234. return m_aria_owns;
  235. }
  236. String AriaData::aria_placeholder_or_default() const
  237. {
  238. return m_aria_placeholder;
  239. }
  240. Optional<i32> AriaData::aria_pos_in_set_or_default() const
  241. {
  242. return m_aria_pos_in_set;
  243. }
  244. Tristate AriaData::aria_pressed_or_default() const
  245. {
  246. return m_aria_pressed;
  247. }
  248. bool AriaData::aria_read_only_or_default() const
  249. {
  250. return m_aria_read_only;
  251. }
  252. Vector<AriaRelevant> AriaData::aria_relevant_or_default() const
  253. {
  254. return m_aria_relevant;
  255. }
  256. bool AriaData::aria_required_or_default() const
  257. {
  258. return m_aria_required;
  259. }
  260. String AriaData::aria_role_description_or_default() const
  261. {
  262. return m_aria_role_description;
  263. }
  264. Optional<i32> AriaData::aria_row_count_or_default() const
  265. {
  266. return m_aria_row_count;
  267. }
  268. Optional<i32> AriaData::aria_row_index_or_default() const
  269. {
  270. return m_aria_row_index;
  271. }
  272. Optional<i32> AriaData::aria_row_span_or_default() const
  273. {
  274. return m_aria_row_span;
  275. }
  276. Optional<bool> AriaData::aria_selected_or_default() const
  277. {
  278. return m_aria_selected;
  279. }
  280. Optional<i32> AriaData::aria_set_size_or_default() const
  281. {
  282. return m_aria_set_size;
  283. }
  284. AriaSort AriaData::aria_sort_or_default() const
  285. {
  286. return m_aria_sort;
  287. }
  288. Optional<f64> AriaData::aria_value_max_or_default(Optional<f64> default_value) const
  289. {
  290. auto value = m_aria_value_max;
  291. if (!value.has_value())
  292. return default_value;
  293. return value;
  294. }
  295. Optional<f64> AriaData::aria_value_min_or_default(Optional<f64> default_value) const
  296. {
  297. auto value = m_aria_value_min;
  298. if (!value.has_value())
  299. return default_value;
  300. return value;
  301. }
  302. Optional<f64> AriaData::aria_value_now_or_default() const
  303. {
  304. return m_aria_value_now;
  305. }
  306. String AriaData::aria_value_text_or_default() const
  307. {
  308. return m_aria_value_text;
  309. }
  310. AriaAutocomplete AriaData::parse_aria_autocomplete(Optional<String> const& value)
  311. {
  312. if (value == "inline"sv)
  313. return AriaAutocomplete::Inline;
  314. if (value == "list"sv)
  315. return AriaAutocomplete::List;
  316. if (value == "both"sv)
  317. return AriaAutocomplete::Both;
  318. if (value == "none"sv)
  319. return AriaAutocomplete::None;
  320. return AriaAutocomplete::None;
  321. }
  322. AriaCurrent AriaData::parse_aria_current(Optional<String> const& value)
  323. {
  324. if (value == "page"sv)
  325. return AriaCurrent::Page;
  326. if (value == "step"sv)
  327. return AriaCurrent::Step;
  328. if (value == "location"sv)
  329. return AriaCurrent::Location;
  330. if (value == "date"sv)
  331. return AriaCurrent::Date;
  332. if (value == "time"sv)
  333. return AriaCurrent::Time;
  334. if (value == "true"sv)
  335. return AriaCurrent::True;
  336. if (value == "false"sv)
  337. return AriaCurrent::False;
  338. return AriaCurrent::False;
  339. }
  340. Vector<AriaDropEffect> AriaData::parse_aria_drop_effect(Optional<String> const& value)
  341. {
  342. if (!value.has_value())
  343. return {};
  344. Vector<AriaDropEffect> result;
  345. for (auto token : value->bytes_as_string_view().split_view_if(Infra::is_ascii_whitespace)) {
  346. if (token == "copy"sv)
  347. result.append(AriaDropEffect::Copy);
  348. else if (token == "execute"sv)
  349. result.append(AriaDropEffect::Execute);
  350. else if (token == "link"sv)
  351. result.append(AriaDropEffect::Link);
  352. else if (token == "move"sv)
  353. result.append(AriaDropEffect::Move);
  354. else if (token == "popup"sv)
  355. result.append(AriaDropEffect::Popup);
  356. }
  357. // None combined with any other token value is ignored
  358. if (result.is_empty())
  359. result.append(AriaDropEffect::None);
  360. return result;
  361. }
  362. AriaHasPopup AriaData::parse_aria_has_popup(Optional<String> const& value)
  363. {
  364. if (value == "false"sv)
  365. return AriaHasPopup::False;
  366. if (value == "true"sv)
  367. return AriaHasPopup::True;
  368. if (value == "menu"sv)
  369. return AriaHasPopup::Menu;
  370. if (value == "listbox"sv)
  371. return AriaHasPopup::Listbox;
  372. if (value == "tree"sv)
  373. return AriaHasPopup::Tree;
  374. if (value == "grid"sv)
  375. return AriaHasPopup::Grid;
  376. if (value == "dialog"sv)
  377. return AriaHasPopup::Dialog;
  378. return AriaHasPopup::False;
  379. }
  380. AriaInvalid AriaData::parse_aria_invalid(Optional<String> const& value)
  381. {
  382. if (value == "grammar"sv)
  383. return AriaInvalid::Grammar;
  384. if (value == "false"sv)
  385. return AriaInvalid::False;
  386. if (value == "spelling"sv)
  387. return AriaInvalid::Spelling;
  388. if (value == "true"sv)
  389. return AriaInvalid::True;
  390. return AriaInvalid::False;
  391. }
  392. Optional<AriaLive> AriaData::parse_aria_live(Optional<String> const& value)
  393. {
  394. if (value == "assertive"sv)
  395. return AriaLive::Assertive;
  396. if (value == "off"sv)
  397. return AriaLive::Off;
  398. if (value == "polite"sv)
  399. return AriaLive::Polite;
  400. return {};
  401. }
  402. Optional<AriaOrientation> AriaData::parse_aria_orientation(Optional<String> const& value)
  403. {
  404. if (value == "horizontal"sv)
  405. return AriaOrientation::Horizontal;
  406. if (value == "undefined"sv)
  407. return AriaOrientation::Undefined;
  408. if (value == "vertical"sv)
  409. return AriaOrientation::Vertical;
  410. return {};
  411. }
  412. Vector<AriaRelevant> AriaData::parse_aria_relevant(Optional<String> const& value)
  413. {
  414. if (!value.has_value())
  415. return {};
  416. Vector<AriaRelevant> result;
  417. auto tokens = value->bytes_as_string_view().split_view_if(Infra::is_ascii_whitespace);
  418. for (size_t i = 0; i < tokens.size(); i++) {
  419. if (tokens[i] == "additions"sv) {
  420. if (i + 1 < tokens.size()) {
  421. if (tokens[i + 1] == "text"sv) {
  422. result.append(AriaRelevant::AdditionsText);
  423. ++i;
  424. continue;
  425. }
  426. if (tokens[i + 1] == "removals"sv && i + 2 < tokens.size() && tokens[i + 2] == "text"sv) {
  427. result.append(AriaRelevant::All);
  428. i += 2;
  429. continue;
  430. }
  431. }
  432. result.append(AriaRelevant::Additions);
  433. } else if (tokens[i] == "all"sv)
  434. result.append(AriaRelevant::All);
  435. else if (tokens[i] == "removals"sv)
  436. result.append(AriaRelevant::Removals);
  437. else if (tokens[i] == "text"sv)
  438. result.append(AriaRelevant::Text);
  439. }
  440. if (result.is_empty())
  441. result.append(AriaRelevant::AdditionsText);
  442. return result;
  443. }
  444. AriaSort AriaData::parse_aria_sort(Optional<String> const& value)
  445. {
  446. if (value == "ascending"sv)
  447. return AriaSort::Ascending;
  448. if (value == "descending"sv)
  449. return AriaSort::Descending;
  450. if (value == "none"sv)
  451. return AriaSort::None;
  452. if (value == "other"sv)
  453. return AriaSort::Other;
  454. return AriaSort::None;
  455. }
  456. Optional<bool> AriaData::parse_optional_true_false(Optional<String> const& value)
  457. {
  458. if (value == "true"sv)
  459. return true;
  460. if (value == "false"sv)
  461. return false;
  462. return {};
  463. }
  464. }