diff --git a/accessible/ipc/win/handler/AccessibleHandler.cpp b/accessible/ipc/win/handler/AccessibleHandler.cpp index b15b30114e3f..06b3c6cbbc0f 100644 --- a/accessible/ipc/win/handler/AccessibleHandler.cpp +++ b/accessible/ipc/win/handler/AccessibleHandler.cpp @@ -26,6 +26,7 @@ #include "AccessibleHypertext.h" #include "AccessibleHypertext2.h" +#include "AccessibleRole.h" #include "Accessible2_i.c" #include "Accessible2_2_i.c" #include "Accessible2_3_i.c" @@ -402,6 +403,26 @@ AccessibleHandler::QueryHandlerInterface(IUnknown* aProxyUnknown, REFIID aIid, if (mCachedData.mDynamicData.mChildCount == 0) { return E_NOINTERFACE; } + if (mCachedData.mDynamicData.mIA2Role == IA2_ROLE_INTERNAL_FRAME && + mCachedData.mDynamicData.mChildCount == 1) { + // This is for an iframe. HandlerChildEnumerator works fine for iframes + // rendered in the same content process. However, for out-of-process + // iframes, HandlerProvider::get_AllChildren (called by + // HandlerChildEnumerator) will fail. This is because we only send down + // an IDispatch COM proxy for the embedded document, but get_AllChildren + // will try to QueryInterface this to IAccessible2 to reduce QI calls + // from the parent process. Because the content process is sandboxed, + // it can't make the outgoing COM call to QI the proxy from IDispatch to + // IAccessible2 and so it fails. + // Since an iframe only has one child anyway, we don't need the bulk fetch + // optimization offered by HandlerChildEnumerator or even IEnumVARIANT. + // Therefore, we explicitly tell the client this interface is not + // supported, which will cause the oleacc AccessibleChildren function + // to fall back to accChild. + // If we return E_NOINTERFACE here, mscom::Handler will try the COM + // proxy. S_FALSE signals that the proxy should not be tried. + return S_FALSE; + } RefPtr childEnum( new HandlerChildEnumerator(this, mCachedData.mGeckoBackChannel)); childEnum.forget(aOutInterface);