Commit fd65313a authored by cfleizach@apple.com's avatar cfleizach@apple.com

AXObjectCache gets recreated during document tear-down.

https://bugs.webkit.org/show_bug.cgi?id=112525

Reviewed by Simon Fraser.

In many cases, a document's AXObjectCache was being created after the
document had detached, which is wasteful and could potentially lead to
crashes because the AXObjectCache has a timer and relies on its document
to exist.

This patch provides a way to get the existing AX object cache, instead of
always creating a new one.
It moves the accessibilityEnabled() checks into the axObjectCache retrieval
for easier readability.
It adds a number of ASSERTs to vieryf that only the correct (top) document is used
for cache manipulation.

* accessibility/AXObjectCache.cpp:
(WebCore::AXObjectCache::stopCachingComputedObjectAttributes):
* dom/ContainerNode.cpp:
(WebCore::ContainerNode::~ContainerNode):
* dom/Document.cpp:
(WebCore::Document::~Document):
(WebCore::Document::clearAXObjectCache):
(WebCore::Document::existingAXObjectCache):
(WebCore::Document::axObjectCache):
(WebCore::Document::setFocusedNode):
* dom/Document.h:
(Document):
* dom/Element.cpp:
(WebCore::Element::attributeChanged):
* dom/Node.cpp:
(WebCore::Node::~Node):
(WebCore::Node::isEditableToAccessibility):
(WebCore::Node::attach):
(WebCore::Node::rootEditableElement):
(WebCore::Node::didMoveToNewDocument):
* editing/AppendNodeCommand.cpp:
(WebCore::sendAXTextChangedIgnoringLineBreaks):
* editing/DeleteFromTextNodeCommand.cpp:
(WebCore::DeleteFromTextNodeCommand::doApply):
(WebCore::DeleteFromTextNodeCommand::doUnapply):
* editing/Editor.cpp:
(WebCore::Editor::respondToChangedContents):
(WebCore::Editor::markAndReplaceFor):
* editing/InsertIntoTextNodeCommand.cpp:
(WebCore::InsertIntoTextNodeCommand::doApply):
(WebCore::InsertIntoTextNodeCommand::doUnapply):
* editing/InsertNodeBeforeCommand.cpp:
(WebCore::InsertNodeBeforeCommand::doApply):
(WebCore::InsertNodeBeforeCommand::doUnapply):
* editing/atk/FrameSelectionAtk.cpp:
(WebCore::FrameSelection::notifyAccessibilityForSelectionChange):
* editing/chromium/FrameSelectionChromium.cpp:
(WebCore::FrameSelection::notifyAccessibilityForSelectionChange):
* editing/mac/FrameSelectionMac.mm:
(WebCore::FrameSelection::notifyAccessibilityForSelectionChange):
* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::setChecked):
* html/HTMLSelectElement.cpp:
(WebCore::HTMLSelectElement::optionElementChildrenChanged):
(WebCore::HTMLSelectElement::setRecalcListItems):
* html/HTMLTextFormControlElement.cpp:
(WebCore::HTMLTextFormControlElement::setInnerTextValue):
* html/InputType.cpp:
(WebCore::InputType::applyStep):
* html/RangeInputType.cpp:
(WebCore::RangeInputType::handleKeydownEvent):
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::prepareForLoadStart):
(WebCore::FrameLoader::checkLoadCompleteForThisFrame):
* page/FocusController.cpp:
(WebCore::FocusController::setInitialFocus):
* page/Frame.cpp:
(WebCore::Frame::disconnectOwnerElement):
* page/FrameView.cpp:
(WebCore::FrameView::removeFromAXObjectCache):
(WebCore::FrameView::layout):
(WebCore::FrameView::scrollToAnchor):
(WebCore::FrameView::axObjectCache):
* platform/ScrollView.cpp:
(WebCore::ScrollView::setHasHorizontalScrollbar):
(WebCore::ScrollView::setHasVerticalScrollbar):
* platform/Scrollbar.cpp:
(WebCore::Scrollbar::~Scrollbar):
(WebCore):
(WebCore::Scrollbar::existingAXObjectCache):
* platform/Scrollbar.h:
(Scrollbar):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::deleteLineBoxTree):
(WebCore::RenderBlock::createRootInlineBox):
(WebCore::RenderBlock::createAndAppendRootInlineBox):
* rendering/RenderListBox.cpp:
(WebCore::RenderListBox::selectionChanged):
* rendering/RenderMenuList.cpp:
(WebCore::RenderMenuList::addChild):
(WebCore::RenderMenuList::didUpdateActiveOption):
* rendering/RenderObject.cpp:
(WebCore::RenderObject::styleWillChange):
(WebCore::RenderObject::willBeDestroyed):
* rendering/RenderObjectChildList.cpp:
(WebCore::RenderObjectChildList::removeChildNode):
(WebCore::RenderObjectChildList::insertChildNode):
* rendering/RenderText.cpp:
(WebCore::RenderText::setText):
* rendering/RenderWidget.cpp:
(WebCore::RenderWidget::willBeDestroyed):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@146726 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 4b7f8fdd
2013-03-24 Chris Fleizach <cfleizach@apple.com>
AXObjectCache gets recreated during document tear-down.
https://bugs.webkit.org/show_bug.cgi?id=112525
Reviewed by Simon Fraser.
In many cases, a document's AXObjectCache was being created after the
document had detached, which is wasteful and could potentially lead to
crashes because the AXObjectCache has a timer and relies on its document
to exist.
This patch provides a way to get the existing AX object cache, instead of
always creating a new one.
It moves the accessibilityEnabled() checks into the axObjectCache retrieval
for easier readability.
It adds a number of ASSERTs to vieryf that only the correct (top) document is used
for cache manipulation.
* accessibility/AXObjectCache.cpp:
(WebCore::AXObjectCache::stopCachingComputedObjectAttributes):
* dom/ContainerNode.cpp:
(WebCore::ContainerNode::~ContainerNode):
* dom/Document.cpp:
(WebCore::Document::~Document):
(WebCore::Document::clearAXObjectCache):
(WebCore::Document::existingAXObjectCache):
(WebCore::Document::axObjectCache):
(WebCore::Document::setFocusedNode):
* dom/Document.h:
(Document):
* dom/Element.cpp:
(WebCore::Element::attributeChanged):
* dom/Node.cpp:
(WebCore::Node::~Node):
(WebCore::Node::isEditableToAccessibility):
(WebCore::Node::attach):
(WebCore::Node::rootEditableElement):
(WebCore::Node::didMoveToNewDocument):
* editing/AppendNodeCommand.cpp:
(WebCore::sendAXTextChangedIgnoringLineBreaks):
* editing/DeleteFromTextNodeCommand.cpp:
(WebCore::DeleteFromTextNodeCommand::doApply):
(WebCore::DeleteFromTextNodeCommand::doUnapply):
* editing/Editor.cpp:
(WebCore::Editor::respondToChangedContents):
(WebCore::Editor::markAndReplaceFor):
* editing/InsertIntoTextNodeCommand.cpp:
(WebCore::InsertIntoTextNodeCommand::doApply):
(WebCore::InsertIntoTextNodeCommand::doUnapply):
* editing/InsertNodeBeforeCommand.cpp:
(WebCore::InsertNodeBeforeCommand::doApply):
(WebCore::InsertNodeBeforeCommand::doUnapply):
* editing/atk/FrameSelectionAtk.cpp:
(WebCore::FrameSelection::notifyAccessibilityForSelectionChange):
* editing/chromium/FrameSelectionChromium.cpp:
(WebCore::FrameSelection::notifyAccessibilityForSelectionChange):
* editing/mac/FrameSelectionMac.mm:
(WebCore::FrameSelection::notifyAccessibilityForSelectionChange):
* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::setChecked):
* html/HTMLSelectElement.cpp:
(WebCore::HTMLSelectElement::optionElementChildrenChanged):
(WebCore::HTMLSelectElement::setRecalcListItems):
* html/HTMLTextFormControlElement.cpp:
(WebCore::HTMLTextFormControlElement::setInnerTextValue):
* html/InputType.cpp:
(WebCore::InputType::applyStep):
* html/RangeInputType.cpp:
(WebCore::RangeInputType::handleKeydownEvent):
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::prepareForLoadStart):
(WebCore::FrameLoader::checkLoadCompleteForThisFrame):
* page/FocusController.cpp:
(WebCore::FocusController::setInitialFocus):
* page/Frame.cpp:
(WebCore::Frame::disconnectOwnerElement):
* page/FrameView.cpp:
(WebCore::FrameView::removeFromAXObjectCache):
(WebCore::FrameView::layout):
(WebCore::FrameView::scrollToAnchor):
(WebCore::FrameView::axObjectCache):
* platform/ScrollView.cpp:
(WebCore::ScrollView::setHasHorizontalScrollbar):
(WebCore::ScrollView::setHasVerticalScrollbar):
* platform/Scrollbar.cpp:
(WebCore::Scrollbar::~Scrollbar):
(WebCore):
(WebCore::Scrollbar::existingAXObjectCache):
* platform/Scrollbar.h:
(Scrollbar):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::deleteLineBoxTree):
(WebCore::RenderBlock::createRootInlineBox):
(WebCore::RenderBlock::createAndAppendRootInlineBox):
* rendering/RenderListBox.cpp:
(WebCore::RenderListBox::selectionChanged):
* rendering/RenderMenuList.cpp:
(WebCore::RenderMenuList::addChild):
(WebCore::RenderMenuList::didUpdateActiveOption):
* rendering/RenderObject.cpp:
(WebCore::RenderObject::styleWillChange):
(WebCore::RenderObject::willBeDestroyed):
* rendering/RenderObjectChildList.cpp:
(WebCore::RenderObjectChildList::removeChildNode):
(WebCore::RenderObjectChildList::insertChildNode):
* rendering/RenderText.cpp:
(WebCore::RenderText::setText):
* rendering/RenderWidget.cpp:
(WebCore::RenderWidget::willBeDestroyed):
2013-03-23 Mike West <mkwst@chromium.org>
Drop full URLs from cross-origin access errors caused by sandboxing.
......@@ -846,7 +846,8 @@ void AXObjectCache::startCachingComputedObjectAttributesUntilTreeMutates()
void AXObjectCache::stopCachingComputedObjectAttributes()
{
m_computedObjectAttributeCache.clear();
if (m_computedObjectAttributeCache)
m_computedObjectAttributeCache.clear();
}
VisiblePosition AXObjectCache::visiblePositionForTextMarkerData(TextMarkerData& textMarkerData)
......
......@@ -138,8 +138,10 @@ void ContainerNode::takeAllChildrenFrom(ContainerNode* oldParent)
ContainerNode::~ContainerNode()
{
if (AXObjectCache::accessibilityEnabled() && documentInternal() && documentInternal()->axObjectCacheExists())
documentInternal()->axObjectCache()->remove(this);
if (documentInternal()) {
if (AXObjectCache* cache = documentInternal()->existingAXObjectCache())
cache->remove(this);
}
removeDetachedChildren();
}
......
......@@ -629,7 +629,8 @@ Document::~Document()
m_renderArena.clear();
clearAXObjectCache();
if (this == topDocument())
clearAXObjectCache();
m_decoder = 0;
......@@ -2211,23 +2212,40 @@ void Document::resumeActiveDOMObjects()
void Document::clearAXObjectCache()
{
ASSERT(topDocument() == this);
// Clear the cache member variable before calling delete because attempts
// are made to access it during destruction.
topDocument()->m_axObjectCache.release();
m_axObjectCache.clear();
}
bool Document::axObjectCacheExists() const
AXObjectCache* Document::existingAXObjectCache() const
{
return topDocument()->m_axObjectCache;
if (!AXObjectCache::accessibilityEnabled())
return 0;
// If the renderer is gone then we are in the process of destruction.
// This method will be called before m_frame = 0.
if (!topDocument()->renderer())
return 0;
return topDocument()->m_axObjectCache.get();
}
AXObjectCache* Document::axObjectCache() const
{
if (!AXObjectCache::accessibilityEnabled())
return 0;
// The only document that actually has a AXObjectCache is the top-level
// document. This is because we need to be able to get from any WebCoreAXObject
// to any other WebCoreAXObject on the same page. Using a single cache allows
// lookups across nested webareas (i.e. multiple documents).
Document* topDocument = this->topDocument();
// If the document has already been detached, do not make a new axObjectCache.
if (!topDocument->renderer())
return 0;
ASSERT(topDocument == this || !m_axObjectCache);
if (!topDocument->m_axObjectCache)
topDocument->m_axObjectCache = adoptPtr(new AXObjectCache(topDocument));
......@@ -3476,10 +3494,12 @@ bool Document::setFocusedNode(PassRefPtr<Node> prpNewFocusedNode, FocusDirection
}
}
#if PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(CHROMIUM)
if (!focusChangeBlocked && m_focusedNode && AXObjectCache::accessibilityEnabled())
axObjectCache()->handleFocusedUIElementChanged(oldFocusedNode.get(), newFocusedNode.get());
#endif
if (!focusChangeBlocked && m_focusedNode) {
// Create the AXObject cache in a focus change because Chromium relies on it.
if (AXObjectCache* cache = axObjectCache())
cache->handleFocusedUIElementChanged(oldFocusedNode.get(), newFocusedNode.get());
}
if (!focusChangeBlocked)
page()->chrome()->focusedNodeChanged(m_focusedNode.get());
......
......@@ -559,10 +559,10 @@ public:
Node::setRenderer(renderer);
}
void clearAXObjectCache();
AXObjectCache* existingAXObjectCache() const;
AXObjectCache* axObjectCache() const;
bool axObjectCacheExists() const;
void clearAXObjectCache();
// to get visually ordered hebrew and arabic pages right
void setVisuallyOrdered();
bool visuallyOrdered() const { return m_visuallyOrdered; }
......
......@@ -884,8 +884,8 @@ void Element::attributeChanged(const QualifiedName& name, const AtomicString& ne
if (shouldInvalidateStyle)
setNeedsStyleRecalc();
if (AXObjectCache::accessibilityEnabled())
document()->axObjectCache()->handleAttributeChanged(name, this);
if (AXObjectCache* cache = document()->existingAXObjectCache())
cache->handleAttributeChanged(name, this);
}
inline void Element::attributeChangedFromParserOrByCloning(const QualifiedName& name, const AtomicString& newValue)
......
......@@ -431,8 +431,10 @@ Node::~Node()
if (renderer())
detach();
if (AXObjectCache::accessibilityEnabled() && doc && doc->axObjectCacheExists() && !isContainerNode())
doc->axObjectCache()->remove(this);
if (doc && !isContainerNode()) {
if (AXObjectCache* cache = doc->existingAXObjectCache())
cache->remove(this);
}
if (m_previous)
m_previous->setNextSibling(0);
......@@ -726,10 +728,12 @@ bool Node::isEditableToAccessibility(EditableLevel editableLevel) const
ASSERT(document());
ASSERT(AXObjectCache::accessibilityEnabled());
ASSERT(document()->axObjectCacheExists());
ASSERT(document()->existingAXObjectCache());
if (document() && AXObjectCache::accessibilityEnabled() && document()->axObjectCacheExists())
return document()->axObjectCache()->rootAXEditableElement(this);
if (document()) {
if (AXObjectCache* cache = document()->existingAXObjectCache())
return cache->rootAXEditableElement(this);
}
return false;
}
......@@ -1090,9 +1094,10 @@ void Node::attach()
setAttached();
clearNeedsStyleRecalc();
Document* doc = documentInternal();
if (AXObjectCache::accessibilityEnabled() && doc && doc->axObjectCacheExists())
doc->axObjectCache()->updateCacheAfterNodeIsAttached(this);
if (Document* doc = documentInternal()) {
if (AXObjectCache* cache = doc->axObjectCache())
cache->updateCacheAfterNodeIsAttached(this);
}
}
#ifndef NDEBUG
......@@ -1313,9 +1318,11 @@ bool Node::isRootEditableElement() const
Element* Node::rootEditableElement(EditableType editableType) const
{
if (editableType == HasEditableAXRole)
return const_cast<Element*>(document()->axObjectCache()->rootAXEditableElement(this));
if (editableType == HasEditableAXRole) {
if (AXObjectCache* cache = document()->existingAXObjectCache())
return const_cast<Element*>(cache->rootAXEditableElement(this));
}
return rootEditableElement();
}
......@@ -2093,8 +2100,9 @@ void Node::didMoveToNewDocument(Document* oldDocument)
{
TreeScopeAdopter::ensureDidMoveToNewDocumentWasCalled(oldDocument);
if (AXObjectCache::accessibilityEnabled() && oldDocument && oldDocument->axObjectCacheExists())
oldDocument->axObjectCache()->remove(this);
if (AXObjectCache::accessibilityEnabled() && oldDocument)
if (AXObjectCache* cache = oldDocument->existingAXObjectCache())
cache->remove(this);
// FIXME: Event listener types for this node should be set on the new owner document here.
......
......@@ -52,7 +52,8 @@ static void sendAXTextChangedIgnoringLineBreaks(Node* node, AXObjectCache::AXTex
if (nodeValue == "\n")
return;
node->document()->axObjectCache()->nodeTextChangeNotification(node, textChange, 0, nodeValue);
if (AXObjectCache* cache = node->document()->existingAXObjectCache())
cache->nodeTextChangeNotification(node, textChange, 0, nodeValue);
}
void AppendNodeCommand::doApply()
......
......@@ -57,8 +57,8 @@ void DeleteFromTextNodeCommand::doApply()
return;
// Need to notify this before actually deleting the text
if (AXObjectCache::accessibilityEnabled())
document()->axObjectCache()->nodeTextChangeNotification(m_node.get(), AXObjectCache::AXTextDeleted, m_offset, m_text);
if (AXObjectCache* cache = document()->existingAXObjectCache())
cache->nodeTextChangeNotification(m_node.get(), AXObjectCache::AXTextDeleted, m_offset, m_text);
m_node->deleteData(m_offset, m_count, ec);
}
......@@ -72,8 +72,8 @@ void DeleteFromTextNodeCommand::doUnapply()
m_node->insertData(m_offset, m_text, IGNORE_EXCEPTION);
if (AXObjectCache::accessibilityEnabled())
document()->axObjectCache()->nodeTextChangeNotification(m_node.get(), AXObjectCache::AXTextInserted, m_offset, m_text);
if (AXObjectCache* cache = document()->existingAXObjectCache())
cache->nodeTextChangeNotification(m_node.get(), AXObjectCache::AXTextInserted, m_offset, m_text);
}
#ifndef NDEBUG
......
......@@ -549,8 +549,8 @@ void Editor::respondToChangedContents(const VisibleSelection& endingSelection)
{
if (AXObjectCache::accessibilityEnabled()) {
Node* node = endingSelection.start().deprecatedNode();
if (node)
m_frame->document()->axObjectCache()->postNotification(node, AXObjectCache::AXValueChanged, false);
if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache())
cache->postNotification(node, AXObjectCache::AXValueChanged, false);
}
updateMarkersForWordsAffectedByEditing(true);
......@@ -2273,9 +2273,9 @@ void Editor::markAndReplaceFor(PassRefPtr<SpellCheckRequest> request, const Vect
RefPtr<Range> newParagraphRange = TextIterator::rangeFromLocationAndLength(toContainerNode(root), paragraphStartIndex, paragraphLength + replacementLength - resultLength);
paragraph = TextCheckingParagraph(TextIterator::subrange(newParagraphRange.get(), resultLocation, replacementLength), newParagraphRange);
if (AXObjectCache::accessibilityEnabled()) {
if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache()) {
if (Element* root = m_frame->selection()->selection().rootEditableElement())
m_frame->document()->axObjectCache()->postNotification(root, AXObjectCache::AXAutocorrectionOccured, true);
cache->postNotification(root, AXObjectCache::AXAutocorrectionOccured, true);
}
selectionChanged = true;
......
......@@ -63,8 +63,8 @@ void InsertIntoTextNodeCommand::doApply()
m_node->insertData(m_offset, m_text, IGNORE_EXCEPTION);
if (AXObjectCache::accessibilityEnabled())
document()->axObjectCache()->nodeTextChangeNotification(m_node.get(), AXObjectCache::AXTextInserted, m_offset, m_text);
if (AXObjectCache* cache = document()->existingAXObjectCache())
cache->nodeTextChangeNotification(m_node.get(), AXObjectCache::AXTextInserted, m_offset, m_text);
}
void InsertIntoTextNodeCommand::doUnapply()
......@@ -73,8 +73,8 @@ void InsertIntoTextNodeCommand::doUnapply()
return;
// Need to notify this before actually deleting the text
if (AXObjectCache::accessibilityEnabled())
document()->axObjectCache()->nodeTextChangeNotification(m_node.get(), AXObjectCache::AXTextDeleted, m_offset, m_text);
if (AXObjectCache* cache = document()->existingAXObjectCache())
cache->nodeTextChangeNotification(m_node.get(), AXObjectCache::AXTextDeleted, m_offset, m_text);
m_node->deleteData(m_offset, m_text.length(), IGNORE_EXCEPTION);
}
......
......@@ -57,8 +57,8 @@ void InsertNodeBeforeCommand::doApply()
parent->insertBefore(m_insertChild.get(), m_refChild.get(), IGNORE_EXCEPTION, AttachLazily);
if (AXObjectCache::accessibilityEnabled())
document()->axObjectCache()->nodeTextChangeNotification(m_insertChild.get(), AXObjectCache::AXTextInserted, 0, m_insertChild->nodeValue());
if (AXObjectCache* cache = document()->existingAXObjectCache())
cache->nodeTextChangeNotification(m_insertChild.get(), AXObjectCache::AXTextInserted, 0, m_insertChild->nodeValue());
}
void InsertNodeBeforeCommand::doUnapply()
......@@ -67,8 +67,8 @@ void InsertNodeBeforeCommand::doUnapply()
return;
// Need to notify this before actually deleting the text
if (AXObjectCache::accessibilityEnabled())
document()->axObjectCache()->nodeTextChangeNotification(m_insertChild.get(), AXObjectCache::AXTextDeleted, 0, m_insertChild->nodeValue());
if (AXObjectCache* cache = document()->existingAXObjectCache())
cache->nodeTextChangeNotification(m_insertChild.get(), AXObjectCache::AXTextDeleted, 0, m_insertChild->nodeValue());
m_insertChild->remove(IGNORE_EXCEPTION);
}
......
......@@ -89,7 +89,11 @@ void FrameSelection::notifyAccessibilityForSelectionChange()
return;
RenderObject* focusedNode = m_selection.end().containerNode()->renderer();
AccessibilityObject* accessibilityObject = m_frame->document()->axObjectCache()->getOrCreate(focusedNode);
AXObjectCache* cache = m_frame->document()->existingAXObjectCache();
if (!cache)
return;
AccessibilityObject* accessibilityObject = cache->getOrCreate(focusedNode);
if (!accessibilityObject)
return;
......
......@@ -40,9 +40,9 @@ namespace WebCore {
void FrameSelection::notifyAccessibilityForSelectionChange()
{
// FIXME: Support editable text in chromium.
if (AXObjectCache::accessibilityEnabled() && m_selection.start().isNotNull() && m_selection.end().isNotNull()) {
Document* document = m_frame->document();
document->axObjectCache()->postNotification(m_selection.start().deprecatedNode(), AXObjectCache::AXSelectedTextChanged, false);
if (m_selection.start().isNotNull() && m_selection.end().isNotNull()) {
if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache())
cache->postNotification(m_selection.start().deprecatedNode(), AXObjectCache::AXSelectedTextChanged, false);
}
}
......
......@@ -49,8 +49,10 @@ void FrameSelection::notifyAccessibilityForSelectionChange()
{
Document* document = m_frame->document();
if (AXObjectCache::accessibilityEnabled() && m_selection.start().isNotNull() && m_selection.end().isNotNull())
document->axObjectCache()->postNotification(m_selection.start().deprecatedNode()->renderer(), AXObjectCache::AXSelectedTextChanged, false);
if (m_selection.start().isNotNull() && m_selection.end().isNotNull()) {
if (AXObjectCache* cache = document->existingAXObjectCache())
cache->postNotification(m_selection.start().deprecatedNode()->renderer(), AXObjectCache::AXSelectedTextChanged, false);
}
// if zoom feature is enabled, insertion point changes should update the zoom
if (!UAZoomEnabled() || !m_selection.isCaret())
......
......@@ -897,8 +897,10 @@ void HTMLInputElement::setChecked(bool nowChecked, TextFieldEventBehavior eventB
// Ideally we'd do this from the render tree (matching
// RenderTextView), but it's not possible to do it at the moment
// because of the way the code is structured.
if (renderer() && AXObjectCache::accessibilityEnabled())
renderer()->document()->axObjectCache()->checkedStateChanged(this);
if (renderer()) {
if (AXObjectCache* cache = renderer()->document()->existingAXObjectCache())
cache->checkedStateChanged(this);
}
// Only send a change event for items in the document (avoid firing during
// parsing) and don't send a change event for a radio button that's getting
......
......@@ -380,8 +380,10 @@ void HTMLSelectElement::optionElementChildrenChanged()
setRecalcListItems();
setNeedsValidityCheck();
if (AXObjectCache::accessibilityEnabled() && renderer())
renderer()->document()->axObjectCache()->childrenChanged(this);
if (renderer()) {
if (AXObjectCache* cache = renderer()->document()->existingAXObjectCache())
cache->childrenChanged(this);
}
}
void HTMLSelectElement::accessKeyAction(bool sendMouseEvents)
......@@ -722,8 +724,10 @@ void HTMLSelectElement::setRecalcListItems()
if (!inDocument())
invalidateSelectedItems();
if (AXObjectCache::accessibilityEnabled() && renderer())
renderer()->document()->axObjectCache()->childrenChanged(this);
if (renderer()) {
if (AXObjectCache* cache = renderer()->document()->existingAXObjectCache())
cache->childrenChanged(this);
}
}
void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const
......
......@@ -534,9 +534,10 @@ void HTMLTextFormControlElement::setInnerTextValue(const String& value)
bool textIsChanged = value != innerTextValue();
if (textIsChanged || !innerTextElement()->hasChildNodes()) {
if (textIsChanged && document() && renderer() && AXObjectCache::accessibilityEnabled())
document()->axObjectCache()->postNotification(this, AXObjectCache::AXValueChanged, false);
if (textIsChanged && document() && renderer()) {
if (AXObjectCache* cache = document()->existingAXObjectCache())
cache->postNotification(this, AXObjectCache::AXValueChanged, false);
}
innerTextElement()->setInnerText(value, ASSERT_NO_EXCEPTION);
if (value.endsWith('\n') || value.endsWith('\r'))
......
......@@ -1013,8 +1013,8 @@ void InputType::applyStep(int count, AnyStepHandling anyStepHandling, TextFieldE
setValueAsDecimal(newValue, eventBehavior, ec);
if (AXObjectCache::accessibilityEnabled())
element()->document()->axObjectCache()->postNotification(element(), AXObjectCache::AXValueChanged, true);
if (AXObjectCache* cache = element()->document()->existingAXObjectCache())
cache->postNotification(element(), AXObjectCache::AXValueChanged, true);
}
bool InputType::getAllowedValueStep(Decimal* step) const
......
......@@ -246,8 +246,8 @@ void RangeInputType::handleKeydownEvent(KeyboardEvent* event)
TextFieldEventBehavior eventBehavior = DispatchChangeEvent;
setValueAsDecimal(newValue, eventBehavior, IGNORE_EXCEPTION);
if (AXObjectCache::accessibilityEnabled())
element()->document()->axObjectCache()->postNotification(element(), AXObjectCache::AXValueChanged, true);
if (AXObjectCache* cache = element()->document()->existingAXObjectCache())
cache->postNotification(element(), AXObjectCache::AXValueChanged, true);
element()->dispatchFormControlChangeEvent();
}
......
......@@ -1120,9 +1120,9 @@ void FrameLoader::prepareForLoadStart()
m_client->dispatchDidStartProvisionalLoad();
// Notify accessibility.
if (AXObjectCache::accessibilityEnabled()) {
if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache()) {
AXObjectCache::AXLoadingEvent loadingEvent = loadType() == FrameLoadTypeReload ? AXObjectCache::AXLoadingReloaded : AXObjectCache::AXLoadingStarted;
m_frame->document()->axObjectCache()->frameLoadingEventNotification(m_frame, loadingEvent);
cache->frameLoadingEventNotification(m_frame, loadingEvent);
}
}
......@@ -2209,8 +2209,8 @@ void FrameLoader::checkLoadCompleteForThisFrame()
}
// Notify accessibility.
if (AXObjectCache::accessibilityEnabled())
m_frame->document()->axObjectCache()->frameLoadingEventNotification(m_frame, loadingEvent);
if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache())
cache->frameLoadingEventNotification(m_frame, loadingEvent);
return;
}
......
......@@ -253,8 +253,8 @@ bool FocusController::setInitialFocus(FocusDirection direction, KeyboardEvent* e
// If focus is being set initially, accessibility needs to be informed that system focus has moved
// into the web area again, even if focus did not change within WebCore. PostNotification is called instead
// of handleFocusedUIElementChanged, because this will send the notification even if the element is the same.
if (AXObjectCache::accessibilityEnabled())
focusedOrMainFrame()->document()->axObjectCache()->postNotification(focusedOrMainFrame()->document(), AXObjectCache::AXFocusedUIElementChanged, true);
if (AXObjectCache* cache = focusedOrMainFrame()->document()->existingAXObjectCache())
cache->postNotification(focusedOrMainFrame()->document(), AXObjectCache::AXFocusedUIElementChanged, true);
return didAdvanceFocus;
}
......
......@@ -704,7 +704,7 @@ void Frame::disconnectOwnerElement()
{
if (m_ownerElement) {
if (Document* doc = document())
doc->clearAXObjectCache();
doc->topDocument()->clearAXObjectCache();
m_ownerElement->clearContentFrame();
if (m_page)
m_page->decrementSubframeCount();
......
......@@ -302,8 +302,8 @@ void FrameView::reset()
void FrameView::removeFromAXObjectCache()
{
if (AXObjectCache::accessibilityEnabled() && axObjectCache())
axObjectCache()->remove(this);
if (AXObjectCache* cache = axObjectCache())
cache->remove(this);
}
void FrameView::clearFrame()
......@@ -1305,8 +1305,8 @@ void FrameView::layout(bool allowSubtree)
m_layoutCount++;
#if PLATFORM(MAC) || PLATFORM(CHROMIUM)
if (AXObjectCache::accessibilityEnabled())
root->document()->axObjectCache()->postNotification(root, AXObjectCache::AXLayoutComplete, true);
if (AXObjectCache* cache = root->document()->existingAXObjectCache())
cache->postNotification(root, AXObjectCache::AXLayoutComplete, true);
#endif
#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(DRAGGABLE_REGION)
updateAnnotatedRegions();
......@@ -2504,8 +2504,8 @@ void FrameView::scrollToAnchor()
// Align to the top and to the closest side (this matches other browsers).
anchorNode->renderer()->scrollRectToVisible(rect, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
if (AXObjectCache::accessibilityEnabled())
m_frame->document()->axObjectCache()->handleScrolledToAnchor(anchorNode.get());
if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache())
cache->handleScrolledToAnchor(anchorNode.get());
// scrollRectToVisible can call into setScrollPosition(), which resets m_maintainScrollPositionAnchor.
m_maintainScrollPositionAnchor = anchorNode;
......@@ -3972,8 +3972,8 @@ void FrameView::notifyWidgetsInAllFrames(WidgetNotification notification)
AXObjectCache* FrameView::axObjectCache() const
{
if (frame() && frame()->document() && frame()->document()->axObjectCacheExists())