OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "config.h" |
| 6 |
| 7 #include "AXObjectCache.h" |
| 8 #include "Document.h" |
| 9 #include "Frame.h" |
| 10 #include "RefPtr.h" |
| 11 #undef LOG |
| 12 |
| 13 #include "webkit/glue/webaccessibilitymanager_impl.h" |
| 14 |
| 15 #include "webkit/glue/glue_accessibility_object.h" |
| 16 #include "webkit/glue/glue_util.h" |
| 17 #include "webkit/glue/webframe_impl.h" |
| 18 #include "webkit/glue/webview_impl.h" |
| 19 |
| 20 namespace webkit_glue { |
| 21 |
| 22 // struct WebAccessibilityManagerImpl::GlueAccessibilityObjectRoot |
| 23 struct WebAccessibilityManagerImpl::GlueAccessibilityObjectRoot { |
| 24 GlueAccessibilityObjectRoot() {} |
| 25 |
| 26 // Root of the WebKit AccessibilityObject tree. |
| 27 RefPtr<GlueAccessibilityObject> acc_obj_root_; |
| 28 }; |
| 29 |
| 30 /*static*/ |
| 31 WebAccessibilityManager* WebAccessibilityManager::Create() { |
| 32 return new WebAccessibilityManagerImpl(); |
| 33 } |
| 34 |
| 35 // class WebAccessibilityManagerImpl |
| 36 WebAccessibilityManagerImpl::WebAccessibilityManagerImpl() |
| 37 : root_(new GlueAccessibilityObjectRoot) { |
| 38 } |
| 39 |
| 40 bool WebAccessibilityManagerImpl::GetAccObjInfo(WebView* view, |
| 41 const WebAccessibility::InParams& in_params, |
| 42 WebAccessibility::OutParams* out_params) { |
| 43 if (!root_->acc_obj_root_ && !InitAccObjRoot(view)) { |
| 44 // Failure in retrieving or initializing the root. |
| 45 return false; |
| 46 } |
| 47 |
| 48 // Find GlueAccessibilityObject requested by [in_params.object_id]. |
| 49 IntToAccObjMap::iterator it = |
| 50 int_to_acc_obj_map_.find(in_params.object_id); |
| 51 if (it == int_to_acc_obj_map_.end() || !it->second) { |
| 52 // Map did not contain a valid instance of the data requested. |
| 53 return false; |
| 54 } |
| 55 RefPtr<GlueAccessibilityObject> active_acc_obj = it->second; |
| 56 |
| 57 // Function input parameters. |
| 58 int child_id = in_params.child_id; |
| 59 |
| 60 // Temp paramters for holding output information. |
| 61 RefPtr<GlueAccessibilityObject> out_acc_obj = NULL; |
| 62 WebCore::String out_string; |
| 63 |
| 64 switch (in_params.function_id) { |
| 65 case WebAccessibility::FUNCTION_DODEFAULTACTION : |
| 66 if (!active_acc_obj->DoDefaultAction(child_id)) |
| 67 return false; |
| 68 break; |
| 69 case WebAccessibility::FUNCTION_HITTEST : |
| 70 out_acc_obj = active_acc_obj->HitTest(in_params.input_long1, |
| 71 in_params.input_long2); |
| 72 if (!out_acc_obj.get()) |
| 73 return false; |
| 74 break; |
| 75 case WebAccessibility::FUNCTION_LOCATION : |
| 76 if (!active_acc_obj->Location(&out_params->output_long1, |
| 77 &out_params->output_long2, |
| 78 &out_params->output_long3, |
| 79 &out_params->output_long4, |
| 80 child_id)) { |
| 81 return false; |
| 82 } |
| 83 break; |
| 84 case WebAccessibility::FUNCTION_NAVIGATE : |
| 85 out_acc_obj = active_acc_obj->Navigate( |
| 86 static_cast<WebAccessibility::Direction>(in_params.input_long1), |
| 87 child_id); |
| 88 if (!out_acc_obj.get()) |
| 89 return false; |
| 90 break; |
| 91 case WebAccessibility::FUNCTION_GETCHILD : |
| 92 if (child_id == 0) { |
| 93 // If child requested is self, stay with the same accessibility object. |
| 94 out_params->object_id = in_params.object_id; |
| 95 out_acc_obj = active_acc_obj.get(); |
| 96 } else { |
| 97 out_acc_obj = active_acc_obj->GetChild(child_id); |
| 98 } |
| 99 |
| 100 if (!out_acc_obj.get()) |
| 101 return false; |
| 102 break; |
| 103 case WebAccessibility::FUNCTION_CHILDCOUNT : |
| 104 if (!active_acc_obj->ChildCount(&out_params->output_long1)) |
| 105 return false; |
| 106 break; |
| 107 case WebAccessibility::FUNCTION_DEFAULTACTION : |
| 108 if (!active_acc_obj->DefaultAction(child_id, &out_string)) |
| 109 return false; |
| 110 break; |
| 111 case WebAccessibility::FUNCTION_DESCRIPTION : |
| 112 if (!active_acc_obj->Description(child_id, &out_string)) |
| 113 return false; |
| 114 break; |
| 115 case WebAccessibility::FUNCTION_GETFOCUSEDCHILD : |
| 116 out_acc_obj = active_acc_obj->GetFocusedChild(); |
| 117 if (!out_acc_obj.get()) |
| 118 return false; |
| 119 break; |
| 120 case WebAccessibility::FUNCTION_HELPTEXT : |
| 121 if (!active_acc_obj->HelpText(child_id, &out_string)) |
| 122 return false; |
| 123 break; |
| 124 case WebAccessibility::FUNCTION_KEYBOARDSHORTCUT : |
| 125 if (!active_acc_obj->KeyboardShortcut(child_id, &out_string)) |
| 126 return false; |
| 127 break; |
| 128 case WebAccessibility::FUNCTION_NAME : |
| 129 if (!active_acc_obj->Name(child_id, &out_string)) |
| 130 return false; |
| 131 break; |
| 132 case WebAccessibility::FUNCTION_GETPARENT : |
| 133 out_acc_obj = active_acc_obj->GetParent(); |
| 134 if (!out_acc_obj.get()) |
| 135 return false; |
| 136 break; |
| 137 case WebAccessibility::FUNCTION_ROLE : |
| 138 if (!active_acc_obj->Role(child_id, &out_params->output_long1)) |
| 139 return false; |
| 140 break; |
| 141 case WebAccessibility::FUNCTION_STATE : |
| 142 if (!active_acc_obj->State(child_id, &out_params->output_long1)) |
| 143 return false; |
| 144 break; |
| 145 case WebAccessibility::FUNCTION_VALUE : |
| 146 if (!active_acc_obj->Value(child_id, &out_string)) |
| 147 return false; |
| 148 break; |
| 149 default: |
| 150 // Non-supported function id. |
| 151 return false; |
| 152 } |
| 153 |
| 154 // Output and hashmap assignments, as appropriate. |
| 155 if (!out_string.isEmpty()) |
| 156 out_params->output_string = StringToString16(out_string); |
| 157 |
| 158 if (out_acc_obj) { |
| 159 AccObjToIntMap::iterator it = acc_obj_to_int_map_.find(out_acc_obj.get()); |
| 160 |
| 161 if (it != acc_obj_to_int_map_.end()) { |
| 162 // Data already present in map, return previously assigned id. |
| 163 out_params->object_id = it->second; |
| 164 out_params->output_long1 = -1; |
| 165 } else { |
| 166 // Insert new GlueAccessibilityObject in hashmaps. |
| 167 int_to_acc_obj_map_[acc_obj_id_] = out_acc_obj.get(); |
| 168 acc_obj_to_int_map_[out_acc_obj.get()] = acc_obj_id_; |
| 169 out_params->object_id = acc_obj_id_++; |
| 170 out_params->output_long1 = -1; |
| 171 } |
| 172 } |
| 173 // TODO(klink): Handle simple objects returned. |
| 174 return true; |
| 175 } |
| 176 |
| 177 bool WebAccessibilityManagerImpl::InitAccObjRoot(WebView* view) { |
| 178 // Root id is always 0. |
| 179 acc_obj_id_ = 0; |
| 180 |
| 181 // Enable accessibility and retrieve Document. |
| 182 WebCore::AXObjectCache::enableAccessibility(); |
| 183 WebFrameImpl* main_frame_impl = |
| 184 static_cast<WebFrameImpl*>(view->GetMainFrame()); |
| 185 if (!main_frame_impl || !main_frame_impl->frame()) |
| 186 return false; |
| 187 |
| 188 WebCore::Document* doc = main_frame_impl->frame()->document(); |
| 189 |
| 190 if (!doc || !doc->renderer()) |
| 191 return false; |
| 192 |
| 193 if (!root_->acc_obj_root_) { |
| 194 // Either we've never had a wrapper for this frame's top-level Document, |
| 195 // the Document renderer was destroyed and its wrapper was detached, or |
| 196 // the previous Document is in the page cache, and the current document |
| 197 // needs to be wrapped. |
| 198 root_->acc_obj_root_ = GlueAccessibilityObject::CreateInstance(doc-> |
| 199 axObjectCache()->getOrCreate(doc->renderer())); |
| 200 } |
| 201 // Insert root in hashmaps. |
| 202 int_to_acc_obj_map_[acc_obj_id_] = root_->acc_obj_root_.get(); |
| 203 acc_obj_to_int_map_[root_->acc_obj_root_.get()] = acc_obj_id_++; |
| 204 |
| 205 return true; |
| 206 } |
| 207 |
| 208 bool WebAccessibilityManagerImpl::ClearAccObjMap(int acc_obj_id, |
| 209 bool clear_all) { |
| 210 if (clear_all) { |
| 211 // Clear maps and invalidate root. |
| 212 int_to_acc_obj_map_.clear(); |
| 213 acc_obj_to_int_map_.clear(); |
| 214 root_->acc_obj_root_ = 0; |
| 215 return true; |
| 216 } |
| 217 |
| 218 IntToAccObjMap::iterator it = int_to_acc_obj_map_.find(acc_obj_id); |
| 219 |
| 220 if (it == int_to_acc_obj_map_.end()) { |
| 221 // Element not found. |
| 222 return false; |
| 223 } |
| 224 |
| 225 if (it->second) { |
| 226 // Erase element from reverse hashmap. |
| 227 AccObjToIntMap::iterator it2 = acc_obj_to_int_map_.find(it->second); |
| 228 |
| 229 if (it2 != acc_obj_to_int_map_.end()) |
| 230 acc_obj_to_int_map_.erase(it2); |
| 231 } |
| 232 int_to_acc_obj_map_.erase(it); |
| 233 |
| 234 if (acc_obj_id == 0) { |
| 235 // Invalidate root. |
| 236 root_->acc_obj_root_ = 0; |
| 237 } |
| 238 return true; |
| 239 } |
| 240 |
| 241 }; // namespace webkit_glue |
OLD | NEW |