Add the ability to search the AccessibilityObject cache
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 29 Jul 2011 17:37:31 +0000 (17:37 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 29 Jul 2011 17:37:31 +0000 (17:37 +0000)
https://bugs.webkit.org/show_bug.cgi?id=64994

To support searching the AccessibilityObject cache, we first need to
implement a minimal set of functions that will allow AccessibilityObjects
to be identified when searching using common search criteria. The additional
functions below complement the existing identification functionality already
available and together provide a basic working set to build search on top of.
Additionally, the blockquoteLevel function has been moved into the AccessibilityObject
class to make it available to all platforms.

Patch by Samuel White <samuel_white@apple.com> on 2011-07-29
Reviewed by Chris Fleizach.

New tests will be included in the following patch that will also implement
basic search functionality.

* accessibility/AccessibilityObject.cpp:
(WebCore::AccessibilityObject::isBlockquote):
(WebCore::AccessibilityObject::isLandmark):
(WebCore::AccessibilityObject::hasMisspelling):
(WebCore::AccessibilityObject::blockquoteLevel):
* accessibility/AccessibilityObject.h:
(WebCore::AccessibilityObject::isUnvisited):
(WebCore::AccessibilityObject::hasBoldFont):
(WebCore::AccessibilityObject::hasItalicFont):
(WebCore::AccessibilityObject::hasPlainText):
(WebCore::AccessibilityObject::hasSameFont):
(WebCore::AccessibilityObject::hasSameFontColor):
(WebCore::AccessibilityObject::hasSameStyle):
(WebCore::AccessibilityObject::hasStaticText):
(WebCore::AccessibilityObject::hasUnderline):
(WebCore::AccessibilityObject::tableLevel):
* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::isUnvisited):
(WebCore::AccessibilityRenderObject::hasBoldFont):
(WebCore::AccessibilityRenderObject::hasItalicFont):
(WebCore::AccessibilityRenderObject::hasPlainText):
(WebCore::AccessibilityRenderObject::hasSameFont):
(WebCore::AccessibilityRenderObject::hasSameFontColor):
(WebCore::AccessibilityRenderObject::hasSameStyle):
(WebCore::AccessibilityRenderObject::hasUnderline):
* accessibility/AccessibilityRenderObject.h:
* accessibility/AccessibilityTable.cpp:
(WebCore::AccessibilityTable::tableLevel):
* accessibility/AccessibilityTable.h:
* accessibility/mac/AccessibilityObjectWrapper.mm:
(AXAttributeStringSetBlockquoteLevel):
(-[AccessibilityObjectWrapper accessibilityAttributeValue:]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@92000 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/accessibility/AccessibilityObject.cpp
Source/WebCore/accessibility/AccessibilityObject.h
Source/WebCore/accessibility/AccessibilityRenderObject.cpp
Source/WebCore/accessibility/AccessibilityRenderObject.h
Source/WebCore/accessibility/AccessibilityTable.cpp
Source/WebCore/accessibility/AccessibilityTable.h
Source/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm

index a897a92..1833837 100644 (file)
@@ -1,3 +1,54 @@
+2011-07-29  Samuel White  <samuel_white@apple.com>
+
+        Add the ability to search the AccessibilityObject cache
+        https://bugs.webkit.org/show_bug.cgi?id=64994
+        
+        To support searching the AccessibilityObject cache, we first need to
+        implement a minimal set of functions that will allow AccessibilityObjects
+        to be identified when searching using common search criteria. The additional
+        functions below complement the existing identification functionality already
+        available and together provide a basic working set to build search on top of.
+        Additionally, the blockquoteLevel function has been moved into the AccessibilityObject
+        class to make it available to all platforms.
+
+        Reviewed by Chris Fleizach.
+
+        New tests will be included in the following patch that will also implement
+        basic search functionality.
+
+        * accessibility/AccessibilityObject.cpp:
+        (WebCore::AccessibilityObject::isBlockquote):
+        (WebCore::AccessibilityObject::isLandmark):
+        (WebCore::AccessibilityObject::hasMisspelling):
+        (WebCore::AccessibilityObject::blockquoteLevel):
+        * accessibility/AccessibilityObject.h:
+        (WebCore::AccessibilityObject::isUnvisited):
+        (WebCore::AccessibilityObject::hasBoldFont):
+        (WebCore::AccessibilityObject::hasItalicFont):
+        (WebCore::AccessibilityObject::hasPlainText):
+        (WebCore::AccessibilityObject::hasSameFont):
+        (WebCore::AccessibilityObject::hasSameFontColor):
+        (WebCore::AccessibilityObject::hasSameStyle):
+        (WebCore::AccessibilityObject::hasStaticText):
+        (WebCore::AccessibilityObject::hasUnderline):
+        (WebCore::AccessibilityObject::tableLevel):
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::isUnvisited):
+        (WebCore::AccessibilityRenderObject::hasBoldFont):
+        (WebCore::AccessibilityRenderObject::hasItalicFont):
+        (WebCore::AccessibilityRenderObject::hasPlainText):
+        (WebCore::AccessibilityRenderObject::hasSameFont):
+        (WebCore::AccessibilityRenderObject::hasSameFontColor):
+        (WebCore::AccessibilityRenderObject::hasSameStyle):
+        (WebCore::AccessibilityRenderObject::hasUnderline):
+        * accessibility/AccessibilityRenderObject.h:
+        * accessibility/AccessibilityTable.cpp:
+        (WebCore::AccessibilityTable::tableLevel):
+        * accessibility/AccessibilityTable.h:
+        * accessibility/mac/AccessibilityObjectWrapper.mm:
+        (AXAttributeStringSetBlockquoteLevel):
+        (-[AccessibilityObjectWrapper accessibilityAttributeValue:]):
+
 2011-07-29  Zeng Huiqing  <huiqing.zeng@intel.com>
 
         Avoid calling animation timer updates while the page is loading
