mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Bug 1211352 part.1 IMEContentObserver should be created when a plugin has focus r=smaug
This commit is contained in:
parent
2814f667b7
commit
27b1c48ce9
@ -218,8 +218,6 @@ IMEContentObserver::Init(nsIWidget* aWidget,
|
||||
nsIContent* aContent,
|
||||
nsIEditor* aEditor)
|
||||
{
|
||||
MOZ_ASSERT(aEditor, "aEditor must not be null");
|
||||
|
||||
State state = GetState();
|
||||
if (NS_WARN_IF(state == eState_Observing)) {
|
||||
return; // Nothing to do.
|
||||
@ -231,10 +229,7 @@ IMEContentObserver::Init(nsIWidget* aWidget,
|
||||
// should be registered again for simpler implementation.
|
||||
UnregisterObservers();
|
||||
// Clear members which may not be initialized again.
|
||||
mRootContent = nullptr;
|
||||
mEditor = nullptr;
|
||||
mSelection = nullptr;
|
||||
mDocShell = nullptr;
|
||||
Clear();
|
||||
}
|
||||
|
||||
mESM = aPresContext->EventStateManager();
|
||||
@ -242,51 +237,17 @@ IMEContentObserver::Init(nsIWidget* aWidget,
|
||||
|
||||
mWidget = aWidget;
|
||||
|
||||
mEditableNode =
|
||||
IMEStateManager::GetRootEditableNode(aPresContext, aContent);
|
||||
if (!mEditableNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
mEditor = aEditor;
|
||||
|
||||
nsIPresShell* presShell = aPresContext->PresShell();
|
||||
|
||||
// get selection and root content
|
||||
nsCOMPtr<nsISelectionController> selCon;
|
||||
if (mEditableNode->IsNodeOfType(nsINode::eCONTENT)) {
|
||||
nsIFrame* frame =
|
||||
static_cast<nsIContent*>(mEditableNode.get())->GetPrimaryFrame();
|
||||
NS_ENSURE_TRUE_VOID(frame);
|
||||
|
||||
frame->GetSelectionController(aPresContext,
|
||||
getter_AddRefs(selCon));
|
||||
if (aWidget->GetInputContext().mIMEState.mEnabled == IMEState::PLUGIN) {
|
||||
if (!InitWithPlugin(aPresContext, aContent)) {
|
||||
Clear();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// mEditableNode is a document
|
||||
selCon = do_QueryInterface(presShell);
|
||||
if (!InitWithEditor(aPresContext, aContent, aEditor)) {
|
||||
Clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
NS_ENSURE_TRUE_VOID(selCon);
|
||||
|
||||
selCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
|
||||
getter_AddRefs(mSelection));
|
||||
NS_ENSURE_TRUE_VOID(mSelection);
|
||||
|
||||
nsCOMPtr<nsIDOMRange> selDomRange;
|
||||
if (NS_SUCCEEDED(mSelection->GetRangeAt(0, getter_AddRefs(selDomRange)))) {
|
||||
nsRange* selRange = static_cast<nsRange*>(selDomRange.get());
|
||||
NS_ENSURE_TRUE_VOID(selRange && selRange->GetStartParent());
|
||||
|
||||
mRootContent = selRange->GetStartParent()->
|
||||
GetSelectionRootContent(presShell);
|
||||
} else {
|
||||
mRootContent = mEditableNode->GetSelectionRootContent(presShell);
|
||||
}
|
||||
if (!mRootContent && mEditableNode->IsNodeOfType(nsINode::eDOCUMENT)) {
|
||||
// The document node is editable, but there are no contents, this document
|
||||
// is not editable.
|
||||
return;
|
||||
}
|
||||
NS_ENSURE_TRUE_VOID(mRootContent);
|
||||
|
||||
if (firstInitialization) {
|
||||
MaybeNotifyIMEOfFocusSet();
|
||||
@ -307,8 +268,6 @@ IMEContentObserver::Init(nsIWidget* aWidget,
|
||||
}
|
||||
}
|
||||
|
||||
mDocShell = aPresContext->GetDocShell();
|
||||
|
||||
ObserveEditableNode();
|
||||
|
||||
// Some change events may wait to notify IME because this was being
|
||||
@ -316,16 +275,138 @@ IMEContentObserver::Init(nsIWidget* aWidget,
|
||||
FlushMergeableNotifications();
|
||||
}
|
||||
|
||||
bool
|
||||
IMEContentObserver::InitWithEditor(nsPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIEditor* aEditor)
|
||||
{
|
||||
MOZ_ASSERT(aEditor);
|
||||
|
||||
mEditableNode =
|
||||
IMEStateManager::GetRootEditableNode(aPresContext, aContent);
|
||||
if (NS_WARN_IF(!mEditableNode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mEditor = aEditor;
|
||||
if (NS_WARN_IF(!mEditor)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsIPresShell* presShell = aPresContext->PresShell();
|
||||
|
||||
// get selection and root content
|
||||
nsCOMPtr<nsISelectionController> selCon;
|
||||
if (mEditableNode->IsNodeOfType(nsINode::eCONTENT)) {
|
||||
nsIFrame* frame =
|
||||
static_cast<nsIContent*>(mEditableNode.get())->GetPrimaryFrame();
|
||||
if (NS_WARN_IF(!frame)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
frame->GetSelectionController(aPresContext,
|
||||
getter_AddRefs(selCon));
|
||||
} else {
|
||||
// mEditableNode is a document
|
||||
selCon = do_QueryInterface(presShell);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!selCon)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
selCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
|
||||
getter_AddRefs(mSelection));
|
||||
if (NS_WARN_IF(!mSelection)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMRange> selDomRange;
|
||||
if (NS_SUCCEEDED(mSelection->GetRangeAt(0, getter_AddRefs(selDomRange)))) {
|
||||
nsRange* selRange = static_cast<nsRange*>(selDomRange.get());
|
||||
if (NS_WARN_IF(!selRange) || NS_WARN_IF(!selRange->GetStartParent())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mRootContent = selRange->GetStartParent()->
|
||||
GetSelectionRootContent(presShell);
|
||||
} else {
|
||||
mRootContent = mEditableNode->GetSelectionRootContent(presShell);
|
||||
}
|
||||
if (!mRootContent && mEditableNode->IsNodeOfType(nsINode::eDOCUMENT)) {
|
||||
// The document node is editable, but there are no contents, this document
|
||||
// is not editable.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!mRootContent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mDocShell = aPresContext->GetDocShell();
|
||||
if (NS_WARN_IF(!mDocShell)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IMEContentObserver::InitWithPlugin(nsPresContext* aPresContext,
|
||||
nsIContent* aContent)
|
||||
{
|
||||
if (NS_WARN_IF(!aContent) ||
|
||||
NS_WARN_IF(aContent->GetDesiredIMEState().mEnabled != IMEState::PLUGIN)) {
|
||||
return false;
|
||||
}
|
||||
nsIFrame* frame = aContent->GetPrimaryFrame();
|
||||
if (NS_WARN_IF(!frame)) {
|
||||
return false;
|
||||
}
|
||||
nsCOMPtr<nsISelectionController> selCon;
|
||||
frame->GetSelectionController(aPresContext, getter_AddRefs(selCon));
|
||||
if (NS_WARN_IF(!selCon)) {
|
||||
return false;
|
||||
}
|
||||
selCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
|
||||
getter_AddRefs(mSelection));
|
||||
if (NS_WARN_IF(!mSelection)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mEditor = nullptr;
|
||||
mEditableNode = aContent;
|
||||
mRootContent = aContent;
|
||||
|
||||
mDocShell = aPresContext->GetDocShell();
|
||||
if (NS_WARN_IF(!mDocShell)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
IMEContentObserver::Clear()
|
||||
{
|
||||
mEditor = nullptr;
|
||||
mSelection = nullptr;
|
||||
mEditableNode = nullptr;
|
||||
mRootContent = nullptr;
|
||||
mDocShell = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
IMEContentObserver::ObserveEditableNode()
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(mEditor);
|
||||
MOZ_RELEASE_ASSERT(mSelection);
|
||||
MOZ_RELEASE_ASSERT(mRootContent);
|
||||
MOZ_RELEASE_ASSERT(GetState() != eState_Observing);
|
||||
|
||||
mIsObserving = true;
|
||||
mEditor->AddEditorObserver(this);
|
||||
if (mEditor) {
|
||||
mEditor->AddEditorObserver(this);
|
||||
}
|
||||
|
||||
mUpdatePreference = mWidget->GetIMEUpdatePreference();
|
||||
if (mUpdatePreference.WantSelectionChange()) {
|
||||
@ -430,13 +511,9 @@ IMEContentObserver::Destroy()
|
||||
|
||||
NotifyIMEOfBlur();
|
||||
UnregisterObservers();
|
||||
Clear();
|
||||
|
||||
mEditor = nullptr;
|
||||
mWidget = nullptr;
|
||||
mSelection = nullptr;
|
||||
mRootContent = nullptr;
|
||||
mEditableNode = nullptr;
|
||||
mDocShell = nullptr;
|
||||
mUpdatePreference.mWantUpdates = nsIMEUpdatePreference::NOTIFY_NOTHING;
|
||||
|
||||
if (mESM) {
|
||||
@ -492,8 +569,10 @@ bool
|
||||
IMEContentObserver::IsObservingContent(nsPresContext* aPresContext,
|
||||
nsIContent* aContent) const
|
||||
{
|
||||
return mEditableNode == IMEStateManager::GetRootEditableNode(aPresContext,
|
||||
aContent);
|
||||
return IsInitializedWithPlugin() ?
|
||||
mRootContent == aContent && mRootContent != nullptr :
|
||||
mEditableNode == IMEStateManager::GetRootEditableNode(aPresContext,
|
||||
aContent);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -113,6 +113,11 @@ private:
|
||||
eState_Observing
|
||||
};
|
||||
State GetState() const;
|
||||
bool InitWithEditor(nsPresContext* aPresContext, nsIContent* aContent,
|
||||
nsIEditor* aEditor);
|
||||
bool InitWithPlugin(nsPresContext* aPresContext, nsIContent* aContent);
|
||||
bool IsInitializedWithPlugin() const { return !mEditor; }
|
||||
void Clear();
|
||||
bool IsObservingContent(nsPresContext* aPresContext,
|
||||
nsIContent* aContent) const;
|
||||
bool IsReflowLocked() const;
|
||||
|
@ -510,8 +510,12 @@ IMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
|
||||
sPresContext = aPresContext;
|
||||
sContent = aContent;
|
||||
|
||||
// Don't call CreateIMEContentObserver() here, it should be called from
|
||||
// focus event handler of editor.
|
||||
// Don't call CreateIMEContentObserver() here except when a plugin gets
|
||||
// focus because it will be called from the focus event handler of focused
|
||||
// editor.
|
||||
if (newState.mEnabled == IMEState::PLUGIN) {
|
||||
CreateIMEContentObserver(nullptr);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1515,7 +1519,7 @@ IMEStateManager::GetRootEditableNode(nsPresContext* aPresContext,
|
||||
bool
|
||||
IMEStateManager::IsIMEObserverNeeded(const IMEState& aState)
|
||||
{
|
||||
return aState.IsEditable();
|
||||
return aState.MaybeEditable();
|
||||
}
|
||||
|
||||
// static
|
||||
|
Loading…
Reference in New Issue
Block a user