Index: webkit/glue/glue_accessibility.cc |
=================================================================== |
--- webkit/glue/glue_accessibility.cc (revision 0) |
+++ webkit/glue/glue_accessibility.cc (revision 0) |
@@ -0,0 +1,281 @@ |
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <comdef.h> |
+ |
+#include "config.h" |
+ |
+#pragma warning(push, 0) |
+#include "AccessibleDocument.h" |
+#include "AXObjectCache.h" |
+#include "Document.h" |
+#include "Frame.h" |
+#pragma warning(pop) |
+#undef LOG |
+ |
+#include "webkit/glue/glue_accessibility.h" |
+ |
+#include "chrome/browser/iaccessible_function_ids.h" |
+#include "webkit/glue/webframe_impl.h" |
+#include "webkit/glue/webview_impl.h" |
+ |
+// struct GlueAccessibility::GlueAccessibilityRoot |
+struct GlueAccessibility::GlueAccessibilityRoot { |
+ GlueAccessibilityRoot() {} |
+ |
+ // Root of the WebKit IAccessible tree. |
+ COMPtr<AccessibleDocument> accessibility_root_; |
+}; |
+ |
+// class GlueAccessibility |
+GlueAccessibility::GlueAccessibility() |
+ : root_(new GlueAccessibilityRoot) { |
+} |
+ |
+GlueAccessibility::~GlueAccessibility() { |
+ delete root_; |
+} |
+ |
+bool GlueAccessibility::GetAccessibilityInfo(WebView* view, |
+ const ViewMsg_Accessibility_In_Params& in_params, |
+ ViewHostMsg_Accessibility_Out_Params* out_params) { |
+ if (!root_->accessibility_root_ && !InitAccessibilityRoot(view)) { |
+ // Failure in retrieving the root. |
+ return false; |
+ } |
+ |
+ // Temporary storing for the currently active IAccessible. |
+ COMPtr<IAccessible> active_iaccessible; |
+ IntToIAccessibleMap::iterator it = |
+ int_to_iaccessible_map_.find(in_params.iaccessible_id); |
+ |
+ if (it == int_to_iaccessible_map_.end()) { |
+ // Map did not contain the data requested. |
+ return false; |
+ } |
+ |
+ active_iaccessible = it->second; |
+ |
+ if (!active_iaccessible) { |
+ // Requested IAccessible not found. Paranoia check. |
+ NOTREACHED(); |
+ return false; |
+ } |
+ |
+ // Input VARIANT, determined by the browser side to be of type VT_I4. |
+ VARIANT input_variant; |
+ input_variant.vt = VT_I4; |
+ input_variant.lVal = in_params.input_variant_lval; |
+ |
+ // Output variables, used locally to retrieve data. |
+ VARIANT output_variant; |
+ ::VariantInit(&output_variant); |
+ BSTR output_bstr; |
+ bool string_output = false; |
+ HRESULT hr = S_FALSE; |
+ |
+ switch (in_params.iaccessible_function_id) { |
+ case IACCESSIBLE_FUNC_ACCDODEFAULTACTION : |
+ hr = active_iaccessible->accDoDefaultAction(input_variant); |
+ break; |
+ case IACCESSIBLE_FUNC_ACCHITTEST : |
+ hr = active_iaccessible->accHitTest(in_params.input_long1, |
+ in_params.input_long2, |
+ &output_variant); |
+ break; |
+ case IACCESSIBLE_FUNC_ACCLOCATION : |
+ hr = active_iaccessible->accLocation(&out_params->output_long1, |
+ &out_params->output_long2, |
+ &out_params->output_long3, |
+ &out_params->output_long4, |
+ input_variant); |
+ break; |
+ case IACCESSIBLE_FUNC_ACCNAVIGATE : |
+ hr = active_iaccessible->accNavigate(in_params.input_long1, input_variant, |
+ &output_variant); |
+ break; |
+ case IACCESSIBLE_FUNC_GET_ACCCHILD : |
+ if (input_variant.lVal == CHILDID_SELF) { |
+ // If child requested is CHILDID_SELF, stay with the same IAccessible. |
+ out_params->iaccessible_id = in_params.iaccessible_id; |
+ hr = S_OK; |
+ break; |
+ } |
+ hr = active_iaccessible->get_accChild(input_variant, |
+ reinterpret_cast<IDispatch **>(&output_variant.pdispVal)); |
+ output_variant.vt = VT_DISPATCH; |
+ break; |
+ case IACCESSIBLE_FUNC_GET_ACCCHILDCOUNT : |
+ hr = active_iaccessible->get_accChildCount(&out_params->output_long1); |
+ break; |
+ case IACCESSIBLE_FUNC_GET_ACCDEFAULTACTION : |
+ hr = active_iaccessible->get_accDefaultAction(input_variant, |
+ &output_bstr); |
+ string_output = true; |
+ break; |
+ case IACCESSIBLE_FUNC_GET_ACCDESCRIPTION : |
+ hr = active_iaccessible->get_accDescription(input_variant, &output_bstr); |
+ string_output = true; |
+ break; |
+ case IACCESSIBLE_FUNC_GET_ACCFOCUS : |
+ hr = active_iaccessible->get_accFocus(&output_variant); |
+ break; |
+ case IACCESSIBLE_FUNC_GET_ACCHELP : |
+ hr = active_iaccessible->get_accHelp(input_variant, &output_bstr); |
+ string_output = true; |
+ break; |
+ case IACCESSIBLE_FUNC_GET_ACCKEYBOARDSHORTCUT : |
+ hr = active_iaccessible->get_accKeyboardShortcut(input_variant, |
+ &output_bstr); |
+ string_output = true; |
+ break; |
+ case IACCESSIBLE_FUNC_GET_ACCNAME : |
+ hr = active_iaccessible->get_accName(input_variant, &output_bstr); |
+ string_output = true; |
+ break; |
+ case IACCESSIBLE_FUNC_GET_ACCPARENT : |
+ hr = active_iaccessible->get_accParent( |
+ reinterpret_cast<IDispatch **>(&output_variant.pdispVal)); |
+ output_variant.vt = VT_DISPATCH; |
+ break; |
+ case IACCESSIBLE_FUNC_GET_ACCROLE : |
+ hr = active_iaccessible->get_accRole(input_variant, &output_variant); |
+ break; |
+ case IACCESSIBLE_FUNC_GET_ACCSTATE : |
+ hr = active_iaccessible->get_accState(input_variant, &output_variant); |
+ break; |
+ case IACCESSIBLE_FUNC_GET_ACCVALUE : |
+ hr = active_iaccessible->get_accValue(input_variant, &output_bstr); |
+ string_output = true; |
+ break; |
+ default: |
+ // Memory cleanup. |
+ ::VariantClear(&input_variant); |
+ ::VariantClear(&output_variant); |
+ |
+ // Non-supported function id. |
+ return false; |
+ } |
+ |
+ // Return code handling. |
+ if (hr == S_OK) { |
+ out_params->return_code = true; |
+ |
+ // All is ok, assign output string if needed. |
+ if (string_output) { |
+ out_params->output_string = _bstr_t(output_bstr); |
+ ::SysFreeString(output_bstr); |
+ } |
+ |
+ } else if (hr == S_FALSE) { |
+ out_params->return_code = false; |
+ } else { |
+ // Memory cleanup. |
+ ::VariantClear(&input_variant); |
+ ::VariantClear(&output_variant); |
+ |
+ // Generate a generic failure on the browser side. Input validation is the |
+ // responsibility of the browser side, as is correctly handling calls to |
+ // non-supported functions appropriately. |
+ return false; |
+ } |
+ |
+ // Output and hashmap assignments, as appropriate. |
+ if (output_variant.vt == VT_DISPATCH && output_variant.pdispVal) { |
+ IAccessibleToIntMap::iterator it = |
+ iaccessible_to_int_map_.find( |
+ reinterpret_cast<IAccessible *>(output_variant.pdispVal)); |
+ |
+ if (it != iaccessible_to_int_map_.end()) { |
+ // Data already present in map, return previously assigned id. |
+ out_params->iaccessible_id = it->second; |
+ out_params->output_long1 = -1; |
+ } else { |
+ // Insert new IAccessible in hashmaps. |
+ int_to_iaccessible_map_[iaccessible_id_] = |
+ reinterpret_cast<IAccessible *>(output_variant.pdispVal); |
+ iaccessible_to_int_map_[ |
+ reinterpret_cast<IAccessible *>(output_variant.pdispVal)] = |
+ iaccessible_id_; |
+ out_params->iaccessible_id = iaccessible_id_++; |
+ out_params->output_long1 = -1; |
+ } |
+ } else if (output_variant.vt == VT_I4) { |
+ out_params->output_long1 = output_variant.lVal; |
+ } |
+ |
+ // Memory cleanup. |
+ ::VariantClear(&input_variant); |
+ ::VariantClear(&output_variant); |
+ |
+ return true; |
+} |
+ |
+bool GlueAccessibility::InitAccessibilityRoot(WebView* view) { |
+ WebCore::AXObjectCache::enableAccessibility(); |
+ iaccessible_id_ = 0; |
+ |
+ WebFrame* main_frame = view->GetMainFrame(); |
+ |
+ if (!main_frame) |
+ return false; |
+ |
+ WebFrameImpl* main_frame_impl = static_cast<WebFrameImpl*>(main_frame); |
+ WebCore::Frame* frame = main_frame_impl->frame(); |
+ |
+ WebCore::Document* currentDocument = frame->document(); |
+ if (!currentDocument) { |
+ root_->accessibility_root_ = 0; |
+ return false; |
+ } else if (!root_->accessibility_root_ || |
+ root_->accessibility_root_->document() != currentDocument) { |
+ // Either we've never had a wrapper for this frame's top-level Document, |
+ // the Document renderer was destroyed and its wrapper was detached, or |
+ // the previous Document is in the page cache, and the current document |
+ // needs to be wrapped. |
+ root_->accessibility_root_ = new AccessibleDocument(currentDocument); |
+ } |
+ // Insert root in hashmaps. |
+ int_to_iaccessible_map_[iaccessible_id_] = root_->accessibility_root_.get(); |
+ iaccessible_to_int_map_[root_->accessibility_root_.get()] = iaccessible_id_++; |
+ |
+ return true; |
+} |
+ |
+bool GlueAccessibility::ClearIAccessibleMap(int iaccessible_id, |
+ bool clear_all) { |
+ if (clear_all) { |
+ // Clear maps and invalidate root. |
+ int_to_iaccessible_map_.clear(); |
+ iaccessible_to_int_map_.clear(); |
+ root_->accessibility_root_ = 0; |
+ return true; |
+ } |
+ |
+ IntToIAccessibleMap::iterator it = |
+ int_to_iaccessible_map_.find(iaccessible_id); |
+ |
+ if (it == int_to_iaccessible_map_.end()) { |
+ // Element not found. |
+ return false; |
+ } else { |
+ if (it->second) { |
+ // Erase element from reverse hashmap. |
+ IAccessibleToIntMap::iterator it2 = |
+ iaccessible_to_int_map_.find(it->second); |
+ |
+ DCHECK(it2 != iaccessible_to_int_map_.end()); |
+ iaccessible_to_int_map_.erase(it2); |
+ } |
+ |
+ int_to_iaccessible_map_.erase(it); |
+ |
+ if (iaccessible_id == 0) { |
+ // Invalidate root. |
+ root_->accessibility_root_ = 0; |
+ } |
+ } |
+ |
+ return true; |
+} |
Property changes on: webkit\glue\glue_accessibility.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |