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
Родитель 8ec082edad
Коммит 2c38b0b6b7
6 изменённых файлов: 48 добавлений и 15 удалений

Просмотреть файл

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

Просмотреть файл

@ -12,6 +12,7 @@
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsIDocument.h" #include "nsIDocument.h"
#include "nsIDOMWindow.h" #include "nsIDOMWindow.h"
#include "nsIEditor.h"
#include "nsPIDOMWindow.h" #include "nsPIDOMWindow.h"
#include "nsIDOMElement.h" #include "nsIDOMElement.h"
#include "nsIDOMDocument.h" #include "nsIDOMDocument.h"
@ -815,8 +816,7 @@ nsFocusManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent)
// element as well, but don't fire any events. // element as well, but don't fire any events.
if (window == mFocusedWindow) { if (window == mFocusedWindow) {
mFocusedContent = nullptr; mFocusedContent = nullptr;
} } else {
else {
// Check if the node that was focused is an iframe or similar by looking // 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 // 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 // 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); NotifyFocusStateChange(content, shouldShowFocusRing, false);
} }

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -21,7 +21,7 @@ interface nsIEditActionListener;
interface nsIInlineSpellChecker; interface nsIInlineSpellChecker;
interface nsITransferable; interface nsITransferable;
[scriptable, uuid(04714a01-e02f-4ef5-a388-612451d0db16)] [scriptable, uuid(a1ddae68-35d0-11e4-9329-cb55463f21c9)]
interface nsIEditor : nsISupports interface nsIEditor : nsISupports
{ {
@ -42,6 +42,11 @@ interface nsIEditor : nsISupports
readonly attribute nsISelection selection; 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 * Init is to tell the implementation of nsIEditor to begin its services
* @param aDoc The dom document interface being observed * @param aDoc The dom document interface being observed

Просмотреть файл

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