diff --git a/editor/libeditor/text/nsEditorEventListeners.cpp b/editor/libeditor/text/nsEditorEventListeners.cpp index bea8b90ca44..aa1469e1b18 100644 --- a/editor/libeditor/text/nsEditorEventListeners.cpp +++ b/editor/libeditor/text/nsEditorEventListeners.cpp @@ -969,14 +969,16 @@ NS_NewEditorCompositionListener(nsIDOMEventListener** aInstancePtrResult, nsIEdi nsresult NS_NewEditorFocusListener(nsIDOMEventListener ** aInstancePtrResult, - nsIEditor *aEditor) + nsIEditor *aEditor, + nsIPresShell *aPresShell) { - nsTextEditorFocusListener* it = new nsTextEditorFocusListener(); - if (nsnull == it) { + nsTextEditorFocusListener* it = + new nsTextEditorFocusListener(aEditor, aPresShell); + if (!it) { return NS_ERROR_OUT_OF_MEMORY; } - it->SetEditor(aEditor); - return it->QueryInterface(NS_GET_IID(nsIDOMEventListener), (void **) aInstancePtrResult); + + return CallQueryInterface(it, aInstancePtrResult); } @@ -988,7 +990,10 @@ NS_NewEditorFocusListener(nsIDOMEventListener ** aInstancePtrResult, NS_IMPL_ISUPPORTS2(nsTextEditorFocusListener, nsIDOMEventListener, nsIDOMFocusListener) -nsTextEditorFocusListener::nsTextEditorFocusListener() +nsTextEditorFocusListener::nsTextEditorFocusListener(nsIEditor *aEditor, + nsIPresShell *aShell) + : mEditor(aEditor), + mPresShell(do_GetWeakReference(aShell)) { } @@ -1034,27 +1039,54 @@ IsTargetFocused(nsIDOMEventTarget* aTarget) return (focusedContent == content); } -static nsIContent* -FindEditableRoot(nsIContent *aContent) +static already_AddRefed +FindSelectionRoot(nsIEditor *aEditor, nsIContent *aContent) { + PRUint32 flags; + aEditor->GetFlags(&flags); + nsIDocument *document = aContent->GetCurrentDoc(); if (!document) { return nsnull; } + nsIContent *root; if (document->HasFlag(NODE_IS_EDITABLE)) { - return document->GetRootContent(); + NS_IF_ADDREF(root = document->GetRootContent()); + + return root; + } + + if (flags & nsIPlaintextEditor::eEditorReadonlyMask) { + // We still want to allow selection in a readonly editor. + nsCOMPtr rootElement; + aEditor->GetRootElement(getter_AddRefs(rootElement)); + + CallQueryInterface(rootElement, &root); + + if (!root) { + nsIDocument *document = aContent->GetCurrentDoc(); + if (document) { + NS_IF_ADDREF(root = document->GetRootContent()); + } + } + + return root; } if (!aContent->HasFlag(NODE_IS_EDITABLE)) { return nsnull; } + // For non-readonly editors we want to find the root of the editable subtree + // containing aContent. nsIContent *parent, *content = aContent; while ((parent = content->GetParent()) && parent->HasFlag(NODE_IS_EDITABLE)) { content = parent; } + NS_IF_ADDREF(content); + return content; } @@ -1085,17 +1117,18 @@ nsTextEditorFocusListener::Focus(nsIDOMEvent* aEvent) { // only enable caret and selection if the editor is not disabled nsCOMPtr content = do_QueryInterface(target); - nsIContent *editableRoot = content ? FindEditableRoot(content) : nsnull; + nsCOMPtr editableRoot = + content ? FindSelectionRoot(mEditor, content) : nsnull; nsCOMPtr selCon; mEditor->GetSelectionController(getter_AddRefs(selCon)); - nsCOMPtr presShell = do_QueryInterface(selCon); if (selCon && editableRoot) { nsCOMPtr selection; selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection)); + nsCOMPtr presShell = do_QueryReferent(mPresShell); if (presShell && selection) { nsCOMPtr caret; presShell->GetCaret(getter_AddRefs(caret)); diff --git a/editor/libeditor/text/nsEditorEventListeners.h b/editor/libeditor/text/nsEditorEventListeners.h index 9ef7eb9f0ba..63accc648ca 100644 --- a/editor/libeditor/text/nsEditorEventListeners.h +++ b/editor/libeditor/text/nsEditorEventListeners.h @@ -248,16 +248,11 @@ class nsTextEditorFocusListener : public nsIDOMFocusListener public: /** default constructor */ - nsTextEditorFocusListener(); + nsTextEditorFocusListener(nsIEditor *aEditor, nsIPresShell *aPresShell); /** default destructor */ virtual ~nsTextEditorFocusListener(); - /** SetEditor gives an address to the editor that will be accessed - * @param aEditor the editor this listener calls for editing operations - */ - void SetEditor(nsIEditor *aEditor){mEditor = aEditor;} - /*interfaces for addref and release and queryinterface*/ NS_DECL_ISUPPORTS @@ -269,6 +264,7 @@ public: protected: nsIEditor* mEditor; // weak reference + nsWeakPtr mPresShell; }; @@ -296,7 +292,9 @@ extern nsresult NS_NewEditorCompositionListener(nsIDOMEventListener** aInstanceP /** factory for the editor composition listener */ -extern nsresult NS_NewEditorFocusListener(nsIDOMEventListener** aInstancePtrResult, nsIEditor *aEditor); +extern nsresult +NS_NewEditorFocusListener(nsIDOMEventListener** aInstancePtrResult, + nsIEditor *aEditor, nsIPresShell *aPresShell); #endif //editorInterfaces_h__ diff --git a/editor/libeditor/text/nsPlaintextEditor.cpp b/editor/libeditor/text/nsPlaintextEditor.cpp index 7f77615443d..eb701524bff 100644 --- a/editor/libeditor/text/nsPlaintextEditor.cpp +++ b/editor/libeditor/text/nsPlaintextEditor.cpp @@ -300,16 +300,17 @@ nsPlaintextEditor::CreateEventListeners() this); } + nsCOMPtr presShell = do_QueryReferent(mPresShellWeak); if (!mDragListenerP) { // get a drag listener - nsCOMPtr presShell = do_QueryReferent(mPresShellWeak); rv |= NS_NewEditorDragListener(getter_AddRefs(mDragListenerP), presShell, this); } if (!mFocusListenerP) { // get a focus listener - rv |= NS_NewEditorFocusListener(getter_AddRefs(mFocusListenerP), this); + rv |= NS_NewEditorFocusListener(getter_AddRefs(mFocusListenerP), + this, presShell); } return rv;