| /* |
| * Copyright (C) 2014, Google Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of |
| * its contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
| * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_OBJECT_CACHE_IMPL_H_ |
| #define THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_OBJECT_CACHE_IMPL_H_ |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "base/dcheck_is_on.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/macros.h" |
| #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" |
| #include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink-forward.h" |
| #include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink.h" |
| #include "third_party/blink/public/web/web_ax_enums.h" |
| #include "third_party/blink/renderer/core/accessibility/ax_object_cache_base.h" |
| #include "third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h" |
| #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" |
| #include "third_party/blink/renderer/core/frame/local_frame_view.h" |
| #include "third_party/blink/renderer/modules/accessibility/ax_object.h" |
| #include "third_party/blink/renderer/modules/modules_export.h" |
| #include "third_party/blink/renderer/platform/heap/handle.h" |
| #include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h" |
| #include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" |
| #include "third_party/blink/renderer/platform/wtf/hash_map.h" |
| #include "third_party/blink/renderer/platform/wtf/hash_set.h" |
| #include "third_party/blink/renderer/platform/wtf/vector.h" |
| #include "ui/accessibility/ax_enums.mojom-blink-forward.h" |
| #include "ui/accessibility/ax_mode.h" |
| |
| namespace blink { |
| |
| class AbstractInlineTextBox; |
| class AXRelationCache; |
| class HTMLAreaElement; |
| class LocalFrameView; |
| |
| // This class should only be used from inside the accessibility directory. |
| class MODULES_EXPORT AXObjectCacheImpl |
| : public AXObjectCacheBase, |
| public mojom::blink::PermissionObserver { |
| public: |
| static AXObjectCache* Create(Document&, const ui::AXMode&); |
| |
| AXObjectCacheImpl(Document&, const ui::AXMode&); |
| ~AXObjectCacheImpl() override; |
| void Trace(Visitor*) const override; |
| |
| Document& GetDocument() const { return *document_; } |
| AXObject* FocusedObject(); |
| |
| const ui::AXMode& GetAXMode() override; |
| void SetAXMode(const ui::AXMode&) override; |
| |
| void Dispose() override; |
| |
| void Freeze() override { is_frozen_ = true; } |
| void Thaw() override { is_frozen_ = false; } |
| bool IsFrozen() { return is_frozen_; } |
| |
| // |
| // Iterators. |
| // |
| |
| void SelectionChanged(Node*) override; |
| void UpdateReverseRelations(const AXObject* relation_source, |
| const Vector<String>& target_ids); |
| void ChildrenChanged(AXObject*); |
| void ChildrenChangedWithCleanLayout(AXObject*); |
| void ChildrenChanged(Node*) override; |
| void ChildrenChanged(const LayoutObject*) override; |
| void ChildrenChanged(AccessibleNode*) override; |
| void SlotAssignmentWillChange(Node*) override; |
| void CheckedStateChanged(Node*) override; |
| void ListboxOptionStateChanged(HTMLOptionElement*) override; |
| void ListboxSelectedChildrenChanged(HTMLSelectElement*) override; |
| void ListboxActiveIndexChanged(HTMLSelectElement*) override; |
| void LocationChanged(const LayoutObject*) override; |
| void ImageLoaded(const LayoutObject*) override; |
| |
| void Remove(AccessibleNode*) override; |
| // Returns false if no associated AXObject exists in the cache. |
| bool Remove(LayoutObject*) override; |
| void Remove(Node*) override; |
| void Remove(AbstractInlineTextBox*) override; |
| void Remove(AXObject*); // Calls more specific Remove methods as necessary. |
| // For any ancestor that could contain the passed-in AXObject* in their cached |
| // children, clear their children and set needs to update children on them. |
| // In addition, ChildrenChanged() on an included ancestor that might contain |
| // this child, if one exists. |
| void ChildrenChangedOnAncestorOf(AXObject*); |
| |
| const Element* RootAXEditableElement(const Node*) override; |
| |
| // Called when aspects of the style (e.g. color, alignment) change. |
| void StyleChanged(const LayoutObject*) override; |
| |
| // Called by a node when text or a text equivalent (e.g. alt) attribute is |
| // changed. |
| void TextChanged(const LayoutObject*) override; |
| void TextChangedWithCleanLayout(Node* optional_node, AXObject*); |
| void FocusableChangedWithCleanLayout(Element* element); |
| void DocumentTitleChanged() override; |
| // Called when a layout tree for a node has just been attached, so we can make |
| // sure we have the right subclass of AXObject. |
| void UpdateCacheAfterNodeIsAttached(Node*) override; |
| // A DOM node was inserted , but does not necessarily have a layout tree. |
| void DidInsertChildrenOfNode(Node*) override; |
| |
| void HandleAttributeChanged(const QualifiedName& attr_name, |
| Element*) override; |
| void HandleValidationMessageVisibilityChanged( |
| const Node* form_control) override; |
| void HandleEventListenerAdded(const Node& node, |
| const AtomicString& event_type) override; |
| void HandleEventListenerRemoved(const Node& node, |
| const AtomicString& event_type) override; |
| void HandleFocusedUIElementChanged(Element* old_focused_element, |
| Element* new_focused_element) override; |
| void HandleInitialFocus() override; |
| void HandleTextFormControlChanged(Node*) override; |
| void HandleEditableTextContentChanged(Node*) override; |
| void HandleScaleAndLocationChanged(Document*) override; |
| void HandleTextMarkerDataAdded(Node* start, Node* end) override; |
| void HandleValueChanged(Node*) override; |
| void HandleUpdateActiveMenuOption(Node*) override; |
| void DidShowMenuListPopup(LayoutObject*) override; |
| void DidHideMenuListPopup(LayoutObject*) override; |
| void HandleLoadComplete(Document*) override; |
| void HandleLayoutComplete(Document*) override; |
| void HandleClicked(Node*) override; |
| void HandleAttributeChanged(const QualifiedName& attr_name, |
| AccessibleNode*) override; |
| |
| void SetCanvasObjectBounds(HTMLCanvasElement*, |
| Element*, |
| const LayoutRect&) override; |
| |
| void InlineTextBoxesUpdated(LayoutObject*) override; |
| void ProcessDeferredAccessibilityEvents(Document&) override; |
| // Is there work to be done when layout becomes clean? |
| bool IsDirty() const override; |
| |
| // Called when a HTMLFrameOwnerElement (such as an iframe element) changes the |
| // embedding token of its child frame. |
| void EmbeddingTokenChanged(HTMLFrameOwnerElement*) override; |
| |
| // Called when the scroll offset changes. |
| void HandleScrollPositionChanged(LocalFrameView*) override; |
| void HandleScrollPositionChanged(LayoutObject*) override; |
| |
| void HandleScrolledToAnchor(const Node* anchor_node) override; |
| |
| // Called when the frame rect changes, which can sometimes happen |
| // without producing any layout or other notifications. |
| void HandleFrameRectsChanged(Document&) override; |
| |
| // Invalidates the bounding box, which can be later retrieved by |
| // GetAllObjectsWithChangedBounds. |
| void InvalidateBoundingBox(const LayoutObject*) override; |
| |
| const AtomicString& ComputedRoleForNode(Node*) override; |
| String ComputedNameForNode(Node*) override; |
| |
| void OnTouchAccessibilityHover(const IntPoint&) override; |
| |
| AXObject* ObjectFromAXID(AXID id) const { return objects_.at(id); } |
| AXObject* Root(); |
| |
| // Used for objects without backing DOM nodes, layout objects, etc. |
| AXObject* CreateAndInit(ax::mojom::blink::Role, AXObject* parent); |
| |
| AXObject* GetOrCreate(AccessibleNode*, AXObject* parent); |
| AXObject* GetOrCreate(LayoutObject*, AXObject* parent_if_known) override; |
| AXObject* GetOrCreate(LayoutObject* layout_object); |
| AXObject* GetOrCreate(const Node*, AXObject* parent_if_known); |
| AXObject* GetOrCreate(Node*, AXObject* parent_if_known); |
| AXObject* GetOrCreate(Node*); |
| AXObject* GetOrCreate(const Node*); |
| AXObject* GetOrCreate(AbstractInlineTextBox*, AXObject* parent_if_known); |
| |
| AXID GetAXID(Node*) override; |
| Element* GetElementFromAXID(AXID) override; |
| |
| AXObject* Get(AccessibleNode*); |
| AXObject* Get(AbstractInlineTextBox*); |
| |
| // Get an AXObject* backed by the passed-in DOM node or the node's layout |
| // object, whichever is available. |
| // If it no longer the correct type of AXObject (AXNodeObject/AXLayoutObject), |
| // will Invalidate() the AXObject so that it is refreshed with a new object |
| // when safe to do so. |
| AXObject* Get(const Node*); |
| AXObject* Get(const LayoutObject*); |
| |
| // Get an AXObject* without any potential side effects, such as queuing up an |
| // invalidation for objects that need to be removed or replaced. |
| AXObject* GetWithoutInvalidation(const Node* node); |
| |
| // Return true if the object is still part of the tree, meaning that ancestors |
| // exist or can be repaired all the way to the root. |
| bool IsStillInTree(AXObject*); |
| |
| void ChildrenChangedWithCleanLayout(Node* optional_node_for_relation_update, |
| AXObject*); |
| |
| // When an object is created or its id changes, this must be called so that |
| // the relation cache is updated. |
| void MaybeNewRelationTarget(Node& node, AXObject* obj); |
| |
| void HandleActiveDescendantChangedWithCleanLayout(Node*); |
| void SectionOrRegionRoleMaybeChanged(Element* element); |
| void HandleRoleChangeWithCleanLayout(Node*); |
| void HandleAriaHiddenChangedWithCleanLayout(Node*); |
| void HandleAriaExpandedChangeWithCleanLayout(Node*); |
| void HandleAriaSelectedChangedWithCleanLayout(Node*); |
| void HandleNodeLostFocusWithCleanLayout(Node*); |
| void HandleNodeGainedFocusWithCleanLayout(Node*); |
| void HandleLoadCompleteWithCleanLayout(Node*); |
| void UpdateCacheAfterNodeIsAttachedWithCleanLayout(Node*); |
| void DidShowMenuListPopupWithCleanLayout(Node*); |
| void DidHideMenuListPopupWithCleanLayout(Node*); |
| void StyleChangedWithCleanLayout(Node*); |
| void HandleScrollPositionChangedWithCleanLayout(Node*); |
| void HandleValidationMessageVisibilityChangedWithCleanLayout(const Node*); |
| void HandleUpdateActiveMenuOptionWithCleanLayout(Node*); |
| void HandleEditableTextContentChangedWithCleanLayout(Node*); |
| |
| bool InlineTextBoxAccessibilityEnabled(); |
| |
| void RemoveAXID(AXObject*); |
| |
| AXID GenerateAXID() const; |
| |
| // Counts the number of times the document has been modified. Some attribute |
| // values are cached as long as the modification count hasn't changed. |
| int ModificationCount() const { return modification_count_; } |
| void IncrementModificationCount() { ++modification_count_; } |
| |
| void PostNotification(const LayoutObject*, ax::mojom::blink::Event); |
| // Creates object if necessary. |
| void EnsurePostNotification(Node*, ax::mojom::blink::Event); |
| // Does not create object. |
| // TODO(accessibility) Find out if we can merge with EnsurePostNotification(). |
| void PostNotification(Node*, ax::mojom::blink::Event); |
| void PostNotification(AXObject*, ax::mojom::blink::Event); |
| void MarkAXObjectDirtyWithCleanLayout( |
| AXObject*, |
| bool subtree, |
| ax::mojom::blink::Action event_from_action = |
| ax::mojom::blink::Action::kNone); |
| |
| // |
| // Aria-owns support. |
| // |
| |
| // Returns true if the given object's position in the tree was due to |
| // aria-owns. |
| bool IsAriaOwned(const AXObject*) const; |
| |
| // Returns the parent of the given object due to aria-owns. |
| AXObject* GetAriaOwnedParent(const AXObject*) const; |
| |
| // Given an object that has an aria-owns attribute, return the validated |
| // set of aria-owned children. |
| void GetAriaOwnedChildren(const AXObject* owner, |
| HeapVector<Member<AXObject>>& owned_children); |
| |
| // Given a <map> element, get the image currently associated with it, if any. |
| AXObject* GetAXImageForMap(HTMLMapElement& map); |
| |
| // Adds |object| to |fixed_or_sticky_node_ids_| if it has a fixed or sticky |
| // position. |
| void AddToFixedOrStickyNodeList(const AXObject* object); |
| |
| bool MayHaveHTMLLabel(const HTMLElement& elem); |
| |
| // Synchronously returns whether or not we currently have permission to |
| // call AOM event listeners. |
| bool CanCallAOMEventListeners() const; |
| |
| // This is called when an accessibility event is triggered and there are |
| // AOM event listeners registered that would have been called. |
| // Asynchronously requests permission from the user. If permission is |
| // granted, it only applies to the next event received. |
| void RequestAOMEventListenerPermission(); |
| |
| // For built-in HTML form validation messages. Set notify_children_changed to |
| // true if not already processing changed children. |
| AXObject* ValidationMessageObjectIfInvalid(bool notify_children_changed); |
| |
| WebAXAutofillState GetAutofillState(AXID id) const; |
| void SetAutofillState(AXID id, WebAXAutofillState state); |
| |
| std::pair<ax::mojom::blink::EventFrom, ax::mojom::blink::Action> |
| active_event_from_data() const { |
| return std::make_pair(active_event_from_, active_event_from_action_); |
| } |
| |
| void set_active_event_from_data( |
| const ax::mojom::blink::EventFrom event_from, |
| const ax::mojom::blink::Action event_from_action) { |
| active_event_from_ = event_from; |
| active_event_from_action_ = event_from_action; |
| } |
| |
| AXObject* GetActiveAriaModalDialog() const; |
| |
| static bool UseAXMenuList() { return use_ax_menu_list_; } |
| static bool ShouldCreateAXMenuListFor(LayoutObject* layout_object); |
| static bool ShouldCreateAXMenuListOptionFor(const Node*); |
| static bool IsRelevantPseudoElement(const Node& node); |
| static bool IsRelevantPseudoElementDescendant( |
| const LayoutObject& layout_object); |
| |
| #if DCHECK_IS_ON() |
| bool HasBeenDisposed() { return has_been_disposed_; } |
| #endif |
| |
| // Retrieves a vector of all AXObjects whose bounding boxes may have changed |
| // since the last query. Clears the vector so that the next time it's |
| // called, it will only retrieve objects that have changed since now. |
| HeapVector<Member<AXObject>> GetAllObjectsWithChangedBounds(); |
| |
| protected: |
| void PostPlatformNotification( |
| AXObject* obj, |
| ax::mojom::blink::Event event_type, |
| ax::mojom::blink::EventFrom event_from = |
| ax::mojom::blink::EventFrom::kNone, |
| ax::mojom::blink::Action event_from_action = |
| ax::mojom::blink::Action::kNone, |
| const BlinkAXEventIntentsSet& event_intents = BlinkAXEventIntentsSet()); |
| void LabelChangedWithCleanLayout(Element*); |
| |
| // Returns a reference to the set of currently active event intents. |
| BlinkAXEventIntentsSet& ActiveEventIntents() override { |
| return active_event_intents_; |
| } |
| |
| // Create an AXObject, and do not check if a previous one exists. |
| // Also, initialize the object and add it to maps for later retrieval. |
| AXObject* CreateAndInit(Node*, AXObject* parent_if_known, AXID use_axid = 0); |
| AXObject* CreateAndInit(LayoutObject*, |
| AXObject* parent_if_known, |
| AXID use_axid = 0); |
| |
| // Mark object as invalid and needing to be refreshed when layout is clean. |
| // Will result in a new object with the same AXID, and will also call |
| // ChildrenChanged() on the parent of invalidated objects. Automatically |
| // de-dupes extra object refreshes and ChildrenChanged() calls. |
| void Invalidate(Document&, AXID); |
| |
| AXObject* CreateFromRenderer(LayoutObject*); |
| AXObject* CreateFromNode(Node*); |
| AXObject* CreateFromInlineTextBox(AbstractInlineTextBox*); |
| void Remove(AXID); |
| |
| private: |
| struct AXEventParams final : public GarbageCollected<AXEventParams> { |
| AXEventParams(AXObject* target, |
| ax::mojom::blink::Event event_type, |
| ax::mojom::blink::EventFrom event_from, |
| ax::mojom::blink::Action event_from_action, |
| const BlinkAXEventIntentsSet& intents) |
| : target(target), |
| event_type(event_type), |
| event_from(event_from), |
| event_from_action(event_from_action) { |
| for (const auto& intent : intents) { |
| event_intents.insert(intent.key, intent.value); |
| } |
| } |
| Member<AXObject> target; |
| ax::mojom::blink::Event event_type; |
| ax::mojom::blink::EventFrom event_from; |
| ax::mojom::blink::Action event_from_action; |
| BlinkAXEventIntentsSet event_intents; |
| |
| void Trace(Visitor* visitor) const { visitor->Trace(target); } |
| }; |
| |
| struct TreeUpdateParams final : public GarbageCollected<TreeUpdateParams> { |
| TreeUpdateParams(const Node* node, |
| AXID axid, |
| ax::mojom::blink::EventFrom event_from, |
| ax::mojom::blink::Action event_from_action, |
| const BlinkAXEventIntentsSet& intents, |
| base::OnceClosure callback) |
| : node(node), |
| axid(axid), |
| event_from(event_from), |
| event_from_action(event_from_action), |
| callback(std::move(callback)) { |
| for (const auto& intent : intents) { |
| event_intents.insert(intent.key, intent.value); |
| } |
| } |
| WeakMember<const Node> node; |
| AXID axid; |
| ax::mojom::blink::EventFrom event_from; |
| ax::mojom::blink::Action event_from_action; |
| BlinkAXEventIntentsSet event_intents; |
| base::OnceClosure callback; |
| |
| void Trace(Visitor* visitor) const { visitor->Trace(node); } |
| }; |
| typedef HeapVector<Member<TreeUpdateParams>> TreeUpdateCallbackQueue; |
| |
| ax::mojom::blink::EventFrom ComputeEventFrom(); |
| |
| void UpdateCachedAttributeValuesWithCleanLayout(Node* node, AXObject* obj); |
| void MarkAXObjectDirtyHelper(AXObject* obj, |
| bool subtree, |
| ax::mojom::blink::Action event_from_action); |
| void MarkAXObjectDirty(AXObject*, |
| bool subtree, |
| ax::mojom::blink::Action event_from_action = |
| ax::mojom::blink::Action::kNone); |
| void MarkElementDirty(const Node*, bool subtree); |
| void MarkAXSubtreeDirtyWithCleanLayout(AXObject*); |
| void MarkElementDirtyWithCleanLayout(const Node*, bool subtree); |
| |
| // Helper that clears children up to the first included ancestor and returns |
| // the ancestor if a children changed notification should be fired on it. |
| AXObject* InvalidateChildren(AXObject* obj); |
| |
| Member<Document> document_; |
| ui::AXMode ax_mode_; |
| HeapHashMap<AXID, Member<AXObject>> objects_; |
| // LayoutObject and AbstractInlineTextBox are not on the Oilpan heap so we |
| // do not use HeapHashMap for those mappings. |
| HeapHashMap<Member<AccessibleNode>, AXID> accessible_node_mapping_; |
| HashMap<const LayoutObject*, AXID> layout_object_mapping_; |
| HeapHashMap<Member<const Node>, AXID> node_object_mapping_; |
| HashMap<AbstractInlineTextBox*, AXID> inline_text_box_object_mapping_; |
| int modification_count_; |
| |
| HashSet<AXID> ids_in_use_; |
| |
| // Used for a mock AXObject representing the message displayed in the |
| // validation message bubble. |
| // There can be only one of these per document with invalid form controls, |
| // and it will always be related to the currently focused control. |
| AXID validation_message_axid_; |
| |
| // The currently active aria-modal dialog element, if one has been computed, |
| // null if otherwise. This is only ever computed on platforms that have the |
| // AriaModalPrunesAXTree setting enabled, such as Mac. |
| WeakMember<AXObject> active_aria_modal_dialog_; |
| |
| std::unique_ptr<AXRelationCache> relation_cache_; |
| |
| #if DCHECK_IS_ON() |
| // Verified when finalizing. |
| bool has_been_disposed_ = false; |
| #endif |
| |
| HeapVector<Member<AXEventParams>> notifications_to_post_main_; |
| HeapVector<Member<AXEventParams>> notifications_to_post_popup_; |
| |
| // Call the queued callback methods that do processing which must occur when |
| // layout is clean. These callbacks are stored in tree_update_callback_queue_, |
| // and have names like FooBarredWithCleanLayout(). |
| void ProcessCleanLayoutCallbacks(Document&); |
| |
| // Destroy and recreate any objects which are no longer valid, for example |
| // they used to be an AXNodeObject and now must be an AXLayoutObject, or |
| // vice-versa. Also fires children changed on the parent of these nodes. |
| void ProcessInvalidatedObjects(Document&); |
| |
| // Send events to RenderAccessibilityImpl, which serializes them and then |
| // sends the serialized events and dirty objects to the browser process. |
| void PostNotifications(Document&); |
| |
| // Get the currently focused Node element. |
| Node* FocusedElement(); |
| |
| // GetOrCreate the focusable AXObject for a specific Node. |
| AXObject* GetOrCreateFocusedObjectFromNode(Node*); |
| |
| AXObject* FocusedImageMapUIElement(HTMLAreaElement*); |
| |
| // Associate an AXObject with an AXID. Generate one if none is supplied. |
| AXID AssociateAXID(AXObject*, AXID use_axid = 0); |
| |
| void TextChanged(Node*); |
| bool NodeIsTextControl(const Node*); |
| AXObject* NearestExistingAncestor(Node*); |
| |
| Settings* GetSettings(); |
| |
| // Start listenening for updates to the AOM accessibility event permission. |
| void AddPermissionStatusListener(); |
| |
| // mojom::blink::PermissionObserver implementation. |
| // Called when we get an updated AOM event listener permission value from |
| // the browser. |
| void OnPermissionStatusChange(mojom::PermissionStatus) override; |
| |
| // When a <tr> or <td> is inserted or removed, the containing table may have |
| // gained or lost rows or columns. |
| void ContainingTableRowsOrColsMaybeChanged(Node*); |
| |
| // Must be called an entire subtree of accessible objects are no longer valid. |
| void RemoveAXObjectsInLayoutSubtree(AXObject* subtree, int depth); |
| |
| // Object for HTML validation alerts. Created at most once per object cache. |
| AXObject* GetOrCreateValidationMessageObject(); |
| void RemoveValidationMessageObjectWithCleanLayout(Node* document); |
| |
| // Enqueue a callback to the given method to be run after layout is |
| // complete. |
| void DeferTreeUpdate(void (AXObjectCacheImpl::*method)(const Node*), |
| const Node* node); |
| void DeferTreeUpdate(void (AXObjectCacheImpl::*method)(Node*), Node* node); |
| void DeferTreeUpdate( |
| void (AXObjectCacheImpl::*method)(Node* node, |
| ax::mojom::blink::Event event), |
| Node* node, |
| ax::mojom::blink::Event event); |
| void DeferTreeUpdate(void (AXObjectCacheImpl::*method)(const QualifiedName&, |
| Element* element), |
| const QualifiedName& attr_name, |
| Element* element); |
| // Provide either a DOM node or AXObject. If both are provided, then they must |
| // match, meaning that the AXObject's DOM node must equal the provided node. |
| void DeferTreeUpdate(void (AXObjectCacheImpl::*method)(Node*, AXObject*), |
| AXObject* obj); |
| |
| void DeferTreeUpdateInternal(base::OnceClosure callback, const Node* node); |
| void DeferTreeUpdateInternal(base::OnceClosure callback, AXObject* obj); |
| |
| void SelectionChangedWithCleanLayout(Node* node); |
| void TextChangedWithCleanLayout(Node* node); |
| void ChildrenChangedWithCleanLayout(Node* node); |
| void HandleAttributeChangedWithCleanLayout(const QualifiedName& attr_name, |
| Element* element); |
| void HandleUseMapAttributeChangedWithCleanLayout(Element*); |
| void HandleNameAttributeChangedWithCleanLayout(Element*); |
| |
| bool DoesEventListenerImpactIgnoredState( |
| const AtomicString& event_type) const; |
| void HandleEventSubscriptionChanged(const Node& node, |
| const AtomicString& event_type); |
| |
| // |
| // aria-modal support |
| // |
| |
| // This function is only ever called on platforms where the |
| // AriaModalPrunesAXTree setting is enabled, and the accessibility tree must |
| // be manually pruned to remove background content. |
| void UpdateActiveAriaModalDialog(Node* element); |
| |
| // This will return null on platforms without the AriaModalPrunesAXTree |
| // setting enabled, or where there is no active ancestral aria-modal dialog. |
| AXObject* AncestorAriaModalDialog(Node* node); |
| |
| void ScheduleVisualUpdate(); |
| void FireTreeUpdatedEventImmediately( |
| Document& document, |
| ax::mojom::blink::EventFrom event_from, |
| ax::mojom::blink::Action event_from_action, |
| const BlinkAXEventIntentsSet& event_intents, |
| base::OnceClosure callback); |
| void FireAXEventImmediately(AXObject* obj, |
| ax::mojom::blink::Event event_type, |
| ax::mojom::blink::EventFrom event_from, |
| ax::mojom::blink::Action event_from_action, |
| const BlinkAXEventIntentsSet& event_intents); |
| |
| void SetMaxPendingUpdatesForTesting(wtf_size_t max_pending_updates) { |
| max_pending_updates_ = max_pending_updates; |
| } |
| |
| void UpdateNumTreeUpdatesQueuedBeforeLayoutHistogram(); |
| |
| // Invalidates the bounding boxes of fixed or sticky positioned objects which |
| // should be updated when the scroll offset is changed. Like |
| // InvalidateBoundingBox, it can be later retrieved by |
| // GetAllObjectsWithChangedBounds. |
| void InvalidateBoundingBoxForFixedOrStickyPosition(); |
| |
| // Return true if this is the popup document. There can only be one popup |
| // document at a time. If it is not the popup document, it's the main |
| // document stored in |document_|. |
| bool IsPopup(Document& document) const; |
| |
| // Get the invalidated objects for the passed-in document. |
| HashSet<AXID>& GetInvalidatedIds(Document& document); |
| |
| // Get the queued tree update callbacks for the passed-in document |
| TreeUpdateCallbackQueue& GetTreeUpdateCallbackQueue(Document& document); |
| |
| // Get the event notifications to post for the passed-in document. |
| HeapVector<Member<AXEventParams>>& GetNotificationsToPost(Document& document); |
| |
| // Whether the user has granted permission for the user to install event |
| // listeners for accessibility events using the AOM. |
| mojom::PermissionStatus accessibility_event_permission_; |
| // The permission service, enabling us to check for event listener |
| // permission. |
| HeapMojoRemote<mojom::blink::PermissionService> permission_service_; |
| HeapMojoReceiver<mojom::blink::PermissionObserver, AXObjectCacheImpl> |
| permission_observer_receiver_; |
| |
| // Queued callbacks. |
| TreeUpdateCallbackQueue tree_update_callback_queue_main_; |
| TreeUpdateCallbackQueue tree_update_callback_queue_popup_; |
| |
| HeapHashSet<WeakMember<Node>> nodes_with_pending_children_changed_; |
| |
| // If tree_update_callback_queue_ gets improbably large, stop |
| // enqueueing updates and fire a single ChildrenChanged event on the |
| // document once layout occurs. |
| wtf_size_t max_pending_updates_ = 1UL << 16; |
| bool tree_updates_paused_ = false; |
| |
| // Maps ids to their object's autofill state. |
| HashMap<AXID, WebAXAutofillState> autofill_state_map_; |
| |
| // The set of node IDs whose bounds has changed since the last time |
| // GetAllObjectsWithChangedBounds was called. |
| HashSet<AXID> changed_bounds_ids_; |
| |
| // The list of node IDs whose position is fixed or sticky. |
| HashSet<AXID> fixed_or_sticky_node_ids_; |
| |
| // The source of the event that is currently being handled. |
| ax::mojom::blink::EventFrom active_event_from_ = |
| ax::mojom::blink::EventFrom::kNone; |
| |
| // The accessibility action that caused the event. Will only be valid if |
| // active_event_from_ is set to kAction. |
| ax::mojom::blink::Action active_event_from_action_ = |
| ax::mojom::blink::Action::kNone; |
| |
| // A set of currently active event intents. |
| BlinkAXEventIntentsSet active_event_intents_; |
| |
| bool is_frozen_ = false; // Used with Freeze(), Thaw() and IsFrozen() above. |
| |
| // Set of ID's of current AXObjects that need to be destroyed and recreated. |
| HashSet<AXID> invalidated_ids_main_; |
| HashSet<AXID> invalidated_ids_popup_; |
| |
| // If false, exposes the internal accessibility tree of a select pop-up |
| // instead. |
| static bool use_ax_menu_list_; |
| |
| DISALLOW_COPY_AND_ASSIGN(AXObjectCacheImpl); |
| |
| FRIEND_TEST_ALL_PREFIXES(AccessibilityTest, PauseUpdatesAfterMaxNumberQueued); |
| }; |
| |
| // This is the only subclass of AXObjectCache. |
| template <> |
| struct DowncastTraits<AXObjectCacheImpl> { |
| static bool AllowFrom(const AXObjectCache& cache) { return true; } |
| }; |
| |
| // This will let you know if aria-hidden was explicitly set to false. |
| bool IsNodeAriaVisible(Node*); |
| |
| } // namespace blink |
| |
| #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_OBJECT_CACHE_IMPL_H_ |