mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Bug 1540029 - part 10: Get rid of TextEditRules
and HTMLEditRules
r=m_kato
Now, we can get rid of `TextEditRules` and `HTMLEditRules` completely. And also this patch renames their cpp files to `TextEditSubActionHandler` and `HTMLEditSubActionHandler`. `TextEditor::Init()` and `HTMLEditor::Init()` are still complicated due to `AutoEditInitRulesTrigger`. The following patch will remove it. Differential Revision: https://phabricator.services.mozilla.com/D45792 --HG-- rename : editor/libeditor/HTMLEditRules.cpp => editor/libeditor/HTMLEditSubActionHandler.cpp rename : editor/libeditor/TextEditRules.cpp => editor/libeditor/TextEditSubActionHandler.cpp extra : moz-landing-system : lando
This commit is contained in:
parent
c25975635c
commit
6789366d5e
@ -27,7 +27,6 @@
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/TextEditRules.h"
|
||||
#include "mozilla/EventListenerManager.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "DeleteTextTransaction.h" // for DeleteTextTransaction
|
||||
#include "EditAggregateTransaction.h" // for EditAggregateTransaction
|
||||
#include "EditorEventListener.h" // for EditorEventListener
|
||||
#include "HTMLEditRules.h" // for HTMLEditRules
|
||||
#include "InsertNodeTransaction.h" // for InsertNodeTransaction
|
||||
#include "InsertTextTransaction.h" // for InsertTextTransaction
|
||||
#include "JoinNodeTransaction.h" // for JoinNodeTransaction
|
||||
@ -2635,7 +2634,7 @@ EditorRawDOMPoint EditorBase::FindBetterInsertionPoint(
|
||||
// We cannot find "better" insertion point in HTML editor.
|
||||
// WARNING: When you add some code to find better node in HTML editor,
|
||||
// you need to call this before calling InsertTextWithTransaction()
|
||||
// in HTMLEditRules.
|
||||
// in HTMLEditor.
|
||||
return aPoint;
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,6 @@ class SplitNodeResult;
|
||||
class SplitNodeTransaction;
|
||||
class TextComposition;
|
||||
class TextEditor;
|
||||
class TextEditRules;
|
||||
class TextInputListener;
|
||||
class TextServicesDocument;
|
||||
class TypeInState;
|
||||
@ -990,12 +989,10 @@ class EditorBase : public nsIEditor,
|
||||
|
||||
protected: // May be called by friends.
|
||||
/****************************************************************************
|
||||
* Some classes like TextEditRules, HTMLEditRules, WSRunObject which are
|
||||
* part of handling edit actions are allowed to call the following protected
|
||||
* methods. However, those methods won't prepare caches of some objects
|
||||
* which are necessary for them. So, if you want some following methods
|
||||
* to do that for you, you need to create a wrapper method in public scope
|
||||
* and call it.
|
||||
* Some friend classes are allowed to call the following protected methods.
|
||||
* However, those methods won't prepare caches of some objects which are
|
||||
* necessary for them. So, if you call them from friend classes, you need
|
||||
* to make sure that AutoEditActionDataSetter is created.
|
||||
****************************************************************************/
|
||||
|
||||
bool IsEditActionDataAvailable() const {
|
||||
@ -2602,8 +2599,6 @@ class EditorBase : public nsIEditor,
|
||||
// compositionend.
|
||||
RefPtr<TextComposition> mComposition;
|
||||
|
||||
RefPtr<TextEditRules> mRules;
|
||||
|
||||
RefPtr<TextInputListener> mTextInputListener;
|
||||
|
||||
RefPtr<IMEContentObserver> mIMEContentObserver;
|
||||
@ -2669,7 +2664,6 @@ class EditorBase : public nsIEditor,
|
||||
friend class DeleteNodeTransaction;
|
||||
friend class DeleteRangeTransaction;
|
||||
friend class DeleteTextTransaction;
|
||||
friend class HTMLEditRules;
|
||||
friend class HTMLEditUtils;
|
||||
friend class InsertNodeTransaction;
|
||||
friend class InsertTextTransaction;
|
||||
@ -2678,7 +2672,6 @@ class EditorBase : public nsIEditor,
|
||||
friend class ListItemElementSelectionState;
|
||||
friend class ParagraphStateAtSelection;
|
||||
friend class SplitNodeTransaction;
|
||||
friend class TextEditRules;
|
||||
friend class TypeInState;
|
||||
friend class WSRunObject;
|
||||
friend class WSRunScanner;
|
||||
|
@ -7,13 +7,11 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "HTMLEditorEventListener.h"
|
||||
#include "HTMLEditRules.h"
|
||||
#include "HTMLEditUtils.h"
|
||||
#include "TextEditUtils.h"
|
||||
#include "mozilla/EditAction.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/PresShell.h"
|
||||
#include "mozilla/TextEditRules.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/EventTarget.h"
|
||||
|
@ -1,75 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef HTMLEditRules_h
|
||||
#define HTMLEditRules_h
|
||||
|
||||
#include "TypeInState.h"
|
||||
#include "mozilla/EditorDOMPoint.h" // for EditorDOMPoint
|
||||
#include "mozilla/SelectionState.h"
|
||||
#include "mozilla/TextEditRules.h"
|
||||
#include "mozilla/TypeInState.h" // for AutoStyleCacheArray
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIHTMLEditor.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nscore.h"
|
||||
|
||||
class nsAtom;
|
||||
class nsINode;
|
||||
class nsRange;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class EditActionResult;
|
||||
class HTMLEditor;
|
||||
class SplitNodeResult;
|
||||
class TextEditor;
|
||||
enum class EditSubAction : int32_t;
|
||||
|
||||
namespace dom {
|
||||
class Document;
|
||||
class Element;
|
||||
class Selection;
|
||||
} // namespace dom
|
||||
|
||||
/**
|
||||
* Same as TextEditRules, any methods which may modify the DOM tree or
|
||||
* Selection should be marked as MOZ_MUST_USE and return nsresult directly
|
||||
* or with simple class like EditActionResult. And every caller of them
|
||||
* has to check whether the result is NS_ERROR_EDITOR_DESTROYED and if it is,
|
||||
* its callers should stop handling edit action since after mutation event
|
||||
* listener or selectionchange event listener disables the editor, we should
|
||||
* not modify the DOM tree nor Selection anymore. And also when methods of
|
||||
* this class call methods of other classes like HTMLEditor and WSRunObject,
|
||||
* they should check whether CanHandleEditAtion() returns false immediately
|
||||
* after the calls. If it returns false, they should return
|
||||
* NS_ERROR_EDITOR_DESTROYED.
|
||||
*/
|
||||
|
||||
class HTMLEditRules : public TextEditRules {
|
||||
public:
|
||||
HTMLEditRules();
|
||||
|
||||
// TextEditRules methods
|
||||
virtual nsresult DetachEditor() override;
|
||||
|
||||
protected:
|
||||
virtual ~HTMLEditRules() = default;
|
||||
|
||||
HTMLEditor& HTMLEditorRef() const {
|
||||
MOZ_ASSERT(mData);
|
||||
return mData->HTMLEditorRef();
|
||||
}
|
||||
|
||||
protected:
|
||||
HTMLEditor* mHTMLEditor;
|
||||
bool mInitialized;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // #ifndef HTMLEditRules_h
|
@ -4,9 +4,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "HTMLEditRules.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "HTMLEditor.h"
|
||||
|
||||
#include "HTMLEditUtils.h"
|
||||
#include "TextEditUtils.h"
|
||||
@ -17,7 +15,6 @@
|
||||
#include "mozilla/EditAction.h"
|
||||
#include "mozilla/EditorDOMPoint.h"
|
||||
#include "mozilla/EditorUtils.h"
|
||||
#include "mozilla/HTMLEditor.h"
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/mozalloc.h"
|
||||
@ -168,9 +165,6 @@ class MOZ_RAII AutoSetTemporaryAncestorLimiter final {
|
||||
RefPtr<Selection> mSelection;
|
||||
};
|
||||
|
||||
/********************************************************
|
||||
* mozilla::HTMLEditRules
|
||||
********************************************************/
|
||||
template void HTMLEditor::SelectBRElementIfCollapsedInEmptyBlock(
|
||||
RangeBoundary& aStartRef, RangeBoundary& aEndRef);
|
||||
template void HTMLEditor::SelectBRElementIfCollapsedInEmptyBlock(
|
||||
@ -228,10 +222,6 @@ template nsIContent* HTMLEditor::FindNearEditableContent(
|
||||
template nsIContent* HTMLEditor::FindNearEditableContent(
|
||||
const EditorRawDOMPoint& aPoint, nsIEditor::EDirection aDirection);
|
||||
|
||||
HTMLEditRules::HTMLEditRules() : mHTMLEditor(nullptr), mInitialized(false) {
|
||||
mIsHTMLEditRules = true;
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::InitEditorContentAndSelection() {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
@ -262,11 +252,6 @@ nsresult HTMLEditor::InitEditorContentAndSelection() {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult HTMLEditRules::DetachEditor() {
|
||||
mHTMLEditor = nullptr;
|
||||
return TextEditRules::DetachEditor();
|
||||
}
|
||||
|
||||
void HTMLEditor::OnStartToHandleTopLevelEditSubAction(
|
||||
EditSubAction aTopLevelEditSubAction,
|
||||
nsIEditor::EDirection aDirectionOfTopLevelEditSubAction, ErrorResult& aRv) {
|
||||
@ -1673,7 +1658,7 @@ bool HTMLEditor::CanContainParagraph(Element& aElement) const {
|
||||
}
|
||||
|
||||
EditActionResult HTMLEditor::InsertParagraphSeparatorAsSubAction() {
|
||||
if (!mRules) {
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return EditActionIgnored(NS_ERROR_NOT_INITIALIZED);
|
||||
}
|
||||
|
||||
@ -4137,7 +4122,7 @@ EditActionResult HTMLEditor::MakeOrChangeListAndListItemAsSubAction(
|
||||
&aListElementOrListItemElementTagName == nsGkAtoms::dd ||
|
||||
&aListElementOrListItemElementTagName == nsGkAtoms::dt);
|
||||
|
||||
if (!mRules) {
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return EditActionIgnored(NS_ERROR_NOT_INITIALIZED);
|
||||
}
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "nsUnicharUtils.h"
|
||||
|
||||
#include "HTMLEditorEventListener.h"
|
||||
#include "HTMLEditRules.h"
|
||||
#include "HTMLEditUtils.h"
|
||||
#include "TextEditUtils.h"
|
||||
#include "TypeInState.h"
|
||||
@ -452,19 +451,6 @@ HTMLEditor::SetFlags(uint32_t aFlags) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::InitRules() {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
if (!mRules) {
|
||||
// instantiate the rules for the html editor
|
||||
mRules = new HTMLEditRules();
|
||||
}
|
||||
nsresult rv = InitEditorContentAndSelection();
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"InitEditorContentAndSelection() failed");
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLEditor::BeginningOfDocument() {
|
||||
AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
|
||||
@ -2128,7 +2114,7 @@ HTMLEditor::MakeOrChangeList(const nsAString& aListType, bool aEntireList,
|
||||
nsresult HTMLEditor::MakeOrChangeListAsAction(
|
||||
nsAtom& aListTagName, const nsAString& aBulletType,
|
||||
SelectAllOfCurrentList aSelectAllOfCurrentList, nsIPrincipal* aPrincipal) {
|
||||
if (!mRules) {
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
@ -2154,7 +2140,7 @@ HTMLEditor::RemoveList(const nsAString& aListType) {
|
||||
|
||||
nsresult HTMLEditor::RemoveListAsAction(const nsAString& aListType,
|
||||
nsIPrincipal* aPrincipal) {
|
||||
if (!mRules) {
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
@ -2185,7 +2171,7 @@ nsresult HTMLEditor::RemoveListAsAction(const nsAString& aListType,
|
||||
nsresult HTMLEditor::FormatBlockContainerAsSubAction(nsAtom& aTagName) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
if (!mRules) {
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
@ -2268,7 +2254,7 @@ HTMLEditor::Indent(const nsAString& aIndent) {
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::IndentAsAction(nsIPrincipal* aPrincipal) {
|
||||
if (!mRules) {
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
@ -2284,7 +2270,7 @@ nsresult HTMLEditor::IndentAsAction(nsIPrincipal* aPrincipal) {
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::OutdentAsAction(nsIPrincipal* aPrincipal) {
|
||||
if (!mRules) {
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
@ -4258,7 +4244,7 @@ nsresult HTMLEditor::SetCSSBackgroundColorWithTransaction(
|
||||
const nsAString& aColor) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
if (NS_WARN_IF(!mRules)) {
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
|
@ -246,7 +246,7 @@ class HTMLEditor final : public TextEditor,
|
||||
* into the DOM tree.
|
||||
* NOTE: This is available for internal use too since this does not change
|
||||
* the DOM tree nor undo transactions, and does not refer Selection,
|
||||
* HTMLEditRules, etc.
|
||||
* etc.
|
||||
*
|
||||
* @param aTagName The new element's tag name. If the name is
|
||||
* one of "href", "anchor" or "namedanchor",
|
||||
@ -630,12 +630,10 @@ class HTMLEditor final : public TextEditor,
|
||||
|
||||
protected: // May be called by friends.
|
||||
/****************************************************************************
|
||||
* Some classes like TextEditRules, HTMLEditRules, WSRunObject which are
|
||||
* part of handling edit actions are allowed to call the following protected
|
||||
* methods. However, those methods won't prepare caches of some objects
|
||||
* which are necessary for them. So, if you want some following methods
|
||||
* to do that for you, you need to create a wrapper method in public scope
|
||||
* and call it.
|
||||
* Some friend classes are allowed to call the following protected methods.
|
||||
* However, those methods won't prepare caches of some objects which are
|
||||
* necessary for them. So, if you call them from friend classes, you need
|
||||
* to make sure that AutoEditActionDataSetter is created.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
@ -1149,9 +1147,8 @@ class HTMLEditor final : public TextEditor,
|
||||
|
||||
/**
|
||||
* OnModifyDocument() is called when the editor is changed. This should
|
||||
* be called only by HTMLEditRules::DocumentModifiedWorker() to call
|
||||
* HTMLEditRules::OnModifyDocument() with AutoEditActionDataSetter
|
||||
* instance.
|
||||
* be called only by runnable in HTMLEditor::OnDocumentModified() to call
|
||||
* HTMLEditor::OnModifyDocument() with AutoEditActionDataSetter instance.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult OnModifyDocument();
|
||||
|
||||
@ -2688,8 +2685,9 @@ class HTMLEditor final : public TextEditor,
|
||||
EnsureCaretInBlockElement(dom::Element& aElement);
|
||||
|
||||
/**
|
||||
* Called by `HTMLEditRules::AfterEdit()`. This may adjust Selection, remove
|
||||
* unnecessary empty nodes, create `<br>` elements if needed, etc.
|
||||
* Called by `HTMLEditor::OnEndHandlingTopLevelEditSubAction()`. This may
|
||||
* adjust Selection, remove unnecessary empty nodes, create `<br>` elements
|
||||
* if needed, etc.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult
|
||||
OnEndHandlingTopLevelEditSubActionInternal();
|
||||
@ -3488,9 +3486,6 @@ class HTMLEditor final : public TextEditor,
|
||||
bool mDoDeleteSelection;
|
||||
};
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
virtual nsresult InitRules() override;
|
||||
|
||||
virtual void CreateEventListeners() override;
|
||||
virtual nsresult InstallEventListeners() override;
|
||||
virtual void RemoveEventListeners() override;
|
||||
@ -4379,7 +4374,6 @@ class HTMLEditor final : public TextEditor,
|
||||
friend class CSSEditUtils;
|
||||
friend class EditorBase;
|
||||
friend class EmptyEditableFunctor;
|
||||
friend class HTMLEditRules;
|
||||
friend class ListElementSelectionState;
|
||||
friend class ListItemElementSelectionState;
|
||||
friend class ParagraphStateAtSelection;
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "mozilla/OwningNonNull.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/SelectionState.h"
|
||||
#include "mozilla/TextEditRules.h"
|
||||
#include "nsAString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCRTGlue.h" // for CRLF
|
||||
@ -92,7 +91,7 @@ static nsresult FindTargetNode(nsINode* aStart, nsCOMPtr<nsINode>& aResult);
|
||||
nsresult HTMLEditor::LoadHTML(const nsAString& aInputString) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
if (NS_WARN_IF(!mRules)) {
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
@ -197,7 +196,7 @@ nsresult HTMLEditor::DoInsertHTMLWithContext(
|
||||
bool aTrustedInput, bool aClearStyle) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
if (NS_WARN_IF(!mRules)) {
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
@ -1834,7 +1833,6 @@ nsresult HTMLEditor::PasteAsQuotationAsAction(int32_t aClipboardType,
|
||||
return rv;
|
||||
}
|
||||
|
||||
// XXX Why don't we call HTMLEditRules::DidDoAction() after Paste()?
|
||||
// XXX If ePaste event has not been dispatched yet but selected content
|
||||
// has already been removed and created a <blockquote> element.
|
||||
// So, web apps cannot prevent the default of ePaste event which
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "mozilla/EditAction.h"
|
||||
#include "mozilla/EditorUtils.h"
|
||||
#include "mozilla/SelectionState.h"
|
||||
#include "mozilla/TextEditRules.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/mozalloc.h"
|
||||
@ -141,7 +140,7 @@ nsresult HTMLEditor::SetInlinePropertyInternal(
|
||||
nsAtom& aProperty, nsAtom* aAttribute, const nsAString& aAttributeValue) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
if (NS_WARN_IF(!mRules)) {
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
@ -1347,7 +1346,7 @@ nsresult HTMLEditor::RemoveInlinePropertyInternal(nsAtom* aProperty,
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(aAttribute != nsGkAtoms::_empty);
|
||||
|
||||
if (NS_WARN_IF(!mRules)) {
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
|
@ -1,173 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_TextEditRules_h
|
||||
#define mozilla_TextEditRules_h
|
||||
|
||||
#include "mozilla/EditAction.h"
|
||||
#include "mozilla/EditorBase.h"
|
||||
#include "mozilla/EditorDOMPoint.h"
|
||||
#include "mozilla/EditorUtils.h"
|
||||
#include "mozilla/HTMLEditor.h" // for nsIEditor::AsHTMLEditor()
|
||||
#include "mozilla/TextEditor.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsString.h"
|
||||
#include "nscore.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class HTMLEditor;
|
||||
class HTMLEditRules;
|
||||
namespace dom {
|
||||
class HTMLBRElement;
|
||||
class Selection;
|
||||
} // namespace dom
|
||||
|
||||
/**
|
||||
* Object that encapsulates HTML text-specific editing rules.
|
||||
*
|
||||
* To be a good citizen, edit rules must live by these restrictions:
|
||||
* 1. All data manipulation is through the editor.
|
||||
* Content nodes in the document tree must <B>not</B> be manipulated
|
||||
* directly. Content nodes in document fragments that are not part of the
|
||||
* document itself may be manipulated at will. Operations on document
|
||||
* fragments must <B>not</B> go through the editor.
|
||||
* 2. Selection must not be explicitly set by the rule method.
|
||||
* Any manipulation of Selection must be done by the editor.
|
||||
* 3. Stop handling edit action if method returns NS_ERROR_EDITOR_DESTROYED
|
||||
* since if mutation event lister or selectionchange event listener disables
|
||||
* the editor, we should not modify the DOM tree anymore.
|
||||
* 4. Any method callers have to check nsresult return value (both directly or
|
||||
* with simple class like EditActionResult) whether the value is
|
||||
* NS_ERROR_EDITOR_DESTROYED at least.
|
||||
* 5. Callers of methods of other classes such as TextEditor, have to check
|
||||
* CanHandleEditAction() before checking its result and if the result is
|
||||
* false, the method have to return NS_ERROR_EDITOR_DESTROYED. In other
|
||||
* words, any methods which may change Selection or the DOM tree have to
|
||||
* return nsresult directly or with simple class like EditActionResult.
|
||||
* And such methods should be marked as MOZ_MUST_USE.
|
||||
*/
|
||||
class TextEditRules {
|
||||
protected:
|
||||
typedef EditorBase::AutoSelectionRestorer AutoSelectionRestorer;
|
||||
typedef EditorBase::AutoEditSubActionNotifier AutoEditSubActionNotifier;
|
||||
typedef EditorBase::AutoTransactionsConserveSelection
|
||||
AutoTransactionsConserveSelection;
|
||||
|
||||
public:
|
||||
typedef dom::Element Element;
|
||||
typedef dom::Selection Selection;
|
||||
typedef dom::Text Text;
|
||||
template <typename T>
|
||||
using OwningNonNull = OwningNonNull<T>;
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(TextEditRules)
|
||||
|
||||
TextEditRules();
|
||||
|
||||
HTMLEditRules* AsHTMLEditRules();
|
||||
const HTMLEditRules* AsHTMLEditRules() const;
|
||||
|
||||
virtual nsresult DetachEditor();
|
||||
|
||||
protected:
|
||||
virtual ~TextEditRules() = default;
|
||||
|
||||
void InitFields();
|
||||
|
||||
// TextEditRules implementation methods
|
||||
|
||||
bool IsSingleLineEditor() const;
|
||||
bool IsPlaintextEditor() const;
|
||||
|
||||
private:
|
||||
TextEditor* MOZ_NON_OWNING_REF mTextEditor;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* AutoSafeEditorData grabs editor instance and related instances during
|
||||
* handling an edit action. When this is created, its pointer is set to
|
||||
* the mSafeData, and this guarantees the lifetime of grabbing objects
|
||||
* until it's destroyed.
|
||||
*/
|
||||
class MOZ_STACK_CLASS AutoSafeEditorData {
|
||||
public:
|
||||
AutoSafeEditorData(TextEditRules& aTextEditRules, TextEditor& aTextEditor)
|
||||
: mTextEditRules(aTextEditRules), mHTMLEditor(nullptr) {
|
||||
// mTextEditRules may have AutoSafeEditorData instance since in some
|
||||
// cases. E.g., while public methods of *EditRules are called, it
|
||||
// calls attaching editor's method, then, editor will call public
|
||||
// methods of *EditRules again.
|
||||
if (mTextEditRules.mData) {
|
||||
return;
|
||||
}
|
||||
mTextEditor = &aTextEditor;
|
||||
mHTMLEditor = aTextEditor.AsHTMLEditor();
|
||||
mTextEditRules.mData = this;
|
||||
}
|
||||
|
||||
~AutoSafeEditorData() {
|
||||
if (mTextEditRules.mData != this) {
|
||||
return;
|
||||
}
|
||||
mTextEditRules.mData = nullptr;
|
||||
}
|
||||
|
||||
TextEditor& TextEditorRef() const { return *mTextEditor; }
|
||||
HTMLEditor& HTMLEditorRef() const {
|
||||
MOZ_ASSERT(mHTMLEditor);
|
||||
return *mHTMLEditor;
|
||||
}
|
||||
|
||||
private:
|
||||
// This class should be created by public methods TextEditRules and
|
||||
// HTMLEditRules and in the stack. So, the lifetime of this should
|
||||
// be guaranteed the callers of the public methods.
|
||||
TextEditRules& MOZ_NON_OWNING_REF mTextEditRules;
|
||||
RefPtr<TextEditor> mTextEditor;
|
||||
// Shortcut for HTMLEditorRef(). So, not necessary to use RefPtr.
|
||||
HTMLEditor* MOZ_NON_OWNING_REF mHTMLEditor;
|
||||
};
|
||||
AutoSafeEditorData* mData;
|
||||
|
||||
TextEditor& TextEditorRef() const {
|
||||
MOZ_ASSERT(mData);
|
||||
return mData->TextEditorRef();
|
||||
}
|
||||
// SelectionRefPtr() won't return nullptr unless editor instance accidentally
|
||||
// ignored result of AutoEditActionDataSetter::CanHandle() and keep handling
|
||||
// edit action.
|
||||
const RefPtr<Selection>& SelectionRefPtr() const {
|
||||
MOZ_ASSERT(mData);
|
||||
return TextEditorRef().SelectionRefPtr();
|
||||
}
|
||||
bool CanHandleEditAction() const {
|
||||
if (!mTextEditor) {
|
||||
return false;
|
||||
}
|
||||
if (mTextEditor->Destroyed()) {
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(mTextEditor->IsInitialized());
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool IsEditorDataAvailable() const { return !!mData; }
|
||||
#endif // #ifdef DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
bool mIsHandling;
|
||||
#endif // #ifdef DEBUG
|
||||
|
||||
bool mIsHTMLEditRules;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // #ifndef mozilla_TextEditRules_h
|
@ -3,9 +3,8 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/TextEditRules.h"
|
||||
#include "TextEditor.h"
|
||||
|
||||
#include "HTMLEditRules.h"
|
||||
#include "TextEditUtils.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/EditAction.h"
|
||||
@ -14,7 +13,6 @@
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/TextComposition.h"
|
||||
#include "mozilla/TextEditor.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/HTMLBRElement.h"
|
||||
#include "mozilla/dom/NodeFilterBinding.h"
|
||||
@ -50,32 +48,6 @@ using namespace dom;
|
||||
return EditActionCanceled(NS_OK); \
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
* mozilla::TextEditRules
|
||||
********************************************************/
|
||||
|
||||
TextEditRules::TextEditRules()
|
||||
: mTextEditor(nullptr),
|
||||
mData(nullptr),
|
||||
#ifdef DEBUG
|
||||
mIsHandling(false),
|
||||
#endif // #ifdef DEBUG
|
||||
mIsHTMLEditRules(false) {
|
||||
InitFields();
|
||||
}
|
||||
|
||||
void TextEditRules::InitFields() {
|
||||
mTextEditor = nullptr;
|
||||
}
|
||||
|
||||
HTMLEditRules* TextEditRules::AsHTMLEditRules() {
|
||||
return mIsHTMLEditRules ? static_cast<HTMLEditRules*>(this) : nullptr;
|
||||
}
|
||||
|
||||
const HTMLEditRules* TextEditRules::AsHTMLEditRules() const {
|
||||
return mIsHTMLEditRules ? static_cast<const HTMLEditRules*>(this) : nullptr;
|
||||
}
|
||||
|
||||
nsresult TextEditor::InitEditorContentAndSelection() {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
@ -106,11 +78,6 @@ nsresult TextEditor::InitEditorContentAndSelection() {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult TextEditRules::DetachEditor() {
|
||||
mTextEditor = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void TextEditor::OnStartToHandleTopLevelEditSubAction(
|
||||
EditSubAction aTopLevelEditSubAction,
|
||||
nsIEditor::EDirection aDirectionOfTopLevelEditSubAction, ErrorResult& aRv) {
|
||||
@ -304,8 +271,9 @@ nsresult TextEditor::EnsureCaretNotAtEndOfTextNode() {
|
||||
MOZ_ASSERT(IsPlaintextEditor());
|
||||
|
||||
// If there is no selection ranges, we should set to the end of the editor.
|
||||
// This is usually performed in TextEditRules::Init(), however, if the
|
||||
// editor is reframed, this may be called by AfterEdit().
|
||||
// This is usually performed in InitEditorContentAndSelection(), however,
|
||||
// if the editor is reframed, this may be called by
|
||||
// OnEndHandlingTopLevelEditSubAction().
|
||||
if (!SelectionRefPtr()->RangeCount()) {
|
||||
CollapseSelectionToEnd();
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
@ -982,14 +950,6 @@ EditActionResult TextEditor::TruncateInsertionStringForMaxLength(
|
||||
return EditActionHandled();
|
||||
}
|
||||
|
||||
bool TextEditRules::IsSingleLineEditor() const {
|
||||
return mTextEditor ? mTextEditor->IsSingleLineEditor() : false;
|
||||
}
|
||||
|
||||
bool TextEditRules::IsPlaintextEditor() const {
|
||||
return mTextEditor ? mTextEditor->IsPlaintextEditor() : false;
|
||||
}
|
||||
|
||||
bool TextEditor::CanEchoPasswordNow() const {
|
||||
if (!LookAndFeel::GetEchoPassword() ||
|
||||
(mFlags & nsIPlaintextEditor::eEditorDontEchoPassword)) {
|
@ -16,7 +16,6 @@ class TextEditor;
|
||||
|
||||
class TextEditUtils final {
|
||||
public:
|
||||
// from TextEditRules:
|
||||
static bool IsBody(nsINode* aNode);
|
||||
static bool IsBreak(nsINode* aNode);
|
||||
};
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "mozilla/TextEditor.h"
|
||||
|
||||
#include "EditAggregateTransaction.h"
|
||||
#include "HTMLEditRules.h"
|
||||
#include "InternetCiter.h"
|
||||
#include "TextEditUtils.h"
|
||||
#include "gfxFontUtils.h"
|
||||
@ -21,7 +20,6 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/PresShell.h"
|
||||
#include "mozilla/StaticPrefs_editor.h"
|
||||
#include "mozilla/TextEditRules.h"
|
||||
#include "mozilla/TextComposition.h"
|
||||
#include "mozilla/TextEvents.h"
|
||||
#include "mozilla/TextServicesDocument.h"
|
||||
@ -96,16 +94,11 @@ TextEditor::~TextEditor() {
|
||||
// Remove event listeners. Note that if we had an HTML editor,
|
||||
// it installed its own instead of these
|
||||
RemoveEventListeners();
|
||||
|
||||
if (mRules) mRules->DetachEditor();
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(TextEditor)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(TextEditor, EditorBase)
|
||||
if (tmp->mRules) {
|
||||
tmp->mRules->DetachEditor();
|
||||
}
|
||||
if (tmp->mMaskTimer) {
|
||||
tmp->mMaskTimer->Cancel();
|
||||
}
|
||||
@ -130,9 +123,7 @@ NS_INTERFACE_MAP_END_INHERITING(EditorBase)
|
||||
nsresult TextEditor::Init(Document& aDoc, Element* aRoot,
|
||||
nsISelectionController* aSelCon, uint32_t aFlags,
|
||||
const nsAString& aInitialValue) {
|
||||
if (mRules) {
|
||||
mRules->DetachEditor();
|
||||
}
|
||||
mInitSucceeded = false;
|
||||
|
||||
nsresult rulesRv = NS_OK;
|
||||
{
|
||||
@ -197,10 +188,11 @@ nsresult TextEditor::EndEditorInit() {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
nsresult rv = InitRules();
|
||||
nsresult rv = InitEditorContentAndSelection();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Throw away the old transaction manager if this is not the first time that
|
||||
// we're initializing the editor.
|
||||
ClearUndoRedo();
|
||||
@ -314,19 +306,6 @@ bool TextEditor::UpdateMetaCharset(Document& aDocument,
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult TextEditor::InitRules() {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
if (!mRules) {
|
||||
// instantiate the rules for this text editor
|
||||
mRules = new TextEditRules();
|
||||
}
|
||||
nsresult rv = InitEditorContentAndSelection();
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"InitEditorContentAndSelection() failed");
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult TextEditor::HandleKeyPressEvent(WidgetKeyboardEvent* aKeyboardEvent) {
|
||||
// NOTE: When you change this method, you should also change:
|
||||
// * editor/libeditor/tests/test_texteditor_keyevent_handling.html
|
||||
@ -648,7 +627,7 @@ nsresult TextEditor::DeleteSelectionAsSubAction(EDirection aDirectionAndAmount,
|
||||
|
||||
MOZ_ASSERT(aStripWrappers == eStrip || aStripWrappers == eNoStrip);
|
||||
|
||||
if (!mRules) {
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
@ -946,7 +925,7 @@ nsresult TextEditor::InsertTextAsSubAction(const nsAString& aStringToInsert) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(mPlaceholderBatch);
|
||||
|
||||
if (!mRules) {
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
@ -991,7 +970,7 @@ TextEditor::InsertLineBreak() {
|
||||
nsresult TextEditor::InsertLineBreakAsSubAction() {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
if (!mRules) {
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
|
@ -389,12 +389,10 @@ class TextEditor : public EditorBase,
|
||||
|
||||
protected: // May be called by friends.
|
||||
/****************************************************************************
|
||||
* Some classes like TextEditRules, HTMLEditRules, WSRunObject which are
|
||||
* part of handling edit actions are allowed to call the following protected
|
||||
* methods. However, those methods won't prepare caches of some objects
|
||||
* which are necessary for them. So, if you want some following methods
|
||||
* to do that for you, you need to create a wrapper method in public scope
|
||||
* and call it.
|
||||
* Some friend classes are allowed to call the following protected methods.
|
||||
* However, those methods won't prepare caches of some objects which are
|
||||
* necessary for them. So, if you call them from friend classes, you need
|
||||
* to make sure that AutoEditActionDataSetter is created.
|
||||
****************************************************************************/
|
||||
|
||||
// Overrides of EditorBase
|
||||
@ -796,9 +794,6 @@ class TextEditor : public EditorBase,
|
||||
*/
|
||||
bool IsSafeToInsertData(Document* aSourceDoc);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
virtual nsresult InitRules();
|
||||
|
||||
/**
|
||||
* GetAndInitDocEncoder() returns a document encoder instance for aFormatType
|
||||
* after initializing it. The result may be cached for saving recreation
|
||||
@ -925,7 +920,6 @@ class TextEditor : public EditorBase,
|
||||
friend class DeleteNodeTransaction;
|
||||
friend class EditorBase;
|
||||
friend class InsertNodeTransaction;
|
||||
friend class TextEditRules;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -25,8 +25,6 @@ class nsAtom;
|
||||
class nsINode;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class HTMLEditRules;
|
||||
namespace dom {
|
||||
class Selection;
|
||||
} // namespace dom
|
||||
@ -150,8 +148,6 @@ class TypeInState final {
|
||||
nsTArray<PropItem*> mClearedArray;
|
||||
EditorDOMPoint mLastSelectionPoint;
|
||||
int32_t mRelativeFontSize;
|
||||
|
||||
friend class HTMLEditRules;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -187,8 +187,8 @@ already_AddRefed<Element> WSRunObject::InsertBreak(
|
||||
}
|
||||
|
||||
// MOOSE: for now, we always assume non-PRE formatting. Fix this later.
|
||||
// meanwhile, the pre case is handled in WillInsertText in
|
||||
// HTMLEditRules.cpp
|
||||
// meanwhile, the pre case is handled in HandleInsertText() in
|
||||
// HTMLEditSubActionHandler.cpp
|
||||
|
||||
WSFragment* beforeRun = FindNearestRun(aPointToInsert, false);
|
||||
WSFragment* afterRun = FindNearestRun(aPointToInsert, true);
|
||||
@ -260,8 +260,8 @@ nsresult WSRunObject::InsertText(Document& aDocument,
|
||||
EditorRawDOMPoint* aPointAfterInsertedString)
|
||||
MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
|
||||
// MOOSE: for now, we always assume non-PRE formatting. Fix this later.
|
||||
// meanwhile, the pre case is handled in WillInsertText in
|
||||
// HTMLEditRules.cpp
|
||||
// meanwhile, the pre case is handled in HandleInsertText() in
|
||||
// HTMLEditSubActionHandler.cpp
|
||||
|
||||
// MOOSE: for now, just getting the ws logic straight. This implementation
|
||||
// is very slow. Will need to replace edit rules impl with a more efficient
|
||||
|
@ -14,7 +14,6 @@
|
||||
namespace mozilla {
|
||||
|
||||
class HTMLEditor;
|
||||
class HTMLEditRules;
|
||||
|
||||
// class WSRunObject represents the entire whitespace situation
|
||||
// around a given point. It collects up a list of nodes that contain
|
||||
@ -603,8 +602,6 @@ class MOZ_STACK_CLASS WSRunObject final : public WSRunScanner {
|
||||
// Non-owning.
|
||||
HTMLEditor* mHTMLEditor;
|
||||
|
||||
// Opening this class up for pillaging.
|
||||
friend class HTMLEditRules;
|
||||
// Opening this class up for more pillaging.
|
||||
friend class HTMLEditor;
|
||||
};
|
||||
|
@ -28,7 +28,6 @@ EXPORTS.mozilla += [
|
||||
'ManualNAC.h',
|
||||
'SelectionState.h',
|
||||
'TextEditor.h',
|
||||
'TextEditRules.h',
|
||||
'TypeInState.h',
|
||||
]
|
||||
|
||||
@ -57,7 +56,7 @@ UNIFIED_SOURCES += [
|
||||
'HTMLEditorDocumentCommands.cpp',
|
||||
'HTMLEditorEventListener.cpp',
|
||||
'HTMLEditorObjectResizer.cpp',
|
||||
'HTMLEditRules.cpp',
|
||||
'HTMLEditSubActionHandler.cpp',
|
||||
'HTMLEditUtils.cpp',
|
||||
'HTMLInlineTableEditor.cpp',
|
||||
'HTMLStyleEditor.cpp',
|
||||
@ -71,7 +70,7 @@ UNIFIED_SOURCES += [
|
||||
'SplitNodeTransaction.cpp',
|
||||
'TextEditor.cpp',
|
||||
'TextEditorDataTransfer.cpp',
|
||||
'TextEditRules.cpp',
|
||||
'TextEditSubActionHandler.cpp',
|
||||
'TextEditUtils.cpp',
|
||||
'TypeInState.cpp',
|
||||
'WSRunObject.cpp',
|
||||
|
@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for TextEditRules::HandlingNewLines()</title>
|
||||
<title>Test for TextEditor::HandleNewLinesInStringForSingleLineEditor()</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
|
Loading…
Reference in New Issue
Block a user