Bug 1061468 - Notify the editor when removing the focused element is its ancestor limiter. r=ehsan

This commit is contained in:
Mats Palmgren 2014-09-09 23:27:56 +00:00
parent 8ec082edad
commit 2c38b0b6b7
6 changed files with 48 additions and 15 deletions

View File

@ -28,13 +28,14 @@ template<class T> class nsTArray;
native nsDirection(nsDirection);
native ScrollAxis(nsIPresShell::ScrollAxis);
[scriptable, builtinclass, uuid(52629837-7b3f-4434-940d-a14de7ef9b7a)]
[scriptable, builtinclass, uuid(5a82ee9a-35ce-11e4-8c3e-b7043d68ad70)]
interface nsISelectionPrivate : nsISelection
{
const short ENDOFPRECEDINGLINE=0;
const short STARTOFNEXTLINE=1;
attribute boolean interlinePosition;
[noscript] attribute nsIContent ancestorLimiter;
/* startBatchChanges
match this up with endbatchChanges. will stop ui updates while multiple selection methods are called
@ -81,8 +82,6 @@ interface nsISelectionPrivate : nsISelection
*/
[noscript] void getCachedFrameOffset(in nsIFrame aFrame, in int32_t inOffset, in nsPointRef aPoint);
[noscript] void setAncestorLimiter(in nsIContent aContent);
/**
* Set the painting style for the range. The range must be a range in
* the selection. The textRangeStyle will be used by text frame

View File

@ -12,6 +12,7 @@
#include "nsContentUtils.h"
#include "nsIDocument.h"
#include "nsIDOMWindow.h"
#include "nsIEditor.h"
#include "nsPIDOMWindow.h"
#include "nsIDOMElement.h"
#include "nsIDOMDocument.h"
@ -815,8 +816,7 @@ nsFocusManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent)
// element as well, but don't fire any events.
if (window == mFocusedWindow) {
mFocusedContent = nullptr;
}
else {
} else {
// Check if the node that was focused is an iframe or similar by looking
// if it has a subdocument. This would indicate that this focused iframe
// and its descendants will be going away. We will need to move the
@ -834,6 +834,27 @@ nsFocusManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent)
}
}
// Notify the editor in case we removed its ancestor limiter.
if (content->IsEditable()) {
nsCOMPtr<nsIDocShell> docShell = aDocument->GetDocShell();
if (docShell) {
nsCOMPtr<nsIEditor> editor;
docShell->GetEditor(getter_AddRefs(editor));
if (editor) {
nsCOMPtr<nsISelection> s;
editor->GetSelection(getter_AddRefs(s));
nsCOMPtr<nsISelectionPrivate> selection = do_QueryInterface(s);
if (selection) {
nsCOMPtr<nsIContent> limiter;
selection->GetAncestorLimiter(getter_AddRefs(limiter));
if (limiter == content) {
editor->FinalizeSelection();
}
}
}
}
}
NotifyFocusStateChange(content, shouldShowFocusRing, false);
}

View File

@ -4806,30 +4806,30 @@ nsEditor::InitializeSelection(nsIDOMEventTarget* aFocusEventTarget)
return NS_OK;
}
void
NS_IMETHODIMP
nsEditor::FinalizeSelection()
{
nsCOMPtr<nsISelectionController> selCon;
nsresult rv = GetSelectionController(getter_AddRefs(selCon));
NS_ENSURE_SUCCESS_VOID(rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISelection> selection;
rv = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
getter_AddRefs(selection));
NS_ENSURE_SUCCESS_VOID(rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISelectionPrivate> selectionPrivate = do_QueryInterface(selection);
NS_ENSURE_TRUE_VOID(selectionPrivate);
NS_ENSURE_TRUE(selectionPrivate, rv);
selectionPrivate->SetAncestorLimiter(nullptr);
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
NS_ENSURE_TRUE_VOID(presShell);
NS_ENSURE_TRUE(presShell, NS_ERROR_NOT_INITIALIZED);
selCon->SetCaretEnabled(false);
nsFocusManager* fm = nsFocusManager::GetFocusManager();
NS_ENSURE_TRUE_VOID(fm);
NS_ENSURE_TRUE(fm, NS_ERROR_NOT_INITIALIZED);
fm->UpdateCaretForCaretBrowsingMode();
if (!HasIndependentSelection()) {
@ -4860,6 +4860,7 @@ nsEditor::FinalizeSelection()
}
selCon->RepaintSelection(nsISelectionController::SELECTION_NORMAL);
return NS_OK;
}
dom::Element *

View File

@ -801,9 +801,6 @@ public:
// nothing.
nsresult InitializeSelection(nsIDOMEventTarget* aFocusEventTarget);
// Finalizes selection and caret for the editor.
void FinalizeSelection();
// This method has to be called by nsEditorEventListener::Focus.
// All actions that have to be done when the editor is focused needs to be
// added here.

View File

@ -21,7 +21,7 @@ interface nsIEditActionListener;
interface nsIInlineSpellChecker;
interface nsITransferable;
[scriptable, uuid(04714a01-e02f-4ef5-a388-612451d0db16)]
[scriptable, uuid(a1ddae68-35d0-11e4-9329-cb55463f21c9)]
interface nsIEditor : nsISupports
{
@ -42,6 +42,11 @@ interface nsIEditor : nsISupports
readonly attribute nsISelection selection;
/**
* Finalizes selection and caret for the editor.
*/
[noscript] void finalizeSelection();
/**
* Init is to tell the implementation of nsIEditor to begin its services
* @param aDoc The dom document interface being observed

View File

@ -4265,6 +4265,16 @@ Selection::GetCachedFrameOffset(nsIFrame* aFrame, int32_t inOffset,
return rv;
}
NS_IMETHODIMP
Selection::GetAncestorLimiter(nsIContent** aContent)
{
if (mFrameSelection) {
nsCOMPtr<nsIContent> c = mFrameSelection->GetAncestorLimiter();
c.forget(aContent);
}
return NS_OK;
}
NS_IMETHODIMP
Selection::SetAncestorLimiter(nsIContent* aContent)
{