1
0
mirror of https://github.com/roytam1/UXP.git synced 2026-05-26 05:46:58 +00:00

Issue #3011 - Part 1: Add As{Text|Html}Editor() and AsEditorBase()

This adds helper functions to get specific types of content editors (if
possible) through the nsIEditor interface, as opposed to doing manual
casting and the ad hoc `GetHTMLEditor()` function.

Helper functions are spread out over multiple headers due to the
circular dependency issues that would be triggered otherwise.
This commit is contained in:
Moonchild
2026-03-20 13:26:18 +01:00
committed by roytam1
parent 3d131186be
commit 2f20100059
11 changed files with 123 additions and 25 deletions
+1
View File
@@ -16,6 +16,7 @@
#include "mozilla/CORSMode.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/EventListenerManager.h"
#include "mozilla/HTMLEditor.h"
#include "mozilla/InternalMutationEvent.h"
#include "mozilla/Likely.h"
#include "mozilla/MemoryReporting.h"
+1
View File
@@ -142,6 +142,7 @@ EditorBase::EditorBase()
, mDispatchInputEvent(true)
, mIsInEditAction(false)
, mHidingCaret(false)
, mIsHTMLEditorClass(false)
{
}
+20
View File
@@ -114,6 +114,7 @@ class DeleteNodeTransaction;
class DeleteTextTransaction;
class EditAggregateTransaction;
class ErrorResult;
class HTMLEditor;
class InsertNodeTransaction;
class InsertTextTransaction;
class JoinNodeTransaction;
@@ -121,6 +122,7 @@ class PlaceholderTransaction;
class RemoveStyleSheetTransaction;
class SplitNodeTransaction;
class TextComposition;
class TextEditor;
struct EditorDOMPoint;
namespace dom {
@@ -1113,14 +1115,32 @@ protected:
bool mIsInEditAction;
// Whether caret is hidden forcibly.
bool mHidingCaret;
// Whether we are an HTML editor class.
bool mIsHTMLEditorClass;
friend bool NSCanUnload(nsISupports* serviceMgr);
friend class AutoRules;
friend class AutoSelectionRestorer;
friend class AutoTransactionsConserveSelection;
friend class RangeUpdater;
friend class nsIEditor;
};
} // namespace mozilla
// nsIEditor helper functions.
// Here because of code context.
mozilla::EditorBase*
nsIEditor::AsEditorBase()
{
return static_cast<mozilla::EditorBase*>(this);
}
const mozilla::EditorBase*
nsIEditor::AsEditorBase() const
{
return static_cast<const mozilla::EditorBase*>(this);
}
#endif // #ifndef mozilla_EditorBase_h
+8 -1
View File
@@ -233,9 +233,16 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(HTMLEditRules, TextEditRules,
NS_IMETHODIMP
HTMLEditRules::Init(TextEditor* aTextEditor)
{
if (NS_WARN_IF(!aTextEditor)) {
return NS_ERROR_INVALID_ARG;
}
InitFields();
mHTMLEditor = static_cast<HTMLEditor*>(aTextEditor);
mHTMLEditor = aTextEditor->AsHTMLEditor();
if (NS_WARN_IF(!mHTMLEditor)) {
return NS_ERROR_INVALID_ARG;
}
// call through to base class Init
nsresult rv = TextEditRules::Init(aTextEditor);
+2 -1
View File
@@ -132,6 +132,7 @@ HTMLEditor::HTMLEditor()
, mPositionedObjectBorderTop(0)
, mGridSize(0)
{
mIsHTMLEditorClass = true;
}
HTMLEditor::~HTMLEditor()
@@ -501,7 +502,7 @@ HTMLEditor::InitRules()
// instantiate the rules for the html editor
mRules = new HTMLEditRules();
}
return mRules->Init(static_cast<TextEditor*>(this));
return mRules->Init(this);
}
NS_IMETHODIMP
+16
View File
@@ -1108,4 +1108,20 @@ private:
} // namespace mozilla
// nsIEditor helper functions.
// Here because of code context.
mozilla::HTMLEditor*
nsIEditor::AsHTMLEditor()
{
return static_cast<mozilla::EditorBase*>(this)->mIsHTMLEditorClass ?
static_cast<mozilla::HTMLEditor*>(this) : nullptr;
}
const mozilla::HTMLEditor*
nsIEditor::AsHTMLEditor() const
{
return static_cast<const mozilla::EditorBase*>(this)->mIsHTMLEditorClass ?
static_cast<const mozilla::HTMLEditor*>(this) : nullptr;
}
#endif // #ifndef mozilla_HTMLEditor_h
+21 -18
View File
@@ -30,24 +30,18 @@ namespace mozilla {
using namespace dom;
#ifdef DEBUG
nsresult
HTMLEditorEventListener::Connect(EditorBase* aEditorBase)
{
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryObject(aEditorBase);
nsCOMPtr<nsIHTMLInlineTableEditor> htmlInlineTableEditor =
do_QueryObject(aEditorBase);
NS_PRECONDITION(htmlEditor && htmlInlineTableEditor,
"Set HTMLEditor or its sub class");
return EditorEventListener::Connect(aEditorBase);
}
#endif
HTMLEditor*
HTMLEditorEventListener::GetHTMLEditor()
{
// mEditor must be HTMLEditor or its subclass.
return static_cast<HTMLEditor*>(mEditorBase);
if (NS_WARN_IF(!aEditorBase)) {
return NS_ERROR_INVALID_ARG;
}
// Guarantee that mEditorBase is always HTMLEditor.
HTMLEditor* htmlEditor = aEditorBase->AsHTMLEditor();
if (NS_WARN_IF(!htmlEditor)) {
return NS_ERROR_INVALID_ARG;
}
return EditorEventListener::Connect(htmlEditor);
}
nsresult
@@ -59,7 +53,8 @@ HTMLEditorEventListener::MouseUp(nsIDOMMouseEvent* aMouseEvent)
// FYI: We need to notify HTML editor of mouseup even if it's consumed
// because HTML editor always needs to release grabbing resizer.
HTMLEditor* htmlEditor = GetHTMLEditor();
HTMLEditor* htmlEditor = mEditorBase->AsHTMLEditor();
MOZ_ASSERT(htmlEditor);
nsCOMPtr<nsIDOMEventTarget> target;
nsresult rv = aMouseEvent->AsEvent()->GetTarget(getter_AddRefs(target));
@@ -85,7 +80,9 @@ HTMLEditorEventListener::MouseDown(nsIDOMMouseEvent* aMouseEvent)
WidgetMouseEvent* mousedownEvent =
aMouseEvent->AsEvent()->WidgetEventPtr()->AsMouseEvent();
HTMLEditor* htmlEditor = GetHTMLEditor();
HTMLEditor* htmlEditor = mEditorBase->AsHTMLEditor();
MOZ_ASSERT(htmlEditor);
// Contenteditable should disregard mousedowns outside it.
// IsAcceptableInputEvent() checks it for a mouse event.
if (!htmlEditor->IsAcceptableInputEvent(mousedownEvent)) {
@@ -221,13 +218,19 @@ HTMLEditorEventListener::MouseDown(nsIDOMMouseEvent* aMouseEvent)
nsresult
HTMLEditorEventListener::MouseClick(nsIDOMMouseEvent* aMouseEvent)
{
if (NS_WARN_IF(DetachedFromEditor())) {
return NS_OK;
}
nsCOMPtr<nsIDOMEventTarget> target;
nsresult rv = aMouseEvent->AsEvent()->GetTarget(getter_AddRefs(target));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(target, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(target);
GetHTMLEditor()->DoInlineTableEditingAction(element);
HTMLEditor* htmlEditor = mEditorBase->AsHTMLEditor();
MOZ_ASSERT(htmlEditor);
htmlEditor->DoInlineTableEditingAction(element);
return EditorEventListener::MouseClick(aMouseEvent);
}
+1 -5
View File
@@ -25,17 +25,13 @@ public:
{
}
#ifdef DEBUG
// WARNING: You must be use HTMLEditor or its sub class for this class.
// Connect() fails if aEditorBase isn't an HTMLEditor instance.
virtual nsresult Connect(EditorBase* aEditorBase) override;
#endif
protected:
virtual nsresult MouseDown(nsIDOMMouseEvent* aMouseEvent) override;
virtual nsresult MouseUp(nsIDOMMouseEvent* aMouseEvent) override;
virtual nsresult MouseClick(nsIDOMMouseEvent* aMouseEvent) override;
inline HTMLEditor* GetHTMLEditor();
};
} // namespace mozilla
+1
View File
@@ -10,6 +10,7 @@
#include "gfxFontUtils.h"
#include "mozilla/Assertions.h"
#include "mozilla/EditorUtils.h" // AutoEditBatch, AutoRules
#include "mozilla/HTMLEditor.h"
#include "mozilla/mozalloc.h"
#include "mozilla/Preferences.h"
#include "mozilla/TextEditRules.h"
+14
View File
@@ -247,4 +247,18 @@ protected:
} // namespace mozilla
// nsIEditor helper functions.
// Here because of code context.
mozilla::TextEditor*
nsIEditor::AsTextEditor()
{
return static_cast<mozilla::TextEditor*>(this);
}
const mozilla::TextEditor*
nsIEditor::AsTextEditor() const
{
return static_cast<const mozilla::TextEditor*>(this);
}
#endif // #ifndef mozilla_TextEditor_h
+38
View File
@@ -21,6 +21,14 @@ interface nsIEditActionListener;
interface nsIInlineSpellChecker;
interface nsITransferable;
%{C++
namespace mozilla {
class EditorBase;
class HTMLEditor;
class TextEditor;
} // namespace mozilla
%}
[scriptable, uuid(094be624-f0bf-400f-89e2-6a84baab9474)]
interface nsIEditor : nsISupports
{
@@ -564,4 +572,34 @@ interface nsIEditor : nsISupports
* or nsIEditorObserver::CancelEditAction(). Otherwise, false.
*/
[noscript] readonly attribute boolean isInEditAction;
%{C++
/**
* AsEditorBase() returns a pointer to EditorBase class.
*
* In order to avoid circular dependency issues, this method is defined
* in mozilla/EditorBase.h. Consumers need to #include that header.
*/
inline mozilla::EditorBase* AsEditorBase();
inline const mozilla::EditorBase* AsEditorBase() const;
/**
* AsTextEditor() returns a pointer to TextEditor class.
*
* In order to avoid circular dependency issues, this method is defined
* in mozilla/TextEditor.h. Consumers need to #include that header.
*/
inline mozilla::TextEditor* AsTextEditor();
inline const mozilla::TextEditor* AsTextEditor() const;
/**
* AsHTMLEditor() returns a pointer to HTMLEditor class.
*
* In order to avoid circular dependency issues, this method is defined
* in mozilla/HTMLEditor.h. Consumers need to #include that header.
*/
inline mozilla::HTMLEditor* AsHTMLEditor();
inline const mozilla::HTMLEditor* AsHTMLEditor() const;
%}
};