2001-09-26 02:53:13 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* 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/. */
|
1999-03-29 10:21:01 +04:00
|
|
|
|
2016-07-07 13:05:51 +03:00
|
|
|
#ifndef HTMLEditRules_h
|
|
|
|
#define HTMLEditRules_h
|
1999-03-29 10:21:01 +04:00
|
|
|
|
2003-06-03 02:21:06 +04:00
|
|
|
#include "TypeInState.h"
|
2017-11-01 08:41:03 +03:00
|
|
|
#include "mozilla/EditorDOMPoint.h" // for EditorDOMPoint
|
2016-07-09 05:34:41 +03:00
|
|
|
#include "mozilla/SelectionState.h"
|
|
|
|
#include "mozilla/TextEditRules.h"
|
2012-07-13 10:33:42 +04:00
|
|
|
#include "nsCOMPtr.h"
|
|
|
|
#include "nsIEditor.h"
|
|
|
|
#include "nsIHTMLEditor.h"
|
|
|
|
#include "nsISupportsImpl.h"
|
2009-04-22 12:43:15 +04:00
|
|
|
#include "nsTArray.h"
|
2012-07-13 10:33:42 +04:00
|
|
|
#include "nscore.h"
|
1999-03-29 10:21:01 +04:00
|
|
|
|
2017-10-03 01:05:19 +03:00
|
|
|
class nsAtom;
|
2000-05-04 12:33:48 +04:00
|
|
|
class nsIEditor;
|
2012-07-13 10:33:42 +04:00
|
|
|
class nsINode;
|
|
|
|
class nsRange;
|
2016-07-07 13:05:51 +03:00
|
|
|
|
2012-07-13 10:33:42 +04:00
|
|
|
namespace mozilla {
|
2016-07-07 13:05:51 +03:00
|
|
|
|
2016-11-18 11:59:23 +03:00
|
|
|
class EditActionResult;
|
2016-07-09 05:42:33 +03:00
|
|
|
class HTMLEditor;
|
2017-11-17 10:03:11 +03:00
|
|
|
class SplitNodeResult;
|
2016-07-09 05:54:50 +03:00
|
|
|
class TextEditor;
|
Bug 1463985 - part 1: Rename EditAction to EditSubAction and related stuff r=m_kato
When we implement InputEvent.inputType, we need to set a stack class to record
which edit action is currently handled. However, currently, we call smaller
jobs as edit action. For example, when user types a character at selecting
some characters, then, EditAction::deleteSelection is performed first, then,
EditAction::insertText is performed. However, for the InputEvent.inputType,
we need inserText information. So, for making new enum EditAction, we need
to rename current EditAction to EditSubAction.
And also this renames related stuff:
EditorBase::mIsInEditAction -> EditorBase::mIsInEditSubAction
EditorBase::IsInEditAction() -> EditorBase::IsInEditSubAction()
EditorBase::mAction -> EditorBase::mTopLevelEditSubAction
TextEditRules::mTheAction -> TextEditRules::mTopLevelEditSubAction
EditorBase::StartOperation() ->
EditorBase::OnStartToHandleTopLevelEditSubAction()
EditorBase::EndOperation() ->
EditorBase::OnEndHandlingTopLevelEditSubAction()
AutoRules -> AutoTopLevelEditSubActionNotifier
RulesInfo -> EditSubActionInfo
MozReview-Commit-ID: cvSkPUjFm1
--HG--
extra : rebase_source : baf527a3e353b7a8ebe9a46be2243b059c500234
2018-05-28 14:12:34 +03:00
|
|
|
enum class EditSubAction : int32_t;
|
2018-01-12 13:01:04 +03:00
|
|
|
|
2012-07-13 10:33:42 +04:00
|
|
|
namespace dom {
|
2019-01-02 16:05:23 +03:00
|
|
|
class Document;
|
2012-07-13 10:33:42 +04:00
|
|
|
class Element;
|
2014-04-10 20:09:40 +04:00
|
|
|
class Selection;
|
2015-07-13 18:25:42 +03:00
|
|
|
} // namespace dom
|
1999-06-16 09:02:43 +04:00
|
|
|
|
2016-07-07 13:05:51 +03:00
|
|
|
struct StyleCache final : public PropItem {
|
2011-09-29 10:19:26 +04:00
|
|
|
bool mPresent;
|
2015-05-28 18:58:42 +03:00
|
|
|
|
2007-12-12 06:23:34 +03:00
|
|
|
StyleCache() : PropItem(), mPresent(false) { MOZ_COUNT_CTOR(StyleCache); }
|
|
|
|
|
2017-10-03 01:05:19 +03:00
|
|
|
StyleCache(nsAtom* aTag, nsAtom* aAttr, const nsAString& aValue)
|
2016-07-07 13:05:51 +03:00
|
|
|
: PropItem(aTag, aAttr, aValue), mPresent(false) {
|
2007-12-12 06:23:34 +03:00
|
|
|
MOZ_COUNT_CTOR(StyleCache);
|
|
|
|
}
|
|
|
|
|
2017-10-03 01:05:19 +03:00
|
|
|
StyleCache(nsAtom* aTag, nsAtom* aAttr)
|
2017-01-06 16:35:48 +03:00
|
|
|
: PropItem(aTag, aAttr, EmptyString()), mPresent(false) {
|
|
|
|
MOZ_COUNT_CTOR(StyleCache);
|
|
|
|
}
|
|
|
|
|
2007-12-12 06:23:34 +03:00
|
|
|
~StyleCache() { MOZ_COUNT_DTOR(StyleCache); }
|
2003-06-03 02:21:06 +04:00
|
|
|
};
|
|
|
|
|
2018-05-18 06:38:32 +03:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2003-06-03 02:21:06 +04:00
|
|
|
#define SIZE_STYLE_TABLE 19
|
|
|
|
|
2016-07-09 05:34:41 +03:00
|
|
|
class HTMLEditRules : public TextEditRules {
|
1999-03-29 10:21:01 +04:00
|
|
|
public:
|
2000-03-24 03:26:47 +03:00
|
|
|
NS_DECL_ISUPPORTS_INHERITED
|
2016-07-09 05:34:41 +03:00
|
|
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLEditRules, TextEditRules)
|
1999-03-29 10:21:01 +04:00
|
|
|
|
2016-07-07 13:05:51 +03:00
|
|
|
HTMLEditRules();
|
2000-03-24 03:26:47 +03:00
|
|
|
|
2017-12-21 08:52:32 +03:00
|
|
|
// TextEditRules methods
|
|
|
|
virtual nsresult Init(TextEditor* aTextEditor) override;
|
|
|
|
virtual nsresult DetachEditor() override;
|
Bug 1463985 - part 1: Rename EditAction to EditSubAction and related stuff r=m_kato
When we implement InputEvent.inputType, we need to set a stack class to record
which edit action is currently handled. However, currently, we call smaller
jobs as edit action. For example, when user types a character at selecting
some characters, then, EditAction::deleteSelection is performed first, then,
EditAction::insertText is performed. However, for the InputEvent.inputType,
we need inserText information. So, for making new enum EditAction, we need
to rename current EditAction to EditSubAction.
And also this renames related stuff:
EditorBase::mIsInEditAction -> EditorBase::mIsInEditSubAction
EditorBase::IsInEditAction() -> EditorBase::IsInEditSubAction()
EditorBase::mAction -> EditorBase::mTopLevelEditSubAction
TextEditRules::mTheAction -> TextEditRules::mTopLevelEditSubAction
EditorBase::StartOperation() ->
EditorBase::OnStartToHandleTopLevelEditSubAction()
EditorBase::EndOperation() ->
EditorBase::OnEndHandlingTopLevelEditSubAction()
AutoRules -> AutoTopLevelEditSubActionNotifier
RulesInfo -> EditSubActionInfo
MozReview-Commit-ID: cvSkPUjFm1
--HG--
extra : rebase_source : baf527a3e353b7a8ebe9a46be2243b059c500234
2018-05-28 14:12:34 +03:00
|
|
|
virtual nsresult BeforeEdit(EditSubAction aEditSubAction,
|
2017-12-21 08:52:32 +03:00
|
|
|
nsIEditor::EDirection aDirection) override;
|
Bug 1463985 - part 1: Rename EditAction to EditSubAction and related stuff r=m_kato
When we implement InputEvent.inputType, we need to set a stack class to record
which edit action is currently handled. However, currently, we call smaller
jobs as edit action. For example, when user types a character at selecting
some characters, then, EditAction::deleteSelection is performed first, then,
EditAction::insertText is performed. However, for the InputEvent.inputType,
we need inserText information. So, for making new enum EditAction, we need
to rename current EditAction to EditSubAction.
And also this renames related stuff:
EditorBase::mIsInEditAction -> EditorBase::mIsInEditSubAction
EditorBase::IsInEditAction() -> EditorBase::IsInEditSubAction()
EditorBase::mAction -> EditorBase::mTopLevelEditSubAction
TextEditRules::mTheAction -> TextEditRules::mTopLevelEditSubAction
EditorBase::StartOperation() ->
EditorBase::OnStartToHandleTopLevelEditSubAction()
EditorBase::EndOperation() ->
EditorBase::OnEndHandlingTopLevelEditSubAction()
AutoRules -> AutoTopLevelEditSubActionNotifier
RulesInfo -> EditSubActionInfo
MozReview-Commit-ID: cvSkPUjFm1
--HG--
extra : rebase_source : baf527a3e353b7a8ebe9a46be2243b059c500234
2018-05-28 14:12:34 +03:00
|
|
|
virtual nsresult AfterEdit(EditSubAction aEditSubAction,
|
2017-12-21 08:52:32 +03:00
|
|
|
nsIEditor::EDirection aDirection) override;
|
2018-11-03 14:20:06 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
2018-10-30 13:02:58 +03:00
|
|
|
virtual nsresult WillDoAction(EditSubActionInfo& aInfo, bool* aCancel,
|
2017-12-21 08:52:32 +03:00
|
|
|
bool* aHandled) override;
|
2018-10-30 13:02:58 +03:00
|
|
|
virtual nsresult DidDoAction(EditSubActionInfo& aInfo,
|
2017-12-21 08:52:32 +03:00
|
|
|
nsresult aResult) override;
|
|
|
|
virtual bool DocumentIsEmpty() override;
|
2018-10-25 08:55:04 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* DocumentModified() is called when editor content is changed.
|
|
|
|
*/
|
|
|
|
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult DocumentModified();
|
1999-04-05 21:21:59 +04:00
|
|
|
|
2016-07-07 13:05:51 +03:00
|
|
|
nsresult GetListState(bool* aMixed, bool* aOL, bool* aUL, bool* aDL);
|
|
|
|
nsresult GetListItemState(bool* aMixed, bool* aLI, bool* aDT, bool* aDD);
|
|
|
|
nsresult GetAlignment(bool* aMixed, nsIHTMLEditor::EAlignment* aAlign);
|
|
|
|
nsresult GetParagraphState(bool* aMixed, nsAString& outFormat);
|
2018-05-12 05:25:23 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* MakeSureElemStartsAndEndsOnCR() inserts <br> element at start (and/or end)
|
|
|
|
* of aNode if neither:
|
|
|
|
* - first (last) editable child of aNode is a block or a <br>,
|
|
|
|
* - previous (next) sibling of aNode is block or a <br>
|
|
|
|
* - nor no previous (next) sibling of aNode.
|
|
|
|
*
|
|
|
|
* @param aNode The node which may be inserted <br> elements.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult MakeSureElemStartsAndEndsOnCR(nsINode& aNode);
|
2000-05-03 04:14:28 +04:00
|
|
|
|
2018-10-30 13:02:58 +03:00
|
|
|
void DidCreateNode(Element& aNewElement);
|
|
|
|
void DidInsertNode(nsIContent& aNode);
|
|
|
|
void WillDeleteNode(nsINode& aChild);
|
|
|
|
void DidSplitNode(nsINode& aExistingRightNode, nsINode& aNewLeftNode);
|
2018-01-12 18:21:17 +03:00
|
|
|
void WillJoinNodes(nsINode& aLeftNode, nsINode& aRightNode);
|
2018-10-30 13:02:58 +03:00
|
|
|
void DidJoinNodes(nsINode& aLeftNode, nsINode& aRightNode);
|
|
|
|
void DidInsertText(nsINode& aTextNode, int32_t aOffset,
|
2018-01-12 18:21:17 +03:00
|
|
|
const nsAString& aString);
|
2018-10-30 13:02:58 +03:00
|
|
|
void DidDeleteText(nsINode& aTextNode, int32_t aOffset, int32_t aLength);
|
|
|
|
void WillDeleteSelection();
|
2018-01-12 18:21:17 +03:00
|
|
|
|
Bug 1463985 - part 1: Rename EditAction to EditSubAction and related stuff r=m_kato
When we implement InputEvent.inputType, we need to set a stack class to record
which edit action is currently handled. However, currently, we call smaller
jobs as edit action. For example, when user types a character at selecting
some characters, then, EditAction::deleteSelection is performed first, then,
EditAction::insertText is performed. However, for the InputEvent.inputType,
we need inserText information. So, for making new enum EditAction, we need
to rename current EditAction to EditSubAction.
And also this renames related stuff:
EditorBase::mIsInEditAction -> EditorBase::mIsInEditSubAction
EditorBase::IsInEditAction() -> EditorBase::IsInEditSubAction()
EditorBase::mAction -> EditorBase::mTopLevelEditSubAction
TextEditRules::mTheAction -> TextEditRules::mTopLevelEditSubAction
EditorBase::StartOperation() ->
EditorBase::OnStartToHandleTopLevelEditSubAction()
EditorBase::EndOperation() ->
EditorBase::OnEndHandlingTopLevelEditSubAction()
AutoRules -> AutoTopLevelEditSubActionNotifier
RulesInfo -> EditSubActionInfo
MozReview-Commit-ID: cvSkPUjFm1
--HG--
extra : rebase_source : baf527a3e353b7a8ebe9a46be2243b059c500234
2018-05-28 14:12:34 +03:00
|
|
|
void StartToListenToEditSubActions() { mListenerEnabled = true; }
|
|
|
|
void EndListeningToEditSubActions() { mListenerEnabled = false; }
|
2018-01-12 18:21:17 +03:00
|
|
|
|
2018-10-25 08:55:04 +03:00
|
|
|
/**
|
|
|
|
* OnModifyDocument() is called when DocumentModifiedWorker() calls
|
2018-10-30 13:02:58 +03:00
|
|
|
* HTMLEditor::OnModifyDocument(). The caller guarantees that there
|
|
|
|
* is AutoEditActionDataSetter instance in the editor.
|
2018-10-25 08:55:04 +03:00
|
|
|
*/
|
2018-10-30 13:02:58 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT void OnModifyDocument();
|
2018-10-25 08:55:04 +03:00
|
|
|
|
1999-04-05 21:21:59 +04:00
|
|
|
protected:
|
2016-07-07 13:05:51 +03:00
|
|
|
virtual ~HTMLEditRules();
|
1999-04-05 21:21:59 +04:00
|
|
|
|
2018-04-26 16:41:34 +03:00
|
|
|
HTMLEditor& HTMLEditorRef() const {
|
|
|
|
MOZ_ASSERT(mData);
|
|
|
|
return mData->HTMLEditorRef();
|
|
|
|
}
|
|
|
|
|
Bug 1463327 - part 3: Change scope of some methods of HTMLEditor which won't be called by non-helper classes of editing to protected r=m_kato
HTMLEditor has 2 type of public methods. One is rue-public methods. I.e.,
they should be able to be called by anybody. E.g., command handlers, event
listeners, or JS via nsIEditor interface. The other is semi-public methods.
They are not called by the above examples but called by other classes which
are helper classes to handle edit actions. E.g., TextEditRules, HTMLEditRules,
HTMLEditUtils, CSSEditUtils and Transaction classes.
When we will implement InputEvent.inputType, we need to create new stack
class and create its instance at every true-public methods to manage current
inputType (like TextEditRules::AutoSafeEditorData). Therefore, it should not
happen that new code starts to call semi-public methods without the new
stack class instance.
For preventing this issue, we should make HTMLEditor have only the true-public
methods as public. The other public methods should be protected and their
users should be friend classes. Then, we can protect such method from external
classes.
Note that this patch just moves the methods without any changes in HTMLEditor.h
(except removes BlockTransformationType since it's unused and replaces
ResizingRequestID with new enum class ResizeAt since normal enum isn't hit by
searchfox.org).
MozReview-Commit-ID: 7PC8E8vD7w2
--HG--
extra : rebase_source : 13f51565f2b89ab816ba529af18ee88193a9c932
2018-05-22 12:28:50 +03:00
|
|
|
static bool IsBlockNode(const nsINode& aNode) {
|
|
|
|
return HTMLEditor::NodeIsBlockStatic(&aNode);
|
|
|
|
}
|
|
|
|
static bool IsInlineNode(const nsINode& aNode) { return !IsBlockNode(aNode); }
|
|
|
|
|
1999-06-16 09:02:43 +04:00
|
|
|
enum RulesEndpoint { kStart, kEnd };
|
|
|
|
|
2014-05-10 01:02:29 +04:00
|
|
|
void InitFields();
|
|
|
|
|
2018-05-16 08:21:21 +03:00
|
|
|
/**
|
|
|
|
* Called before inserting something into the editor.
|
|
|
|
* This method may removes mBougsNode if there is. Therefore, this method
|
|
|
|
* might cause destroying the editor.
|
|
|
|
*
|
|
|
|
* @param aCancel Returns true if the operation is canceled.
|
|
|
|
* This can be nullptr.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult WillInsert(bool* aCancel = nullptr);
|
2018-05-16 08:05:10 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Called before inserting text.
|
|
|
|
* This method may actually inserts text into the editor. Therefore, this
|
|
|
|
* might cause destroying the editor.
|
|
|
|
*
|
2018-05-28 15:44:39 +03:00
|
|
|
* @param aEditSubAction Must be EditSubAction::eInsertTextComingFromIME
|
|
|
|
* or EditSubAction::eInsertText.
|
2018-05-16 08:05:10 +03:00
|
|
|
* @param aCancel Returns true if the operation is canceled.
|
|
|
|
* @param aHandled Returns true if the edit action is handled.
|
|
|
|
* @param inString String to be inserted.
|
|
|
|
* @param outString String actually inserted.
|
|
|
|
* @param aMaxLength The maximum string length which the editor
|
|
|
|
* allows to set.
|
|
|
|
*/
|
Bug 1463985 - part 1: Rename EditAction to EditSubAction and related stuff r=m_kato
When we implement InputEvent.inputType, we need to set a stack class to record
which edit action is currently handled. However, currently, we call smaller
jobs as edit action. For example, when user types a character at selecting
some characters, then, EditAction::deleteSelection is performed first, then,
EditAction::insertText is performed. However, for the InputEvent.inputType,
we need inserText information. So, for making new enum EditAction, we need
to rename current EditAction to EditSubAction.
And also this renames related stuff:
EditorBase::mIsInEditAction -> EditorBase::mIsInEditSubAction
EditorBase::IsInEditAction() -> EditorBase::IsInEditSubAction()
EditorBase::mAction -> EditorBase::mTopLevelEditSubAction
TextEditRules::mTheAction -> TextEditRules::mTopLevelEditSubAction
EditorBase::StartOperation() ->
EditorBase::OnStartToHandleTopLevelEditSubAction()
EditorBase::EndOperation() ->
EditorBase::OnEndHandlingTopLevelEditSubAction()
AutoRules -> AutoTopLevelEditSubActionNotifier
RulesInfo -> EditSubActionInfo
MozReview-Commit-ID: cvSkPUjFm1
--HG--
extra : rebase_source : baf527a3e353b7a8ebe9a46be2243b059c500234
2018-05-28 14:12:34 +03:00
|
|
|
MOZ_MUST_USE nsresult WillInsertText(EditSubAction aEditSubAction,
|
|
|
|
bool* aCancel, bool* aHandled,
|
2018-05-16 08:05:10 +03:00
|
|
|
const nsAString* inString,
|
|
|
|
nsAString* outString,
|
|
|
|
int32_t aMaxLength);
|
2018-05-16 07:56:33 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* WillLoadHTML() is called before loading enter document from source.
|
|
|
|
* This removes bogus node if there is.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult WillLoadHTML();
|
2018-05-16 07:49:56 +03:00
|
|
|
|
|
|
|
/**
|
2018-11-03 14:20:06 +03:00
|
|
|
* WillInsertParagraphSeparator() is called when insertParagraph command is
|
|
|
|
* executed or something equivalent. This method actually tries to insert
|
|
|
|
* new paragraph or <br> element, etc.
|
2018-05-16 07:49:56 +03:00
|
|
|
*/
|
2018-11-03 14:20:06 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT
|
|
|
|
MOZ_MUST_USE EditActionResult WillInsertParagraphSeparator();
|
2017-12-11 12:28:46 +03:00
|
|
|
|
2018-05-17 18:31:20 +03:00
|
|
|
/**
|
|
|
|
* If aNode is a text node that contains only collapsed whitespace, delete
|
|
|
|
* it. It doesn't serve any useful purpose, and we don't want it to confuse
|
|
|
|
* code that doesn't correctly skip over it.
|
|
|
|
*
|
|
|
|
* If deleting the node fails (like if it's not editable), the caller should
|
|
|
|
* proceed as usual, so don't return any errors.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult DeleteNodeIfCollapsedText(nsINode& aNode);
|
2018-04-26 16:41:34 +03:00
|
|
|
|
2017-12-11 12:28:46 +03:00
|
|
|
/**
|
|
|
|
* InsertBRElement() inserts a <br> element into aInsertToBreak.
|
|
|
|
*
|
|
|
|
* @param aInsertToBreak The point where new <br> element will be
|
|
|
|
* inserted before.
|
|
|
|
*/
|
2018-05-15 19:47:54 +03:00
|
|
|
MOZ_MUST_USE nsresult InsertBRElement(const EditorDOMPoint& aInsertToBreak);
|
2017-12-11 12:28:46 +03:00
|
|
|
|
2018-05-15 19:30:44 +03:00
|
|
|
/**
|
|
|
|
* SplitMailCites() splits mail-cite elements at start of Selection if
|
|
|
|
* Selection starts from inside a mail-cite element. Of course, if it's
|
|
|
|
* necessary, this inserts <br> node to new left nodes or existing right
|
|
|
|
* nodes.
|
|
|
|
*/
|
2018-11-03 14:20:06 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT
|
|
|
|
MOZ_MUST_USE EditActionResult SplitMailCites();
|
2018-05-15 19:30:44 +03:00
|
|
|
|
2018-05-17 18:43:52 +03:00
|
|
|
/**
|
|
|
|
* Called before deleting selected contents. This method actually removes
|
|
|
|
* selected contents.
|
|
|
|
*
|
|
|
|
* @param aAction Direction of the deletion.
|
|
|
|
* @param aStripWrappers Must be eStrip or eNoStrip.
|
|
|
|
* @param aCancel Returns true if the operation is canceled.
|
|
|
|
* @param aHandled Returns true if the edit action is handled.
|
|
|
|
*/
|
2019-03-26 13:09:47 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT
|
2018-05-17 18:43:52 +03:00
|
|
|
MOZ_MUST_USE nsresult WillDeleteSelection(
|
|
|
|
nsIEditor::EDirection aAction, nsIEditor::EStripWrappers aStripWrappers,
|
|
|
|
bool* aCancel, bool* aHandled);
|
2018-05-17 17:21:52 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Called after deleting selected content.
|
|
|
|
* This method removes unnecessary empty nodes and/or inserts <br> if
|
|
|
|
* necessary.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult DidDeleteSelection();
|
|
|
|
|
2018-05-18 06:41:53 +03:00
|
|
|
/**
|
|
|
|
* InsertBRIfNeeded() determines if a br is needed for current selection to
|
|
|
|
* not be spastic. If so, it inserts one. Callers responsibility to only
|
|
|
|
* call with collapsed selection.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult InsertBRIfNeeded();
|
2017-08-01 16:38:50 +03:00
|
|
|
|
2017-10-26 19:27:44 +03:00
|
|
|
/**
|
|
|
|
* CanContainParagraph() returns true if aElement can have a <p> element as
|
|
|
|
* its child or its descendant.
|
|
|
|
*/
|
|
|
|
bool CanContainParagraph(Element& aElement) const;
|
|
|
|
|
2018-05-12 05:56:56 +03:00
|
|
|
/**
|
|
|
|
* Insert normal <br> element into aNode when aNode is a block and it has
|
|
|
|
* no children.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult InsertBRIfNeeded(nsINode& aNode) {
|
|
|
|
return InsertBRIfNeededInternal(aNode, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Insert moz-<br> element (<br type="_moz">) into aNode when aNode is a
|
|
|
|
* block and it has no children.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult InsertMozBRIfNeeded(nsINode& aNode) {
|
|
|
|
return InsertBRIfNeededInternal(aNode, true);
|
|
|
|
}
|
|
|
|
|
2017-08-01 16:38:50 +03:00
|
|
|
/**
|
|
|
|
* Insert a normal <br> element or a moz-<br> element to aNode when
|
2018-05-12 05:56:56 +03:00
|
|
|
* aNode is a block and it has no children. Use InsertBRIfNeeded() or
|
|
|
|
* InsertMozBRIfNeeded() instead.
|
2017-08-01 16:38:50 +03:00
|
|
|
*
|
|
|
|
* @param aNode Reference to a block parent.
|
|
|
|
* @param aInsertMozBR true if this should insert a moz-<br> element.
|
|
|
|
* Otherwise, i.e., this should insert a normal <br>
|
|
|
|
* element, false.
|
|
|
|
*/
|
2018-05-12 05:56:56 +03:00
|
|
|
MOZ_MUST_USE nsresult InsertBRIfNeededInternal(nsINode& aNode,
|
|
|
|
bool aInsertMozBR);
|
2017-08-01 16:38:50 +03:00
|
|
|
|
2018-05-18 06:38:32 +03:00
|
|
|
/**
|
|
|
|
* GetGoodSelPointForNode() finds where at a node you would want to set the
|
|
|
|
* selection if you were trying to have a caret next to it. Always returns a
|
|
|
|
* valid value (unless mHTMLEditor has gone away).
|
|
|
|
*
|
|
|
|
* @param aNode The node
|
|
|
|
* @param aAction Which edge to find:
|
|
|
|
* eNext/eNextWord/eToEndOfLine indicates beginning,
|
|
|
|
* ePrevious/PreviousWord/eToBeginningOfLine ending.
|
|
|
|
*/
|
2017-11-01 08:41:03 +03:00
|
|
|
EditorDOMPoint GetGoodSelPointForNode(nsINode& aNode,
|
|
|
|
nsIEditor::EDirection aAction);
|
Bug 1316302 part.1 Helper methods for HTMLEditRules::WillDeleteSelection() should have an out argument to indicates if it actually handles the action r=smaug
When HTMLEditRules::WillDeleteSelection() tries to remove something from the end/start of a block to its last/first text node but it's contained by block elements, it tries to join the container and the block. However, JoinBlocks() always fails to join them since it's impossible operation. In this case, HTMLEditRules::WillDeleteSelection() should retry to remove something in the leaf, however, it's impossible for now because JoinBlocks() and its helper methods don't return if it handles the action actually.
This patch renames |JoinBlocks()| to |TryToJoinBlocks()| for representing what it is. And this patch adds |bool* aHandled| to the helper methods. Then, *aHandled and *aCancel are now always returns the result of each method. Therefore, for merging the result of multiple helper methods, callers need to receive the result with temporary variables and merge them by themselves.
Note that when they modify DOM node actually or the action should do nothing (for example, selection is across tables), aHandled is set to true.
MozReview-Commit-ID: 7ApUOgtLUog
--HG--
extra : rebase_source : 4abc1ec208107b782a719df058623fd7f92d180c
2016-11-18 11:54:31 +03:00
|
|
|
|
|
|
|
/**
|
2018-04-09 21:46:44 +03:00
|
|
|
* TryToJoinBlocksWithTransaction() tries to join two block elements. The
|
|
|
|
* right element is always joined to the left element. If the elements are
|
|
|
|
* the same type and not nested within each other,
|
|
|
|
* JoinEditableNodesWithTransaction() is called (example, joining two list
|
|
|
|
* items together into one). If the elements are not the same type, or one
|
|
|
|
* is a descendant of the other, we instead destroy the right block placing
|
|
|
|
* its children into leftblock. DTD containment rules are followed
|
Bug 1316302 part.1 Helper methods for HTMLEditRules::WillDeleteSelection() should have an out argument to indicates if it actually handles the action r=smaug
When HTMLEditRules::WillDeleteSelection() tries to remove something from the end/start of a block to its last/first text node but it's contained by block elements, it tries to join the container and the block. However, JoinBlocks() always fails to join them since it's impossible operation. In this case, HTMLEditRules::WillDeleteSelection() should retry to remove something in the leaf, however, it's impossible for now because JoinBlocks() and its helper methods don't return if it handles the action actually.
This patch renames |JoinBlocks()| to |TryToJoinBlocks()| for representing what it is. And this patch adds |bool* aHandled| to the helper methods. Then, *aHandled and *aCancel are now always returns the result of each method. Therefore, for merging the result of multiple helper methods, callers need to receive the result with temporary variables and merge them by themselves.
Note that when they modify DOM node actually or the action should do nothing (for example, selection is across tables), aHandled is set to true.
MozReview-Commit-ID: 7ApUOgtLUog
--HG--
extra : rebase_source : 4abc1ec208107b782a719df058623fd7f92d180c
2016-11-18 11:54:31 +03:00
|
|
|
* throughout.
|
|
|
|
*
|
2016-11-18 11:59:23 +03:00
|
|
|
* @return Sets canceled to true if the operation should do
|
|
|
|
* nothing anymore even if this doesn't join the blocks.
|
|
|
|
* Sets handled to true if this actually handles the
|
|
|
|
* request. Note that this may set it to true even if this
|
|
|
|
* does not join the block. E.g., if the blocks shouldn't
|
|
|
|
* be joined or it's impossible to join them but it's not
|
Bug 1316302 part.1 Helper methods for HTMLEditRules::WillDeleteSelection() should have an out argument to indicates if it actually handles the action r=smaug
When HTMLEditRules::WillDeleteSelection() tries to remove something from the end/start of a block to its last/first text node but it's contained by block elements, it tries to join the container and the block. However, JoinBlocks() always fails to join them since it's impossible operation. In this case, HTMLEditRules::WillDeleteSelection() should retry to remove something in the leaf, however, it's impossible for now because JoinBlocks() and its helper methods don't return if it handles the action actually.
This patch renames |JoinBlocks()| to |TryToJoinBlocks()| for representing what it is. And this patch adds |bool* aHandled| to the helper methods. Then, *aHandled and *aCancel are now always returns the result of each method. Therefore, for merging the result of multiple helper methods, callers need to receive the result with temporary variables and merge them by themselves.
Note that when they modify DOM node actually or the action should do nothing (for example, selection is across tables), aHandled is set to true.
MozReview-Commit-ID: 7ApUOgtLUog
--HG--
extra : rebase_source : 4abc1ec208107b782a719df058623fd7f92d180c
2016-11-18 11:54:31 +03:00
|
|
|
* unexpected case, this returns true with this.
|
|
|
|
*/
|
2018-05-17 18:22:43 +03:00
|
|
|
MOZ_MUST_USE EditActionResult
|
|
|
|
TryToJoinBlocksWithTransaction(nsIContent& aLeftNode, nsIContent& aRightNode);
|
Bug 1316302 part.1 Helper methods for HTMLEditRules::WillDeleteSelection() should have an out argument to indicates if it actually handles the action r=smaug
When HTMLEditRules::WillDeleteSelection() tries to remove something from the end/start of a block to its last/first text node but it's contained by block elements, it tries to join the container and the block. However, JoinBlocks() always fails to join them since it's impossible operation. In this case, HTMLEditRules::WillDeleteSelection() should retry to remove something in the leaf, however, it's impossible for now because JoinBlocks() and its helper methods don't return if it handles the action actually.
This patch renames |JoinBlocks()| to |TryToJoinBlocks()| for representing what it is. And this patch adds |bool* aHandled| to the helper methods. Then, *aHandled and *aCancel are now always returns the result of each method. Therefore, for merging the result of multiple helper methods, callers need to receive the result with temporary variables and merge them by themselves.
Note that when they modify DOM node actually or the action should do nothing (for example, selection is across tables), aHandled is set to true.
MozReview-Commit-ID: 7ApUOgtLUog
--HG--
extra : rebase_source : 4abc1ec208107b782a719df058623fd7f92d180c
2016-11-18 11:54:31 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* MoveBlock() moves the content from aRightBlock starting from aRightOffset
|
|
|
|
* into aLeftBlock at aLeftOffset. Note that the "block" can be inline nodes
|
|
|
|
* between <br>s, or between blocks, etc. DTD containment rules are followed
|
|
|
|
* throughout.
|
|
|
|
*
|
2016-11-18 11:59:23 +03:00
|
|
|
* @return Sets handled to true if this actually joins the nodes.
|
|
|
|
* canceled is always false.
|
Bug 1316302 part.1 Helper methods for HTMLEditRules::WillDeleteSelection() should have an out argument to indicates if it actually handles the action r=smaug
When HTMLEditRules::WillDeleteSelection() tries to remove something from the end/start of a block to its last/first text node but it's contained by block elements, it tries to join the container and the block. However, JoinBlocks() always fails to join them since it's impossible operation. In this case, HTMLEditRules::WillDeleteSelection() should retry to remove something in the leaf, however, it's impossible for now because JoinBlocks() and its helper methods don't return if it handles the action actually.
This patch renames |JoinBlocks()| to |TryToJoinBlocks()| for representing what it is. And this patch adds |bool* aHandled| to the helper methods. Then, *aHandled and *aCancel are now always returns the result of each method. Therefore, for merging the result of multiple helper methods, callers need to receive the result with temporary variables and merge them by themselves.
Note that when they modify DOM node actually or the action should do nothing (for example, selection is across tables), aHandled is set to true.
MozReview-Commit-ID: 7ApUOgtLUog
--HG--
extra : rebase_source : 4abc1ec208107b782a719df058623fd7f92d180c
2016-11-18 11:54:31 +03:00
|
|
|
*/
|
2018-05-17 18:08:58 +03:00
|
|
|
MOZ_MUST_USE EditActionResult MoveBlock(Element& aLeftBlock,
|
|
|
|
Element& aRightBlock,
|
|
|
|
int32_t aLeftOffset,
|
|
|
|
int32_t aRightOffset);
|
Bug 1316302 part.1 Helper methods for HTMLEditRules::WillDeleteSelection() should have an out argument to indicates if it actually handles the action r=smaug
When HTMLEditRules::WillDeleteSelection() tries to remove something from the end/start of a block to its last/first text node but it's contained by block elements, it tries to join the container and the block. However, JoinBlocks() always fails to join them since it's impossible operation. In this case, HTMLEditRules::WillDeleteSelection() should retry to remove something in the leaf, however, it's impossible for now because JoinBlocks() and its helper methods don't return if it handles the action actually.
This patch renames |JoinBlocks()| to |TryToJoinBlocks()| for representing what it is. And this patch adds |bool* aHandled| to the helper methods. Then, *aHandled and *aCancel are now always returns the result of each method. Therefore, for merging the result of multiple helper methods, callers need to receive the result with temporary variables and merge them by themselves.
Note that when they modify DOM node actually or the action should do nothing (for example, selection is across tables), aHandled is set to true.
MozReview-Commit-ID: 7ApUOgtLUog
--HG--
extra : rebase_source : 4abc1ec208107b782a719df058623fd7f92d180c
2016-11-18 11:54:31 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* MoveNodeSmart() moves aNode to (aDestElement, aInOutDestOffset).
|
|
|
|
* DTD containment rules are followed throughout.
|
|
|
|
*
|
|
|
|
* @param aOffset returns the point after inserted content.
|
2016-11-18 11:59:23 +03:00
|
|
|
* @return Sets true to handled if this actually moves
|
|
|
|
* the nodes.
|
|
|
|
* canceled is always false.
|
Bug 1316302 part.1 Helper methods for HTMLEditRules::WillDeleteSelection() should have an out argument to indicates if it actually handles the action r=smaug
When HTMLEditRules::WillDeleteSelection() tries to remove something from the end/start of a block to its last/first text node but it's contained by block elements, it tries to join the container and the block. However, JoinBlocks() always fails to join them since it's impossible operation. In this case, HTMLEditRules::WillDeleteSelection() should retry to remove something in the leaf, however, it's impossible for now because JoinBlocks() and its helper methods don't return if it handles the action actually.
This patch renames |JoinBlocks()| to |TryToJoinBlocks()| for representing what it is. And this patch adds |bool* aHandled| to the helper methods. Then, *aHandled and *aCancel are now always returns the result of each method. Therefore, for merging the result of multiple helper methods, callers need to receive the result with temporary variables and merge them by themselves.
Note that when they modify DOM node actually or the action should do nothing (for example, selection is across tables), aHandled is set to true.
MozReview-Commit-ID: 7ApUOgtLUog
--HG--
extra : rebase_source : 4abc1ec208107b782a719df058623fd7f92d180c
2016-11-18 11:54:31 +03:00
|
|
|
*/
|
2018-05-17 18:02:00 +03:00
|
|
|
MOZ_MUST_USE EditActionResult MoveNodeSmart(nsIContent& aNode,
|
|
|
|
Element& aDestElement,
|
|
|
|
int32_t* aInOutDestOffset);
|
Bug 1316302 part.1 Helper methods for HTMLEditRules::WillDeleteSelection() should have an out argument to indicates if it actually handles the action r=smaug
When HTMLEditRules::WillDeleteSelection() tries to remove something from the end/start of a block to its last/first text node but it's contained by block elements, it tries to join the container and the block. However, JoinBlocks() always fails to join them since it's impossible operation. In this case, HTMLEditRules::WillDeleteSelection() should retry to remove something in the leaf, however, it's impossible for now because JoinBlocks() and its helper methods don't return if it handles the action actually.
This patch renames |JoinBlocks()| to |TryToJoinBlocks()| for representing what it is. And this patch adds |bool* aHandled| to the helper methods. Then, *aHandled and *aCancel are now always returns the result of each method. Therefore, for merging the result of multiple helper methods, callers need to receive the result with temporary variables and merge them by themselves.
Note that when they modify DOM node actually or the action should do nothing (for example, selection is across tables), aHandled is set to true.
MozReview-Commit-ID: 7ApUOgtLUog
--HG--
extra : rebase_source : 4abc1ec208107b782a719df058623fd7f92d180c
2016-11-18 11:54:31 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* MoveContents() moves the contents of aElement to (aDestElement,
|
|
|
|
* aInOutDestOffset). DTD containment rules are followed throughout.
|
|
|
|
*
|
|
|
|
* @param aInOutDestOffset updated to point after inserted content.
|
2016-11-18 11:59:23 +03:00
|
|
|
* @return Sets true to handled if this actually moves
|
|
|
|
* the nodes.
|
|
|
|
* canceled is always false.
|
Bug 1316302 part.1 Helper methods for HTMLEditRules::WillDeleteSelection() should have an out argument to indicates if it actually handles the action r=smaug
When HTMLEditRules::WillDeleteSelection() tries to remove something from the end/start of a block to its last/first text node but it's contained by block elements, it tries to join the container and the block. However, JoinBlocks() always fails to join them since it's impossible operation. In this case, HTMLEditRules::WillDeleteSelection() should retry to remove something in the leaf, however, it's impossible for now because JoinBlocks() and its helper methods don't return if it handles the action actually.
This patch renames |JoinBlocks()| to |TryToJoinBlocks()| for representing what it is. And this patch adds |bool* aHandled| to the helper methods. Then, *aHandled and *aCancel are now always returns the result of each method. Therefore, for merging the result of multiple helper methods, callers need to receive the result with temporary variables and merge them by themselves.
Note that when they modify DOM node actually or the action should do nothing (for example, selection is across tables), aHandled is set to true.
MozReview-Commit-ID: 7ApUOgtLUog
--HG--
extra : rebase_source : 4abc1ec208107b782a719df058623fd7f92d180c
2016-11-18 11:54:31 +03:00
|
|
|
*/
|
2018-05-17 17:52:47 +03:00
|
|
|
MOZ_MUST_USE EditActionResult MoveContents(Element& aElement,
|
|
|
|
Element& aDestElement,
|
|
|
|
int32_t* aInOutDestOffset);
|
Bug 1316302 part.1 Helper methods for HTMLEditRules::WillDeleteSelection() should have an out argument to indicates if it actually handles the action r=smaug
When HTMLEditRules::WillDeleteSelection() tries to remove something from the end/start of a block to its last/first text node but it's contained by block elements, it tries to join the container and the block. However, JoinBlocks() always fails to join them since it's impossible operation. In this case, HTMLEditRules::WillDeleteSelection() should retry to remove something in the leaf, however, it's impossible for now because JoinBlocks() and its helper methods don't return if it handles the action actually.
This patch renames |JoinBlocks()| to |TryToJoinBlocks()| for representing what it is. And this patch adds |bool* aHandled| to the helper methods. Then, *aHandled and *aCancel are now always returns the result of each method. Therefore, for merging the result of multiple helper methods, callers need to receive the result with temporary variables and merge them by themselves.
Note that when they modify DOM node actually or the action should do nothing (for example, selection is across tables), aHandled is set to true.
MozReview-Commit-ID: 7ApUOgtLUog
--HG--
extra : rebase_source : 4abc1ec208107b782a719df058623fd7f92d180c
2016-11-18 11:54:31 +03:00
|
|
|
|
2018-05-17 17:46:00 +03:00
|
|
|
/**
|
|
|
|
* DeleteElementsExceptTableRelatedElements() removes elements except
|
|
|
|
* table related elements (except <table> itself) and their contents
|
|
|
|
* from the DOM tree.
|
|
|
|
*
|
|
|
|
* @param aNode If this is not a table related element, this
|
|
|
|
* node will be removed from the DOM tree.
|
|
|
|
* Otherwise, this method calls itself recursively
|
|
|
|
* with its children.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult
|
|
|
|
DeleteElementsExceptTableRelatedElements(nsINode& aNode);
|
2018-05-17 14:51:56 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* XXX Should document what this does.
|
|
|
|
*/
|
2019-03-26 13:09:47 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT
|
2018-05-17 14:51:56 +03:00
|
|
|
MOZ_MUST_USE nsresult WillMakeList(const nsAString* aListType,
|
|
|
|
bool aEntireList,
|
|
|
|
const nsAString* aBulletType,
|
|
|
|
bool* aCancel, bool* aHandled,
|
|
|
|
const nsAString* aItemType = nullptr);
|
2018-05-17 14:27:53 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Called before removing a list element. This method actually removes
|
|
|
|
* list elements and list item elements at Selection. And move contents
|
|
|
|
* in them where the removed list was.
|
|
|
|
*
|
|
|
|
* @param aCancel Returns true if the operation is canceled.
|
|
|
|
* @param aHandled Returns true if the edit action is handled.
|
|
|
|
*/
|
2019-03-26 13:09:47 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT
|
2018-05-17 14:27:53 +03:00
|
|
|
MOZ_MUST_USE nsresult WillRemoveList(bool* aCancel, bool* aHandled);
|
2018-05-17 12:34:00 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Called before indenting around Selection. This method actually tries to
|
|
|
|
* indent the contents.
|
|
|
|
*
|
|
|
|
* @param aCancel Returns true if the operation is canceled.
|
|
|
|
* @param aHandled Returns true if the edit action is handled.
|
|
|
|
*/
|
2019-03-26 13:09:47 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT
|
2018-05-17 12:34:00 +03:00
|
|
|
MOZ_MUST_USE nsresult WillIndent(bool* aCancel, bool* aHandled);
|
2018-05-17 12:27:35 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Called before indenting around Selection and it's in CSS mode.
|
|
|
|
* This method actually tries to indent the contents.
|
|
|
|
*
|
|
|
|
* @param aCancel Returns true if the operation is canceled.
|
|
|
|
* @param aHandled Returns true if the edit action is handled.
|
|
|
|
*/
|
2019-03-26 13:09:47 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT
|
2018-05-17 12:27:35 +03:00
|
|
|
MOZ_MUST_USE nsresult WillCSSIndent(bool* aCancel, bool* aHandled);
|
2018-05-17 12:14:01 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Called before indenting around Selection and it's not in CSS mode.
|
|
|
|
* This method actually tries to indent the contents.
|
|
|
|
*
|
|
|
|
* @param aCancel Returns true if the operation is canceled.
|
|
|
|
* @param aHandled Returns true if the edit action is handled.
|
|
|
|
*/
|
2019-03-26 13:09:47 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT
|
2018-05-17 12:14:01 +03:00
|
|
|
MOZ_MUST_USE nsresult WillHTMLIndent(bool* aCancel, bool* aHandled);
|
2018-05-17 11:57:09 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Called before outdenting around Selection. This method actually tries
|
|
|
|
* to indent the contents.
|
|
|
|
*
|
|
|
|
* @param aCancel Returns true if the operation is canceled.
|
|
|
|
* @param aHandled Returns true if the edit action is handled.
|
|
|
|
*/
|
2019-03-26 13:09:47 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT
|
2018-05-17 11:57:09 +03:00
|
|
|
MOZ_MUST_USE nsresult WillOutdent(bool* aCancel, bool* aHandled);
|
2018-05-16 09:23:52 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Called before aligning contents around Selection. This method actually
|
|
|
|
* sets align attributes to align contents.
|
|
|
|
*
|
|
|
|
* @param aAlignType New align attribute value where the contents
|
|
|
|
* should be aligned to.
|
|
|
|
* @param aCancel Returns true if the operation is canceled.
|
|
|
|
* @param aHandled Returns true if the edit action is handled.
|
|
|
|
*/
|
2019-03-26 13:09:47 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT
|
2018-05-10 09:03:21 +03:00
|
|
|
nsresult WillAlign(const nsAString& aAlignType, bool* aCancel,
|
2012-07-23 14:27:22 +04:00
|
|
|
bool* aHandled);
|
2018-05-11 13:32:00 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Called before changing absolute positioned element to static positioned.
|
|
|
|
* This method actually changes the position property of nearest absolute
|
|
|
|
* positioned element. Therefore, this might cause destroying the HTML
|
|
|
|
* editor.
|
|
|
|
*
|
|
|
|
* @param aCancel Returns true if the operation is canceled.
|
|
|
|
* @param aHandled Returns true if the edit action is handled.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult WillRemoveAbsolutePosition(bool* aCancel,
|
|
|
|
bool* aHandled);
|
2018-05-11 13:24:35 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Called before changing z-index.
|
|
|
|
* This method actually changes z-index of nearest absolute positioned
|
|
|
|
* element relatively. Therefore, this might cause destroying the HTML
|
|
|
|
* editor.
|
|
|
|
*
|
|
|
|
* @param aChange Amount to change z-index.
|
|
|
|
* @param aCancel Returns true if the operation is canceled.
|
|
|
|
* @param aHandled Returns true if the edit action is handled.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult WillRelativeChangeZIndex(int32_t aChange, bool* aCancel,
|
|
|
|
bool* aHandled);
|
|
|
|
|
2018-05-17 14:18:49 +03:00
|
|
|
/**
|
|
|
|
* Called before creating aDefinitionListItemTag around Selection. This
|
|
|
|
* method just calls WillMakeList() with "dl" as aListType and
|
|
|
|
* aDefinitionListItemTag as aItemType.
|
|
|
|
*
|
|
|
|
* @param aDefinitionListItemTag Should be "dt" or "dd".
|
|
|
|
* @param aEntireList XXX not sure
|
|
|
|
* @param aCancel Returns true if the operation is canceled.
|
|
|
|
* @param aHandled Returns true if the edit action is handled.
|
|
|
|
*/
|
2019-03-26 13:09:47 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT
|
2018-05-17 14:18:49 +03:00
|
|
|
MOZ_MUST_USE nsresult WillMakeDefListItem(const nsAString* aBlockType,
|
|
|
|
bool aEntireList, bool* aCancel,
|
|
|
|
bool* aHandled);
|
2018-05-17 14:01:19 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* WillMakeBasicBlock() called before changing block style around Selection.
|
|
|
|
* This method actually does something with calling MakeBasicBlock().
|
|
|
|
*
|
|
|
|
* @param aBlockType Necessary block style as string.
|
|
|
|
* @param aCancel Returns true if the operation is canceled.
|
|
|
|
* @param aHandled Returns true if the edit action is handled.
|
|
|
|
*/
|
2019-03-26 13:09:47 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT
|
2018-05-17 14:01:19 +03:00
|
|
|
MOZ_MUST_USE nsresult WillMakeBasicBlock(const nsAString& aBlockType,
|
|
|
|
bool* aCancel, bool* aHandled);
|
2018-05-17 13:56:41 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* MakeBasicBlock() applies or clears block style around Selection.
|
|
|
|
* This method creates AutoSelectionRestorer. Therefore, each caller
|
|
|
|
* need to check if the editor is still available even if this returns
|
|
|
|
* NS_OK.
|
|
|
|
*
|
|
|
|
* @param aBlockType New block tag name.
|
|
|
|
* If nsGkAtoms::normal or nsGkAtoms::_empty,
|
|
|
|
* RemoveBlockStyle() will be called.
|
|
|
|
* If nsGkAtoms::blockquote, MakeBlockquote()
|
|
|
|
* will be called.
|
|
|
|
* Otherwise, ApplyBlockStyle() will be called.
|
|
|
|
*/
|
2019-03-26 13:09:47 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT
|
2018-05-17 13:56:41 +03:00
|
|
|
MOZ_MUST_USE nsresult MakeBasicBlock(nsAtom& aBlockType);
|
2018-05-17 13:05:26 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Called after creating a basic block, indenting, outdenting or aligning
|
|
|
|
* contents. This method inserts moz-<br> element if start container of
|
|
|
|
* Selection needs it.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult DidMakeBasicBlock();
|
2018-05-11 13:39:26 +03:00
|
|
|
|
2018-05-11 14:25:01 +03:00
|
|
|
/**
|
|
|
|
* Called before changing an element to absolute positioned.
|
|
|
|
* This method only prepares the operation since DidAbsolutePosition() will
|
|
|
|
* change it actually later. mNewBlock is set to the target element and
|
|
|
|
* if necessary, some ancestor nodes of selection may be split.
|
|
|
|
*
|
|
|
|
* @param aCancel Returns true if the operation is canceled.
|
|
|
|
* @param aHandled Returns true if the edit action is handled.
|
|
|
|
*/
|
2019-03-26 13:09:47 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT
|
2018-05-11 14:25:01 +03:00
|
|
|
MOZ_MUST_USE nsresult WillAbsolutePosition(bool* aCancel, bool* aHandled);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* PrepareToMakeElementAbsolutePosition() is helper method of
|
|
|
|
* WillAbsolutePosition() since in some cases, needs to restore selection
|
|
|
|
* with AutoSelectionRestorer. So, all callers have to check if
|
|
|
|
* CanHandleEditAction() still returns true after a call of this method.
|
|
|
|
* XXX Should be documented outline of this method.
|
|
|
|
*
|
|
|
|
* @param aHandled Returns true if the edit action is handled.
|
|
|
|
* @param aTargetElement Returns target element which should be
|
|
|
|
* changed to absolute positioned.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult PrepareToMakeElementAbsolutePosition(
|
|
|
|
bool* aHandled, RefPtr<Element>* aTargetElement);
|
|
|
|
|
2018-05-11 13:39:26 +03:00
|
|
|
/**
|
|
|
|
* Called if nobody handles the edit action to make an element absolute
|
|
|
|
* positioned.
|
|
|
|
* This method actually changes the element which is computed by
|
|
|
|
* WillAbsolutePosition() to absolute positioned.
|
|
|
|
* Therefore, this might cause destroying the HTML editor.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult DidAbsolutePosition();
|
|
|
|
|
2018-05-16 08:54:33 +03:00
|
|
|
/**
|
|
|
|
* AlignInnerBlocks() calls AlignBlockContents() for every list item element
|
|
|
|
* and table cell element in aNode.
|
|
|
|
*
|
|
|
|
* @param aNode The node whose descendants should be aligned
|
|
|
|
* to aAlignType.
|
|
|
|
* @param aAlignType New value of align attribute of <div>.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult AlignInnerBlocks(nsINode& aNode,
|
|
|
|
const nsAString& aAlignType);
|
2018-05-16 08:45:34 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* AlignBlockContents() sets align attribute of <div> element which is
|
|
|
|
* only child of aNode to aAlignType. If aNode has 2 or more children or
|
|
|
|
* does not have a <div> element has only child, inserts a <div> element
|
|
|
|
* into aNode and move all children of aNode into the new <div> element.
|
|
|
|
*
|
|
|
|
* @param aNode The node whose contents should be aligned
|
|
|
|
* to aAlignType.
|
|
|
|
* @param aAlignType New value of align attribute of <div> which
|
|
|
|
* is only child of aNode.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult AlignBlockContents(nsINode& aNode,
|
|
|
|
const nsAString& aAlignType);
|
|
|
|
|
2018-05-16 09:23:52 +03:00
|
|
|
/**
|
|
|
|
* AlignContentsAtSelection() aligns contents around Selection to aAlignType.
|
|
|
|
* This creates AutoSelectionRestorer. Therefore, even if this returns
|
|
|
|
* NS_OK, CanHandleEditAction() may return false if the editor is destroyed
|
|
|
|
* during restoring the Selection. So, every caller needs to check if
|
|
|
|
* CanHandleEditAction() returns true before modifying the DOM tree or
|
|
|
|
* changing Selection.
|
|
|
|
*
|
|
|
|
* @param aAlignType New align attribute value where the contents
|
|
|
|
* should be aligned to.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult AlignContentsAtSelection(const nsAString& aAlignType);
|
|
|
|
|
2016-05-01 16:15:14 +03:00
|
|
|
nsresult AppendInnerFormatNodes(nsTArray<OwningNonNull<nsINode>>& aArray,
|
2012-05-18 12:29:39 +04:00
|
|
|
nsINode* aNode);
|
2018-01-30 07:10:52 +03:00
|
|
|
nsresult GetFormatString(nsINode* aNode, nsAString& outFormat);
|
2018-05-18 06:38:32 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* aLists and aTables allow the caller to specify what kind of content to
|
|
|
|
* "look inside". If aTables is Tables::yes, look inside any table content,
|
|
|
|
* and insert the inner content into the supplied nsTArray at offset
|
|
|
|
* aIndex. Similarly with aLists and list content. aIndex is updated to
|
|
|
|
* point past inserted elements.
|
|
|
|
*/
|
2015-04-24 14:27:34 +03:00
|
|
|
enum class Lists { no, yes };
|
|
|
|
enum class Tables { no, yes };
|
|
|
|
void GetInnerContent(nsINode& aNode,
|
2016-05-01 16:15:14 +03:00
|
|
|
nsTArray<OwningNonNull<nsINode>>& aOutArrayOfNodes,
|
2015-04-24 14:27:34 +03:00
|
|
|
int32_t* aIndex, Lists aLists = Lists::yes,
|
|
|
|
Tables aTables = Tables::yes);
|
2018-05-18 06:38:32 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* If aNode is the descendant of a listitem, return that li. But table
|
|
|
|
* element boundaries are stoppers on the search. Also stops on the active
|
|
|
|
* editor host (contenteditable). Also test if aNode is an li itself.
|
|
|
|
*/
|
2016-05-01 16:15:14 +03:00
|
|
|
Element* IsInListItem(nsINode* aNode);
|
2018-05-18 06:38:32 +03:00
|
|
|
|
2017-10-03 01:05:19 +03:00
|
|
|
nsAtom& DefaultParagraphSeparator();
|
2018-05-15 10:36:53 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* ReturnInHeader() handles insertParagraph command (i.e., handling Enter
|
|
|
|
* key press) in a heading element. This splits aHeader element at
|
|
|
|
* aOffset in aNode. Then, if right heading element is empty, it'll be
|
|
|
|
* removed and new paragraph is created (its type is decided with default
|
|
|
|
* paragraph separator).
|
|
|
|
*
|
|
|
|
* @param aHeader The heading element to be split.
|
|
|
|
* @param aNode Typically, Selection start container,
|
|
|
|
* where to be split.
|
|
|
|
* @param aOffset Typically, Selection start offset in the
|
|
|
|
* start container, where to be split.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult ReturnInHeader(Element& aHeader, nsINode& aNode,
|
|
|
|
int32_t aOffset);
|
2017-11-10 08:58:53 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* ReturnInParagraph() does the right thing for Enter key press or
|
2017-11-10 10:51:24 +03:00
|
|
|
* 'insertParagraph' command in aParentDivOrP. aParentDivOrP will be
|
|
|
|
* split at start of first selection range.
|
2017-11-10 08:58:53 +03:00
|
|
|
*
|
|
|
|
* @param aParentDivOrP The parent block. This must be <p> or <div>
|
|
|
|
* element.
|
|
|
|
* @return Returns with NS_OK if this doesn't meat any
|
|
|
|
* unexpected situation. If this method tries to
|
|
|
|
* split the paragraph, marked as handled.
|
|
|
|
*/
|
2018-05-15 10:22:59 +03:00
|
|
|
MOZ_MUST_USE EditActionResult ReturnInParagraph(Element& aParentDivOrP);
|
2017-11-10 08:43:13 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* SplitParagraph() splits the parent block, aPara, at aSelNode - aOffset.
|
|
|
|
*
|
2017-11-16 07:26:58 +03:00
|
|
|
* @param aParentDivOrP The parent block to be split. This must be <p>
|
|
|
|
* or <div> element.
|
|
|
|
* @param aStartOfRightNode The point to be start of right node after
|
|
|
|
* split. This must be descendant of
|
|
|
|
* aParentDivOrP.
|
|
|
|
* @param aNextBRNode Next <br> node if there is. Otherwise, nullptr.
|
|
|
|
* If this is not nullptr, the <br> node may be
|
|
|
|
* removed.
|
2017-11-10 08:43:13 +03:00
|
|
|
*/
|
2018-03-20 08:05:47 +03:00
|
|
|
template <typename PT, typename CT>
|
2018-05-15 10:15:35 +03:00
|
|
|
MOZ_MUST_USE nsresult SplitParagraph(
|
|
|
|
Element& aParentDivOrP,
|
|
|
|
const EditorDOMPointBase<PT, CT>& aStartOfRightNode, nsIContent* aBRNode);
|
2017-11-10 08:43:13 +03:00
|
|
|
|
2018-05-15 09:32:11 +03:00
|
|
|
/**
|
|
|
|
* ReturnInListItem() handles insertParagraph command (i.e., handling
|
|
|
|
* Enter key press) in a list item element.
|
|
|
|
*
|
|
|
|
* @param aListItem The list item which has the following point.
|
|
|
|
* @param aNode Typically, Selection start container, where to
|
|
|
|
* insert a break.
|
|
|
|
* @param aOffset Typically, Selection start offset in the
|
|
|
|
* start container, where to insert a break.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult ReturnInListItem(Element& aListItem, nsINode& aNode,
|
|
|
|
int32_t aOffset);
|
|
|
|
|
2018-05-16 08:32:47 +03:00
|
|
|
/**
|
|
|
|
* Called after handling edit action. This may adjust Selection, remove
|
|
|
|
* unnecessary empty nodes, create <br> elements if needed, etc.
|
|
|
|
*/
|
Bug 1463985 - part 1: Rename EditAction to EditSubAction and related stuff r=m_kato
When we implement InputEvent.inputType, we need to set a stack class to record
which edit action is currently handled. However, currently, we call smaller
jobs as edit action. For example, when user types a character at selecting
some characters, then, EditAction::deleteSelection is performed first, then,
EditAction::insertText is performed. However, for the InputEvent.inputType,
we need inserText information. So, for making new enum EditAction, we need
to rename current EditAction to EditSubAction.
And also this renames related stuff:
EditorBase::mIsInEditAction -> EditorBase::mIsInEditSubAction
EditorBase::IsInEditAction() -> EditorBase::IsInEditSubAction()
EditorBase::mAction -> EditorBase::mTopLevelEditSubAction
TextEditRules::mTheAction -> TextEditRules::mTopLevelEditSubAction
EditorBase::StartOperation() ->
EditorBase::OnStartToHandleTopLevelEditSubAction()
EditorBase::EndOperation() ->
EditorBase::OnEndHandlingTopLevelEditSubAction()
AutoRules -> AutoTopLevelEditSubActionNotifier
RulesInfo -> EditSubActionInfo
MozReview-Commit-ID: cvSkPUjFm1
--HG--
extra : rebase_source : baf527a3e353b7a8ebe9a46be2243b059c500234
2018-05-28 14:12:34 +03:00
|
|
|
MOZ_MUST_USE nsresult AfterEditInner(EditSubAction aEditSubAction,
|
|
|
|
nsIEditor::EDirection aDirection);
|
2018-05-16 08:32:47 +03:00
|
|
|
|
2018-05-17 12:27:35 +03:00
|
|
|
/**
|
|
|
|
* IndentAroundSelectionWithCSS() indents around Selection with CSS.
|
|
|
|
* This method creates AutoSelectionRestorer. Therefore, each caller
|
|
|
|
* need to check if the editor is still available even if this returns
|
|
|
|
* NS_OK.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult IndentAroundSelectionWithCSS();
|
|
|
|
|
2018-05-17 12:14:01 +03:00
|
|
|
/**
|
|
|
|
* IndentAroundSelectionWithHTML() indents around Selection with HTML.
|
|
|
|
* This method creates AutoSelectionRestorer. Therefore, each caller
|
|
|
|
* need to check if the editor is still available even if this returns
|
|
|
|
* NS_OK.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult IndentAroundSelectionWithHTML();
|
|
|
|
|
2018-05-17 11:57:09 +03:00
|
|
|
/**
|
|
|
|
* OutdentAroundSelection() outdents contents around Selection.
|
|
|
|
* This method creates AutoSelectionRestorer. Therefore, each caller
|
|
|
|
* need to check if the editor is still available even if this returns
|
|
|
|
* NS_OK.
|
|
|
|
*
|
|
|
|
* @return The left content is left content of last
|
|
|
|
* outdented element.
|
|
|
|
* The right content is right content of last
|
|
|
|
* outdented element.
|
|
|
|
* The middle content is middle content of last
|
|
|
|
* outdented element.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE SplitRangeOffFromNodeResult OutdentAroundSelection();
|
|
|
|
|
2018-05-17 11:13:04 +03:00
|
|
|
/**
|
|
|
|
* SplitRangeOffFromBlockAndRemoveMiddleContainer() splits the nodes
|
|
|
|
* between aStartOfRange and aEndOfRange, then, removes the middle element
|
|
|
|
* and moves its content to where the middle element was.
|
|
|
|
*
|
|
|
|
* @param aBlockElement The node which will be split.
|
|
|
|
* @param aStartOfRange The first node which will be unwrapped
|
|
|
|
* from aBlockElement.
|
|
|
|
* @param aEndOfRange The last node which will be unwrapped from
|
|
|
|
* aBlockElement.
|
|
|
|
* @return The left content is new created left
|
|
|
|
* element of aBlockElement.
|
|
|
|
* The right content is split element,
|
|
|
|
* i.e., must be aBlockElement.
|
|
|
|
* The middle content is nullptr since
|
|
|
|
* removing it is the job of this method.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE SplitRangeOffFromNodeResult
|
|
|
|
SplitRangeOffFromBlockAndRemoveMiddleContainer(Element& aBlockElement,
|
|
|
|
nsIContent& aStartOfRange,
|
|
|
|
nsIContent& aEndOfRange);
|
2018-05-17 10:28:52 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* SplitRangeOffFromBlock() splits aBlock at two points, before aStartChild
|
|
|
|
* and after aEndChild. If they are very start or very end of aBlcok, this
|
|
|
|
* won't create empty block.
|
|
|
|
*
|
|
|
|
* @param aBlockElement A block element which will be split.
|
|
|
|
* @param aStartOfMiddleElement Start node of middle block element.
|
|
|
|
* @param aEndOfMiddleElement End node of middle block element.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE SplitRangeOffFromNodeResult SplitRangeOffFromBlock(
|
|
|
|
Element& aBlockElement, nsIContent& aStartOfMiddleElement,
|
|
|
|
nsIContent& aEndOfMiddleElement);
|
|
|
|
|
2018-05-17 10:53:18 +03:00
|
|
|
/**
|
|
|
|
* OutdentPartOfBlock() outdents the nodes between aStartOfOutdent and
|
|
|
|
* aEndOfOutdent. This splits the range off from aBlockElement first.
|
|
|
|
* Then, removes the middle element if aIsBlockIndentedWithCSS is false.
|
|
|
|
* Otherwise, decreases the margin of the middle element.
|
|
|
|
*
|
|
|
|
* @param aBlockElement A block element which includes both
|
|
|
|
* aStartOfOutdent and aEndOfOutdent.
|
|
|
|
* @param aStartOfOutdent First node which is descendant of
|
|
|
|
* aBlockElement will be outdented.
|
|
|
|
* @param aEndOfOutdent Last node which is descandant of
|
|
|
|
* aBlockElement will be outdented.
|
|
|
|
* @param aIsBlockIndentedWithCSS true if aBlockElement is indented with
|
|
|
|
* CSS margin property.
|
|
|
|
* false if aBlockElement is <blockquote>
|
|
|
|
* or something.
|
|
|
|
* @return The left content is new created element
|
|
|
|
* splitting before aStartOfOutdent.
|
|
|
|
* The right content is existing element.
|
|
|
|
* The middle content is outdented element
|
|
|
|
* if aIsBlockIndentedWithCSS is true.
|
|
|
|
* Otherwise, nullptr.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE SplitRangeOffFromNodeResult
|
|
|
|
OutdentPartOfBlock(Element& aBlockElement, nsIContent& aStartOfOutdent,
|
|
|
|
nsIContent& aEndOutdent, bool aIsBlockIndentedWithCSS);
|
2012-06-06 11:36:46 +04:00
|
|
|
|
2018-05-17 14:51:56 +03:00
|
|
|
/**
|
|
|
|
* XXX Should document what this does.
|
|
|
|
* This method creates AutoSelectionRestorer. Therefore, each caller
|
|
|
|
* need to check if the editor is still available even if this returns
|
|
|
|
* NS_OK.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult MakeList(nsAtom& aListType, bool aEntireList,
|
|
|
|
const nsAString* aBulletType, bool* aCancel,
|
|
|
|
nsAtom& aItemType);
|
|
|
|
|
2018-05-17 08:28:47 +03:00
|
|
|
/**
|
|
|
|
* ConvertListType() replaces child list items of aListElement with
|
|
|
|
* new list item element whose tag name is aNewListItemTag.
|
|
|
|
* Note that if there are other list elements as children of aListElement,
|
|
|
|
* this calls itself recursively even though it's invalid structure.
|
|
|
|
*
|
|
|
|
* @param aListElement The list element whose list items will be
|
|
|
|
* replaced.
|
|
|
|
* @param aNewListTag New list tag name.
|
|
|
|
* @param aNewListItemTag New list item tag name.
|
|
|
|
* @return New list element or an error code if it fails.
|
|
|
|
* New list element may be aListElement if its
|
|
|
|
* tag name is same as aNewListTag.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE CreateElementResult ConvertListType(Element& aListElement,
|
|
|
|
nsAtom& aListType,
|
|
|
|
nsAtom& aItemType);
|
2012-06-06 11:36:46 +04:00
|
|
|
|
2018-05-16 09:36:20 +03:00
|
|
|
/**
|
|
|
|
* CreateStyleForInsertText() sets CSS properties which are stored in
|
|
|
|
* TypeInState to proper element node.
|
|
|
|
*
|
|
|
|
* @param aDocument The document of the editor.
|
|
|
|
*/
|
2019-01-02 16:05:23 +03:00
|
|
|
MOZ_MUST_USE nsresult CreateStyleForInsertText(dom::Document& aDocument);
|
2017-12-20 16:25:12 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* IsEmptyBlockElement() returns true if aElement is a block level element
|
|
|
|
* and it doesn't have any visible content.
|
|
|
|
*/
|
|
|
|
enum class IgnoreSingleBR { eYes, eNo };
|
|
|
|
bool IsEmptyBlockElement(Element& aElement, IgnoreSingleBR aIgnoreSingleBR);
|
|
|
|
|
2018-05-15 18:10:11 +03:00
|
|
|
/**
|
|
|
|
* MaybeDeleteTopMostEmptyAncestor() looks for top most empty block ancestor
|
|
|
|
* of aStartNode in aEditingHostElement.
|
|
|
|
* If found empty ancestor is a list item element, inserts a <br> element
|
|
|
|
* before its parent element if grand parent is a list element. Then,
|
|
|
|
* collapse Selection to after the empty block.
|
|
|
|
* If found empty ancestor is not a list item element, collapse Selection to
|
|
|
|
* somewhere depending on aAction.
|
|
|
|
* Finally, removes the empty block ancestor.
|
|
|
|
*
|
|
|
|
* @param aStartNode Start node to look for empty ancestors.
|
|
|
|
* @param aEditingHostElement Current editing host.
|
|
|
|
* @param aAction If found empty ancestor block is a list item
|
|
|
|
* element, this is ignored. Otherwise:
|
|
|
|
* - If eNext, eNextWord or eToEndOfLine, collapse
|
|
|
|
* Selection to after found empty ancestor.
|
|
|
|
* - If ePrevious, ePreviousWord or
|
|
|
|
* eToBeginningOfLine, collapse Selection to
|
|
|
|
* end of previous editable node.
|
|
|
|
* Otherwise, eNone is allowed but does nothing.
|
|
|
|
* @param aHandled Returns true if this method removes an empty
|
|
|
|
* block ancestor of aStartNode.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult MaybeDeleteTopMostEmptyAncestor(
|
|
|
|
nsINode& aStartNode, Element& aEditingHostElement,
|
|
|
|
nsIEditor::EDirection aAction, bool* aHandled);
|
|
|
|
|
2016-05-01 16:15:02 +03:00
|
|
|
enum class BRLocation { beforeBlock, blockEnd };
|
2016-05-01 16:15:14 +03:00
|
|
|
Element* CheckForInvisibleBR(Element& aBlock, BRLocation aWhere,
|
|
|
|
int32_t aOffset = 0);
|
2018-05-15 13:15:56 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* ExpandSelectionForDeletion() may expand Selection range if it's not
|
|
|
|
* collapsed and there is only one range. This may expand to include
|
|
|
|
* invisible <br> element for preventing delete action handler to keep
|
|
|
|
* unexpected nodes.
|
|
|
|
*/
|
2019-03-26 13:09:47 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT
|
2018-05-15 13:15:56 +03:00
|
|
|
MOZ_MUST_USE nsresult ExpandSelectionForDeletion();
|
2018-05-15 12:59:27 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* NormalizeSelection() adjust Selection if it's not collapsed and there is
|
|
|
|
* only one range. If range start and/or end point is <br> node or something
|
|
|
|
* non-editable point, they should be moved to nearest text node or something
|
|
|
|
* where the other methods easier to handle edit action.
|
|
|
|
*/
|
2019-03-26 13:09:47 +03:00
|
|
|
MOZ_CAN_RUN_SCRIPT
|
2018-05-15 12:59:27 +03:00
|
|
|
MOZ_MUST_USE nsresult NormalizeSelection();
|
|
|
|
|
2018-05-18 06:38:32 +03:00
|
|
|
/**
|
|
|
|
* GetPromotedPoint() figures out where a start or end point for a block
|
|
|
|
* operation really is.
|
|
|
|
*/
|
Bug 1463985 - part 1: Rename EditAction to EditSubAction and related stuff r=m_kato
When we implement InputEvent.inputType, we need to set a stack class to record
which edit action is currently handled. However, currently, we call smaller
jobs as edit action. For example, when user types a character at selecting
some characters, then, EditAction::deleteSelection is performed first, then,
EditAction::insertText is performed. However, for the InputEvent.inputType,
we need inserText information. So, for making new enum EditAction, we need
to rename current EditAction to EditSubAction.
And also this renames related stuff:
EditorBase::mIsInEditAction -> EditorBase::mIsInEditSubAction
EditorBase::IsInEditAction() -> EditorBase::IsInEditSubAction()
EditorBase::mAction -> EditorBase::mTopLevelEditSubAction
TextEditRules::mTheAction -> TextEditRules::mTopLevelEditSubAction
EditorBase::StartOperation() ->
EditorBase::OnStartToHandleTopLevelEditSubAction()
EditorBase::EndOperation() ->
EditorBase::OnEndHandlingTopLevelEditSubAction()
AutoRules -> AutoTopLevelEditSubActionNotifier
RulesInfo -> EditSubActionInfo
MozReview-Commit-ID: cvSkPUjFm1
--HG--
extra : rebase_source : baf527a3e353b7a8ebe9a46be2243b059c500234
2018-05-28 14:12:34 +03:00
|
|
|
EditorDOMPoint GetPromotedPoint(RulesEndpoint aWhere, nsINode& aNode,
|
|
|
|
int32_t aOffset,
|
|
|
|
EditSubAction aEditSubAction);
|
2018-05-18 06:38:32 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* GetPromotedRanges() runs all the selection range endpoint through
|
|
|
|
* GetPromotedPoint().
|
|
|
|
*/
|
2018-05-10 09:03:21 +03:00
|
|
|
void GetPromotedRanges(nsTArray<RefPtr<nsRange>>& outArrayOfRanges,
|
Bug 1463985 - part 1: Rename EditAction to EditSubAction and related stuff r=m_kato
When we implement InputEvent.inputType, we need to set a stack class to record
which edit action is currently handled. However, currently, we call smaller
jobs as edit action. For example, when user types a character at selecting
some characters, then, EditAction::deleteSelection is performed first, then,
EditAction::insertText is performed. However, for the InputEvent.inputType,
we need inserText information. So, for making new enum EditAction, we need
to rename current EditAction to EditSubAction.
And also this renames related stuff:
EditorBase::mIsInEditAction -> EditorBase::mIsInEditSubAction
EditorBase::IsInEditAction() -> EditorBase::IsInEditSubAction()
EditorBase::mAction -> EditorBase::mTopLevelEditSubAction
TextEditRules::mTheAction -> TextEditRules::mTopLevelEditSubAction
EditorBase::StartOperation() ->
EditorBase::OnStartToHandleTopLevelEditSubAction()
EditorBase::EndOperation() ->
EditorBase::OnEndHandlingTopLevelEditSubAction()
AutoRules -> AutoTopLevelEditSubActionNotifier
RulesInfo -> EditSubActionInfo
MozReview-Commit-ID: cvSkPUjFm1
--HG--
extra : rebase_source : baf527a3e353b7a8ebe9a46be2243b059c500234
2018-05-28 14:12:34 +03:00
|
|
|
EditSubAction aEditSubAction);
|
2018-05-18 06:38:32 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* PromoteRange() expands a range to include any parents for which all
|
|
|
|
* editable children are already in range.
|
|
|
|
*/
|
Bug 1463985 - part 1: Rename EditAction to EditSubAction and related stuff r=m_kato
When we implement InputEvent.inputType, we need to set a stack class to record
which edit action is currently handled. However, currently, we call smaller
jobs as edit action. For example, when user types a character at selecting
some characters, then, EditAction::deleteSelection is performed first, then,
EditAction::insertText is performed. However, for the InputEvent.inputType,
we need inserText information. So, for making new enum EditAction, we need
to rename current EditAction to EditSubAction.
And also this renames related stuff:
EditorBase::mIsInEditAction -> EditorBase::mIsInEditSubAction
EditorBase::IsInEditAction() -> EditorBase::IsInEditSubAction()
EditorBase::mAction -> EditorBase::mTopLevelEditSubAction
TextEditRules::mTheAction -> TextEditRules::mTopLevelEditSubAction
EditorBase::StartOperation() ->
EditorBase::OnStartToHandleTopLevelEditSubAction()
EditorBase::EndOperation() ->
EditorBase::OnEndHandlingTopLevelEditSubAction()
AutoRules -> AutoTopLevelEditSubActionNotifier
RulesInfo -> EditSubActionInfo
MozReview-Commit-ID: cvSkPUjFm1
--HG--
extra : rebase_source : baf527a3e353b7a8ebe9a46be2243b059c500234
2018-05-28 14:12:34 +03:00
|
|
|
void PromoteRange(nsRange& aRange, EditSubAction aEditSubAction);
|
2018-05-18 06:38:32 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* GetNodesForOperation() runs through the ranges in the array and construct a
|
|
|
|
* new array of nodes to be acted on.
|
|
|
|
*
|
|
|
|
* XXX This name stats with "Get" but actually this modifies the DOM tree with
|
|
|
|
* transaction. We should rename this to making clearer what this does.
|
|
|
|
*/
|
2015-04-24 14:27:34 +03:00
|
|
|
enum class TouchContent { no, yes };
|
2018-05-15 12:07:34 +03:00
|
|
|
MOZ_MUST_USE nsresult GetNodesForOperation(
|
|
|
|
nsTArray<RefPtr<nsRange>>& aArrayOfRanges,
|
|
|
|
nsTArray<OwningNonNull<nsINode>>& aOutArrayOfNodes,
|
Bug 1463985 - part 1: Rename EditAction to EditSubAction and related stuff r=m_kato
When we implement InputEvent.inputType, we need to set a stack class to record
which edit action is currently handled. However, currently, we call smaller
jobs as edit action. For example, when user types a character at selecting
some characters, then, EditAction::deleteSelection is performed first, then,
EditAction::insertText is performed. However, for the InputEvent.inputType,
we need inserText information. So, for making new enum EditAction, we need
to rename current EditAction to EditSubAction.
And also this renames related stuff:
EditorBase::mIsInEditAction -> EditorBase::mIsInEditSubAction
EditorBase::IsInEditAction() -> EditorBase::IsInEditSubAction()
EditorBase::mAction -> EditorBase::mTopLevelEditSubAction
TextEditRules::mTheAction -> TextEditRules::mTopLevelEditSubAction
EditorBase::StartOperation() ->
EditorBase::OnStartToHandleTopLevelEditSubAction()
EditorBase::EndOperation() ->
EditorBase::OnEndHandlingTopLevelEditSubAction()
AutoRules -> AutoTopLevelEditSubActionNotifier
RulesInfo -> EditSubActionInfo
MozReview-Commit-ID: cvSkPUjFm1
--HG--
extra : rebase_source : baf527a3e353b7a8ebe9a46be2243b059c500234
2018-05-28 14:12:34 +03:00
|
|
|
EditSubAction aEditSubAction, TouchContent aTouchContent);
|
2018-05-18 06:38:32 +03:00
|
|
|
|
2016-07-07 13:05:51 +03:00
|
|
|
void GetChildNodesForOperation(
|
|
|
|
nsINode& aNode, nsTArray<OwningNonNull<nsINode>>& outArrayOfNodes);
|
2018-05-18 06:38:32 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* GetNodesFromPoint() constructs a list of nodes from a point that will be
|
|
|
|
* operated on.
|
|
|
|
*/
|
2018-05-15 12:07:34 +03:00
|
|
|
MOZ_MUST_USE nsresult
|
Bug 1463985 - part 1: Rename EditAction to EditSubAction and related stuff r=m_kato
When we implement InputEvent.inputType, we need to set a stack class to record
which edit action is currently handled. However, currently, we call smaller
jobs as edit action. For example, when user types a character at selecting
some characters, then, EditAction::deleteSelection is performed first, then,
EditAction::insertText is performed. However, for the InputEvent.inputType,
we need inserText information. So, for making new enum EditAction, we need
to rename current EditAction to EditSubAction.
And also this renames related stuff:
EditorBase::mIsInEditAction -> EditorBase::mIsInEditSubAction
EditorBase::IsInEditAction() -> EditorBase::IsInEditSubAction()
EditorBase::mAction -> EditorBase::mTopLevelEditSubAction
TextEditRules::mTheAction -> TextEditRules::mTopLevelEditSubAction
EditorBase::StartOperation() ->
EditorBase::OnStartToHandleTopLevelEditSubAction()
EditorBase::EndOperation() ->
EditorBase::OnEndHandlingTopLevelEditSubAction()
AutoRules -> AutoTopLevelEditSubActionNotifier
RulesInfo -> EditSubActionInfo
MozReview-Commit-ID: cvSkPUjFm1
--HG--
extra : rebase_source : baf527a3e353b7a8ebe9a46be2243b059c500234
2018-05-28 14:12:34 +03:00
|
|
|
GetNodesFromPoint(const EditorDOMPoint& aPoint, EditSubAction aEditSubAction,
|
2018-05-15 12:07:34 +03:00
|
|
|
nsTArray<OwningNonNull<nsINode>>& outArrayOfNodes,
|
|
|
|
TouchContent aTouchContent);
|
2018-05-18 06:38:32 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* GetNodesFromSelection() constructs a list of nodes from the selection that
|
|
|
|
* will be operated on.
|
|
|
|
*/
|
2018-05-15 12:07:34 +03:00
|
|
|
MOZ_MUST_USE nsresult
|
Bug 1463985 - part 1: Rename EditAction to EditSubAction and related stuff r=m_kato
When we implement InputEvent.inputType, we need to set a stack class to record
which edit action is currently handled. However, currently, we call smaller
jobs as edit action. For example, when user types a character at selecting
some characters, then, EditAction::deleteSelection is performed first, then,
EditAction::insertText is performed. However, for the InputEvent.inputType,
we need inserText information. So, for making new enum EditAction, we need
to rename current EditAction to EditSubAction.
And also this renames related stuff:
EditorBase::mIsInEditAction -> EditorBase::mIsInEditSubAction
EditorBase::IsInEditAction() -> EditorBase::IsInEditSubAction()
EditorBase::mAction -> EditorBase::mTopLevelEditSubAction
TextEditRules::mTheAction -> TextEditRules::mTopLevelEditSubAction
EditorBase::StartOperation() ->
EditorBase::OnStartToHandleTopLevelEditSubAction()
EditorBase::EndOperation() ->
EditorBase::OnEndHandlingTopLevelEditSubAction()
AutoRules -> AutoTopLevelEditSubActionNotifier
RulesInfo -> EditSubActionInfo
MozReview-Commit-ID: cvSkPUjFm1
--HG--
extra : rebase_source : baf527a3e353b7a8ebe9a46be2243b059c500234
2018-05-28 14:12:34 +03:00
|
|
|
GetNodesFromSelection(EditSubAction aEditSubAction,
|
2018-05-15 12:07:34 +03:00
|
|
|
nsTArray<OwningNonNull<nsINode>>& outArrayOfNodes,
|
|
|
|
TouchContent aTouchContent);
|
2018-05-18 06:38:32 +03:00
|
|
|
|
2015-04-24 14:27:34 +03:00
|
|
|
enum class EntireList { no, yes };
|
2018-05-15 12:07:34 +03:00
|
|
|
MOZ_MUST_USE nsresult
|
|
|
|
GetListActionNodes(nsTArray<OwningNonNull<nsINode>>& aOutArrayOfNodes,
|
|
|
|
EntireList aEntireList, TouchContent aTouchContent);
|
2016-05-01 16:15:14 +03:00
|
|
|
void GetDefinitionListItemTypes(Element* aElement, bool* aDT, bool* aDD);
|
2018-05-15 12:07:34 +03:00
|
|
|
nsresult GetParagraphFormatNodes(
|
|
|
|
nsTArray<OwningNonNull<nsINode>>& outArrayOfNodes);
|
2016-05-01 16:15:14 +03:00
|
|
|
void LookInsideDivBQandList(nsTArray<OwningNonNull<nsINode>>& aNodeArray);
|
2018-05-15 11:21:08 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* BustUpInlinesAtRangeEndpoints() splits nodes at both start and end of
|
|
|
|
* aRangeItem. If this splits at every point, this modifies aRangeItem
|
|
|
|
* to point each split point (typically, right node). Note that this splits
|
|
|
|
* nodes only in highest inline element at every point.
|
|
|
|
*
|
|
|
|
* @param aRangeItem One or two DOM points where should be split.
|
|
|
|
* Will be modified to split point if they're
|
|
|
|
* split.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult BustUpInlinesAtRangeEndpoints(RangeItem& aRangeItem);
|
2018-05-15 11:04:28 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* BustUpInlinesAtBRs() splits before all <br> elements in aNode. All <br>
|
|
|
|
* nodes will be moved before right node at splitting its parent. Finally,
|
|
|
|
* this returns all <br> elements, every left node and aNode with
|
|
|
|
* aOutArrayNodes.
|
|
|
|
*
|
|
|
|
* @param aNode An inline container element.
|
|
|
|
* @param aOutArrayOfNodes All found <br> elements, left nodes (may not
|
|
|
|
* be set if <br> is at start edge of aNode) and
|
|
|
|
* aNode itself.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult BustUpInlinesAtBRs(
|
|
|
|
nsIContent& aNode, nsTArray<OwningNonNull<nsINode>>& aOutArrayOfNodes);
|
|
|
|
|
Bug 1411345 - HTMLEditRules::GetHighestInlineParent() shouldn't return editing host even when it's the highest inline parent of aNode r=m_kato
HTMLEditRules::BustUpInlinesAtRangeEndpoints() tries to split all inline nodes
at range start and range end. It uses EditorBase::SplitNodeDeep() to split
the nodes and HTMLEditRules::GetHighestInlineParent() to retrieve the highest
inline parent of them.
Currently, HTMLEditRules::GetHighestInlineParent() may return editing host or
ancestor of it if active editing host is not block. Then, it may cause
splitting editing host or its parents and following methods of HTMLEditRules
will fail to modify the nodes created outside the editing host.
So, HTMLEditRules::GetHighestInlineParent() should return only one of the
descendants of active editing host.
Unfortunately, even if just adding the test case as a crash test, I cannot
reproduce the crash with automated tests. Therefore, this patch doesn't
include any automated tests.
And this patch changes a crash test, 1402196.html, which expects that an inline
editing host is split by execCommand("insertOrderedList"). However, this patch
fixes this wrong behavior. Therefore, this patch changes the event target of
event listener from <p> inside the editing host to the editing host itself.
MozReview-Commit-ID: 8i5ci1fcrDd
--HG--
extra : rebase_source : 572a7b22550a38ca71c954f62eefa695addd53c2
2017-10-30 19:14:58 +03:00
|
|
|
/**
|
|
|
|
* GetHiestInlineParent() returns the highest inline node parent between
|
|
|
|
* aNode and the editing host. Even if the editing host is an inline
|
|
|
|
* element, this method never returns the editing host as the result.
|
|
|
|
*/
|
2016-05-01 16:13:51 +03:00
|
|
|
nsIContent* GetHighestInlineParent(nsINode& aNode);
|
2018-05-18 06:38:32 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* MakeTransitionList() detects all the transitions in the array, where a
|
|
|
|
* transition means that adjacent nodes in the array don't have the same
|
|
|
|
* parent.
|
|
|
|
*/
|
2016-05-01 16:15:14 +03:00
|
|
|
void MakeTransitionList(nsTArray<OwningNonNull<nsINode>>& aNodeArray,
|
2015-04-24 14:27:35 +03:00
|
|
|
nsTArray<bool>& aTransitionArray);
|
2018-05-14 18:43:07 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* RemoveBlockStyle() removes all format blocks, table related element,
|
|
|
|
* etc in aNodeArray.
|
|
|
|
* If aNodeArray has a format node, it will be removed and its contents
|
|
|
|
* will be moved to where it was.
|
|
|
|
* If aNodeArray has a table related element, <li>, <blockquote> or <div>,
|
|
|
|
* it will removed and its contents will be moved to where it was.
|
|
|
|
*/
|
2016-05-01 16:15:14 +03:00
|
|
|
nsresult RemoveBlockStyle(nsTArray<OwningNonNull<nsINode>>& aNodeArray);
|
Bug 1406726 - HTMLEditRules::WillInsertBreak() should reset mNewNode with caret position r=m_kato
HTMLEditRules::WillInsertBreak() started to use HTMLEditRules::MakeBasicBlock()
to wrap existing inline elements with default paragraph separator if inline
elements are children of editing host. However,
HTMLEditRules::ApplyBlockStyle() called by HTMLEditRules::MakeBasicBlock() sets
mNewNode to last new block node. So, if it wraps inline elements after caret
position, mNewNode becomes after expected caret position and
HTMLEditRules::AfterEditInner() will move caret into it.
This patch make HTMLEditRules::WillInsertBreak() reset mNewNode with
caret position after calling HTMLEditRules::MakeBasicBlock().
Additionally, this patch fixes a bug of HTMLEditor::IsVisibleBRElement().
That is, it uses only editable nodes to check if given <br> element is
visible. However, editable state is not related to this check. If <br>
element is followed by non-editable inline node (except invisible data
nodes), it always visible. This bug caused getting wrong nodes with
HTMLEditRules::GetNodesFromSelection() which is used by
HTMLEditRules::MakeBasicBlock(). Therefore, this patch also adds lots of
EditorBase::Get(Next|Previous)ElementOrText*() and
HTMLEditor::Get(Next|Previous)HTMLElementOrText*() to ignore only invisible
data nodes.
Note that even with this fix, the range of nodes computed by
HTMLEditRules::GetNodesFromSelection() is still odd if only non-editable
elements follow a <br> node which is first <br> element after the caret
position. However, what is expected by the execCommand spec is unclear.
So, automated test added by this patch checks current inconsistent behavior
for now.
MozReview-Commit-ID: 2m52StwoEEH
--HG--
extra : rebase_source : 6b9b2338e35c4d2e89a405fd8e1ffc7b0873ca1e
2018-02-13 13:01:42 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* ApplyBlockStyle() formats all nodes in aNodeArray with block elements
|
|
|
|
* whose name is aBlockTag.
|
|
|
|
* If aNodeArray has an inline element, a block element is created and the
|
|
|
|
* inline element and following inline elements are moved into the new block
|
|
|
|
* element.
|
|
|
|
* If aNodeArray has <br> elements, they'll be removed from the DOM tree and
|
|
|
|
* new block element will be created when there are some remaining inline
|
|
|
|
* elements.
|
|
|
|
* If aNodeArray has a block element, this calls itself with children of
|
|
|
|
* the block element. Then, new block element will be created when there
|
|
|
|
* are some remaining inline elements.
|
|
|
|
*
|
|
|
|
* @param aNodeArray Must be descendants of a node.
|
|
|
|
* @param aBlockTag The element name of new block elements.
|
|
|
|
*/
|
2018-05-14 18:08:46 +03:00
|
|
|
MOZ_MUST_USE nsresult ApplyBlockStyle(
|
|
|
|
nsTArray<OwningNonNull<nsINode>>& aNodeArray, nsAtom& aBlockTag);
|
Bug 1406726 - HTMLEditRules::WillInsertBreak() should reset mNewNode with caret position r=m_kato
HTMLEditRules::WillInsertBreak() started to use HTMLEditRules::MakeBasicBlock()
to wrap existing inline elements with default paragraph separator if inline
elements are children of editing host. However,
HTMLEditRules::ApplyBlockStyle() called by HTMLEditRules::MakeBasicBlock() sets
mNewNode to last new block node. So, if it wraps inline elements after caret
position, mNewNode becomes after expected caret position and
HTMLEditRules::AfterEditInner() will move caret into it.
This patch make HTMLEditRules::WillInsertBreak() reset mNewNode with
caret position after calling HTMLEditRules::MakeBasicBlock().
Additionally, this patch fixes a bug of HTMLEditor::IsVisibleBRElement().
That is, it uses only editable nodes to check if given <br> element is
visible. However, editable state is not related to this check. If <br>
element is followed by non-editable inline node (except invisible data
nodes), it always visible. This bug caused getting wrong nodes with
HTMLEditRules::GetNodesFromSelection() which is used by
HTMLEditRules::MakeBasicBlock(). Therefore, this patch also adds lots of
EditorBase::Get(Next|Previous)ElementOrText*() and
HTMLEditor::Get(Next|Previous)HTMLElementOrText*() to ignore only invisible
data nodes.
Note that even with this fix, the range of nodes computed by
HTMLEditRules::GetNodesFromSelection() is still odd if only non-editable
elements follow a <br> node which is first <br> element after the caret
position. However, what is expected by the execCommand spec is unclear.
So, automated test added by this patch checks current inconsistent behavior
for now.
MozReview-Commit-ID: 2m52StwoEEH
--HG--
extra : rebase_source : 6b9b2338e35c4d2e89a405fd8e1ffc7b0873ca1e
2018-02-13 13:01:42 +03:00
|
|
|
|
2018-05-15 09:09:13 +03:00
|
|
|
/**
|
|
|
|
* MakeBlockquote() inserts at least one <blockquote> element and moves
|
|
|
|
* nodes in aNodeArray into new <blockquote> elements. If aNodeArray
|
|
|
|
* includes a table related element except <table>, this calls itself
|
|
|
|
* recursively to insert <blockquote> into the cell.
|
|
|
|
*
|
|
|
|
* @param aNodeArray Nodes which will be moved into created
|
|
|
|
* <blockquote> elements.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult
|
|
|
|
MakeBlockquote(nsTArray<OwningNonNull<nsINode>>& aNodeArray);
|
2017-11-17 10:03:11 +03:00
|
|
|
|
|
|
|
/**
|
2018-04-09 20:16:49 +03:00
|
|
|
* MaybeSplitAncestorsForInsertWithTransaction() does nothing if container of
|
2017-11-17 10:03:11 +03:00
|
|
|
* aStartOfDeepestRightNode can have an element whose tag name is aTag.
|
|
|
|
* Otherwise, looks for an ancestor node which is or is in active editing
|
|
|
|
* host and can have an element whose name is aTag. If there is such
|
|
|
|
* ancestor, its descendants are split.
|
|
|
|
*
|
|
|
|
* Note that this may create empty elements while splitting ancestors.
|
|
|
|
*
|
|
|
|
* @param aTag The name of element to be inserted
|
|
|
|
* after calling this method.
|
|
|
|
* @param aStartOfDeepestRightNode The start point of deepest right node.
|
|
|
|
* This point must be descendant of
|
|
|
|
* active editing host.
|
|
|
|
* @return When succeeded, SplitPoint() returns
|
|
|
|
* the point to insert the element.
|
|
|
|
*/
|
2018-03-20 08:05:47 +03:00
|
|
|
template <typename PT, typename CT>
|
2018-05-14 17:55:53 +03:00
|
|
|
MOZ_MUST_USE SplitNodeResult MaybeSplitAncestorsForInsertWithTransaction(
|
|
|
|
nsAtom& aTag, const EditorDOMPointBase<PT, CT>& aStartOfDeepestRightNode);
|
2017-11-17 10:03:11 +03:00
|
|
|
|
2018-04-09 21:46:44 +03:00
|
|
|
/**
|
|
|
|
* JoinNearestEditableNodesWithTransaction() joins two editable nodes which
|
|
|
|
* are themselves or the nearest editable node of aLeftNode and aRightNode.
|
|
|
|
* XXX This method's behavior is odd. For example, if user types Backspace
|
|
|
|
* key at the second editable paragraph in this case:
|
|
|
|
* <div contenteditable>
|
|
|
|
* <p>first editable paragraph</p>
|
|
|
|
* <p contenteditable="false">non-editable paragraph</p>
|
|
|
|
* <p>second editable paragraph</p>
|
|
|
|
* </div>
|
|
|
|
* The first editable paragraph's content will be moved into the second
|
|
|
|
* editable paragraph and the non-editable paragraph becomes the first
|
|
|
|
* paragraph of the editor. I don't think that it's expected behavior of
|
|
|
|
* any users...
|
|
|
|
*
|
|
|
|
* @param aLeftNode The node which will be removed.
|
|
|
|
* @param aRightNode The node which will be inserted the content of
|
|
|
|
* aLeftNode.
|
2018-05-14 17:51:23 +03:00
|
|
|
* @param aNewFirstChildOfRightNode
|
|
|
|
* The point at the first child of aRightNode.
|
2018-04-09 21:46:44 +03:00
|
|
|
*/
|
2018-05-14 17:51:23 +03:00
|
|
|
MOZ_MUST_USE nsresult JoinNearestEditableNodesWithTransaction(
|
|
|
|
nsIContent& aLeftNode, nsIContent& aRightNode,
|
|
|
|
EditorDOMPoint* aNewFirstChildOfRightNode);
|
2018-04-09 21:46:44 +03:00
|
|
|
|
2016-05-01 16:15:14 +03:00
|
|
|
Element* GetTopEnclosingMailCite(nsINode& aNode);
|
2018-05-14 12:18:24 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* PopListItem() tries to move aListItem outside its parent. If it's
|
|
|
|
* in a middle of a list element, the parent list element is split before
|
|
|
|
* aListItem. Then, moves aListItem to before its parent list element.
|
|
|
|
* I.e., moves aListItem between the 2 list elements if original parent
|
|
|
|
* was split. Then, if new parent is not a list element, the list item
|
|
|
|
* element is removed and its contents are moved to where the list item
|
|
|
|
* element was.
|
|
|
|
*
|
|
|
|
* @param aListItem Should be a <li>, <dt> or <dd> element.
|
|
|
|
* If it's not so, returns NS_ERROR_FAILURE.
|
|
|
|
* @param aOutOfList Returns true if the list item element is
|
|
|
|
* removed (i.e., unwrapped contents of
|
|
|
|
* aListItem). Otherwise, false.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult PopListItem(nsIContent& aListItem,
|
|
|
|
bool* aOutOfList = nullptr);
|
2018-05-14 11:47:21 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* RemoveListStructure() destroys the list structure of aListElement.
|
|
|
|
* If aListElement has <li>, <dl> or <dt> as a child, the element is removed
|
|
|
|
* but its descendants are moved to where the list item element was.
|
|
|
|
* If aListElement has another <ul>, <ol> or <dl> as a child, this method
|
|
|
|
* is called recursively.
|
|
|
|
* If aListElement has other nodes as its child, they are just removed.
|
|
|
|
* Finally, aListElement is removed. and its all children are moved to
|
|
|
|
* where the aListElement was.
|
|
|
|
*
|
|
|
|
* @param aListElement A <ul>, <ol> or <dl> element.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult RemoveListStructure(Element& aListElement);
|
|
|
|
|
2018-05-14 17:24:40 +03:00
|
|
|
/**
|
|
|
|
* CacheInlineStyles() caches style of aNode into mCachedStyles.
|
|
|
|
* This may cause flushing layout at retrieving computed value of CSS
|
|
|
|
* properties.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult CacheInlineStyles(nsINode* aNode);
|
2018-05-14 17:14:50 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* ReapplyCachedStyles() restores some styles which are disappeared during
|
|
|
|
* handling edit action and it should be restored. This may cause flushing
|
|
|
|
* layout at retrieving computed value of CSS properties.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult ReapplyCachedStyles();
|
|
|
|
|
2013-02-07 12:08:57 +04:00
|
|
|
void ClearCachedStyles();
|
2018-05-14 16:56:06 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* InsertBRElementToEmptyListItemsAndTableCellsInChangedRange() inserts
|
|
|
|
* <br> element into empty list item or table cell elements.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult
|
|
|
|
InsertBRElementToEmptyListItemsAndTableCellsInChangedRange();
|
2018-05-14 16:42:08 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* AdjustWhitespace() may replace whitespaces with NBSP or something.
|
|
|
|
* See WSRunObject::AdjustWhitespace() for the detail.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult AdjustWhitespace();
|
2018-05-14 16:37:33 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* PinSelectionToNewBlock() may collapse Selection around mNewNode if it's
|
|
|
|
* necessary,
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult PinSelectionToNewBlock();
|
|
|
|
|
2018-05-10 09:03:21 +03:00
|
|
|
void CheckInterlinePosition();
|
2018-05-14 13:25:48 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* AdjustSelection() may adjust Selection range to nearest editable content.
|
|
|
|
* Despite of the name, this may change the DOM tree. If it needs to create
|
|
|
|
* a <br> to put caret, this tries to create a <br> element.
|
|
|
|
*
|
|
|
|
* @param aAction Maybe used to look for a good point to put caret.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult AdjustSelection(nsIEditor::EDirection aAction);
|
Bug 1415800 - part 5: Redesign HTMLEditRules::FindNearSelectableNode() r=m_kato
First, the method name is not correct. It tries to find an editable node near
the given DOM point. Therefore, it should be FindNearEditableNode().
Next, the implementation did something odd. E.g., in the first |if| block,
when |nearNode| is nullptr, it returns nullptr. However, following |if| block
does something only when |nearNode| is nullptr. So, we can get rid of the
second |if| block. Then, nobody will change aDirection. So, we can make it
not a reference now.
Similarly, in |while| block, if |nearNode| becomes nullptr, it returns error.
However, following block checks if |nearNode| is NOT nullptr. So, we can get
rid of this |if| statement and outdent its block.
Additionally, |curNode| isn't necessary. It only increments the refcount
redundantly. So, we can get rid of it.
Finally, FindNearEditableNode() can return found node directly instead of
error code because error code doesn't make sense. Not found an editable
node is not illegal. And also it can take EditorRawDOMPoint instead of
a set of container, child and offset of the child in the container.
MozReview-Commit-ID: CTI581PhJMd
--HG--
extra : rebase_source : 7e05998721ce96727d40dda1be5e7e36b090bcd3
2017-11-09 19:35:10 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* FindNearEditableNode() tries to find an editable node near aPoint.
|
|
|
|
*
|
|
|
|
* @param aPoint The DOM point where to start to search from.
|
|
|
|
* @param aDirection If nsIEditor::ePrevious is set, this searches an
|
|
|
|
* editable node from next nodes. Otherwise, from
|
|
|
|
* previous nodes.
|
|
|
|
* @return If found, returns non-nullptr. Otherwise, nullptr.
|
|
|
|
* Note that if found node is in different table element,
|
|
|
|
* this returns nullptr.
|
|
|
|
* And also if aDirection is not nsIEditor::ePrevious,
|
|
|
|
* the result may be the node pointed by aPoint.
|
|
|
|
*/
|
2018-03-20 08:05:47 +03:00
|
|
|
template <typename PT, typename CT>
|
|
|
|
nsIContent* FindNearEditableNode(const EditorDOMPointBase<PT, CT>& aPoint,
|
Bug 1415800 - part 5: Redesign HTMLEditRules::FindNearSelectableNode() r=m_kato
First, the method name is not correct. It tries to find an editable node near
the given DOM point. Therefore, it should be FindNearEditableNode().
Next, the implementation did something odd. E.g., in the first |if| block,
when |nearNode| is nullptr, it returns nullptr. However, following |if| block
does something only when |nearNode| is nullptr. So, we can get rid of the
second |if| block. Then, nobody will change aDirection. So, we can make it
not a reference now.
Similarly, in |while| block, if |nearNode| becomes nullptr, it returns error.
However, following block checks if |nearNode| is NOT nullptr. So, we can get
rid of this |if| statement and outdent its block.
Additionally, |curNode| isn't necessary. It only increments the refcount
redundantly. So, we can get rid of it.
Finally, FindNearEditableNode() can return found node directly instead of
error code because error code doesn't make sense. Not found an editable
node is not illegal. And also it can take EditorRawDOMPoint instead of
a set of container, child and offset of the child in the container.
MozReview-Commit-ID: CTI581PhJMd
--HG--
extra : rebase_source : 7e05998721ce96727d40dda1be5e7e36b090bcd3
2017-11-09 19:35:10 +03:00
|
|
|
nsIEditor::EDirection aDirection);
|
2012-07-27 18:03:28 +04:00
|
|
|
/**
|
|
|
|
* Returns true if aNode1 or aNode2 or both is the descendant of some type of
|
|
|
|
* table element, but their nearest table element ancestors differ. "Table
|
|
|
|
* element" here includes not just <table> but also <td>, <tbody>, <tr>, etc.
|
|
|
|
* The nodes count as being their own descendants for this purpose, so a
|
|
|
|
* table element is its own nearest table element ancestor.
|
|
|
|
*/
|
2016-07-07 13:05:51 +03:00
|
|
|
bool InDifferentTableElements(nsINode* aNode1, nsINode* aNode2);
|
2018-05-14 13:07:59 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* RemoveEmptyNodesInChangedRange() removes all empty nodes in
|
|
|
|
* mDocChangeRange. However, if mail-cite node has only a <br> element,
|
|
|
|
* the node will be removed but <br> element is moved to where the
|
|
|
|
* mail-cite node was.
|
|
|
|
* XXX This method is expensive if mDocChangeRange is too wide and may
|
|
|
|
* remove unexpected empty element, e.g., it was created by JS, but
|
|
|
|
* we haven't touched it. Cannot we remove this method and make
|
|
|
|
* guarantee that empty nodes won't be created?
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult RemoveEmptyNodesInChangedRange();
|
|
|
|
|
2016-07-07 13:05:51 +03:00
|
|
|
nsresult SelectionEndpointInNode(nsINode* aNode, bool* aResult);
|
2014-11-02 15:04:13 +03:00
|
|
|
nsresult UpdateDocChangeRange(nsRange* aRange);
|
2018-05-14 11:47:21 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* ConfirmSelectionInBody() makes sure that Selection is in editor root
|
|
|
|
* element typically <body> element (see HTMLEditor::UpdateRootElement())
|
|
|
|
* and only one Selection range.
|
|
|
|
* XXX This method is not necessary because even if selection is outside the
|
|
|
|
* <body> element, elements outside the <body> element should be
|
|
|
|
* editable, e.g., any element can be inserted siblings as <body> element
|
|
|
|
* and other browsers allow to edit such elements.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult ConfirmSelectionInBody();
|
2017-08-01 16:38:50 +03:00
|
|
|
|
2018-05-18 06:38:32 +03:00
|
|
|
/**
|
|
|
|
* IsEmptyInline: Return true if aNode is an empty inline container
|
|
|
|
*/
|
2016-07-07 13:05:51 +03:00
|
|
|
bool IsEmptyInline(nsINode& aNode);
|
2018-05-18 06:38:32 +03:00
|
|
|
|
2016-07-07 13:05:51 +03:00
|
|
|
bool ListIsEmptyLine(nsTArray<OwningNonNull<nsINode>>& arrayOfNodes);
|
2018-05-12 05:39:01 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* RemoveAlignment() removes align attributes, text-align properties and
|
|
|
|
* <center> elements in aNode.
|
|
|
|
*
|
|
|
|
* @param aNode Alignment information of the node and/or its
|
|
|
|
* descendants will be removed.
|
|
|
|
* @param aAlignType New align value to be set only when it's in
|
|
|
|
* CSS mode and this method meets <table> or <hr>.
|
|
|
|
* XXX This is odd and not clear when you see
|
|
|
|
* caller of this method. Do you have better
|
|
|
|
* idea?
|
|
|
|
* @param aDescendantsOnly true if align information of aNode itself
|
|
|
|
* shouldn't be removed. Otherwise, false.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult RemoveAlignment(nsINode& aNode,
|
|
|
|
const nsAString& aAlignType,
|
|
|
|
bool aDescendantsOnly);
|
2018-05-12 05:25:23 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* MakeSureElemStartsOrEndsOnCR() inserts <br> element at start (end) of
|
|
|
|
* aNode if neither:
|
|
|
|
* - first (last) editable child of aNode is a block or a <br>,
|
|
|
|
* - previous (next) sibling of aNode is block or a <br>
|
|
|
|
* - nor no previous (next) sibling of aNode.
|
|
|
|
*
|
|
|
|
* @param aNode The node which may be inserted <br> element.
|
|
|
|
* @param aStarts true for trying to insert <br> to the start.
|
|
|
|
* false for trying to insert <br> to the end.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult MakeSureElemStartsOrEndsOnCR(nsINode& aNode,
|
|
|
|
bool aStarts);
|
2018-05-12 04:58:57 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* AlignBlock() resets align attribute, text-align property, etc first.
|
|
|
|
* Then, aligns contents of aElement on aAlignType.
|
|
|
|
*
|
|
|
|
* @param aElement The element whose contents will be aligned.
|
|
|
|
* @param aAlignType Boundary or "center" which contents should be
|
|
|
|
* aligned on.
|
|
|
|
* @param aResetAlignOf Resets align of whether element and its
|
|
|
|
* descendants or only descendants.
|
|
|
|
*/
|
|
|
|
enum class ResetAlignOf { ElementAndDescendants, OnlyDescendants };
|
|
|
|
MOZ_MUST_USE nsresult AlignBlock(Element& aElement,
|
|
|
|
const nsAString& aAlignType,
|
|
|
|
ResetAlignOf aResetAlignOf);
|
2018-05-12 04:29:41 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* IncreaseMarginToIndent() increases the margin of aElement. See the
|
|
|
|
* document of ChangeMarginStart() for the detail.
|
|
|
|
* XXX This is not aware of vertical writing-mode.
|
|
|
|
*
|
|
|
|
* @param aElement The element to be indented.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult IncreaseMarginToIndent(Element& aElement) {
|
|
|
|
return ChangeMarginStart(aElement, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* DecreaseMarginToOutdent() decreases the margin of aElement. See the
|
|
|
|
* document of ChangeMarginStart() for the detail.
|
|
|
|
* XXX This is not aware of vertical writing-mode.
|
|
|
|
*
|
|
|
|
* @param aElement The element to be outdented.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult DecreaseMarginToOutdent(Element& aElement) {
|
|
|
|
return ChangeMarginStart(aElement, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ChangeMarginStart() changes margin of aElement to indent or outdent.
|
|
|
|
* However, use IncreaseMarginToIndent() and DecreaseMarginToOutdent()
|
|
|
|
* instead. If it's rtl text, margin-right will be changed. Otherwise,
|
|
|
|
* margin-left.
|
|
|
|
* XXX This is not aware of vertical writing-mode.
|
|
|
|
*
|
|
|
|
* @param aElement The element to be indented or outdented.
|
|
|
|
* @param aIncrease true for indent, false for outdent.
|
|
|
|
*/
|
|
|
|
MOZ_MUST_USE nsresult ChangeMarginStart(Element& aElement, bool aIncrease);
|
|
|
|
|
2018-10-25 08:55:04 +03:00
|
|
|
/**
|
|
|
|
* DocumentModifiedWorker() is called by DocumentModified() either
|
|
|
|
* synchronously or asynchronously.
|
|
|
|
*/
|
|
|
|
MOZ_CAN_RUN_SCRIPT void DocumentModifiedWorker();
|
1999-11-25 03:19:45 +03:00
|
|
|
|
2017-01-06 16:35:48 +03:00
|
|
|
/**
|
|
|
|
* InitStyleCacheArray() initializes aStyleCache for usable with
|
|
|
|
* GetInlineStyles().
|
|
|
|
*/
|
|
|
|
void InitStyleCacheArray(StyleCache aStyleCache[SIZE_STYLE_TABLE]);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* GetInlineStyles() retrieves the style of aNode and modifies each item of
|
2018-05-14 17:20:28 +03:00
|
|
|
* aStyleCache. This might cause flushing layout at retrieving computed
|
|
|
|
* values of CSS properties.
|
2017-01-06 16:35:48 +03:00
|
|
|
*/
|
2018-05-14 17:20:28 +03:00
|
|
|
MOZ_MUST_USE nsresult
|
|
|
|
GetInlineStyles(nsINode* aNode, StyleCache aStyleCache[SIZE_STYLE_TABLE]);
|
2017-01-06 16:35:48 +03:00
|
|
|
|
1999-11-25 03:19:45 +03:00
|
|
|
protected:
|
2016-07-09 05:42:33 +03:00
|
|
|
HTMLEditor* mHTMLEditor;
|
2016-07-07 13:05:51 +03:00
|
|
|
RefPtr<nsRange> mDocChangeRange;
|
|
|
|
bool mListenerEnabled;
|
|
|
|
bool mReturnInEmptyLIKillsList;
|
|
|
|
bool mDidDeleteSelection;
|
|
|
|
bool mDidRangedDelete;
|
|
|
|
bool mRestoreContentEditableCount;
|
|
|
|
RefPtr<nsRange> mUtilRange;
|
|
|
|
// Need to remember an int across willJoin/didJoin...
|
|
|
|
uint32_t mJoinOffset;
|
2018-05-11 14:25:01 +03:00
|
|
|
RefPtr<Element> mNewBlock;
|
2016-07-07 13:05:51 +03:00
|
|
|
RefPtr<RangeItem> mRangeItem;
|
2017-01-06 16:35:48 +03:00
|
|
|
|
|
|
|
// XXX In strict speaking, mCachedStyles isn't enough to cache inline styles
|
|
|
|
// because inline style can be specified with "style" attribute and/or
|
|
|
|
// CSS in <style> elements or CSS files. So, we need to look for better
|
|
|
|
// implementation about this.
|
2016-07-07 13:05:51 +03:00
|
|
|
StyleCache mCachedStyles[SIZE_STYLE_TABLE];
|
1999-11-25 03:19:45 +03:00
|
|
|
};
|
|
|
|
|
2016-07-07 13:05:51 +03:00
|
|
|
} // namespace mozilla
|
1999-03-29 10:21:01 +04:00
|
|
|
|
2016-07-07 13:05:51 +03:00
|
|
|
#endif // #ifndef HTMLEditRules_h
|