index 6b370bc..af4430d 100644 (file)
@@ -49,6 +49,7 @@
 #include "RenderTheme.h"
 #include "RenderView.h"
 #include "RenderWidget.h"
+#include "TextCheckerClient.h"
 #include "TextIterator.h"
 #include "htmlediting.h"
 #include "visible_units.h"
@@ -85,6 +86,76 @@ void AccessibilityObject::detach()
 #endif    
 }
 
+bool AccessibilityObject::isBlockquote() const
+{
+    return node() && node()->hasTagName(blockquoteTag);
+}
+
+bool AccessibilityObject::isLandmark() const
+{
+    AccessibilityRole role = roleValue();
+    
+    return role == LandmarkApplicationRole
+        || role == LandmarkBannerRole
+        || role == LandmarkComplementaryRole
+        || role == LandmarkContentInfoRole
+        || role == LandmarkMainRole
+        || role == LandmarkNavigationRole
+        || role == LandmarkSearchRole;
+}
+
+bool AccessibilityObject::hasMisspelling() const
+{
+    if (!node())
+        return false;
+    
+    Document* document = node()->document();
+    if (!document)
+        return false;
+    
+    Frame* frame = document->frame();
+    if (!frame)
+        return false;
+    
+    Editor* editor = frame->editor();
+    if (!editor)
+        return false;
+    
+    TextCheckerClient* textChecker = editor->textChecker();
+    if (!textChecker)
+        return false;
+    
+    const UChar* chars = stringValue().characters();
+    int charsLength = stringValue().length();
+    bool isMisspelled = false;
+    
+#if USE(UNIFIED_TEXT_CHECKING)
+    Vector<TextCheckingResult> results;
+    textChecker->checkTextOfParagraph(chars, charsLength, TextCheckingTypeSpelling, results);
+    if (!results.isEmpty())
+        isMisspelled = true;
+#else
+    int misspellingLength = 0;
+    int misspellingLocation = -1;
+    textChecker->checkSpellingOfString(chars, charsLength, &misspellingLocation, &misspellingLength);
+    if (misspellingLength || misspellingLocation != -1)
+        isMisspelled = true;
+#endif
+    
+    return isMisspelled;
+}
+
+int AccessibilityObject::blockquoteLevel() const
+{
+    int level = 0;
+    for (Node* elementNode = node(); elementNode; elementNode = elementNode->parentNode()) {
+        if (elementNode->hasTagName(blockquoteTag))
+            ++level;
+    }
+    
+    return level;
+}
+
 AccessibilityObject* AccessibilityObject::parentObjectUnignored() const
 {
     AccessibilityObject* parent;
index bf66e52..014b195 100644 (file)
@@ -313,6 +313,8 @@ public:
     bool isListItem() const { return roleValue() == ListItemRole; }
     bool isCheckboxOrRadio() const { return isCheckbox() || isRadioButton(); }
     bool isScrollView() const { return roleValue() == ScrollAreaRole; }
+    bool isBlockquote() const;
+    bool isLandmark() const;
     
     virtual bool isChecked() const { return false; }
     virtual bool isEnabled() const { return false; }
@@ -325,6 +327,7 @@ public:
     virtual bool isOffScreen() const { return false; }
     virtual bool isPressed() const { return false; }
     virtual bool isReadOnly() const { return false; }
+    virtual bool isUnvisited() const { return false; }
     virtual bool isVisited() const { return false; }
     virtual bool isRequired() const { return false; }
     virtual bool isLinked() const { return false; }
@@ -333,6 +336,16 @@ public:
     virtual bool isCollapsed() const { return false; }
     virtual void setIsExpanded(bool) { }
 
+    virtual bool hasBoldFont() const { return false; }
+    virtual bool hasItalicFont() const { return false; }
+    bool hasMisspelling() const;
+    virtual bool hasPlainText() const { return false; }
+    virtual bool hasSameFont(RenderObject*) const { return false; }
+    virtual bool hasSameFontColor(RenderObject*) const { return false; }
+    virtual bool hasSameStyle(RenderObject*) const { return false; }
+    bool hasStaticText() const { return roleValue() == StaticTextRole; }
+    virtual bool hasUnderline() const { return false; }
+
     virtual bool canSetFocusAttribute() const { return false; }
     virtual bool canSetTextRangeAttributes() const { return false; }
     virtual bool canSetValueAttribute() const { return false; }
@@ -348,7 +361,9 @@ public:
     virtual RenderObject* renderer() const { return 0; }
     virtual bool accessibilityIsIgnored() const  { return true; }
 
+    int blockquoteLevel() const;
     virtual int headingLevel() const { return 0; }
+    virtual int tableLevel() const { return 0; }
     virtual AccessibilityButtonState checkboxOrRadioValue() const;
     virtual String valueDescription() const { return String(); }
     virtual float valueForRange() const { return 0.0f; }
index 12c167d..3b710c0 100644 (file)
@@ -2081,6 +2081,12 @@ KURL AccessibilityRenderObject::url() const
     return KURL();
 }
 
