AriaData.cpp 14 KB

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