AX: Defer attribute computation until needed.
[WebKit-https.git] / Source / WebCore / accessibility / AccessibleNode.cpp
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "config.h"
30 #include "AccessibleNode.h"
31
32 #include "AXObjectCache.h"
33 #include "HTMLNames.h"
34
35 namespace WebCore {
36
37 using namespace HTMLNames;
38
39 using ARIAAttributeMap = HashMap<AXPropertyName, QualifiedName, WTF::IntHash<AXPropertyName>, AXPropertyHashTraits>;
40
41 static ARIAAttributeMap& ariaAttributeMap()
42 {
43     static NeverDestroyed<ARIAAttributeMap> ariaAttributeMap = [] {
44         const struct AttributeEntry {
45             AXPropertyName name;
46             QualifiedName ariaAttribute;
47         } attributes[] = {
48             { AXPropertyName::ActiveDescendant, aria_activedescendantAttr },
49             { AXPropertyName::Atomic, aria_atomicAttr },
50             { AXPropertyName::Autocomplete, aria_autocompleteAttr },
51             { AXPropertyName::Busy, aria_busyAttr },
52             { AXPropertyName::Checked, aria_checkedAttr },
53             { AXPropertyName::ColCount, aria_colcountAttr },
54             { AXPropertyName::ColIndex, aria_colindexAttr },
55             { AXPropertyName::ColSpan, aria_colspanAttr },
56             { AXPropertyName::Current, aria_currentAttr },
57             { AXPropertyName::Details, aria_detailsAttr },
58             { AXPropertyName::Disabled, aria_disabledAttr },
59             { AXPropertyName::ErrorMessage, aria_errormessageAttr },
60             { AXPropertyName::Expanded, aria_expandedAttr },
61             { AXPropertyName::HasPopUp, aria_haspopupAttr },
62             { AXPropertyName::Hidden, aria_hiddenAttr },
63             { AXPropertyName::Invalid, aria_invalidAttr },
64             { AXPropertyName::KeyShortcuts, aria_keyshortcutsAttr },
65             { AXPropertyName::Label, aria_labelAttr },
66             { AXPropertyName::Level, aria_levelAttr },
67             { AXPropertyName::Live, aria_liveAttr },
68             { AXPropertyName::Modal, aria_modalAttr },
69             { AXPropertyName::Multiline, aria_multilineAttr },
70             { AXPropertyName::Multiselectable, aria_multiselectableAttr },
71             { AXPropertyName::Orientation, aria_orientationAttr },
72             { AXPropertyName::Placeholder, aria_placeholderAttr },
73             { AXPropertyName::PosInSet, aria_posinsetAttr },
74             { AXPropertyName::Pressed, aria_pressedAttr },
75             { AXPropertyName::ReadOnly, aria_readonlyAttr },
76             { AXPropertyName::Relevant, aria_relevantAttr },
77             { AXPropertyName::Required, aria_requiredAttr },
78             { AXPropertyName::Role, roleAttr },
79             { AXPropertyName::RoleDescription, aria_roledescriptionAttr },
80             { AXPropertyName::RowCount, aria_rowcountAttr },
81             { AXPropertyName::RowIndex, aria_rowindexAttr },
82             { AXPropertyName::RowSpan, aria_rowspanAttr },
83             { AXPropertyName::Selected, aria_selectedAttr },
84             { AXPropertyName::SetSize, aria_setsizeAttr },
85             { AXPropertyName::Sort, aria_sortAttr },
86             { AXPropertyName::ValueMax, aria_valuemaxAttr },
87             { AXPropertyName::ValueMin, aria_valueminAttr },
88             { AXPropertyName::ValueNow, aria_valuenowAttr },
89             { AXPropertyName::ValueText, aria_valuetextAttr }
90         };
91         ARIAAttributeMap map;
92         for (auto& attribute : attributes)
93             map.set(attribute.name, attribute.ariaAttribute);
94         return map;
95     }();
96     return ariaAttributeMap;
97 }
98
99 static bool isPropertyValueString(AXPropertyName propertyName)
100 {
101     switch (propertyName) {
102     case AXPropertyName::Autocomplete:
103     case AXPropertyName::Checked:
104     case AXPropertyName::Current:
105     case AXPropertyName::HasPopUp:
106     case AXPropertyName::Invalid:
107     case AXPropertyName::KeyShortcuts:
108     case AXPropertyName::Label:
109     case AXPropertyName::Live:
110     case AXPropertyName::Orientation:
111     case AXPropertyName::Placeholder:
112     case AXPropertyName::Pressed:
113     case AXPropertyName::Relevant:
114     case AXPropertyName::Role:
115     case AXPropertyName::RoleDescription:
116     case AXPropertyName::Sort:
117     case AXPropertyName::ValueText:
118         return true;
119     default:
120         return false;
121     }
122 }
123
124 static bool isPropertyValueBoolean(AXPropertyName propertyName)
125 {
126     switch (propertyName) {
127     case AXPropertyName::Atomic:
128     case AXPropertyName::Busy:
129     case AXPropertyName::Disabled:
130     case AXPropertyName::Expanded:
131     case AXPropertyName::Hidden:
132     case AXPropertyName::Modal:
133     case AXPropertyName::Multiline:
134     case AXPropertyName::Multiselectable:
135     case AXPropertyName::ReadOnly:
136     case AXPropertyName::Required:
137     case AXPropertyName::Selected:
138         return true;
139     default:
140         return false;
141     }
142 }
143
144 static bool isPropertyValueInt(AXPropertyName propertyName)
145 {
146     switch (propertyName) {
147     case AXPropertyName::ColCount:
148     case AXPropertyName::RowCount:
149     case AXPropertyName::SetSize:
150         return true;
151     default:
152         return false;
153     }
154 }
155
156 static bool isPropertyValueUnsigned(AXPropertyName propertyName)
157 {
158     switch (propertyName) {
159     case AXPropertyName::ColIndex:
160     case AXPropertyName::ColSpan:
161     case AXPropertyName::Level:
162     case AXPropertyName::PosInSet:
163     case AXPropertyName::RowIndex:
164     case AXPropertyName::RowSpan:
165         return true;
166     default:
167         return false;
168     }
169 }
170
171 static bool isPropertyValueFloat(AXPropertyName propertyName)
172 {
173     switch (propertyName) {
174     case AXPropertyName::ValueMax:
175     case AXPropertyName::ValueMin:
176     case AXPropertyName::ValueNow:
177         return true;
178     default:
179         return false;
180     }
181 }
182
183 static bool isPropertyValueRelation(AXPropertyName propertyName)
184 {
185     switch (propertyName) {
186     case AXPropertyName::ActiveDescendant:
187     case AXPropertyName::Details:
188     case AXPropertyName::ErrorMessage:
189         return true;
190     default:
191         return false;
192     }
193 }
194
195 QualifiedName AccessibleNode::attributeFromAXPropertyName(AXPropertyName propertyName)
196 {
197     return ariaAttributeMap().get(propertyName);
198 }
199
200 bool AccessibleNode::hasProperty(Element& element, AXPropertyName propertyName)
201 {
202     if (auto* accessibleNode = element.existingAccessibleNode()) {
203         if (accessibleNode->m_propertyMap.contains(propertyName))
204             return true;
205     }
206
207     if (ariaAttributeMap().contains(propertyName))
208         return element.hasAttributeWithoutSynchronization(ariaAttributeMap().get(propertyName));
209
210     return false;
211 }
212
213 const PropertyValueVariant AccessibleNode::valueForProperty(Element& element, AXPropertyName propertyName)
214 {
215     if (auto* accessibleNode = element.existingAccessibleNode()) {
216         if (accessibleNode->m_propertyMap.contains(propertyName))
217             return accessibleNode->m_propertyMap.get(propertyName);
218     }
219
220     return nullptr;
221 }
222
223 void AccessibleNode::setProperty(AXPropertyName propertyName, PropertyValueVariant&& value, bool shouldRemove)
224 {
225     if (shouldRemove) {
226         m_propertyMap.remove(propertyName);
227         return;
228     }
229     m_propertyMap.set(propertyName, value);
230 }
231
232 template<typename T>
233 void AccessibleNode::setOptionalProperty(AXPropertyName propertyName, std::optional<T> optional)
234 {
235     setProperty(propertyName, optional.value(), !optional.has_value());
236 }
237
238 void AccessibleNode::setStringProperty(AXPropertyName propertyName, const String& value)
239 {
240     setProperty(propertyName, value, value.isEmpty());
241 }
242
243 void AccessibleNode::setRelationProperty(AXPropertyName propertyName, AccessibleNode* value)
244 {
245     Vector<RefPtr<AccessibleNode>> accessibleNodes;
246     if (value)
247         accessibleNodes.append(value);
248     setProperty(propertyName, accessibleNodes, !value);
249 }
250
251 const String AccessibleNode::effectiveStringValueForElement(Element& element, AXPropertyName propertyName)
252 {
253     const String& value = stringValueForProperty(element, propertyName);
254     if (!value.isEmpty())
255         return value;
256
257     if (ariaAttributeMap().contains(propertyName) && isPropertyValueString(propertyName))
258         return element.attributeWithoutSynchronization(ariaAttributeMap().get(propertyName));
259
260     return nullAtom();
261 }
262
263 const String AccessibleNode::stringValueForProperty(Element& element, AXPropertyName propertyName)
264 {
265     const PropertyValueVariant&& variant = AccessibleNode::valueForProperty(element, propertyName);
266     if (WTF::holds_alternative<String>(variant))
267         return WTF::get<String>(variant);
268     return nullAtom();
269 }
270
271 template<typename T>
272 std::optional<T> AccessibleNode::optionalValueForProperty(Element& element, AXPropertyName propertyName)
273 {
274     const PropertyValueVariant&& variant = AccessibleNode::valueForProperty(element, propertyName);
275     if (WTF::holds_alternative<std::nullptr_t>(variant))
276         return std::nullopt;
277     if (WTF::holds_alternative<T>(variant))
278         return WTF::get<T>(variant);
279     return std::nullopt;
280 }
281
282 std::optional<bool> AccessibleNode::effectiveBoolValueForElement(Element& element, AXPropertyName propertyName)
283 {
284     auto value = optionalValueForProperty<bool>(element, propertyName);
285     if (value)
286         return *value;
287
288     AtomicString attributeValue;
289     if (ariaAttributeMap().contains(propertyName) && isPropertyValueBoolean(propertyName))
290         attributeValue = element.attributeWithoutSynchronization(ariaAttributeMap().get(propertyName));
291
292     if (equalIgnoringASCIICase(attributeValue, "true"))
293         return true;
294     if (equalIgnoringASCIICase(attributeValue, "false"))
295         return false;
296     return std::nullopt;
297 }
298
299 int AccessibleNode::effectiveIntValueForElement(Element& element, AXPropertyName propertyName)
300 {
301     auto value = optionalValueForProperty<int>(element, propertyName);
302     if (value)
303         return *value;
304
305     if (ariaAttributeMap().contains(propertyName) && isPropertyValueInt(propertyName))
306         return element.attributeWithoutSynchronization(ariaAttributeMap().get(propertyName)).toInt();
307
308     return 0;
309 }
310
311 unsigned AccessibleNode::effectiveUnsignedValueForElement(Element& element, AXPropertyName propertyName)
312 {
313     auto value = optionalValueForProperty<unsigned>(element, propertyName);
314     if (value)
315         return *value;
316
317     if (ariaAttributeMap().contains(propertyName) && isPropertyValueUnsigned(propertyName)) {
318         const String& value = element.attributeWithoutSynchronization(ariaAttributeMap().get(propertyName));
319         return value.toUInt();
320     }
321
322     return 0;
323 }
324
325 double AccessibleNode::effectiveDoubleValueForElement(Element& element, AXPropertyName propertyName)
326 {
327     auto value = optionalValueForProperty<double>(element, propertyName);
328     if (value)
329         return *value;
330
331     if (ariaAttributeMap().contains(propertyName) && isPropertyValueFloat(propertyName))
332         return element.attributeWithoutSynchronization(ariaAttributeMap().get(propertyName)).toDouble();
333
334     return 0.0;
335 }
336
337 RefPtr<AccessibleNode> AccessibleNode::singleRelationValueForProperty(Element& element, AXPropertyName propertyName)
338 {
339     Vector<RefPtr<AccessibleNode>> accessibleNodes = relationsValueForProperty(element, propertyName);
340     size_t size = accessibleNodes.size();
341     ASSERT(!size || size == 1);
342     if (size)
343         return accessibleNodes.first();
344     return nullptr;
345 }
346
347 Vector<RefPtr<AccessibleNode>> AccessibleNode::relationsValueForProperty(Element& element, AXPropertyName propertyName)
348 {
349     const PropertyValueVariant&& variant = AccessibleNode::valueForProperty(element, propertyName);
350     if (WTF::holds_alternative<Vector<RefPtr<AccessibleNode>>>(variant))
351         return WTF::get<Vector<RefPtr<AccessibleNode>>>(variant);
352     return Vector<RefPtr<AccessibleNode>> { };
353 }
354
355 Vector<RefPtr<Element>> AccessibleNode::effectiveElementsValueForElement(Element& element, AXPropertyName propertyName)
356 {
357     Vector<RefPtr<Element>> elements;
358     auto value = relationsValueForProperty(element, propertyName);
359     if (value.size()) {
360         for (auto accessibleNode : value)
361             elements.append(&accessibleNode->m_ownerElement);
362         return elements;
363     }
364
365     if (ariaAttributeMap().contains(propertyName) && isPropertyValueRelation(propertyName)) {
366         const AtomicString& attrStr = element.attributeWithoutSynchronization(ariaAttributeMap().get(propertyName));
367         if (attrStr.isNull() || attrStr.isEmpty())
368             return elements;
369         auto spaceSplitString = SpaceSplitString(attrStr, false);
370         size_t length = spaceSplitString.size();
371         for (size_t i = 0; i < length; ++i) {
372             if (auto* idElement = element.treeScope().getElementById(spaceSplitString[i]))
373                 elements.append(idElement);
374         }
375     }
376     return elements;
377 }
378
379 void AccessibleNode::notifyAttributeChanged(const WebCore::QualifiedName& name)
380 {
381     if (AXObjectCache* cache = m_ownerElement.document().axObjectCache())
382         cache->deferAttributeChangeIfNeeded(name, &m_ownerElement);
383 }
384
385 RefPtr<AccessibleNode> AccessibleNode::activeDescendant() const
386 {
387     return singleRelationValueForProperty(m_ownerElement, AXPropertyName::ActiveDescendant);
388 }
389
390 void AccessibleNode::setActiveDescendant(AccessibleNode* value)
391 {
392     setRelationProperty(AXPropertyName::ActiveDescendant, value);
393     notifyAttributeChanged(aria_activedescendantAttr);
394 }
395
396 std::optional<bool> AccessibleNode::atomic() const
397 {
398     return optionalValueForProperty<bool>(m_ownerElement, AXPropertyName::Atomic);
399 }
400
401 void AccessibleNode::setAtomic(std::optional<bool> value)
402 {
403     setOptionalProperty<bool>(AXPropertyName::Atomic, value);
404     notifyAttributeChanged(aria_atomicAttr);
405 }
406
407 String AccessibleNode::autocomplete() const
408 {
409     return stringValueForProperty(m_ownerElement, AXPropertyName::Autocomplete);
410 }
411
412 void AccessibleNode::setAutocomplete(const String& autocomplete)
413 {
414     setStringProperty(AXPropertyName::Autocomplete, autocomplete);
415     notifyAttributeChanged(aria_autocompleteAttr);
416 }
417
418 std::optional<bool> AccessibleNode::busy() const
419 {
420     return optionalValueForProperty<bool>(m_ownerElement, AXPropertyName::Busy);
421 }
422
423 void AccessibleNode::setBusy(std::optional<bool> value)
424 {
425     setOptionalProperty<bool>(AXPropertyName::Busy, value);
426     notifyAttributeChanged(aria_busyAttr);
427 }
428
429 String AccessibleNode::checked() const
430 {
431     return stringValueForProperty(m_ownerElement, AXPropertyName::Checked);
432 }
433
434 void AccessibleNode::setChecked(const String& checked)
435 {
436     setStringProperty(AXPropertyName::Checked, checked);
437     notifyAttributeChanged(aria_checkedAttr);
438 }
439
440 std::optional<int> AccessibleNode::colCount() const
441 {
442     return optionalValueForProperty<int>(m_ownerElement, AXPropertyName::ColCount);
443 }
444
445 void AccessibleNode::setColCount(std::optional<int> value)
446 {
447     setOptionalProperty<int>(AXPropertyName::ColCount, value);
448     notifyAttributeChanged(aria_colcountAttr);
449 }
450
451 std::optional<unsigned> AccessibleNode::colIndex() const
452 {
453     return optionalValueForProperty<unsigned>(m_ownerElement, AXPropertyName::ColCount);
454 }
455
456 void AccessibleNode::setColIndex(std::optional<unsigned> value)
457 {
458     setOptionalProperty<unsigned>(AXPropertyName::ColIndex, value);
459     notifyAttributeChanged(aria_colindexAttr);
460 }
461
462 std::optional<unsigned> AccessibleNode::colSpan() const
463 {
464     return optionalValueForProperty<unsigned>(m_ownerElement, AXPropertyName::ColSpan);
465 }
466
467 void AccessibleNode::setColSpan(std::optional<unsigned> value)
468 {
469     setOptionalProperty<unsigned>(AXPropertyName::ColSpan, value);
470     notifyAttributeChanged(aria_colspanAttr);
471 }
472
473 String AccessibleNode::current() const
474 {
475     return stringValueForProperty(m_ownerElement, AXPropertyName::Current);
476 }
477
478 void AccessibleNode::setCurrent(const String& current)
479 {
480     setStringProperty(AXPropertyName::Current, current);
481     notifyAttributeChanged(aria_currentAttr);
482 }
483
484 RefPtr<AccessibleNode> AccessibleNode::details() const
485 {
486     return singleRelationValueForProperty(m_ownerElement, AXPropertyName::Details);
487 }
488
489 void AccessibleNode::setDetails(AccessibleNode* value)
490 {
491     setRelationProperty(AXPropertyName::Details, value);
492     notifyAttributeChanged(aria_detailsAttr);
493 }
494
495 std::optional<bool> AccessibleNode::disabled() const
496 {
497     return optionalValueForProperty<bool>(m_ownerElement, AXPropertyName::Disabled);
498 }
499
500 RefPtr<AccessibleNode> AccessibleNode::errorMessage() const
501 {
502     return singleRelationValueForProperty(m_ownerElement, AXPropertyName::ErrorMessage);
503 }
504
505 void AccessibleNode::setErrorMessage(AccessibleNode* value)
506 {
507     setRelationProperty(AXPropertyName::ErrorMessage, value);
508     notifyAttributeChanged(aria_errormessageAttr);
509 }
510
511
512 void AccessibleNode::setDisabled(std::optional<bool> value)
513 {
514     setOptionalProperty<bool>(AXPropertyName::Disabled, value);
515     notifyAttributeChanged(aria_disabledAttr);
516 }
517
518 std::optional<bool> AccessibleNode::expanded() const
519 {
520     return optionalValueForProperty<bool>(m_ownerElement, AXPropertyName::Expanded);
521 }
522
523 void AccessibleNode::setExpanded(std::optional<bool> value)
524 {
525     setOptionalProperty<bool>(AXPropertyName::Expanded, value);
526     notifyAttributeChanged(aria_expandedAttr);
527 }
528
529 String AccessibleNode::hasPopUp() const
530 {
531     return stringValueForProperty(m_ownerElement, AXPropertyName::HasPopUp);
532 }
533
534 void AccessibleNode::setHasPopUp(const String& hasPopUp)
535 {
536     setStringProperty(AXPropertyName::HasPopUp, hasPopUp);
537     notifyAttributeChanged(aria_haspopupAttr);
538 }
539
540 std::optional<bool> AccessibleNode::hidden() const
541 {
542     return optionalValueForProperty<bool>(m_ownerElement, AXPropertyName::Hidden);
543 }
544
545 void AccessibleNode::setHidden(std::optional<bool> value)
546 {
547     setOptionalProperty<bool>(AXPropertyName::Hidden, value);
548     notifyAttributeChanged(aria_hiddenAttr);
549 }
550
551 String AccessibleNode::invalid() const
552 {
553     return stringValueForProperty(m_ownerElement, AXPropertyName::Invalid);
554 }
555
556 void AccessibleNode::setInvalid(const String& invalid)
557 {
558     setStringProperty(AXPropertyName::Invalid, invalid);
559     notifyAttributeChanged(aria_invalidAttr);
560 }
561
562 String AccessibleNode::keyShortcuts() const
563 {
564     return stringValueForProperty(m_ownerElement, AXPropertyName::KeyShortcuts);
565 }
566
567 void AccessibleNode::setKeyShortcuts(const String& keyShortcuts)
568 {
569     setStringProperty(AXPropertyName::KeyShortcuts, keyShortcuts);
570     notifyAttributeChanged(aria_keyshortcutsAttr);
571 }
572
573 String AccessibleNode::label() const
574 {
575     return stringValueForProperty(m_ownerElement, AXPropertyName::Label);
576 }
577
578 void AccessibleNode::setLabel(const String& label)
579 {
580     setStringProperty(AXPropertyName::Label, label);
581     notifyAttributeChanged(aria_labelAttr);
582 }
583
584 std::optional<unsigned> AccessibleNode::level() const
585 {
586     return optionalValueForProperty<unsigned>(m_ownerElement, AXPropertyName::Level);
587 }
588
589 void AccessibleNode::setLevel(std::optional<unsigned> value)
590 {
591     setOptionalProperty<unsigned>(AXPropertyName::Level, value);
592     notifyAttributeChanged(aria_levelAttr);
593 }
594
595 String AccessibleNode::live() const
596 {
597     return stringValueForProperty(m_ownerElement, AXPropertyName::Live);
598 }
599
600 void AccessibleNode::setLive(const String& live)
601 {
602     setStringProperty(AXPropertyName::Live, live);
603     notifyAttributeChanged(aria_liveAttr);
604 }
605
606 std::optional<bool> AccessibleNode::modal() const
607 {
608     return optionalValueForProperty<bool>(m_ownerElement, AXPropertyName::Modal);
609 }
610
611 void AccessibleNode::setModal(std::optional<bool> value)
612 {
613     setOptionalProperty<bool>(AXPropertyName::Modal, value);
614     notifyAttributeChanged(aria_modalAttr);
615 }
616
617 std::optional<bool> AccessibleNode::multiline() const
618 {
619     return optionalValueForProperty<bool>(m_ownerElement, AXPropertyName::Multiline);
620 }
621
622 void AccessibleNode::setMultiline(std::optional<bool> value)
623 {
624     setOptionalProperty<bool>(AXPropertyName::Multiline, value);
625     notifyAttributeChanged(aria_multilineAttr);
626 }
627
628 std::optional<bool> AccessibleNode::multiselectable() const
629 {
630     return optionalValueForProperty<bool>(m_ownerElement, AXPropertyName::Multiselectable);
631 }
632
633 void AccessibleNode::setMultiselectable(std::optional<bool> value)
634 {
635     setOptionalProperty<bool>(AXPropertyName::Multiselectable, value);
636     notifyAttributeChanged(aria_multiselectableAttr);
637 }
638
639 String AccessibleNode::orientation() const
640 {
641     return stringValueForProperty(m_ownerElement, AXPropertyName::Orientation);
642 }
643
644 void AccessibleNode::setOrientation(const String& orientation)
645 {
646     setStringProperty(AXPropertyName::Orientation, orientation);
647     notifyAttributeChanged(aria_orientationAttr);
648 }
649
650 String AccessibleNode::placeholder() const
651 {
652     return stringValueForProperty(m_ownerElement, AXPropertyName::Placeholder);
653 }
654
655 void AccessibleNode::setPlaceholder(const String& placeholder)
656 {
657     setStringProperty(AXPropertyName::Placeholder, placeholder);
658     notifyAttributeChanged(aria_placeholderAttr);
659 }
660
661 std::optional<unsigned> AccessibleNode::posInSet() const
662 {
663     return optionalValueForProperty<unsigned>(m_ownerElement, AXPropertyName::PosInSet);
664 }
665
666 void AccessibleNode::setPosInSet(std::optional<unsigned> value)
667 {
668     setOptionalProperty<unsigned>(AXPropertyName::PosInSet, value);
669     notifyAttributeChanged(aria_posinsetAttr);
670 }
671
672 String AccessibleNode::pressed() const
673 {
674     return stringValueForProperty(m_ownerElement, AXPropertyName::Pressed);
675 }
676
677 void AccessibleNode::setPressed(const String& pressed)
678 {
679     setStringProperty(AXPropertyName::Pressed, pressed);
680     notifyAttributeChanged(aria_pressedAttr);
681 }
682
683 std::optional<bool> AccessibleNode::readOnly() const
684 {
685     return optionalValueForProperty<bool>(m_ownerElement, AXPropertyName::ReadOnly);
686 }
687
688 void AccessibleNode::setReadOnly(std::optional<bool> value)
689 {
690     setOptionalProperty<bool>(AXPropertyName::ReadOnly, value);
691     notifyAttributeChanged(aria_readonlyAttr);
692 }
693
694 String AccessibleNode::relevant() const
695 {
696     return stringValueForProperty(m_ownerElement, AXPropertyName::Relevant);
697 }
698
699 void AccessibleNode::setRelevant(const String& relevant)
700 {
701     setStringProperty(AXPropertyName::Relevant, relevant);
702     notifyAttributeChanged(aria_relevantAttr);
703 }
704
705 std::optional<bool> AccessibleNode::required() const
706 {
707     return optionalValueForProperty<bool>(m_ownerElement, AXPropertyName::Required);
708 }
709
710 void AccessibleNode::setRequired(std::optional<bool> value)
711 {
712     setOptionalProperty<bool>(AXPropertyName::Required, value);
713     notifyAttributeChanged(aria_requiredAttr);
714 }
715
716 String AccessibleNode::role() const
717 {
718     return stringValueForProperty(m_ownerElement, AXPropertyName::Role);
719 }
720
721 void AccessibleNode::setRole(const String& role)
722 {
723     setStringProperty(AXPropertyName::Role, role);
724     notifyAttributeChanged(roleAttr);
725 }
726
727 String AccessibleNode::roleDescription() const
728 {
729     return stringValueForProperty(m_ownerElement, AXPropertyName::RoleDescription);
730 }
731
732 void AccessibleNode::setRoleDescription(const String& roleDescription)
733 {
734     setStringProperty(AXPropertyName::RoleDescription, roleDescription);
735     notifyAttributeChanged(aria_roledescriptionAttr);
736 }
737
738 std::optional<int> AccessibleNode::rowCount() const
739 {
740     return optionalValueForProperty<int>(m_ownerElement, AXPropertyName::RowCount);
741 }
742
743 void AccessibleNode::setRowCount(std::optional<int> value)
744 {
745     setOptionalProperty<int>(AXPropertyName::RowCount, value);
746     notifyAttributeChanged(aria_rowcountAttr);
747 }
748
749 std::optional<unsigned> AccessibleNode::rowIndex() const
750 {
751     return optionalValueForProperty<unsigned>(m_ownerElement, AXPropertyName::RowCount);
752 }
753
754 void AccessibleNode::setRowIndex(std::optional<unsigned> value)
755 {
756     setOptionalProperty<unsigned>(AXPropertyName::RowIndex, value);
757     notifyAttributeChanged(aria_rowindexAttr);
758 }
759
760 std::optional<unsigned> AccessibleNode::rowSpan() const
761 {
762     return optionalValueForProperty<unsigned>(m_ownerElement, AXPropertyName::RowSpan);
763 }
764
765 void AccessibleNode::setRowSpan(std::optional<unsigned> value)
766 {
767     setOptionalProperty<unsigned>(AXPropertyName::RowSpan, value);
768     notifyAttributeChanged(aria_rowspanAttr);
769 }
770
771 std::optional<bool> AccessibleNode::selected() const
772 {
773     return optionalValueForProperty<bool>(m_ownerElement, AXPropertyName::Selected);
774 }
775
776 void AccessibleNode::setSelected(std::optional<bool> value)
777 {
778     setOptionalProperty<bool>(AXPropertyName::Selected, value);
779     notifyAttributeChanged(aria_selectedAttr);
780 }
781
782 std::optional<int> AccessibleNode::setSize() const
783 {
784     return optionalValueForProperty<int>(m_ownerElement, AXPropertyName::SetSize);
785 }
786
787 void AccessibleNode::setSetSize(std::optional<int> value)
788 {
789     setOptionalProperty<int>(AXPropertyName::SetSize, value);
790     notifyAttributeChanged(aria_setsizeAttr);
791 }
792
793 String AccessibleNode::sort() const
794 {
795     return stringValueForProperty(m_ownerElement, AXPropertyName::Sort);
796 }
797
798 void AccessibleNode::setSort(const String& sort)
799 {
800     setStringProperty(AXPropertyName::Sort, sort);
801     notifyAttributeChanged(aria_sortAttr);
802 }
803
804 std::optional<double> AccessibleNode::valueMax() const
805 {
806     return optionalValueForProperty<double>(m_ownerElement, AXPropertyName::ValueMax);
807 }
808
809 void AccessibleNode::setValueMax(std::optional<double> value)
810 {
811     setOptionalProperty<double>(AXPropertyName::ValueMax, value);
812     notifyAttributeChanged(aria_valuemaxAttr);
813 }
814
815 std::optional<double> AccessibleNode::valueMin() const
816 {
817     return optionalValueForProperty<double>(m_ownerElement, AXPropertyName::ValueMin);
818 }
819
820 void AccessibleNode::setValueMin(std::optional<double> value)
821 {
822     setOptionalProperty<double>(AXPropertyName::ValueMin, value);
823     notifyAttributeChanged(aria_valueminAttr);
824 }
825
826 std::optional<double> AccessibleNode::valueNow() const
827 {
828     return optionalValueForProperty<double>(m_ownerElement, AXPropertyName::ValueNow);
829 }
830
831 void AccessibleNode::setValueNow(std::optional<double> value)
832 {
833     setOptionalProperty<double>(AXPropertyName::ValueNow, value);
834     notifyAttributeChanged(aria_valuenowAttr);
835 }
836
837 String AccessibleNode::valueText() const
838 {
839     return stringValueForProperty(m_ownerElement, AXPropertyName::ValueText);
840 }
841
842 void AccessibleNode::setValueText(const String& valueText)
843 {
844     setStringProperty(AXPropertyName::ValueText, valueText);
845     notifyAttributeChanged(aria_valuetextAttr);
846 }
847
848 } // namespace WebCore