+bool AccessibilityRenderObject::isUnvisited() const
+{
+    // FIXME: Is it a privacy violation to expose unvisited information to accessibility APIs?
+    return m_renderer->style()->isLink() && m_renderer->style()->insideLink() == InsideUnvisitedLink;
+}
+
 bool AccessibilityRenderObject::isVisited() const
 {
     // FIXME: Is it a privacy violation to expose visited information to accessibility APIs?
@@ -3665,6 +3671,66 @@ bool AccessibilityRenderObject::isLinked() const
     return !static_cast<HTMLAnchorElement*>(anchor)->href().isEmpty();
 }
 
+bool AccessibilityRenderObject::hasBoldFont() const
+{
+    if (!m_renderer)
+        return false;
+    
+    return m_renderer->style()->fontDescription().weight() >= FontWeightBold;
+}
+
+bool AccessibilityRenderObject::hasItalicFont() const
+{
+    if (!m_renderer)
+        return false;
+    
+    return m_renderer->style()->fontDescription().italic() == FontItalicOn;
+}
+
+bool AccessibilityRenderObject::hasPlainText() const
+{
+    if (!m_renderer)
+        return false;
+    
+    RenderStyle* style = m_renderer->style();
+    
+    return style->fontDescription().weight() == FontWeightNormal
+        && style->fontDescription().italic() == FontItalicOff
+        && style->textDecorationsInEffect() == TDNONE;
+}
+
+bool AccessibilityRenderObject::hasSameFont(RenderObject* renderer) const
+{
+    if (!m_renderer || !renderer)
+        return false;
+    
+    return m_renderer->style()->fontDescription().family() == renderer->style()->fontDescription().family();
+}
+
+bool AccessibilityRenderObject::hasSameFontColor(RenderObject* renderer) const
+{
+    if (!m_renderer || !renderer)
+        return false;
+    
+    return m_renderer->style()->visitedDependentColor(CSSPropertyColor) == renderer->style()->visitedDependentColor(CSSPropertyColor);
+}
+
+bool AccessibilityRenderObject::hasSameStyle(RenderObject* renderer) const
+{
+    if (!m_renderer || !renderer)
+        return false;
+    
+    return m_renderer->style() == renderer->style();
+}
+
+bool AccessibilityRenderObject::hasUnderline() const
+{
+    if (!m_renderer)
+        return false;
+    
+    return m_renderer->style()->textDecorationsInEffect() & UNDERLINE;
+}
+
 String AccessibilityRenderObject::nameForMSAA() const
 {
     if (m_renderer && m_renderer->isText())
index 361deee..d0b67fa 100644 (file)
@@ -98,9 +98,17 @@ public:
     virtual bool isOffScreen() const;
     virtual bool isPressed() const;
     virtual bool isReadOnly() const;
+    virtual bool isUnvisited() const;
     virtual bool isVisited() const;        
     virtual bool isRequired() const;
     virtual bool isLinked() const;
+    virtual bool hasBoldFont() const;
+    virtual bool hasItalicFont() const;
+    virtual bool hasPlainText() const;
+    virtual bool hasSameFont(RenderObject*) const;
+    virtual bool hasSameFontColor(RenderObject*) const;
+    virtual bool hasSameStyle(RenderObject*) const;
+    virtual bool hasUnderline() const;
 
     virtual bool canSetFocusAttribute() const;
     virtual bool canSetTextRangeAttributes() const;
index aa51f9e..e9464be 100644 (file)
@@ -446,7 +446,18 @@ unsigned AccessibilityTable::rowCount()
     
     return m_rows.size();
 }
