📄 accessiblebase.cpp
字号:
static String accessKeyModifiers; if (accessKeyModifiers.isNull()) { unsigned modifiers = EventHandler::accessKeyModifiers(); // Follow the same order as Mozilla MSAA implementation: // Ctrl+Alt+Shift+Meta+key. MSDN states that keyboard shortcut strings // should not be localized and defines the separator as "+". if (modifiers & PlatformKeyboardEvent::CtrlKey) accessKeyModifiers += "Ctrl+"; if (modifiers & PlatformKeyboardEvent::AltKey) accessKeyModifiers += "Alt+"; if (modifiers & PlatformKeyboardEvent::ShiftKey) accessKeyModifiers += "Shift+"; if (modifiers & PlatformKeyboardEvent::MetaKey) accessKeyModifiers += "Win+"; } *shortcut = BString(accessKeyModifiers + accessKey).release(); return S_OK;}HRESULT STDMETHODCALLTYPE AccessibleBase::accSelect(long, VARIANT){ return E_NOTIMPL;}HRESULT STDMETHODCALLTYPE AccessibleBase::get_accSelection(VARIANT*){ return E_NOTIMPL;}HRESULT STDMETHODCALLTYPE AccessibleBase::get_accFocus(VARIANT* pvFocusedChild){ if (!pvFocusedChild) return E_POINTER; ::VariantInit(pvFocusedChild); if (!m_object) return E_FAIL; AccessibilityObject* focusedObj = m_object->focusedUIElement(); if (!focusedObj) return S_FALSE; if (focusedObj == m_object) { V_VT(pvFocusedChild) = VT_I4; V_I4(pvFocusedChild) = CHILDID_SELF; return S_OK; } V_VT(pvFocusedChild) = VT_DISPATCH; V_DISPATCH(pvFocusedChild) = wrapper(focusedObj); V_DISPATCH(pvFocusedChild)->AddRef(); return S_OK;}HRESULT STDMETHODCALLTYPE AccessibleBase::get_accDefaultAction(VARIANT vChild, BSTR* action){ if (!action) return E_POINTER; *action = 0; AccessibilityObject* childObj; HRESULT hr = getAccessibilityObjectForChild(vChild, childObj); if (FAILED(hr)) return hr; if (*action = BString(childObj->actionVerb()).release()) return S_OK; return S_FALSE;}HRESULT STDMETHODCALLTYPE AccessibleBase::accLocation(long* left, long* top, long* width, long* height, VARIANT vChild){ if (!left || !top || !width || !height) return E_POINTER; *left = *top = *width = *height = 0; AccessibilityObject* childObj; HRESULT hr = getAccessibilityObjectForChild(vChild, childObj); if (FAILED(hr)) return hr; if (!childObj->documentFrameView()) return E_FAIL; IntRect screenRect(childObj->documentFrameView()->contentsToScreen(childObj->boundingBoxRect())); *left = screenRect.x(); *top = screenRect.y(); *width = screenRect.width(); *height = screenRect.height(); return S_OK;}HRESULT STDMETHODCALLTYPE AccessibleBase::accNavigate(long direction, VARIANT vFromChild, VARIANT* pvNavigatedTo){ if (!pvNavigatedTo) return E_POINTER; ::VariantInit(pvNavigatedTo); AccessibilityObject* childObj = 0; switch (direction) { case NAVDIR_DOWN: case NAVDIR_UP: case NAVDIR_LEFT: case NAVDIR_RIGHT: // These directions are not implemented, matching Mozilla and IE. return E_NOTIMPL; case NAVDIR_LASTCHILD: case NAVDIR_FIRSTCHILD: // MSDN states that navigating to first/last child can only be from self. if (vFromChild.lVal != CHILDID_SELF) return E_INVALIDARG; if (!m_object) return E_FAIL; if (direction == NAVDIR_FIRSTCHILD) childObj = m_object->firstChild(); else childObj = m_object->lastChild(); break; case NAVDIR_NEXT: case NAVDIR_PREVIOUS: { // Navigating to next and previous is allowed from self or any of our children. HRESULT hr = getAccessibilityObjectForChild(vFromChild, childObj); if (FAILED(hr)) return hr; if (direction == NAVDIR_NEXT) childObj = childObj->nextSibling(); else childObj = childObj->previousSibling(); break; } default: ASSERT_NOT_REACHED(); return E_INVALIDARG; } if (!childObj) return S_FALSE; V_VT(pvNavigatedTo) = VT_DISPATCH; V_DISPATCH(pvNavigatedTo) = wrapper(childObj); V_DISPATCH(pvNavigatedTo)->AddRef(); return S_OK;}HRESULT STDMETHODCALLTYPE AccessibleBase::accHitTest(long x, long y, VARIANT* pvChildAtPoint){ if (!pvChildAtPoint) return E_POINTER; ::VariantInit(pvChildAtPoint); if (!m_object || !m_object->documentFrameView()) return E_FAIL; IntPoint point = m_object->documentFrameView()->screenToContents(IntPoint(x, y)); AccessibilityObject* childObj = m_object->doAccessibilityHitTest(point); if (!childObj) { // If we did not hit any child objects, test whether the point hit us, and // report that. if (!m_object->boundingBoxRect().contains(point)) return S_FALSE; childObj = m_object; } if (childObj == m_object) { V_VT(pvChildAtPoint) = VT_I4; V_I4(pvChildAtPoint) = CHILDID_SELF; } else { V_VT(pvChildAtPoint) = VT_DISPATCH; V_DISPATCH(pvChildAtPoint) = static_cast<IDispatch*>(wrapper(childObj)); V_DISPATCH(pvChildAtPoint)->AddRef(); } return S_OK;}HRESULT STDMETHODCALLTYPE AccessibleBase::accDoDefaultAction(VARIANT vChild){ AccessibilityObject* childObj; HRESULT hr = getAccessibilityObjectForChild(vChild, childObj); if (FAILED(hr)) return hr; if (!childObj->performDefaultAction()) return S_FALSE; return S_OK;}// AccessibleBaseString AccessibleBase::name() const{ return m_object->title();}String AccessibleBase::value() const{ return m_object->stringValue();}String AccessibleBase::description() const{ String desc = m_object->accessibilityDescription(); if (desc.isNull()) return desc; // From the Mozilla MSAA implementation: // "Signal to screen readers that this description is speakable and is not // a formatted positional information description. Don't localize the // 'Description: ' part of this string, it will be parsed out by assistive // technologies." return "Description: " + desc;}static long MSAARole(AccessibilityRole role){ switch (role) { case WebCore::ButtonRole: return ROLE_SYSTEM_PUSHBUTTON; case WebCore::RadioButtonRole: return ROLE_SYSTEM_RADIOBUTTON; case WebCore::CheckBoxRole: return ROLE_SYSTEM_CHECKBUTTON; case WebCore::SliderRole: return ROLE_SYSTEM_SLIDER; case WebCore::TabGroupRole: return ROLE_SYSTEM_PAGETABLIST; case WebCore::TextFieldRole: case WebCore::TextAreaRole: case WebCore::ListMarkerRole: return ROLE_SYSTEM_TEXT; case WebCore::StaticTextRole: return ROLE_SYSTEM_STATICTEXT; case WebCore::OutlineRole: return ROLE_SYSTEM_OUTLINE; case WebCore::ColumnRole: return ROLE_SYSTEM_COLUMN; case WebCore::RowRole: return ROLE_SYSTEM_ROW; case WebCore::GroupRole: return ROLE_SYSTEM_GROUPING; case WebCore::ListRole: return ROLE_SYSTEM_LIST; case WebCore::TableRole: return ROLE_SYSTEM_TABLE; case WebCore::LinkRole: case WebCore::WebCoreLinkRole: return ROLE_SYSTEM_LINK; case WebCore::ImageMapRole: case WebCore::ImageRole: return ROLE_SYSTEM_GRAPHIC; default: // This is the default role for MSAA. return ROLE_SYSTEM_CLIENT; }}long AccessibleBase::role() const{ return MSAARole(m_object->roleValue());}HRESULT AccessibleBase::getAccessibilityObjectForChild(VARIANT vChild, AccessibilityObject*& childObj) const{ childObj = 0; if (!m_object) return E_FAIL; if (vChild.vt != VT_I4) return E_INVALIDARG; if (vChild.lVal == CHILDID_SELF) childObj = m_object; else { size_t childIndex = static_cast<size_t>(vChild.lVal - 1); if (childIndex >= m_object->children().size()) return E_FAIL; childObj = m_object->children().at(childIndex).get(); } if (!childObj) return E_FAIL; return S_OK;}AccessibleBase* AccessibleBase::wrapper(AccessibilityObject* obj){ AccessibleBase* result = static_cast<AccessibleBase*>(obj->wrapper()); if (!result) result = createInstance(obj); return result;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -