[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
cfleizach at apple.com
cfleizach at apple.com
Wed Dec 22 13:52:24 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit c6d72ecf63cc7d244d271db93c1dcc61409d8bef
Author: cfleizach at apple.com <cfleizach at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Tue Sep 28 17:59:32 2010 +0000
CrashTracer: 1,382 crashes in Safari at com.apple.WebCore: WebCore::VisiblePosition::canonicalPosition + 78
https://bugs.webkit.org/show_bug.cgi?id=45927
Reviewed by Beth Dakin.
WebCore:
AXTextMarkers store pointers to Nodes without any retain or reference. If a Node is deallocated and then
a client tries to use a text marker that references that node, it leads to this crash.
The AXObjectCache instance now keeps a HashSet of Node's being used. When a node becomes deallocated, it removes itself
from the HashSet. When creating a VisiblePosition from an AXTextMarker, the cache can then check if the node is valid
before proceeding.
Test: platform/mac/accessibility/crash-invalid-text-marker-node.html
* accessibility/AXObjectCache.cpp:
(WebCore::AXObjectCache::visiblePositionForTextMarkerData):
(WebCore::AXObjectCache::textMarkerDataForVisiblePosition):
Modify to check whether a node is valid before proceeeding.
* accessibility/AXObjectCache.h:
(WebCore::AXObjectCache::setNodeInUse):
(WebCore::AXObjectCache::removeNodeForUse):
(WebCore::AXObjectCache::isNodeInUse):
Methods for managing whether a node is in use by text markers.
* accessibility/mac/AccessibilityObjectWrapper.mm:
(textMarkerForVisiblePosition):
(-[AccessibilityObjectWrapper textMarkerForVisiblePosition:]):
(visiblePositionForTextMarker):
(-[AccessibilityObjectWrapper visiblePositionForTextMarker:]):
(visiblePositionForStartOfTextMarkerRange):
(visiblePositionForEndOfTextMarkerRange):
(-[AccessibilityObjectWrapper doAXAttributedStringForTextMarkerRange:]):
(textMarkerRangeFromVisiblePositions):
(-[AccessibilityObjectWrapper textMarkerRangeFromVisiblePositions:endPosition:]):
(-[AccessibilityObjectWrapper visiblePositionRangeForTextMarkerRange:]):
(-[AccessibilityObjectWrapper textMarkerRangeForSelection]):
(-[AccessibilityObjectWrapper accessibilityAttributeValue:]):
(-[AccessibilityObjectWrapper doAXAttributedStringForRange:]):
(-[AccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):
Change these calls so that the axObjectCache() can be passed in to create the visible position.
* dom/Document.cpp:
(WebCore::Document::axObjectCacheExists):
* dom/Document.h:
* dom/Node.cpp:
(WebCore::Node::~Node):
If accessibility is enabled, inform the axObjectCache() that this node is disappearing.
LayoutTests:
* platform/mac/accessibility/crash-invalid-text-marker-node-expected.txt: Added.
* platform/mac/accessibility/crash-invalid-text-marker-node.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@68541 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 128251b..15b7a94 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2010-09-28 Chris Fleizach <cfleizach at apple.com>
+
+ Reviewed by Beth Dakin.
+
+ CrashTracer: 1,382 crashes in Safari at com.apple.WebCore: WebCore::VisiblePosition::canonicalPosition + 78
+ https://bugs.webkit.org/show_bug.cgi?id=45927
+
+ * platform/mac/accessibility/crash-invalid-text-marker-node-expected.txt: Added.
+ * platform/mac/accessibility/crash-invalid-text-marker-node.html: Added.
+
2010-09-28 Ryosuke Niwa <rniwa at webkit.org>
Reviewed by Kent Tamura.
diff --git a/LayoutTests/platform/mac/accessibility/crash-invalid-text-marker-node-expected.txt b/LayoutTests/platform/mac/accessibility/crash-invalid-text-marker-node-expected.txt
new file mode 100644
index 0000000..f39f0cb
--- /dev/null
+++ b/LayoutTests/platform/mac/accessibility/crash-invalid-text-marker-node-expected.txt
@@ -0,0 +1,10 @@
+
+This protects against a crash when a text marker still holds a reference to a node that's been deallocated.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/mac/accessibility/crash-invalid-text-marker-node.html b/LayoutTests/platform/mac/accessibility/crash-invalid-text-marker-node.html
new file mode 100644
index 0000000..7af4075
--- /dev/null
+++ b/LayoutTests/platform/mac/accessibility/crash-invalid-text-marker-node.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../../fast/js/resources/js-test-style.css">
+<script>
+var successfullyParsed = false;
+</script>
+<script src="../../../fast/js/resources/js-test-pre.js"></script>
+</head>
+<body id="body">
+
+<iframe id="iframe" width=100 height=100></iframe>
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+
+ description("This protects against a crash when a text marker still holds a reference to a node that's been deallocated.");
+
+ // Add an element that a text marker can be retrieved from.
+ var contentDoc = document.getElementById("iframe").contentDocument;
+ contentDoc.body.innerHTML = "<h1 tabindex='0'>content</h1>";
+
+ // Tab to the element.
+ // Note: If the element has an "id" it won't get de-allocated in time, so .focus() can't be used.
+ eventSender.keyDown("\t");
+
+ // get a marker that will become invalid when the node disappears.
+ var axDiv = accessibilityController.focusedElement;
+ var textMarkerRange = axDiv.textMarkerRangeForElement(axDiv);
+ var invalidMarker = axDiv.startTextMarkerForTextMarkerRange(textMarkerRange);
+
+</script>
+
+<script>
+ // Write new content to cause all content to disappear.
+ contentDoc.body.innerHTML = "<h2>new content</h2>";
+</script>
+
+<script>
+ // Access the invalid marker (it should not crash).
+ document.getElementById("body").focus();
+ var body = accessibilityController.focusedElement;
+
+ body.accessibilityElementForTextMarker(invalidMarker);
+
+ successfullyParsed = true;
+</script>
+
+<script src="../../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index b2603b9..6d652bf 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,51 @@
+2010-09-28 Chris Fleizach <cfleizach at apple.com>
+
+ Reviewed by Beth Dakin.
+
+ CrashTracer: 1,382 crashes in Safari at com.apple.WebCore: WebCore::VisiblePosition::canonicalPosition + 78
+ https://bugs.webkit.org/show_bug.cgi?id=45927
+
+ AXTextMarkers store pointers to Nodes without any retain or reference. If a Node is deallocated and then
+ a client tries to use a text marker that references that node, it leads to this crash.
+
+ The AXObjectCache instance now keeps a HashSet of Node's being used. When a node becomes deallocated, it removes itself
+ from the HashSet. When creating a VisiblePosition from an AXTextMarker, the cache can then check if the node is valid
+ before proceeding.
+
+ Test: platform/mac/accessibility/crash-invalid-text-marker-node.html
+
+ * accessibility/AXObjectCache.cpp:
+ (WebCore::AXObjectCache::visiblePositionForTextMarkerData):
+ (WebCore::AXObjectCache::textMarkerDataForVisiblePosition):
+ Modify to check whether a node is valid before proceeeding.
+ * accessibility/AXObjectCache.h:
+ (WebCore::AXObjectCache::setNodeInUse):
+ (WebCore::AXObjectCache::removeNodeForUse):
+ (WebCore::AXObjectCache::isNodeInUse):
+ Methods for managing whether a node is in use by text markers.
+ * accessibility/mac/AccessibilityObjectWrapper.mm:
+ (textMarkerForVisiblePosition):
+ (-[AccessibilityObjectWrapper textMarkerForVisiblePosition:]):
+ (visiblePositionForTextMarker):
+ (-[AccessibilityObjectWrapper visiblePositionForTextMarker:]):
+ (visiblePositionForStartOfTextMarkerRange):
+ (visiblePositionForEndOfTextMarkerRange):
+ (-[AccessibilityObjectWrapper doAXAttributedStringForTextMarkerRange:]):
+ (textMarkerRangeFromVisiblePositions):
+ (-[AccessibilityObjectWrapper textMarkerRangeFromVisiblePositions:endPosition:]):
+ (-[AccessibilityObjectWrapper visiblePositionRangeForTextMarkerRange:]):
+ (-[AccessibilityObjectWrapper textMarkerRangeForSelection]):
+ (-[AccessibilityObjectWrapper accessibilityAttributeValue:]):
+ (-[AccessibilityObjectWrapper doAXAttributedStringForRange:]):
+ (-[AccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):
+ Change these calls so that the axObjectCache() can be passed in to create the visible position.
+ * dom/Document.cpp:
+ (WebCore::Document::axObjectCacheExists):
+ * dom/Document.h:
+ * dom/Node.cpp:
+ (WebCore::Node::~Node):
+ If accessibility is enabled, inform the axObjectCache() that this node is disappearing.
+
2010-09-28 Chris Rogers <crogers at google.com>
Reviewed by Kenneth Russell.
diff --git a/WebCore/accessibility/AXObjectCache.cpp b/WebCore/accessibility/AXObjectCache.cpp
index a58b324..30cce3a 100644
--- a/WebCore/accessibility/AXObjectCache.cpp
+++ b/WebCore/accessibility/AXObjectCache.cpp
@@ -505,9 +505,12 @@ void AXObjectCache::handleAriaRoleChanged(RenderObject* renderer)
static_cast<AccessibilityRenderObject*>(obj)->updateAccessibilityRole();
}
#endif
-
+
VisiblePosition AXObjectCache::visiblePositionForTextMarkerData(TextMarkerData& textMarkerData)
{
+ if (!isNodeInUse(textMarkerData.node))
+ return VisiblePosition();
+
VisiblePosition visiblePos = VisiblePosition(textMarkerData.node, textMarkerData.offset, textMarkerData.affinity);
Position deepPos = visiblePos.deepEquivalent();
if (deepPos.isNull())
@@ -559,7 +562,9 @@ void AXObjectCache::textMarkerDataForVisiblePosition(TextMarkerData& textMarkerD
textMarkerData.axID = obj.get()->axObjectID();
textMarkerData.node = domNode;
textMarkerData.offset = deepPos.deprecatedEditingOffset();
- textMarkerData.affinity = visiblePos.affinity();
+ textMarkerData.affinity = visiblePos.affinity();
+
+ cache->setNodeInUse(domNode);
}
} // namespace WebCore
diff --git a/WebCore/accessibility/AXObjectCache.h b/WebCore/accessibility/AXObjectCache.h
index 7189a35..2ee56ee 100644
--- a/WebCore/accessibility/AXObjectCache.h
+++ b/WebCore/accessibility/AXObjectCache.h
@@ -100,9 +100,14 @@ public:
AXID platformGenerateAXID() const;
AccessibilityObject* objectFromAXID(AXID id) const { return m_objects.get(id).get(); }
+ // This is a weak reference cache for knowing if Nodes used by TextMarkers are valid.
+ void setNodeInUse(Node* n) { m_textMarkerNodes.add(n); }
+ void removeNodeForUse(Node* n) { m_textMarkerNodes.remove(n); }
+ bool isNodeInUse(Node* n) { return m_textMarkerNodes.contains(n); }
+
// Text marker utilities.
- static void textMarkerDataForVisiblePosition(TextMarkerData&, const VisiblePosition&);
- static VisiblePosition visiblePositionForTextMarkerData(TextMarkerData&);
+ void textMarkerDataForVisiblePosition(TextMarkerData&, const VisiblePosition&);
+ VisiblePosition visiblePositionForTextMarkerData(TextMarkerData&);
enum AXNotification {
AXActiveDescendantChanged,
@@ -141,6 +146,7 @@ protected:
private:
HashMap<AXID, RefPtr<AccessibilityObject> > m_objects;
HashMap<RenderObject*, AXID> m_renderObjectMapping;
+ HashSet<Node*> m_textMarkerNodes;
static bool gAccessibilityEnabled;
static bool gAccessibilityEnhancedUserInterfaceEnabled;
diff --git a/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm b/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
index 2e7758e..cb983eb 100644
--- a/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
+++ b/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
@@ -230,35 +230,49 @@ typedef unsigned NSUInteger;
return NSAccessibilityUnignoredDescendant(widget->platformWidget());
}
-static WebCoreTextMarker* textMarkerForVisiblePosition(const VisiblePosition& visiblePos)
+static WebCoreTextMarker* textMarkerForVisiblePosition(AXObjectCache* cache, const VisiblePosition& visiblePos)
{
+ ASSERT(cache);
+
TextMarkerData textMarkerData;
- AXObjectCache::textMarkerDataForVisiblePosition(textMarkerData, visiblePos);
+ cache->textMarkerDataForVisiblePosition(textMarkerData, visiblePos);
if (!textMarkerData.axID)
return nil;
return [[WebCoreViewFactory sharedFactory] textMarkerWithBytes:&textMarkerData length:sizeof(textMarkerData)];
}
-static VisiblePosition visiblePositionForTextMarker(WebCoreTextMarker* textMarker)
+- (WebCoreTextMarker *)textMarkerForVisiblePosition:(const VisiblePosition &)visiblePos
+{
+ return textMarkerForVisiblePosition(m_object->axObjectCache(), visiblePos);
+}
+
+static VisiblePosition visiblePositionForTextMarker(AXObjectCache* cache, WebCoreTextMarker* textMarker)
{
+ ASSERT(cache);
+
if (!textMarker)
return VisiblePosition();
TextMarkerData textMarkerData;
if (![[WebCoreViewFactory sharedFactory] getBytes:&textMarkerData fromTextMarker:textMarker length:sizeof(textMarkerData)])
return VisiblePosition();
- return AXObjectCache::visiblePositionForTextMarkerData(textMarkerData);
+ return cache->visiblePositionForTextMarkerData(textMarkerData);
}
-static VisiblePosition visiblePositionForStartOfTextMarkerRange(WebCoreTextMarkerRange* textMarkerRange)
+- (VisiblePosition)visiblePositionForTextMarker:(WebCoreTextMarker *)textMarker
{
- return visiblePositionForTextMarker([[WebCoreViewFactory sharedFactory] startOfTextMarkerRange:textMarkerRange]);
+ return visiblePositionForTextMarker(m_object->axObjectCache(), textMarker);
}
-static VisiblePosition visiblePositionForEndOfTextMarkerRange(WebCoreTextMarkerRange* textMarkerRange)
+static VisiblePosition visiblePositionForStartOfTextMarkerRange(AXObjectCache *cache, WebCoreTextMarkerRange* textMarkerRange)
{
- return visiblePositionForTextMarker([[WebCoreViewFactory sharedFactory] endOfTextMarkerRange:textMarkerRange]);
+ return visiblePositionForTextMarker(cache, [[WebCoreViewFactory sharedFactory] startOfTextMarkerRange:textMarkerRange]);
+}
+
+static VisiblePosition visiblePositionForEndOfTextMarkerRange(AXObjectCache *cache, WebCoreTextMarkerRange* textMarkerRange)
+{
+ return visiblePositionForTextMarker(cache, [[WebCoreViewFactory sharedFactory] endOfTextMarkerRange:textMarkerRange]);
}
static WebCoreTextMarkerRange* textMarkerRangeFromMarkers(WebCoreTextMarker* textMarker1, WebCoreTextMarker* textMarker2)
@@ -528,11 +542,11 @@ static NSString* nsStringForReplacedNode(Node* replacedNode)
return nil;
// extract the start and end VisiblePosition
- VisiblePosition startVisiblePosition = visiblePositionForStartOfTextMarkerRange(textMarkerRange);
+ VisiblePosition startVisiblePosition = visiblePositionForStartOfTextMarkerRange(m_object->axObjectCache(), textMarkerRange);
if (startVisiblePosition.isNull())
return nil;
- VisiblePosition endVisiblePosition = visiblePositionForEndOfTextMarkerRange(textMarkerRange);
+ VisiblePosition endVisiblePosition = visiblePositionForEndOfTextMarkerRange(m_object->axObjectCache(), textMarkerRange);
if (endVisiblePosition.isNull())
return nil;
@@ -578,13 +592,18 @@ static NSString* nsStringForReplacedNode(Node* replacedNode)
return [attrString autorelease];
}
-static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePosition startPosition, VisiblePosition endPosition)
+static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(AXObjectCache *cache, VisiblePosition startPosition, VisiblePosition endPosition)
{
- WebCoreTextMarker* startTextMarker = textMarkerForVisiblePosition(startPosition);
- WebCoreTextMarker* endTextMarker = textMarkerForVisiblePosition(endPosition);
+ WebCoreTextMarker* startTextMarker = textMarkerForVisiblePosition(cache, startPosition);
+ WebCoreTextMarker* endTextMarker = textMarkerForVisiblePosition(cache, endPosition);
return textMarkerRangeFromMarkers(startTextMarker, endTextMarker);
}
+- (WebCoreTextMarkerRange *)textMarkerRangeFromVisiblePositions:(VisiblePosition)startPosition endPosition:(VisiblePosition)endPosition
+{
+ return textMarkerRangeFromVisiblePositions(m_object->axObjectCache(), startPosition, endPosition);
+}
+
- (NSArray*)accessibilityActionNames
{
if (![self updateObjectBackingStore])
@@ -990,7 +1009,8 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
{
if (!textMarkerRange)
return VisiblePositionRange();
- return VisiblePositionRange(visiblePositionForStartOfTextMarkerRange(textMarkerRange), visiblePositionForEndOfTextMarkerRange(textMarkerRange));
+ AXObjectCache* cache = m_object->axObjectCache();
+ return VisiblePositionRange(visiblePositionForStartOfTextMarkerRange(cache, textMarkerRange), visiblePositionForEndOfTextMarkerRange(cache, textMarkerRange));
}
- (NSArray*)renderWidgetChildren
@@ -1036,7 +1056,7 @@ static NSMutableArray* convertToNSArray(const AccessibilityObject::Accessibility
VisibleSelection selection = m_object->selection();
if (selection.isNone())
return nil;
- return textMarkerRangeFromVisiblePositions(selection.visibleStart(), selection.visibleEnd());
+ return [self textMarkerRangeFromVisiblePositions:selection.visibleStart() endPosition:selection.visibleEnd()];
}
- (NSValue*)position
@@ -1788,9 +1808,9 @@ static NSString* roleValueToNSString(AccessibilityRole value)
return nil;
if ([attributeName isEqualToString: @"AXStartTextMarker"])
- return textMarkerForVisiblePosition(startOfDocument(renderer->document()));
+ return [self textMarkerForVisiblePosition:startOfDocument(renderer->document())];
if ([attributeName isEqualToString: @"AXEndTextMarker"])
- return textMarkerForVisiblePosition(endOfDocument(renderer->document()));
+ return [self textMarkerForVisiblePosition:endOfDocument(renderer->document())];
if ([attributeName isEqualToString:NSAccessibilityBlockQuoteLevelAttribute])
return [NSNumber numberWithInt:blockquoteLevel(renderer)];
@@ -2254,7 +2274,7 @@ static RenderObject* rendererForView(NSView* view)
{
PlainTextRange textRange = PlainTextRange(range.location, range.length);
VisiblePositionRange visiblePosRange = m_object->visiblePositionRangeForRange(textRange);
- return [self doAXAttributedStringForTextMarkerRange:textMarkerRangeFromVisiblePositions(visiblePosRange.start, visiblePosRange.end)];
+ return [self doAXAttributedStringForTextMarkerRange:[self textMarkerRangeFromVisiblePositions:visiblePosRange.start endPosition:visiblePosRange.end]];
}
// The RTF representation of the text associated with this accessibility object that is
@@ -2316,7 +2336,7 @@ static RenderObject* rendererForView(NSView* view)
// dispatch
if ([attribute isEqualToString:@"AXUIElementForTextMarker"]) {
- VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
+ VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
AccessibilityObject* axObject = m_object->accessibilityObjectForPosition(visiblePos);
if (!axObject)
return nil;
@@ -2325,17 +2345,17 @@ static RenderObject* rendererForView(NSView* view)
if ([attribute isEqualToString:@"AXTextMarkerRangeForUIElement"]) {
VisiblePositionRange vpRange = uiElement.get()->visiblePositionRange();
- return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
}
if ([attribute isEqualToString:@"AXLineForTextMarker"]) {
- VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
+ VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
return [NSNumber numberWithUnsignedInt:m_object->lineForPosition(visiblePos)];
}
if ([attribute isEqualToString:@"AXTextMarkerRangeForLine"]) {
VisiblePositionRange vpRange = m_object->visiblePositionRangeForLine([number intValue]);
- return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
}
if ([attribute isEqualToString:@"AXStringForTextMarkerRange"]) {
@@ -2345,7 +2365,7 @@ static RenderObject* rendererForView(NSView* view)
if ([attribute isEqualToString:@"AXTextMarkerForPosition"]) {
IntPoint webCorePoint = IntPoint(point);
- return pointSet ? textMarkerForVisiblePosition(m_object->visiblePositionForPoint(webCorePoint)) : nil;
+ return pointSet ? [self textMarkerForVisiblePosition:m_object->visiblePositionForPoint(webCorePoint)] : nil;
}
if ([attribute isEqualToString:@"AXBoundsForTextMarkerRange"]) {
@@ -2384,102 +2404,102 @@ static RenderObject* rendererForView(NSView* view)
|| ![[WebCoreViewFactory sharedFactory] objectIsTextMarker:textMarker2])
return nil;
- VisiblePosition visiblePos1 = visiblePositionForTextMarker(textMarker1);
- VisiblePosition visiblePos2 = visiblePositionForTextMarker(textMarker2);
+ VisiblePosition visiblePos1 = [self visiblePositionForTextMarker:(textMarker1)];
+ VisiblePosition visiblePos2 = [self visiblePositionForTextMarker:(textMarker2)];
VisiblePositionRange vpRange = m_object->visiblePositionRangeForUnorderedPositions(visiblePos1, visiblePos2);
- return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
}
if ([attribute isEqualToString:@"AXNextTextMarkerForTextMarker"]) {
- VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
- return textMarkerForVisiblePosition(m_object->nextVisiblePosition(visiblePos));
+ VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
+ return [self textMarkerForVisiblePosition:m_object->nextVisiblePosition(visiblePos)];
}
if ([attribute isEqualToString:@"AXPreviousTextMarkerForTextMarker"]) {
- VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
- return textMarkerForVisiblePosition(m_object->previousVisiblePosition(visiblePos));
+ VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
+ return [self textMarkerForVisiblePosition:m_object->previousVisiblePosition(visiblePos)];
}
if ([attribute isEqualToString:@"AXLeftWordTextMarkerRangeForTextMarker"]) {
- VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
+ VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
VisiblePositionRange vpRange = m_object->positionOfLeftWord(visiblePos);
- return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
}
if ([attribute isEqualToString:@"AXRightWordTextMarkerRangeForTextMarker"]) {
- VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
+ VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
VisiblePositionRange vpRange = m_object->positionOfRightWord(visiblePos);
- return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
}
if ([attribute isEqualToString:@"AXLeftLineTextMarkerRangeForTextMarker"]) {
- VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
+ VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
VisiblePositionRange vpRange = m_object->leftLineVisiblePositionRange(visiblePos);
- return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
}
if ([attribute isEqualToString:@"AXRightLineTextMarkerRangeForTextMarker"]) {
- VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
+ VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
VisiblePositionRange vpRange = m_object->rightLineVisiblePositionRange(visiblePos);
- return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
}
if ([attribute isEqualToString:@"AXSentenceTextMarkerRangeForTextMarker"]) {
- VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
+ VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
VisiblePositionRange vpRange = m_object->sentenceForPosition(visiblePos);
- return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
}
if ([attribute isEqualToString:@"AXParagraphTextMarkerRangeForTextMarker"]) {
- VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
+ VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
VisiblePositionRange vpRange = m_object->paragraphForPosition(visiblePos);
- return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
}
if ([attribute isEqualToString:@"AXNextWordEndTextMarkerForTextMarker"]) {
- VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
- return textMarkerForVisiblePosition(m_object->nextWordEnd(visiblePos));
+ VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
+ return [self textMarkerForVisiblePosition:m_object->nextWordEnd(visiblePos)];
}
if ([attribute isEqualToString:@"AXPreviousWordStartTextMarkerForTextMarker"]) {
- VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
- return textMarkerForVisiblePosition(m_object->previousWordStart(visiblePos));
+ VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
+ return [self textMarkerForVisiblePosition:m_object->previousWordStart(visiblePos)];
}
if ([attribute isEqualToString:@"AXNextLineEndTextMarkerForTextMarker"]) {
- VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
- return textMarkerForVisiblePosition(m_object->nextLineEndPosition(visiblePos));
+ VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
+ return [self textMarkerForVisiblePosition:m_object->nextLineEndPosition(visiblePos)];
}
if ([attribute isEqualToString:@"AXPreviousLineStartTextMarkerForTextMarker"]) {
- VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
- return textMarkerForVisiblePosition(m_object->previousLineStartPosition(visiblePos));
+ VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
+ return [self textMarkerForVisiblePosition:m_object->previousLineStartPosition(visiblePos)];
}
if ([attribute isEqualToString:@"AXNextSentenceEndTextMarkerForTextMarker"]) {
- VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
- return textMarkerForVisiblePosition(m_object->nextSentenceEndPosition(visiblePos));
+ VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
+ return [self textMarkerForVisiblePosition:m_object->nextSentenceEndPosition(visiblePos)];
}
if ([attribute isEqualToString:@"AXPreviousSentenceStartTextMarkerForTextMarker"]) {
- VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
- return textMarkerForVisiblePosition(m_object->previousSentenceStartPosition(visiblePos));
+ VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
+ return [self textMarkerForVisiblePosition:m_object->previousSentenceStartPosition(visiblePos)];
}
if ([attribute isEqualToString:@"AXNextParagraphEndTextMarkerForTextMarker"]) {
- VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
- return textMarkerForVisiblePosition(m_object->nextParagraphEndPosition(visiblePos));
+ VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
+ return [self textMarkerForVisiblePosition:m_object->nextParagraphEndPosition(visiblePos)];
}
if ([attribute isEqualToString:@"AXPreviousParagraphStartTextMarkerForTextMarker"]) {
- VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
- return textMarkerForVisiblePosition(m_object->previousParagraphStartPosition(visiblePos));
+ VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
+ return [self textMarkerForVisiblePosition:m_object->previousParagraphStartPosition(visiblePos)];
}
if ([attribute isEqualToString:@"AXStyleTextMarkerRangeForTextMarker"]) {
- VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
+ VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
VisiblePositionRange vpRange = m_object->styleRangeForPosition(visiblePos);
- return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
+ return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
}
if ([attribute isEqualToString:@"AXLengthForTextMarkerRange"]) {
@@ -2493,12 +2513,12 @@ static RenderObject* rendererForView(NSView* view)
// Used only by DumpRenderTree (so far).
if ([attribute isEqualToString:@"AXStartTextMarkerForTextMarkerRange"]) {
VisiblePositionRange visiblePosRange = [self visiblePositionRangeForTextMarkerRange:textMarkerRange];
- return textMarkerForVisiblePosition(visiblePosRange.start);
+ return [self textMarkerForVisiblePosition:visiblePosRange.start];
}
if ([attribute isEqualToString:@"AXEndTextMarkerForTextMarkerRange"]) {
VisiblePositionRange visiblePosRange = [self visiblePositionRangeForTextMarkerRange:textMarkerRange];
- return textMarkerForVisiblePosition(visiblePosRange.end);
+ return [self textMarkerForVisiblePosition:visiblePosRange.end];
}
if (m_object->isDataTable()) {
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index 0bda797..9a923f4 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -1782,6 +1782,18 @@ void Document::clearAXObjectCache()
doc->clearAXObjectCache();
}
+bool Document::axObjectCacheExists() const
+{
+ if (m_axObjectCache)
+ return true;
+
+ Document* doc = topDocument();
+ if (doc != this)
+ return doc->axObjectCacheExists();
+
+ return false;
+}
+
AXObjectCache* Document::axObjectCache() const
{
// The only document that actually has a AXObjectCache is the top-level
diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h
index d5021af..fa14e3d 100644
--- a/WebCore/dom/Document.h
+++ b/WebCore/dom/Document.h
@@ -526,6 +526,7 @@ public:
void clearAXObjectCache();
AXObjectCache* axObjectCache() const;
+ bool axObjectCacheExists() const;
// to get visually ordered hebrew and arabic pages right
void setVisuallyOrdered();
diff --git a/WebCore/dom/Node.cpp b/WebCore/dom/Node.cpp
index 547fd04..53395a8 100644
--- a/WebCore/dom/Node.cpp
+++ b/WebCore/dom/Node.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "Node.h"
+#include "AXObjectCache.h"
#include "Attr.h"
#include "Attribute.h"
#include "CSSParser.h"
@@ -381,6 +382,9 @@ Node::~Node()
if (renderer())
detach();
+ if (AXObjectCache::accessibilityEnabled() && m_document && m_document->axObjectCacheExists())
+ m_document->axObjectCache()->removeNodeForUse(this);
+
if (m_previous)
m_previous->setNextSibling(0);
if (m_next)
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list