StateAndProperties.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. /*
  2. * Copyright (c) 2023, Jonah Shafran <jonahshafran@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/Variant.h>
  7. #include <LibWeb/ARIA/StateAndProperties.h>
  8. namespace Web::ARIA {
  9. ErrorOr<String> state_or_property_to_string_value(StateAndProperties state_or_property, AriaData const& aria_data, DefaultValueType default_value)
  10. {
  11. switch (state_or_property) {
  12. case StateAndProperties::AriaActiveDescendant: {
  13. auto value = aria_data.aria_active_descendant_or_default();
  14. return value.has_value() ? String::from_deprecated_string(value.value()) : String::from_utf8(""sv);
  15. }
  16. case StateAndProperties::AriaAtomic: {
  17. bool value;
  18. if (default_value.has<bool>())
  19. value = aria_data.aria_atomic_or_default(default_value.get<bool>());
  20. else
  21. value = aria_data.aria_atomic_or_default();
  22. return value ? "true"_short_string : "false"_short_string;
  23. }
  24. case StateAndProperties::AriaAutoComplete: {
  25. auto value = aria_data.aria_auto_complete_or_default();
  26. switch (value) {
  27. case AriaAutocomplete::None:
  28. return "none"_short_string;
  29. case AriaAutocomplete::List:
  30. return "list"_short_string;
  31. case AriaAutocomplete::Both:
  32. return "both"_short_string;
  33. case AriaAutocomplete::Inline:
  34. return "inline"_short_string;
  35. }
  36. VERIFY_NOT_REACHED();
  37. }
  38. case StateAndProperties::AriaBusy:
  39. return String::from_utf8(aria_data.aria_busy_or_default() ? "true"sv : "false"sv);
  40. case StateAndProperties::AriaChecked:
  41. return ARIA::tristate_to_string(aria_data.aria_checked_or_default());
  42. case StateAndProperties::AriaColCount:
  43. return ARIA::optional_integer_to_string(aria_data.aria_col_count_or_default());
  44. case StateAndProperties::AriaColIndex:
  45. return ARIA::optional_integer_to_string(aria_data.aria_col_index_or_default());
  46. case StateAndProperties::AriaColSpan:
  47. return ARIA::optional_integer_to_string(aria_data.aria_col_span_or_default());
  48. case StateAndProperties::AriaControls:
  49. return id_reference_list_to_string(aria_data.aria_controls_or_default());
  50. case StateAndProperties::AriaCurrent: {
  51. auto value = aria_data.aria_current_or_default();
  52. switch (value) {
  53. case AriaCurrent::False:
  54. return "false"_short_string;
  55. case AriaCurrent::True:
  56. return "true"_short_string;
  57. case AriaCurrent::Date:
  58. return "date"_short_string;
  59. case AriaCurrent::Location:
  60. return "location"_string;
  61. case AriaCurrent::Page:
  62. return "page"_short_string;
  63. case AriaCurrent::Step:
  64. return "step"_short_string;
  65. case AriaCurrent::Time:
  66. return "time"_short_string;
  67. }
  68. VERIFY_NOT_REACHED();
  69. }
  70. case StateAndProperties::AriaDescribedBy:
  71. return id_reference_list_to_string(aria_data.aria_described_by_or_default());
  72. case StateAndProperties::AriaDetails: {
  73. auto value = aria_data.aria_details_or_default();
  74. return value.has_value() ? String::from_deprecated_string(value.value()) : String::from_utf8(""sv);
  75. }
  76. case StateAndProperties::AriaDisabled:
  77. return aria_data.aria_disabled_or_default() ? "true"_short_string : "false"_short_string;
  78. case StateAndProperties::AriaDropEffect: {
  79. StringBuilder builder;
  80. auto value = aria_data.aria_drop_effect_or_default();
  81. for (auto const drop_effect : value) {
  82. StringView to_add;
  83. switch (drop_effect) {
  84. case AriaDropEffect::Copy:
  85. to_add = "copy"sv;
  86. break;
  87. case AriaDropEffect::Execute:
  88. to_add = "execute"sv;
  89. break;
  90. case AriaDropEffect::Link:
  91. to_add = "link"sv;
  92. break;
  93. case AriaDropEffect::Move:
  94. to_add = "move"sv;
  95. break;
  96. case AriaDropEffect::None:
  97. to_add = "none"sv;
  98. break;
  99. case AriaDropEffect::Popup:
  100. to_add = "popup"sv;
  101. break;
  102. }
  103. if (builder.is_empty())
  104. builder.append(to_add);
  105. else {
  106. builder.append(" "sv);
  107. builder.append(to_add);
  108. }
  109. }
  110. return builder.to_string();
  111. }
  112. case StateAndProperties::AriaErrorMessage: {
  113. auto value = aria_data.aria_error_message_or_default();
  114. return value.has_value() ? String::from_deprecated_string(value.value()) : String {};
  115. }
  116. case StateAndProperties::AriaExpanded:
  117. return ARIA::optional_bool_to_string(aria_data.aria_expanded_or_default());
  118. case StateAndProperties::AriaFlowTo:
  119. return id_reference_list_to_string(aria_data.aria_flow_to_or_default());
  120. case StateAndProperties::AriaGrabbed:
  121. return ARIA::optional_bool_to_string(aria_data.aria_grabbed_or_default());
  122. case StateAndProperties::AriaHasPopup: {
  123. auto value = aria_data.aria_has_popup_or_default();
  124. switch (value) {
  125. case AriaHasPopup::False:
  126. return "false"_short_string;
  127. case AriaHasPopup::True:
  128. return "true"_short_string;
  129. case AriaHasPopup::Menu:
  130. return "menu"_short_string;
  131. case AriaHasPopup::Listbox:
  132. return "listbox"_string;
  133. case AriaHasPopup::Tree:
  134. return "tree"_short_string;
  135. case AriaHasPopup::Grid:
  136. return "grid"_short_string;
  137. case AriaHasPopup::Dialog:
  138. return "dialog"_short_string;
  139. }
  140. VERIFY_NOT_REACHED();
  141. }
  142. case StateAndProperties::AriaHidden:
  143. return ARIA::optional_bool_to_string(aria_data.aria_hidden_or_default());
  144. case StateAndProperties::AriaInvalid: {
  145. auto value = aria_data.aria_invalid_or_default();
  146. switch (value) {
  147. case AriaInvalid::Grammar:
  148. return "grammar"_short_string;
  149. case AriaInvalid::False:
  150. return "false"_short_string;
  151. case AriaInvalid::Spelling:
  152. return "spelling"_string;
  153. case AriaInvalid::True:
  154. return "true"_short_string;
  155. }
  156. VERIFY_NOT_REACHED();
  157. }
  158. case StateAndProperties::AriaKeyShortcuts:
  159. return String::from_deprecated_string(aria_data.aria_key_shortcuts_or_default());
  160. case StateAndProperties::AriaLabel:
  161. return String::from_deprecated_string(aria_data.aria_label_or_default());
  162. case StateAndProperties::AriaLabelledBy:
  163. return id_reference_list_to_string(aria_data.aria_labelled_by_or_default());
  164. case StateAndProperties::AriaLevel:
  165. return ARIA::optional_integer_to_string(aria_data.aria_level_or_default());
  166. case StateAndProperties::AriaLive: {
  167. AriaLive value;
  168. if (default_value.has<AriaLive>())
  169. value = aria_data.aria_live_or_default(default_value.get<AriaLive>());
  170. else
  171. value = aria_data.aria_live_or_default();
  172. switch (value) {
  173. case AriaLive::Assertive:
  174. return "assertive"_string;
  175. case AriaLive::Off:
  176. return "off"_short_string;
  177. case AriaLive::Polite:
  178. return "polite"_short_string;
  179. }
  180. VERIFY_NOT_REACHED();
  181. }
  182. case StateAndProperties::AriaModal:
  183. return aria_data.aria_modal_or_default() ? "true"_short_string : "false"_short_string;
  184. case StateAndProperties::AriaMultiLine:
  185. return aria_data.aria_multi_line_or_default() ? "true"_short_string : "false"_short_string;
  186. case StateAndProperties::AriaMultiSelectable:
  187. return aria_data.aria_multi_selectable_or_default() ? "true"_short_string : "false"_short_string;
  188. case StateAndProperties::AriaOrientation: {
  189. AriaOrientation value;
  190. if (default_value.has<AriaOrientation>())
  191. value = aria_data.aria_orientation_or_default(default_value.get<AriaOrientation>());
  192. else
  193. value = aria_data.aria_orientation_or_default();
  194. switch (value) {
  195. case AriaOrientation::Horizontal:
  196. return "horizontal"_string;
  197. case AriaOrientation::Undefined:
  198. return "undefined"_string;
  199. case AriaOrientation::Vertical:
  200. return "vertical"_string;
  201. }
  202. VERIFY_NOT_REACHED();
  203. }
  204. case StateAndProperties::AriaOwns:
  205. return id_reference_list_to_string(aria_data.aria_owns_or_default());
  206. case StateAndProperties::AriaPlaceholder:
  207. return String::from_deprecated_string(aria_data.aria_placeholder_or_default());
  208. case StateAndProperties::AriaPosInSet:
  209. return ARIA::optional_integer_to_string(aria_data.aria_pos_in_set_or_default());
  210. case StateAndProperties::AriaPressed:
  211. return ARIA::tristate_to_string(aria_data.aria_pressed_or_default());
  212. case StateAndProperties::AriaReadOnly:
  213. return aria_data.aria_read_only_or_default() ? "true"_short_string : "false"_short_string;
  214. case StateAndProperties::AriaRelevant: {
  215. StringBuilder builder;
  216. auto value = aria_data.aria_relevant_or_default();
  217. for (auto const relevant : value) {
  218. StringView to_add;
  219. switch (relevant) {
  220. case AriaRelevant::Additions:
  221. to_add = "additions"sv;
  222. break;
  223. case AriaRelevant::AdditionsText:
  224. to_add = "additions text"sv;
  225. break;
  226. case AriaRelevant::All:
  227. to_add = "all"sv;
  228. break;
  229. case AriaRelevant::Removals:
  230. to_add = "removals"sv;
  231. break;
  232. case AriaRelevant::Text:
  233. to_add = "text"sv;
  234. break;
  235. }
  236. if (builder.is_empty())
  237. builder.append(to_add);
  238. else {
  239. builder.append(" "sv);
  240. builder.append(to_add);
  241. }
  242. }
  243. return builder.to_string();
  244. }
  245. case StateAndProperties::AriaRequired:
  246. return String::from_utf8(aria_data.aria_required_or_default() ? "true"sv : "false"sv);
  247. case StateAndProperties::AriaRoleDescription:
  248. return String::from_deprecated_string(aria_data.aria_role_description_or_default());
  249. case StateAndProperties::AriaRowCount:
  250. return ARIA::optional_integer_to_string(aria_data.aria_row_count_or_default());
  251. case StateAndProperties::AriaRowIndex:
  252. return ARIA::optional_integer_to_string(aria_data.aria_row_index_or_default());
  253. case StateAndProperties::AriaRowSpan:
  254. return ARIA::optional_integer_to_string(aria_data.aria_row_span_or_default());
  255. case StateAndProperties::AriaSelected:
  256. return ARIA::optional_bool_to_string(aria_data.aria_selected_or_default());
  257. case StateAndProperties::AriaSetSize:
  258. return ARIA::optional_integer_to_string(aria_data.aria_set_size_or_default());
  259. case StateAndProperties::AriaSort: {
  260. auto value = aria_data.aria_sort_or_default();
  261. switch (value) {
  262. case AriaSort::Ascending:
  263. return "ascending"_string;
  264. case AriaSort::Descending:
  265. return "descending"_string;
  266. case AriaSort::None:
  267. return "none"_short_string;
  268. case AriaSort::Other:
  269. return "other"_short_string;
  270. }
  271. VERIFY_NOT_REACHED();
  272. }
  273. case StateAndProperties::AriaValueMax:
  274. if (default_value.has<f64>())
  275. return ARIA::optional_number_to_string(aria_data.aria_value_max_or_default(default_value.get<f64>()));
  276. else
  277. return ARIA::optional_number_to_string(aria_data.aria_value_max_or_default());
  278. case StateAndProperties::AriaValueMin:
  279. if (default_value.has<f64>())
  280. return ARIA::optional_number_to_string(aria_data.aria_value_min_or_default(default_value.get<f64>()));
  281. else
  282. return ARIA::optional_number_to_string(aria_data.aria_value_min_or_default());
  283. case StateAndProperties::AriaValueNow:
  284. return ARIA::optional_number_to_string(aria_data.aria_value_now_or_default());
  285. case StateAndProperties::AriaValueText:
  286. return String::from_deprecated_string(aria_data.aria_value_text_or_default());
  287. }
  288. VERIFY_NOT_REACHED();
  289. }
  290. ErrorOr<String> tristate_to_string(Tristate value)
  291. {
  292. switch (value) {
  293. case Tristate::False:
  294. return "false"_short_string;
  295. case Tristate::True:
  296. return "true"_short_string;
  297. case Tristate::Undefined:
  298. return "undefined"_string;
  299. case Tristate::Mixed:
  300. return "mixed"_short_string;
  301. }
  302. VERIFY_NOT_REACHED();
  303. }
  304. ErrorOr<String> optional_integer_to_string(Optional<i32> value)
  305. {
  306. if (value.has_value())
  307. return String::number(value.value());
  308. return String {};
  309. }
  310. ErrorOr<String> optional_bool_to_string(Optional<bool> value)
  311. {
  312. if (!value.has_value())
  313. return "undefined"_string;
  314. if (value.value())
  315. return "true"_short_string;
  316. return "false"_short_string;
  317. }
  318. ErrorOr<String> optional_number_to_string(Optional<f64> value)
  319. {
  320. if (!value.has_value())
  321. return "undefined"_string;
  322. return String::number(value.value());
  323. }
  324. ErrorOr<String> id_reference_list_to_string(Vector<DeprecatedString> const& value)
  325. {
  326. StringBuilder builder;
  327. for (auto const& id : value) {
  328. if (builder.is_empty()) {
  329. builder.append(id);
  330. } else {
  331. builder.append(" "sv);
  332. builder.append(id);
  333. }
  334. }
  335. return builder.to_string();
  336. }
  337. StringView state_or_property_to_string(StateAndProperties value)
  338. {
  339. switch (value) {
  340. case StateAndProperties::AriaActiveDescendant:
  341. return "aria-activedescendant"sv;
  342. case StateAndProperties::AriaAtomic:
  343. return "aria-atomic"sv;
  344. case StateAndProperties::AriaAutoComplete:
  345. return "aria-autocomplete"sv;
  346. case StateAndProperties::AriaBusy:
  347. return "aria-busy"sv;
  348. case StateAndProperties::AriaChecked:
  349. return "aria-checked"sv;
  350. case StateAndProperties::AriaColCount:
  351. return "aria-colcount"sv;
  352. case StateAndProperties::AriaColIndex:
  353. return "aria-colindex"sv;
  354. case StateAndProperties::AriaColSpan:
  355. return "aria-colspan"sv;
  356. case StateAndProperties::AriaControls:
  357. return "aria-controls"sv;
  358. case StateAndProperties::AriaCurrent:
  359. return "aria-current"sv;
  360. case StateAndProperties::AriaDescribedBy:
  361. return "aria-describedby"sv;
  362. case StateAndProperties::AriaDetails:
  363. return "aria-details"sv;
  364. case StateAndProperties::AriaDisabled:
  365. return "aria-disabled"sv;
  366. case StateAndProperties::AriaDropEffect:
  367. return "aria-dropeffect"sv;
  368. case StateAndProperties::AriaErrorMessage:
  369. return "aria-errormessage"sv;
  370. case StateAndProperties::AriaExpanded:
  371. return "aria-expanded"sv;
  372. case StateAndProperties::AriaFlowTo:
  373. return "aria-flowto"sv;
  374. case StateAndProperties::AriaGrabbed:
  375. return "aria-grabbed"sv;
  376. case StateAndProperties::AriaHasPopup:
  377. return "aria-haspopup"sv;
  378. case StateAndProperties::AriaHidden:
  379. return "aria-hidden"sv;
  380. case StateAndProperties::AriaInvalid:
  381. return "aria-invalid"sv;
  382. case StateAndProperties::AriaKeyShortcuts:
  383. return "aria-keyshortcuts"sv;
  384. case StateAndProperties::AriaLabel:
  385. return "aria-label"sv;
  386. case StateAndProperties::AriaLabelledBy:
  387. return "aria-labelledby"sv;
  388. case StateAndProperties::AriaLevel:
  389. return "aria-level"sv;
  390. case StateAndProperties::AriaLive:
  391. return "aria-live"sv;
  392. case StateAndProperties::AriaModal:
  393. return "aria-modal"sv;
  394. case StateAndProperties::AriaMultiLine:
  395. return "aria-multiline"sv;
  396. case StateAndProperties::AriaMultiSelectable:
  397. return "aria-multiselectable"sv;
  398. case StateAndProperties::AriaOrientation:
  399. return "aria-orientation"sv;
  400. case StateAndProperties::AriaOwns:
  401. return "aria-owns"sv;
  402. case StateAndProperties::AriaPlaceholder:
  403. return "aria-placeholder"sv;
  404. case StateAndProperties::AriaPosInSet:
  405. return "aria-posinset"sv;
  406. case StateAndProperties::AriaPressed:
  407. return "aria-pressed"sv;
  408. case StateAndProperties::AriaReadOnly:
  409. return "aria-readonly"sv;
  410. case StateAndProperties::AriaRelevant:
  411. return "aria-relevant"sv;
  412. case StateAndProperties::AriaRequired:
  413. return "aria-required"sv;
  414. case StateAndProperties::AriaRoleDescription:
  415. return "aria-roledescription"sv;
  416. case StateAndProperties::AriaRowCount:
  417. return "aria-rowcount"sv;
  418. case StateAndProperties::AriaRowIndex:
  419. return "aria-rowindex"sv;
  420. case StateAndProperties::AriaRowSpan:
  421. return "aria-rowspan"sv;
  422. case StateAndProperties::AriaSelected:
  423. return "aria-selected"sv;
  424. case StateAndProperties::AriaSetSize:
  425. return "aria-setsize"sv;
  426. case StateAndProperties::AriaSort:
  427. return "aria-sort"sv;
  428. case StateAndProperties::AriaValueMax:
  429. return "aria-valuemax"sv;
  430. case StateAndProperties::AriaValueMin:
  431. return "aria-valuemin"sv;
  432. case StateAndProperties::AriaValueNow:
  433. return "aria-valuenow"sv;
  434. case StateAndProperties::AriaValueText:
  435. return "aria-valuetext"sv;
  436. }
  437. VERIFY_NOT_REACHED();
  438. }
  439. }