|
48 | 48 | #include <wtf/RefCounted.h> |
49 | 49 | #include <wtf/ThreadSafeWeakPtr.h> |
50 | 50 | #include <wtf/WallTime.h> |
| 51 | +#include <wtf/threads/BinarySemaphore.h> |
51 | 52 |
|
52 | 53 | #if PLATFORM(WIN) |
53 | 54 | #include "AccessibilityObjectWrapperWin.h" |
@@ -247,6 +248,7 @@ enum class AccessibilityOrientation : uint8_t { |
247 | 248 | Vertical |
248 | 249 | }; |
249 | 250 |
|
| 251 | +enum class DidTimeout : bool { No, Yes }; |
250 | 252 | enum class IncludeListMarkerText : bool { No, Yes }; |
251 | 253 | enum class TrimWhitespace : bool { No, Yes }; |
252 | 254 |
|
@@ -815,6 +817,13 @@ class AXCoreObject : public RefCountedAndCanMakeWeakPtr<AXCoreObject> { |
815 | 817 | virtual String textUnderElement(TextUnderElementMode = { }) const = 0; |
816 | 818 | virtual String text() const = 0; |
817 | 819 | virtual unsigned textLength() const = 0; |
| 820 | + AccessibilityChildrenVector revealableContainers(); |
| 821 | + // Text of objects within revealable containers (e.g. hidden="until-found" or collapsed details elements). |
| 822 | + // Returns empty string for text that is already revealed / visible. |
| 823 | + virtual String revealableText() const = 0; |
| 824 | + // The word "container" is significant in this method name. This should only be true for elements / objects |
| 825 | + // that actually have the hidden-until-found markup, not descendants of hidden-until-found elements / objects. |
| 826 | + virtual bool isHiddenUntilFoundContainer() const = 0; |
818 | 827 | #if PLATFORM(COCOA) |
819 | 828 | enum class SpellCheck : bool { No, Yes }; |
820 | 829 | virtual RetainPtr<NSAttributedString> attributedStringForTextMarkerRange(AXTextMarkerRange&&, SpellCheck) const = 0; |
@@ -1195,6 +1204,7 @@ class AXCoreObject : public RefCountedAndCanMakeWeakPtr<AXCoreObject> { |
1195 | 1204 | virtual AXCoreObject* editableAncestor() const = 0; |
1196 | 1205 | virtual AXCoreObject* highestEditableAncestor() = 0; |
1197 | 1206 | virtual AXCoreObject* exposedTableAncestor(bool includeSelf = false) const = 0; |
| 1207 | + AXCoreObject* detailsAncestor() const; |
1198 | 1208 |
|
1199 | 1209 | virtual AccessibilityChildrenVector documentLinks() = 0; |
1200 | 1210 |
|
@@ -1574,6 +1584,41 @@ template<typename U> inline void performFunctionOnMainThread(U&& lambda) |
1574 | 1584 | }); |
1575 | 1585 | } |
1576 | 1586 |
|
| 1587 | +template<typename U> |
| 1588 | +inline DidTimeout performFunctionOnMainThreadAndWaitWithTimeout(U&& lambda, Seconds timeout) |
| 1589 | +{ |
| 1590 | + if (isMainThread()) { |
| 1591 | + std::forward<U>(lambda)(); |
| 1592 | + return DidTimeout::No; |
| 1593 | + } |
| 1594 | + |
| 1595 | + // Because this is ref-counted, we can give it to the lambda to keep alive |
| 1596 | + // even if this thread gave up due to a timeout and moved on (which would normally destroy |
| 1597 | + // the semaphore, causing a use-after-free). |
| 1598 | + struct TimeoutSafeSemaphore : RefCounted<TimeoutSafeSemaphore> { |
| 1599 | + BinarySemaphore semaphore; |
| 1600 | + std::atomic<bool> shouldSignal { true }; |
| 1601 | + |
| 1602 | + void signal() { semaphore.signal(); } |
| 1603 | + bool wait(Seconds timeout) { return semaphore.waitFor(timeout); } |
| 1604 | + }; |
| 1605 | + |
| 1606 | + Ref<TimeoutSafeSemaphore> semaphore = adoptRef(*new TimeoutSafeSemaphore); |
| 1607 | + ensureOnMainThread([semaphore, lambda = std::forward<U>(lambda)] () mutable { |
| 1608 | + lambda(); |
| 1609 | + // Only signal if the calling thread didn't timeout waiting for the main-thread to complete the lambda. |
| 1610 | + if (semaphore->shouldSignal.exchange(false, std::memory_order_acq_rel)) |
| 1611 | + semaphore->signal(); |
| 1612 | + }); |
| 1613 | + |
| 1614 | + bool completedInTime = semaphore->wait(timeout); |
| 1615 | + if (!completedInTime) { |
| 1616 | + // If we timed out, prevent a later signal attempt from the lambda. |
| 1617 | + semaphore->shouldSignal.exchange(false, std::memory_order_acq_rel); |
| 1618 | + } |
| 1619 | + return completedInTime ? DidTimeout::No : DidTimeout::Yes; |
| 1620 | +} |
| 1621 | + |
1577 | 1622 | template<typename T, typename U> inline T retrieveValueFromMainThread(U&& lambda) |
1578 | 1623 | { |
1579 | 1624 | std::optional<T> value; |
|
0 commit comments