+
+int AccessibilityTable::tableLevel() const
+{
+    int level = 0;
+    for (AccessibilityObject* obj = parentObject(); obj; obj = obj->parentObject()) {
+        if (obj->isAccessibilityTable())
+            ++level;
+    }
     
+    return level;
+}
+
 AccessibilityTableCell* AccessibilityTable::cellForColumnAndRow(unsigned column, unsigned row)
 {
     if (!m_renderer || !m_renderer->isTable())
index be041be..b2ff519 100644 (file)
@@ -68,6 +68,7 @@ public:
     virtual bool supportsSelectedRows() { return false; }
     unsigned columnCount();
     unsigned rowCount();
+    virtual int tableLevel() const;
     
     virtual String title() const;
     
index 8bcfcb3..94ac5f0 100644 (file)
@@ -451,23 +451,10 @@ static void AXAttributeStringSetStyle(NSMutableAttributedString* attrString, Ren
     }
 }
 
-static int blockquoteLevel(RenderObject* renderer)
-{
-    if (!renderer)
-        return 0;
-    
-    int result = 0;
-    for (Node* node = renderer->node(); node; node = node->parentNode()) {
-        if (node->hasTagName(blockquoteTag))
-            result += 1;
-    }
-    
-    return result;
-}
-
 static void AXAttributeStringSetBlockquoteLevel(NSMutableAttributedString* attrString, RenderObject* renderer, NSRange range)
 {
-    int quoteLevel = blockquoteLevel(renderer);
+    AccessibilityObject* obj = renderer->document()->axObjectCache()->getOrCreate(renderer);
+    int quoteLevel = obj->blockquoteLevel();
     
     if (quoteLevel)
         [attrString addAttribute:NSAccessibilityBlockQuoteLevelAttribute value:[NSNumber numberWithInt:quoteLevel] range:range];
@@ -1986,7 +1973,7 @@ static NSString* roleValueToNSString(AccessibilityRole value)
             return [self textMarkerForVisiblePosition:endOfDocument(renderer->document())];
 
         if ([attributeName isEqualToString:NSAccessibilityBlockQuoteLevelAttribute])
-            return [NSNumber numberWithInt:blockquoteLevel(renderer)];
+            return [NSNumber numberWithInt:m_object->blockquoteLevel()];
     } else {
         if ([attributeName isEqualToString:NSAccessibilityBlockQuoteLevelAttribute]) {
             AccessibilityObject* parent = m_object->parentObjectUnignored();