AX: Implement paragraph related text marker functions using TextIterator
[WebKit-https.git] / Source / WebCore / accessibility / AXObjectCache.h
1 /*
2  * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 2011, 2015 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  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #ifndef AXObjectCache_h
27 #define AXObjectCache_h
28
29 #include "AXTextStateChangeIntent.h"
30 #include "AccessibilityObject.h"
31 #include "Range.h"
32 #include "Timer.h"
33 #include "VisibleUnits.h"
34 #include <limits.h>
35 #include <wtf/Forward.h>
36 #include <wtf/HashMap.h>
37 #include <wtf/HashSet.h>
38 #include <wtf/ListHashSet.h>
39 #include <wtf/RefPtr.h>
40
41 namespace WebCore {
42
43 class Document;
44 class HTMLAreaElement;
45 class Node;
46 class Page;
47 class RenderObject;
48 class ScrollView;
49 class VisiblePosition;
50 class Widget;
51
52 struct TextMarkerData {
53     AXID axID;
54     Node* node;
55     int offset;
56     int characterStartIndex;
57     int characterOffset;
58     bool ignored;
59     EAffinity affinity;
60 };
61
62 struct CharacterOffset {
63     Node* node;
64     int startIndex;
65     int offset;
66     int remainingOffset;
67     
68     CharacterOffset(Node* n = nullptr, int startIndex = 0, int offset = 0, int remaining = 0)
69         : node(n)
70         , startIndex(startIndex)
71         , offset(offset)
72         , remainingOffset(remaining)
73     { }
74     
75     int remaining() const { return remainingOffset; }
76     bool isNull() const { return !node; }
77     bool isEqual(CharacterOffset& other) const
78     {
79         if (isNull() || other.isNull())
80             return false;
81         return node == other.node && startIndex == other.startIndex && offset == other.offset;
82     }
83 };
84
85 class AXComputedObjectAttributeCache {
86 public:
87     AccessibilityObjectInclusion getIgnored(AXID) const;
88     void setIgnored(AXID, AccessibilityObjectInclusion);
89
90 private:
91     struct CachedAXObjectAttributes {
92         CachedAXObjectAttributes() : ignored(DefaultBehavior) { }
93
94         AccessibilityObjectInclusion ignored;
95     };
96
97     HashMap<AXID, CachedAXObjectAttributes> m_idMapping;
98 };
99
100 #if !PLATFORM(COCOA)
101 enum AXTextChange { AXTextInserted, AXTextDeleted, AXTextAttributesChanged };
102 #endif
103
104 enum PostTarget { TargetElement, TargetObservableParent };
105
106 enum PostType { PostSynchronously, PostAsynchronously };
107
108 class AXObjectCache {
109     WTF_MAKE_NONCOPYABLE(AXObjectCache); WTF_MAKE_FAST_ALLOCATED;
110 public:
111     explicit AXObjectCache(Document&);
112     ~AXObjectCache();
113
114     WEBCORE_EXPORT static AccessibilityObject* focusedUIElementForPage(const Page*);
115
116     // Returns the root object for the entire document.
117     WEBCORE_EXPORT AccessibilityObject* rootObject();
118     // Returns the root object for a specific frame.
119     WEBCORE_EXPORT AccessibilityObject* rootObjectForFrame(Frame*);
120     
121     // For AX objects with elements that back them.
122     AccessibilityObject* getOrCreate(RenderObject*);
123     AccessibilityObject* getOrCreate(Widget*);
124     AccessibilityObject* getOrCreate(Node*);
125
126     // used for objects without backing elements
127     AccessibilityObject* getOrCreate(AccessibilityRole);
128     
129     // will only return the AccessibilityObject if it already exists
130     AccessibilityObject* get(RenderObject*);
131     AccessibilityObject* get(Widget*);
132     AccessibilityObject* get(Node*);
133     
134     void remove(RenderObject*);
135     void remove(Node*);
136     void remove(Widget*);
137     void remove(AXID);
138
139     void detachWrapper(AccessibilityObject*, AccessibilityDetachmentType);
140     void attachWrapper(AccessibilityObject*);
141     void childrenChanged(Node*, Node* newChild = nullptr);
142     void childrenChanged(RenderObject*, RenderObject* newChild = nullptr);
143     void childrenChanged(AccessibilityObject*);
144     void checkedStateChanged(Node*);
145     void selectedChildrenChanged(Node*);
146     void selectedChildrenChanged(RenderObject*);
147     // Called by a node when text or a text equivalent (e.g. alt) attribute is changed.
148     void textChanged(Node*);
149     void textChanged(RenderObject*);
150     // Called when a node has just been attached, so we can make sure we have the right subclass of AccessibilityObject.
151     void updateCacheAfterNodeIsAttached(Node*);
152
153     void handleActiveDescendantChanged(Node*);
154     void handleAriaRoleChanged(Node*);
155     void handleFocusedUIElementChanged(Node* oldFocusedNode, Node* newFocusedNode);
156     void handleScrolledToAnchor(const Node* anchorNode);
157     void handleAriaExpandedChange(Node*);
158     void handleScrollbarUpdate(ScrollView*);
159     
160     void handleAriaModalChange(Node*);
161     Node* ariaModalNode();
162
163     void handleAttributeChanged(const QualifiedName& attrName, Element*);
164     void recomputeIsIgnored(RenderObject* renderer);
165
166 #if HAVE(ACCESSIBILITY)
167     WEBCORE_EXPORT static void enableAccessibility();
168     WEBCORE_EXPORT static void disableAccessibility();
169
170     // Enhanced user interface accessibility can be toggled by the assistive technology.
171     WEBCORE_EXPORT static void setEnhancedUserInterfaceAccessibility(bool flag);
172     
173     static bool accessibilityEnabled() { return gAccessibilityEnabled; }
174     static bool accessibilityEnhancedUserInterfaceEnabled() { return gAccessibilityEnhancedUserInterfaceEnabled; }
175 #else
176     static void enableAccessibility() { }
177     static void disableAccessibility() { }
178     static void setEnhancedUserInterfaceAccessibility(bool) { }
179     static bool accessibilityEnabled() { return false; }
180     static bool accessibilityEnhancedUserInterfaceEnabled() { return false; }
181 #endif
182
183     void removeAXID(AccessibilityObject*);
184     bool isIDinUse(AXID id) const { return m_idsInUse.contains(id); }
185
186     const Element* rootAXEditableElement(const Node*);
187     bool nodeIsTextControl(const Node*);
188
189     AXID platformGenerateAXID() const;
190     AccessibilityObject* objectFromAXID(AXID id) const { return m_objects.get(id); }
191
192     // Text marker utilities.
193     void textMarkerDataForVisiblePosition(TextMarkerData&, const VisiblePosition&);
194     void textMarkerDataForCharacterOffset(TextMarkerData&, const CharacterOffset&);
195     void textMarkerDataForNextCharacterOffset(TextMarkerData&, const CharacterOffset&);
196     void textMarkerDataForPreviousCharacterOffset(TextMarkerData&, const CharacterOffset&);
197     VisiblePosition visiblePositionForTextMarkerData(TextMarkerData&);
198     CharacterOffset characterOffsetForTextMarkerData(TextMarkerData&);
199     CharacterOffset nextCharacterOffset(const CharacterOffset&, bool ignoreStart = true);
200     CharacterOffset previousCharacterOffset(const CharacterOffset&, bool ignoreStart = true);
201     void startOrEndTextMarkerDataForRange(TextMarkerData&, RefPtr<Range>, bool);
202     AccessibilityObject* accessibilityObjectForTextMarkerData(TextMarkerData&);
203     RefPtr<Range> rangeForUnorderedCharacterOffsets(const CharacterOffset&, const CharacterOffset&);
204     static RefPtr<Range> rangeForNodeContents(Node*);
205     static int lengthForRange(Range*);
206     
207     // Word boundary
208     CharacterOffset nextWordEndCharacterOffset(const CharacterOffset&);
209     CharacterOffset previousWordStartCharacterOffset(const CharacterOffset&);
210     RefPtr<Range> leftWordRange(const CharacterOffset&);
211     RefPtr<Range> rightWordRange(const CharacterOffset&);
212     
213     // Paragraph
214     RefPtr<Range> paragraphForCharacterOffset(const CharacterOffset&);
215     CharacterOffset nextParagraphEndCharacterOffset(const CharacterOffset&);
216     CharacterOffset previousParagraphStartCharacterOffset(const CharacterOffset&);
217
218     enum AXNotification {
219         AXActiveDescendantChanged,
220         AXAutocorrectionOccured,
221         AXCheckedStateChanged,
222         AXChildrenChanged,
223         AXFocusedUIElementChanged,
224         AXLayoutComplete,
225         AXLoadComplete,
226         AXNewDocumentLoadComplete,
227         AXSelectedChildrenChanged,
228         AXSelectedTextChanged,
229         AXValueChanged,
230         AXScrolledToAnchor,
231         AXLiveRegionCreated,
232         AXLiveRegionChanged,
233         AXMenuListItemSelected,
234         AXMenuListValueChanged,
235         AXMenuClosed,
236         AXMenuOpened,
237         AXRowCountChanged,
238         AXRowCollapsed,
239         AXRowExpanded,
240         AXExpandedChanged,
241         AXInvalidStatusChanged,
242         AXTextChanged,
243         AXAriaAttributeChanged,
244         AXElementBusyChanged
245     };
246
247     void postNotification(RenderObject*, AXNotification, PostTarget = TargetElement, PostType = PostAsynchronously);
248     void postNotification(Node*, AXNotification, PostTarget = TargetElement, PostType = PostAsynchronously);
249     void postNotification(AccessibilityObject*, Document*, AXNotification, PostTarget = TargetElement, PostType = PostAsynchronously);
250
251 #ifndef NDEBUG
252     void showIntent(const AXTextStateChangeIntent&);
253 #endif
254
255     void setTextSelectionIntent(const AXTextStateChangeIntent&);
256     void setIsSynchronizingSelection(bool);
257
258     void postTextStateChangeNotification(Node*, AXTextEditType, const String&, const VisiblePosition&);
259     void postTextReplacementNotification(Node*, AXTextEditType deletionType, const String& deletedText, AXTextEditType insertionType, const String& insertedText, const VisiblePosition&);
260     void postTextStateChangeNotification(Node*, const AXTextStateChangeIntent&, const VisibleSelection&);
261     void postTextStateChangeNotification(const Position&, const AXTextStateChangeIntent&, const VisibleSelection&);
262     void postLiveRegionChangeNotification(AccessibilityObject*);
263
264     enum AXLoadingEvent {
265         AXLoadingStarted,
266         AXLoadingReloaded,
267         AXLoadingFailed,
268         AXLoadingFinished
269     };
270
271     void frameLoadingEventNotification(Frame*, AXLoadingEvent);
272
273     void clearTextMarkerNodesInUse(Document*);
274
275     void startCachingComputedObjectAttributesUntilTreeMutates();
276     void stopCachingComputedObjectAttributes();
277
278     AXComputedObjectAttributeCache* computedObjectAttributeCache() { return m_computedObjectAttributeCache.get(); }
279
280     Document& document() const { return m_document; }
281
282 #if PLATFORM(MAC)
283     static void setShouldRepostNotificationsForTests(bool value);
284 #endif
285
286 protected:
287     void postPlatformNotification(AccessibilityObject*, AXNotification);
288     void platformHandleFocusedUIElementChanged(Node* oldFocusedNode, Node* newFocusedNode);
289
290 #if PLATFORM(COCOA)
291     void postTextStateChangePlatformNotification(AccessibilityObject*, const AXTextStateChangeIntent&, const VisibleSelection&);
292     void postTextStateChangePlatformNotification(AccessibilityObject*, AXTextEditType, const String&, const VisiblePosition&);
293     void postTextReplacementPlatformNotification(AccessibilityObject*, AXTextEditType, const String&, AXTextEditType, const String&, const VisiblePosition&);
294 #else
295     static AXTextChange textChangeForEditType(AXTextEditType);
296     void nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, const String&);
297 #endif
298
299     void frameLoadingEventPlatformNotification(AccessibilityObject*, AXLoadingEvent);
300     void textChanged(AccessibilityObject*);
301     void labelChanged(Element*);
302
303     // This is a weak reference cache for knowing if Nodes used by TextMarkers are valid.
304     void setNodeInUse(Node* n) { m_textMarkerNodes.add(n); }
305     void removeNodeForUse(Node* n) { m_textMarkerNodes.remove(n); }
306     bool isNodeInUse(Node* n) { return m_textMarkerNodes.contains(n); }
307     
308     // CharacterOffset functions.
309     enum TraverseOption { TraverseOptionDefault = 1 << 0, TraverseOptionToNodeEnd = 1 << 1, TraverseOptionIncludeStart = 1 << 2 };
310     Node* nextNode(Node*) const;
311     Node* previousNode(Node*) const;
312     CharacterOffset traverseToOffsetInRange(RefPtr<Range>, int, bool, bool stayWithinRange = false);
313     VisiblePosition visiblePositionFromCharacterOffset(const CharacterOffset&);
314     CharacterOffset characterOffsetFromVisiblePosition(const VisiblePosition&);
315     void setTextMarkerDataWithCharacterOffset(TextMarkerData&, const CharacterOffset&);
316     UChar32 characterAfter(const CharacterOffset&);
317     UChar32 characterBefore(const CharacterOffset&);
318     CharacterOffset startOrEndCharacterOffsetForRange(RefPtr<Range>, bool);
319     CharacterOffset characterOffsetForNodeAndOffset(Node&, int, TraverseOption = TraverseOptionDefault);
320     CharacterOffset previousWordBoundary(CharacterOffset&, BoundarySearchFunction);
321     CharacterOffset nextWordBoundary(CharacterOffset&, BoundarySearchFunction);
322     CharacterOffset startCharacterOffsetOfWord(const CharacterOffset&, EWordSide = RightWordIfOnBoundary);
323     CharacterOffset endCharacterOffsetOfWord(const CharacterOffset&, EWordSide = RightWordIfOnBoundary);
324     CharacterOffset startCharacterOffsetOfParagraph(const CharacterOffset&, EditingBoundaryCrossingRule = CannotCrossEditingBoundary);
325     CharacterOffset endCharacterOffsetOfParagraph(const CharacterOffset&, EditingBoundaryCrossingRule = CannotCrossEditingBoundary);
326
327 private:
328     AccessibilityObject* rootWebArea();
329
330     static AccessibilityObject* focusedImageMapUIElement(HTMLAreaElement*);
331
332     AXID getAXID(AccessibilityObject*);
333
334     void notificationPostTimerFired();
335
336     void liveRegionChangedNotificationPostTimerFired();
337
338     void postTextStateChangeNotification(AccessibilityObject*, const AXTextStateChangeIntent&, const VisibleSelection&);
339
340     bool enqueuePasswordValueChangeNotification(AccessibilityObject*);
341     void passwordNotificationPostTimerFired();
342
343     void handleMenuOpened(Node*);
344     void handleLiveRegionCreated(Node*);
345     void handleMenuItemSelected(Node*);
346     
347     // aria-modal related
348     void findAriaModalNodes();
349     void updateCurrentAriaModalNode();
350     bool isNodeVisible(Node*) const;
351
352     Document& m_document;
353     HashMap<AXID, RefPtr<AccessibilityObject>> m_objects;
354     HashMap<RenderObject*, AXID> m_renderObjectMapping;
355     HashMap<Widget*, AXID> m_widgetObjectMapping;
356     HashMap<Node*, AXID> m_nodeObjectMapping;
357     HashSet<Node*> m_textMarkerNodes;
358     std::unique_ptr<AXComputedObjectAttributeCache> m_computedObjectAttributeCache;
359     WEBCORE_EXPORT static bool gAccessibilityEnabled;
360     WEBCORE_EXPORT static bool gAccessibilityEnhancedUserInterfaceEnabled;
361
362     HashSet<AXID> m_idsInUse;
363
364     Timer m_notificationPostTimer;
365     Vector<std::pair<RefPtr<AccessibilityObject>, AXNotification>> m_notificationsToPost;
366
367     Timer m_passwordNotificationPostTimer;
368
369     ListHashSet<RefPtr<AccessibilityObject>> m_passwordNotificationsToPost;
370     
371     Timer m_liveRegionChangedPostTimer;
372     ListHashSet<RefPtr<AccessibilityObject>> m_liveRegionObjectsSet;
373     
374     Node* m_currentAriaModalNode;
375     ListHashSet<Node*> m_ariaModalNodesSet;
376
377     AXTextStateChangeIntent m_textSelectionIntent;
378     bool m_isSynchronizingSelection { false };
379 };
380
381 class AXAttributeCacheEnabler
382 {
383 public:
384     explicit AXAttributeCacheEnabler(AXObjectCache *cache);
385     ~AXAttributeCacheEnabler();
386
387 #if HAVE(ACCESSIBILITY)
388 private:
389     AXObjectCache* m_cache;
390 #endif
391 };
392
393 bool nodeHasRole(Node*, const String& role);
394 // This will let you know if aria-hidden was explicitly set to false.
395 bool isNodeAriaVisible(Node*);
396     
397 #if !HAVE(ACCESSIBILITY)
398 inline AccessibilityObjectInclusion AXComputedObjectAttributeCache::getIgnored(AXID) const { return DefaultBehavior; }
399 inline void AXComputedObjectAttributeCache::setIgnored(AXID, AccessibilityObjectInclusion) { }
400 inline AXObjectCache::AXObjectCache(Document& document) : m_document(document), m_notificationPostTimer(nullptr), m_passwordNotificationPostTimer(nullptr), m_liveRegionChangedPostTimer(nullptr) { }
401 inline AXObjectCache::~AXObjectCache() { }
402 inline AccessibilityObject* AXObjectCache::focusedUIElementForPage(const Page*) { return nullptr; }
403 inline AccessibilityObject* AXObjectCache::get(RenderObject*) { return nullptr; }
404 inline AccessibilityObject* AXObjectCache::get(Node*) { return nullptr; }
405 inline AccessibilityObject* AXObjectCache::get(Widget*) { return nullptr; }
406 inline AccessibilityObject* AXObjectCache::getOrCreate(AccessibilityRole) { return nullptr; }
407 inline AccessibilityObject* AXObjectCache::getOrCreate(RenderObject*) { return nullptr; }
408 inline AccessibilityObject* AXObjectCache::getOrCreate(Node*) { return nullptr; }
409 inline AccessibilityObject* AXObjectCache::getOrCreate(Widget*) { return nullptr; }
410 inline AccessibilityObject* AXObjectCache::rootObject() { return nullptr; }
411 inline AccessibilityObject* AXObjectCache::rootObjectForFrame(Frame*) { return nullptr; }
412 inline bool nodeHasRole(Node*, const String&) { return false; }
413 inline void AXObjectCache::startCachingComputedObjectAttributesUntilTreeMutates() { }
414 inline void AXObjectCache::stopCachingComputedObjectAttributes() { }
415 inline bool isNodeAriaVisible(Node*) { return true; }
416 inline const Element* AXObjectCache::rootAXEditableElement(const Node*) { return nullptr; }
417 inline Node* AXObjectCache::ariaModalNode() { return nullptr; }
418 inline void AXObjectCache::attachWrapper(AccessibilityObject*) { }
419 inline void AXObjectCache::checkedStateChanged(Node*) { }
420 inline void AXObjectCache::childrenChanged(RenderObject*, RenderObject*) { }
421 inline void AXObjectCache::childrenChanged(Node*, Node*) { }
422 inline void AXObjectCache::childrenChanged(AccessibilityObject*) { }
423 inline void AXObjectCache::textChanged(RenderObject*) { }
424 inline void AXObjectCache::textChanged(Node*) { }
425 inline void AXObjectCache::textChanged(AccessibilityObject*) { }
426 inline void AXObjectCache::updateCacheAfterNodeIsAttached(Node*) { }
427 inline void AXObjectCache::detachWrapper(AccessibilityObject*, AccessibilityDetachmentType) { }
428 inline void AXObjectCache::frameLoadingEventNotification(Frame*, AXLoadingEvent) { }
429 inline void AXObjectCache::frameLoadingEventPlatformNotification(AccessibilityObject*, AXLoadingEvent) { }
430 inline void AXObjectCache::handleActiveDescendantChanged(Node*) { }
431 inline void AXObjectCache::handleAriaExpandedChange(Node*) { }
432 inline void AXObjectCache::handleAriaRoleChanged(Node*) { }
433 inline void AXObjectCache::handleAriaModalChange(Node*) { }
434 inline void AXObjectCache::handleFocusedUIElementChanged(Node*, Node*) { }
435 inline void AXObjectCache::handleScrollbarUpdate(ScrollView*) { }
436 inline void AXObjectCache::handleAttributeChanged(const QualifiedName&, Element*) { }
437 inline void AXObjectCache::recomputeIsIgnored(RenderObject*) { }
438 inline void AXObjectCache::handleScrolledToAnchor(const Node*) { }
439 inline void AXObjectCache::postTextStateChangeNotification(Node*, const AXTextStateChangeIntent&, const VisibleSelection&) { }
440 inline void AXObjectCache::postTextStateChangeNotification(Node*, AXTextEditType, const String&, const VisiblePosition&) { }
441 inline void AXObjectCache::postTextReplacementNotification(Node*, AXTextEditType, const String&, AXTextEditType, const String&, const VisiblePosition&) { }
442 inline void AXObjectCache::postNotification(AccessibilityObject*, Document*, AXNotification, PostTarget, PostType) { }
443 inline void AXObjectCache::postNotification(RenderObject*, AXNotification, PostTarget, PostType) { }
444 inline void AXObjectCache::postNotification(Node*, AXNotification, PostTarget, PostType) { }
445 inline void AXObjectCache::postPlatformNotification(AccessibilityObject*, AXNotification) { }
446 inline void AXObjectCache::postLiveRegionChangeNotification(AccessibilityObject*) { }
447 inline RefPtr<Range> AXObjectCache::rangeForNodeContents(Node*) { return nullptr; }
448 inline void AXObjectCache::remove(AXID) { }
449 inline void AXObjectCache::remove(RenderObject*) { }
450 inline void AXObjectCache::remove(Node*) { }
451 inline void AXObjectCache::remove(Widget*) { }
452 inline void AXObjectCache::selectedChildrenChanged(RenderObject*) { }
453 inline void AXObjectCache::selectedChildrenChanged(Node*) { }
454 inline void AXObjectCache::setIsSynchronizingSelection(bool) { }
455 inline void AXObjectCache::setTextSelectionIntent(const AXTextStateChangeIntent&) { }
456 #if PLATFORM(COCOA)
457 inline void AXObjectCache::postTextStateChangePlatformNotification(AccessibilityObject*, const AXTextStateChangeIntent&, const VisibleSelection&) { }
458 inline void AXObjectCache::postTextStateChangePlatformNotification(AccessibilityObject*, AXTextEditType, const String&, const VisiblePosition&) { }
459 inline void AXObjectCache::postTextReplacementPlatformNotification(AccessibilityObject*, AXTextEditType, const String&, AXTextEditType, const String&, const VisiblePosition&) { }
460 #else
461 inline AXTextChange AXObjectCache::textChangeForEditType(AXTextEditType) { return AXTextInserted; }
462 inline void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, const String&) { }
463 #endif
464
465 inline AXAttributeCacheEnabler::AXAttributeCacheEnabler(AXObjectCache*) { }
466 inline AXAttributeCacheEnabler::~AXAttributeCacheEnabler() { }
467
468 #endif
469
470 }
471
472 #endif