зеркало из https://github.com/mozilla/gecko-dev.git
523 строки
22 KiB
C++
523 строки
22 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef HTMLEditorNestedClasses_h
|
|
#define HTMLEditorNestedClasses_h
|
|
|
|
#include "EditorDOMPoint.h"
|
|
#include "EditorForwards.h"
|
|
#include "HTMLEditor.h" // for HTMLEditor
|
|
#include "HTMLEditHelpers.h" // for EditorInlineStyleAndValue
|
|
|
|
#include "mozilla/Attributes.h"
|
|
#include "mozilla/OwningNonNull.h"
|
|
#include "mozilla/Result.h"
|
|
|
|
namespace mozilla {
|
|
|
|
/*****************************************************************************
|
|
* AutoInlineStyleSetter is a temporary class to set an inline style to
|
|
* specific nodes.
|
|
****************************************************************************/
|
|
|
|
class MOZ_STACK_CLASS HTMLEditor::AutoInlineStyleSetter final
|
|
: private EditorInlineStyleAndValue {
|
|
using Element = dom::Element;
|
|
using Text = dom::Text;
|
|
|
|
public:
|
|
explicit AutoInlineStyleSetter(
|
|
const EditorInlineStyleAndValue& aStyleAndValue)
|
|
: EditorInlineStyleAndValue(aStyleAndValue) {}
|
|
|
|
void Reset() {
|
|
mFirstHandledPoint.Clear();
|
|
mLastHandledPoint.Clear();
|
|
}
|
|
|
|
const EditorDOMPoint& FirstHandledPointRef() const {
|
|
return mFirstHandledPoint;
|
|
}
|
|
const EditorDOMPoint& LastHandledPointRef() const {
|
|
return mLastHandledPoint;
|
|
}
|
|
|
|
/**
|
|
* Split aText at aStartOffset and aEndOffset (except when they are start or
|
|
* end of its data) and wrap the middle text node in an element to apply the
|
|
* style.
|
|
*/
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<SplitRangeOffFromNodeResult, nsresult>
|
|
SplitTextNodeAndApplyStyleToMiddleNode(HTMLEditor& aHTMLEditor, Text& aText,
|
|
uint32_t aStartOffset,
|
|
uint32_t aEndOffset);
|
|
|
|
/**
|
|
* Remove same style from children and apply the style entire (except
|
|
* non-editable nodes) aContent.
|
|
*/
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CaretPoint, nsresult>
|
|
ApplyStyleToNodeOrChildrenAndRemoveNestedSameStyle(HTMLEditor& aHTMLEditor,
|
|
nsIContent& aContent);
|
|
|
|
/**
|
|
* Invert the style with creating new element or something. This should
|
|
* be called only when IsInvertibleWithCSS() returns true.
|
|
*/
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
|
|
InvertStyleIfApplied(HTMLEditor& aHTMLEditor, Element& aElement);
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<SplitRangeOffFromNodeResult, nsresult>
|
|
InvertStyleIfApplied(HTMLEditor& aHTMLEditor, Text& aTextNode,
|
|
uint32_t aStartOffset, uint32_t aEndOffset);
|
|
|
|
/**
|
|
* Extend or shrink aRange for applying the style to the range.
|
|
* See comments in the definition what this does.
|
|
*/
|
|
Result<EditorRawDOMRange, nsresult> ExtendOrShrinkRangeToApplyTheStyle(
|
|
const HTMLEditor& aHTMLEditor, const EditorDOMRange& aRange,
|
|
const Element& aEditingHost) const;
|
|
|
|
/**
|
|
* Returns next/previous sibling of aContent or an ancestor of it if it's
|
|
* editable and does not cross block boundary.
|
|
*/
|
|
[[nodiscard]] static nsIContent* GetNextEditableInlineContent(
|
|
const nsIContent& aContent, const nsINode* aLimiter = nullptr);
|
|
[[nodiscard]] static nsIContent* GetPreviousEditableInlineContent(
|
|
const nsIContent& aContent, const nsINode* aLimiter = nullptr);
|
|
|
|
/**
|
|
* GetEmptyTextNodeToApplyNewStyle creates new empty text node to insert
|
|
* a new element which will contain newly inserted text or returns existing
|
|
* empty text node if aCandidatePointToInsert is around it.
|
|
*
|
|
* NOTE: Unfortunately, editor does not want to insert text into empty inline
|
|
* element in some places (e.g., automatically adjusting caret position to
|
|
* nearest text node). Therefore, we need to create new empty text node to
|
|
* prepare new styles for inserting text. This method is designed for the
|
|
* preparation.
|
|
*
|
|
* @param aHTMLEditor The editor.
|
|
* @param aCandidatePointToInsert The point where the caller wants to
|
|
* insert new text.
|
|
* @param aEditingHost The editing host.
|
|
* @return If this creates new empty text node returns it.
|
|
* If this couldn't create new empty text node due to
|
|
* the point or aEditingHost cannot have text node,
|
|
* returns nullptr.
|
|
* Otherwise, returns error.
|
|
*/
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<RefPtr<Text>, nsresult>
|
|
GetEmptyTextNodeToApplyNewStyle(HTMLEditor& aHTMLEditor,
|
|
const EditorDOMPoint& aCandidatePointToInsert,
|
|
const Element& aEditingHost);
|
|
|
|
private:
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CaretPoint, nsresult> ApplyStyle(
|
|
HTMLEditor& aHTMLEditor, nsIContent& aContent);
|
|
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CaretPoint, nsresult>
|
|
ApplyCSSTextDecoration(HTMLEditor& aHTMLEditor, nsIContent& aContent);
|
|
|
|
/**
|
|
* Returns true if aStyledElement is a good element to set `style` attribute.
|
|
*/
|
|
[[nodiscard]] bool ElementIsGoodContainerToSetStyle(
|
|
nsStyledElement& aStyledElement) const;
|
|
|
|
/**
|
|
* ElementIsGoodContainerForTheStyle() returns true if aElement is a
|
|
* good container for applying the style to a node. I.e., if this returns
|
|
* true, moving nodes into aElement is enough to apply the style to them.
|
|
* Otherwise, you need to create new element for the style.
|
|
*/
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<bool, nsresult>
|
|
ElementIsGoodContainerForTheStyle(HTMLEditor& aHTMLEditor,
|
|
Element& aElement) const;
|
|
|
|
/**
|
|
* Return true if the node is an element node and it represents the style or
|
|
* sets the style (including when setting different value) with `style`
|
|
* attribute.
|
|
*/
|
|
[[nodiscard]] bool ContentIsElementSettingTheStyle(
|
|
const HTMLEditor& aHTMLEditor, nsIContent& aContent) const;
|
|
|
|
/**
|
|
* Helper methods to shrink range to apply the style.
|
|
*/
|
|
[[nodiscard]] EditorRawDOMPoint GetShrunkenRangeStart(
|
|
const HTMLEditor& aHTMLEditor, const EditorDOMRange& aRange,
|
|
const nsINode& aCommonAncestorOfRange,
|
|
const nsIContent* aFirstEntirelySelectedContentNodeInRange) const;
|
|
[[nodiscard]] EditorRawDOMPoint GetShrunkenRangeEnd(
|
|
const HTMLEditor& aHTMLEditor, const EditorDOMRange& aRange,
|
|
const nsINode& aCommonAncestorOfRange,
|
|
const nsIContent* aLastEntirelySelectedContentNodeInRange) const;
|
|
|
|
/**
|
|
* Helper methods to extend the range to apply the style.
|
|
*/
|
|
[[nodiscard]] EditorRawDOMPoint
|
|
GetExtendedRangeStartToWrapAncestorApplyingSameStyle(
|
|
const HTMLEditor& aHTMLEditor,
|
|
const EditorRawDOMPoint& aStartPoint) const;
|
|
[[nodiscard]] EditorRawDOMPoint
|
|
GetExtendedRangeEndToWrapAncestorApplyingSameStyle(
|
|
const HTMLEditor& aHTMLEditor, const EditorRawDOMPoint& aEndPoint) const;
|
|
[[nodiscard]] EditorRawDOMRange
|
|
GetExtendedRangeToMinimizeTheNumberOfNewElements(
|
|
const HTMLEditor& aHTMLEditor, const nsINode& aCommonAncestor,
|
|
EditorRawDOMPoint&& aStartPoint, EditorRawDOMPoint&& aEndPoint) const;
|
|
|
|
/**
|
|
* OnHandled() are called when this class creates new element to apply the
|
|
* style, applies new style to existing element or ignores to apply the style
|
|
* due to already set.
|
|
*/
|
|
void OnHandled(const EditorDOMPoint& aStartPoint,
|
|
const EditorDOMPoint& aEndPoint) {
|
|
if (!mFirstHandledPoint.IsSet()) {
|
|
mFirstHandledPoint = aStartPoint;
|
|
}
|
|
mLastHandledPoint = aEndPoint;
|
|
}
|
|
void OnHandled(nsIContent& aContent) {
|
|
if (!mFirstHandledPoint.IsSet()) {
|
|
mFirstHandledPoint.Set(&aContent, 0u);
|
|
}
|
|
mLastHandledPoint = EditorDOMPoint::AtEndOf(aContent);
|
|
}
|
|
|
|
// mFirstHandledPoint and mLastHandledPoint store the first and last points
|
|
// which are newly created or apply the new style, or just ignored at trying
|
|
// to split a text node.
|
|
EditorDOMPoint mFirstHandledPoint;
|
|
EditorDOMPoint mLastHandledPoint;
|
|
};
|
|
|
|
/**
|
|
* AutoMoveOneLineHandler moves the content in a line (between line breaks/block
|
|
* boundaries) to specific point or end of a container element.
|
|
*/
|
|
class MOZ_STACK_CLASS HTMLEditor::AutoMoveOneLineHandler final {
|
|
public:
|
|
/**
|
|
* Use this constructor when you want a line to move specific point.
|
|
*/
|
|
explicit AutoMoveOneLineHandler(const EditorDOMPoint& aPointToInsert)
|
|
: mPointToInsert(aPointToInsert),
|
|
mMoveToEndOfContainer(MoveToEndOfContainer::No) {
|
|
MOZ_ASSERT(mPointToInsert.IsSetAndValid());
|
|
MOZ_ASSERT(mPointToInsert.IsInContentNode());
|
|
}
|
|
/**
|
|
* Use this constructor when you want a line to move end of
|
|
* aNewContainerElement.
|
|
*/
|
|
explicit AutoMoveOneLineHandler(Element& aNewContainerElement)
|
|
: mPointToInsert(&aNewContainerElement, 0),
|
|
mMoveToEndOfContainer(MoveToEndOfContainer::Yes) {
|
|
MOZ_ASSERT(mPointToInsert.IsSetAndValid());
|
|
}
|
|
|
|
/**
|
|
* Must be called before calling Run().
|
|
*
|
|
* @param aHTMLEditor The HTML editor.
|
|
* @param aPointInHardLine A point in a line which you want to move.
|
|
* @param aEditingHost The editing host.
|
|
*/
|
|
[[nodiscard]] nsresult Prepare(HTMLEditor& aHTMLEditor,
|
|
const EditorDOMPoint& aPointInHardLine,
|
|
const Element& aEditingHost);
|
|
/**
|
|
* Must be called if Prepare() returned NS_OK.
|
|
*
|
|
* @param aHTMLEditor The HTML editor.
|
|
* @param aEditingHost The editing host.
|
|
*/
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<MoveNodeResult, nsresult> Run(
|
|
HTMLEditor& aHTMLEditor, const Element& aEditingHost);
|
|
|
|
/**
|
|
* Returns true if there are some content nodes which can be moved to another
|
|
* place or deleted in the line containing aPointInHardLine. Note that if
|
|
* there is only a padding <br> element in an empty block element, this
|
|
* returns false even though it may be deleted.
|
|
*/
|
|
static Result<bool, nsresult> CanMoveOrDeleteSomethingInLine(
|
|
const EditorDOMPoint& aPointInHardLine, const Element& aEditingHost);
|
|
|
|
AutoMoveOneLineHandler(const AutoMoveOneLineHandler& aOther) = delete;
|
|
AutoMoveOneLineHandler(AutoMoveOneLineHandler&& aOther) = delete;
|
|
|
|
private:
|
|
[[nodiscard]] bool ForceMoveToEndOfContainer() const {
|
|
return mMoveToEndOfContainer == MoveToEndOfContainer::Yes;
|
|
}
|
|
[[nodiscard]] EditorDOMPoint& NextInsertionPointRef() {
|
|
if (ForceMoveToEndOfContainer()) {
|
|
mPointToInsert.SetToEndOf(mPointToInsert.GetContainer());
|
|
}
|
|
return mPointToInsert;
|
|
}
|
|
|
|
/**
|
|
* Consider whether Run() should preserve or does not preserve white-space
|
|
* style of moving content.
|
|
*
|
|
* @param aContentInLine Specify a content node in the moving line.
|
|
* Typically, container of aPointInHardLine of
|
|
* Prepare().
|
|
* @param aInclusiveAncestorBlockOfInsertionPoint
|
|
* Inclusive ancestor block element of insertion
|
|
* point. Typically, computed
|
|
* mDestInclusiveAncestorBlock.
|
|
*/
|
|
[[nodiscard]] static PreserveWhiteSpaceStyle
|
|
ConsiderWhetherPreserveWhiteSpaceStyle(
|
|
const nsIContent* aContentInLine,
|
|
const Element* aInclusiveAncestorBlockOfInsertionPoint);
|
|
|
|
/**
|
|
* Look for inclusive ancestor block element of aBlockElement and a descendant
|
|
* of aAncestorElement. If aBlockElement and aAncestorElement are same one,
|
|
* this returns nullptr.
|
|
*
|
|
* @param aBlockElement A block element which is a descendant of
|
|
* aAncestorElement.
|
|
* @param aAncestorElement An inclusive ancestor block element of
|
|
* aBlockElement.
|
|
*/
|
|
[[nodiscard]] static Element*
|
|
GetMostDistantInclusiveAncestorBlockInSpecificAncestorElement(
|
|
Element& aBlockElement, const Element& aAncestorElement);
|
|
|
|
/**
|
|
* Split ancestors at the line range boundaries and collect array of contents
|
|
* in the line to aOutArrayOfContents. Specify aNewContainer to the container
|
|
* of insertion point to avoid splitting the destination.
|
|
*/
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CaretPoint, nsresult>
|
|
SplitToMakeTheLineIsolated(
|
|
HTMLEditor& aHTMLEditor, const nsIContent& aNewContainer,
|
|
const Element& aEditingHost,
|
|
nsTArray<OwningNonNull<nsIContent>>& aOutArrayOfContents) const;
|
|
|
|
/**
|
|
* Delete unnecessary trailing line break in aMovedContentRange if there is.
|
|
*/
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
|
|
DeleteUnnecessaryTrailingLineBreakInMovedLineEnd(
|
|
HTMLEditor& aHTMLEditor, const EditorDOMRange& aMovedContentRange,
|
|
const Element& aEditingHost) const;
|
|
|
|
// Range of selected line.
|
|
EditorDOMRange mLineRange;
|
|
// Next insertion point. If mMoveToEndOfContainer is `Yes`, this is
|
|
// recomputed with its container in NextInsertionPointRef. Therefore, this
|
|
// should not be referred directly.
|
|
EditorDOMPoint mPointToInsert;
|
|
// An inclusive ancestor block element of the moving line.
|
|
RefPtr<Element> mSrcInclusiveAncestorBlock;
|
|
// An inclusive ancestor block element of the insertion point.
|
|
RefPtr<Element> mDestInclusiveAncestorBlock;
|
|
// nullptr if mMovingToParentBlock is false.
|
|
// Must be non-nullptr if mMovingToParentBlock is true. The topmost ancestor
|
|
// block element which contains mSrcInclusiveAncestorBlock and a descendant of
|
|
// mDestInclusiveAncestorBlock. I.e., this may be same as
|
|
// mSrcInclusiveAncestorBlock, but never same as mDestInclusiveAncestorBlock.
|
|
RefPtr<Element> mTopmostSrcAncestorBlockInDestBlock;
|
|
enum class MoveToEndOfContainer { No, Yes };
|
|
MoveToEndOfContainer mMoveToEndOfContainer;
|
|
PreserveWhiteSpaceStyle mPreserveWhiteSpaceStyle =
|
|
PreserveWhiteSpaceStyle::No;
|
|
// true if mDestInclusiveAncestorBlock is an ancestor of
|
|
// mSrcInclusiveAncestorBlock.
|
|
bool mMovingToParentBlock = false;
|
|
};
|
|
|
|
/**
|
|
* Convert contents around aRanges of Run() to specified list element. If there
|
|
* are some different type of list elements, this method converts them to
|
|
* specified list items too. Basically, each line will be wrapped in a list
|
|
* item element. However, only when <p> element is selected, its child <br>
|
|
* elements won't be treated as line separators. Perhaps, this is a bug.
|
|
*/
|
|
class MOZ_STACK_CLASS HTMLEditor::AutoListElementCreator final {
|
|
public:
|
|
/**
|
|
* @param aListElementTagName The new list element tag name.
|
|
* @param aListItemElementTagName The new list item element tag name.
|
|
* @param aBulletType If this is not empty string, it's set
|
|
* to `type` attribute of new list item
|
|
* elements. Otherwise, existing `type`
|
|
* attributes will be removed.
|
|
*/
|
|
AutoListElementCreator(const nsStaticAtom& aListElementTagName,
|
|
const nsStaticAtom& aListItemElementTagName,
|
|
const nsAString& aBulletType)
|
|
// Needs const_cast hack here because the struct users may want
|
|
// non-const nsStaticAtom pointer due to bug 1794954
|
|
: mListTagName(const_cast<nsStaticAtom&>(aListElementTagName)),
|
|
mListItemTagName(const_cast<nsStaticAtom&>(aListItemElementTagName)),
|
|
mBulletType(aBulletType) {
|
|
MOZ_ASSERT(&mListTagName == nsGkAtoms::ul ||
|
|
&mListTagName == nsGkAtoms::ol ||
|
|
&mListTagName == nsGkAtoms::dl);
|
|
MOZ_ASSERT_IF(
|
|
&mListTagName == nsGkAtoms::ul || &mListTagName == nsGkAtoms::ol,
|
|
&mListItemTagName == nsGkAtoms::li);
|
|
MOZ_ASSERT_IF(&mListTagName == nsGkAtoms::dl,
|
|
&mListItemTagName == nsGkAtoms::dt ||
|
|
&mListItemTagName == nsGkAtoms::dd);
|
|
}
|
|
|
|
/**
|
|
* @param aHTMLEditor The HTML editor.
|
|
* @param aRanges [in/out] The ranges which will be converted to list.
|
|
* The instance must not have saved ranges because it'll
|
|
* be used in this method.
|
|
* If succeeded, this will have selection ranges which
|
|
* should be applied to `Selection`.
|
|
* If failed, this keeps storing original selection
|
|
* ranges.
|
|
* @param aSelectAllOfCurrentList Yes if this should treat all of
|
|
* ancestor list element at selection.
|
|
* @param aEditingHost The editing host.
|
|
*/
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<EditActionResult, nsresult> Run(
|
|
HTMLEditor& aHTMLEditor, AutoRangeArray& aRanges,
|
|
HTMLEditor::SelectAllOfCurrentList aSelectAllOfCurrentList,
|
|
const Element& aEditingHost) const;
|
|
|
|
private:
|
|
using ContentNodeArray = nsTArray<OwningNonNull<nsIContent>>;
|
|
using AutoContentNodeArray = AutoTArray<OwningNonNull<nsIContent>, 64>;
|
|
|
|
/**
|
|
* If aSelectAllOfCurrentList is "Yes" and aRanges is in a list element,
|
|
* returns the list element.
|
|
* Otherwise, extend aRanges to select start and end lines selected by it and
|
|
* correct all topmost content nodes in the extended ranges with splitting
|
|
* ancestors at range edges.
|
|
*/
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
|
|
SplitAtRangeEdgesAndCollectContentNodesToMoveIntoList(
|
|
HTMLEditor& aHTMLEditor, AutoRangeArray& aRanges,
|
|
SelectAllOfCurrentList aSelectAllOfCurrentList,
|
|
const Element& aEditingHost, ContentNodeArray& aOutArrayOfContents) const;
|
|
|
|
/**
|
|
* Return true if aArrayOfContents has only <br> elements or empty inline
|
|
* container elements. I.e., it means that aArrayOfContents represents
|
|
* only empty line(s) if this returns true.
|
|
*/
|
|
[[nodiscard]] static bool
|
|
IsEmptyOrContainsOnlyBRElementsOrEmptyInlineElements(
|
|
const ContentNodeArray& aArrayOfContents);
|
|
|
|
/**
|
|
* Delete all content nodes ina ArrayOfContents, and if we can put new list
|
|
* element at start of the first range of aRanges, insert new list element
|
|
* there.
|
|
*
|
|
* @return The empty list item element in new list element.
|
|
*/
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<RefPtr<Element>, nsresult>
|
|
ReplaceContentNodesWithEmptyNewList(
|
|
HTMLEditor& aHTMLEditor, const AutoRangeArray& aRanges,
|
|
const AutoContentNodeArray& aArrayOfContents,
|
|
const Element& aEditingHost) const;
|
|
|
|
/**
|
|
* Creat new list elements or use existing list elements and move
|
|
* aArrayOfContents into list item elements.
|
|
*
|
|
* @return A list or list item element which should have caret.
|
|
*/
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<RefPtr<Element>, nsresult>
|
|
WrapContentNodesIntoNewListElements(HTMLEditor& aHTMLEditor,
|
|
AutoRangeArray& aRanges,
|
|
AutoContentNodeArray& aArrayOfContents,
|
|
const Element& aEditingHost) const;
|
|
|
|
struct MOZ_STACK_CLASS AutoHandlingState final {
|
|
// Current list element which is a good container to create new list item
|
|
// element.
|
|
RefPtr<Element> mCurrentListElement;
|
|
// Previously handled list item element.
|
|
RefPtr<Element> mPreviousListItemElement;
|
|
// List or list item element which should have caret after handling all
|
|
// contents.
|
|
RefPtr<Element> mListOrListItemElementToPutCaret;
|
|
// Replacing block element. This is typically already removed from the DOM
|
|
// tree.
|
|
RefPtr<Element> mReplacingBlockElement;
|
|
// Once id attribute of mReplacingBlockElement copied, the id attribute
|
|
// shouldn't be copied again.
|
|
bool mMaybeCopiedReplacingBlockElementId = false;
|
|
};
|
|
|
|
/**
|
|
* Helper methods of WrapContentNodesIntoNewListElements. They are called for
|
|
* handling one content node of aArrayOfContents. It's set to aHandling*.
|
|
*/
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult HandleChildContent(
|
|
HTMLEditor& aHTMLEditor, nsIContent& aHandlingContent,
|
|
AutoHandlingState& aState, const Element& aEditingHost) const;
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
|
|
HandleChildListElement(HTMLEditor& aHTMLEditor, Element& aHandlingListElement,
|
|
AutoHandlingState& aState) const;
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult HandleChildListItemElement(
|
|
HTMLEditor& aHTMLEditor, Element& aHandlingListItemElement,
|
|
AutoHandlingState& aState) const;
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
|
|
HandleChildListItemInDifferentTypeList(HTMLEditor& aHTMLEditor,
|
|
Element& aHandlingListItemElement,
|
|
AutoHandlingState& aState) const;
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult HandleChildListItemInSameTypeList(
|
|
HTMLEditor& aHTMLEditor, Element& aHandlingListItemElement,
|
|
AutoHandlingState& aState) const;
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult HandleChildDivOrParagraphElement(
|
|
HTMLEditor& aHTMLEditor, Element& aHandlingDivOrParagraphElement,
|
|
AutoHandlingState& aState, const Element& aEditingHost) const;
|
|
enum class EmptyListItem { NotCreate, Create };
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult CreateAndUpdateCurrentListElement(
|
|
HTMLEditor& aHTMLEditor, const EditorDOMPoint& aPointToInsert,
|
|
EmptyListItem aEmptyListItem, AutoHandlingState& aState,
|
|
const Element& aEditingHost) const;
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
|
|
AppendListItemElement(HTMLEditor& aHTMLEditor, const Element& aListElement,
|
|
AutoHandlingState& aState) const;
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT static nsresult
|
|
MaybeCloneAttributesToNewListItem(HTMLEditor& aHTMLEditor,
|
|
Element& aListItemElement,
|
|
AutoHandlingState& aState);
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult HandleChildInlineContent(
|
|
HTMLEditor& aHTMLEditor, nsIContent& aHandlingInlineContent,
|
|
AutoHandlingState& aState) const;
|
|
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult WrapContentIntoNewListItemElement(
|
|
HTMLEditor& aHTMLEditor, nsIContent& aHandlingContent,
|
|
AutoHandlingState& aState) const;
|
|
|
|
/**
|
|
* If aRanges is collapsed outside aListItemOrListToPutCaret, this collapse
|
|
* aRanges in aListItemOrListToPutCaret again.
|
|
*/
|
|
nsresult EnsureCollapsedRangeIsInListItemOrListElement(
|
|
Element& aListItemOrListToPutCaret, AutoRangeArray& aRanges) const;
|
|
|
|
MOZ_KNOWN_LIVE nsStaticAtom& mListTagName;
|
|
MOZ_KNOWN_LIVE nsStaticAtom& mListItemTagName;
|
|
const nsAutoString mBulletType;
|
|
};
|
|
|
|
} // namespace mozilla
|
|
|
|
#endif // #ifndef HTMLEditorNestedClasses_h
|