Bug 950559 part.1 nsContentEventHandler should set plugin's rect to query editor rect event if plugin has focus r=smaug

This commit is contained in:
Masayuki Nakano 2013-12-18 10:43:11 +09:00
parent 77e71bd923
commit e0ff6eabfe
2 changed files with 61 additions and 18 deletions

View File

@ -6,6 +6,7 @@
#include "nsContentEventHandler.h"
#include "nsCOMPtr.h"
#include "nsFocusManager.h"
#include "nsPresContext.h"
#include "nsIPresShell.h"
#include "nsISelection.h"
@ -31,6 +32,7 @@
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::widget;
/******************************************************************/
/* nsContentEventHandler */
@ -127,6 +129,55 @@ nsContentEventHandler::Init(WidgetSelectionEvent* aEvent)
return NS_OK;
}
nsIContent*
nsContentEventHandler::GetFocusedContent()
{
nsIDocument* doc = mPresShell->GetDocument();
if (!doc) {
return nullptr;
}
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(doc->GetWindow());
nsCOMPtr<nsPIDOMWindow> focusedWindow;
return nsFocusManager::GetFocusedDescendant(window, true,
getter_AddRefs(focusedWindow));
}
bool
nsContentEventHandler::IsPlugin(nsIContent* aContent)
{
return aContent &&
aContent->GetDesiredIMEState().mEnabled == IMEState::PLUGIN;
}
nsresult
nsContentEventHandler::QueryContentRect(nsIContent* aContent,
WidgetQueryContentEvent* aEvent)
{
NS_PRECONDITION(aContent, "aContent must not be null");
nsIFrame* frame = aContent->GetPrimaryFrame();
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
// get rect for first frame
nsRect resultRect(nsPoint(0, 0), frame->GetRect().Size());
nsresult rv = ConvertToRootViewRelativeOffset(frame, resultRect);
NS_ENSURE_SUCCESS(rv, rv);
// account for any additional frames
while ((frame = frame->GetNextContinuation()) != nullptr) {
nsRect frameRect(nsPoint(0, 0), frame->GetRect().Size());
rv = ConvertToRootViewRelativeOffset(frame, frameRect);
NS_ENSURE_SUCCESS(rv, rv);
resultRect.UnionRect(resultRect, frameRect);
}
aEvent->mReply.mRect =
resultRect.ToOutsidePixels(mPresContext->AppUnitsPerDevPixel());
aEvent->mSucceeded = true;
return NS_OK;
}
// Editor places a bogus BR node under its root content if the editor doesn't
// have any text. This happens even for single line editors.
// When we get text content and when we change the selection,
@ -676,25 +727,10 @@ nsContentEventHandler::OnQueryEditorRect(WidgetQueryContentEvent* aEvent)
if (NS_FAILED(rv))
return rv;
nsIFrame* frame = mRootContent->GetPrimaryFrame();
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
// get rect for first frame
nsRect resultRect(nsPoint(0, 0), frame->GetRect().Size());
rv = ConvertToRootViewRelativeOffset(frame, resultRect);
nsIContent* focusedContent = GetFocusedContent();
rv = QueryContentRect(IsPlugin(focusedContent) ?
focusedContent : mRootContent.get(), aEvent);
NS_ENSURE_SUCCESS(rv, rv);
// account for any additional frames
while ((frame = frame->GetNextContinuation()) != nullptr) {
nsRect frameRect(nsPoint(0, 0), frame->GetRect().Size());
rv = ConvertToRootViewRelativeOffset(frame, frameRect);
NS_ENSURE_SUCCESS(rv, rv);
resultRect.UnionRect(resultRect, frameRect);
}
aEvent->mReply.mRect =
resultRect.ToOutsidePixels(mPresContext->AppUnitsPerDevPixel());
aEvent->mSucceeded = true;
return NS_OK;
}

View File

@ -81,6 +81,13 @@ public:
static uint32_t GetNativeTextLength(nsIContent* aContent,
uint32_t aMaxLength = UINT32_MAX);
protected:
// Returns focused content (including its descendant documents).
nsIContent* GetFocusedContent();
// Returns true if the content is a plugin host.
bool IsPlugin(nsIContent* aContent);
// QueryContentRect() sets the rect of aContent's frame(s) to aEvent.
nsresult QueryContentRect(nsIContent* aContent,
mozilla::WidgetQueryContentEvent* aEvent);
// Make the DOM range from the offset of FlatText and the text length.
// If aExpandToClusterBoundaries is true, the start offset and the end one are
// expanded to nearest cluster boundaries.