--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -456,23 +456,24 @@ HTMLEditRules::AfterEdit(EditAction aAct
}
return NS_OK;
}
nsresult
HTMLEditRules::AfterEditInner(EditAction aAction,
nsIEditor::EDirection aDirection)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
ConfirmSelectionInBody();
if (aAction == EditAction::ignore) {
return NS_OK;
}
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<Selection> selection = mHTMLEditor->GetSelection();
+ RefPtr<Selection> selection = HTMLEditorRef().GetSelection();
NS_ENSURE_STATE(selection);
nsCOMPtr<nsINode> rangeStartContainer, rangeEndContainer;
uint32_t rangeStartOffset = 0, rangeEndOffset = 0;
// do we have a real range to act on?
bool bDamagedRange = false;
if (mDocChangeRange) {
rangeStartContainer = mDocChangeRange->GetStartContainer();
@@ -483,18 +484,17 @@ HTMLEditRules::AfterEditInner(EditAction
bDamagedRange = true;
}
}
if (bDamagedRange && !((aAction == EditAction::undo) ||
(aAction == EditAction::redo))) {
// don't let any txns in here move the selection around behind our back.
// Note that this won't prevent explicit selection setting from working.
- NS_ENSURE_STATE(mHTMLEditor);
- AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor);
+ AutoTransactionsConserveSelection dontChangeMySelection(&HTMLEditorRef());
// expand the "changed doc range" as needed
PromoteRange(*mDocChangeRange, aAction);
// if we did a ranged deletion or handling backspace key, make sure we have
// a place to put caret.
// Note we only want to do this if the overall operation was deletion,
// not if deletion was done along the way for EditAction::loadHTML, EditAction::insertText, etc.
@@ -505,19 +505,20 @@ HTMLEditRules::AfterEditInner(EditAction
}
// add in any needed <br>s, and remove any unneeded ones.
AdjustSpecialBreaks();
// merge any adjacent text nodes
if (aAction != EditAction::insertText &&
aAction != EditAction::insertIMEText) {
- NS_ENSURE_STATE(mHTMLEditor);
- nsresult rv = mHTMLEditor->CollapseAdjacentTextNodes(mDocChangeRange);
- NS_ENSURE_SUCCESS(rv, rv);
+ nsresult rv = HTMLEditorRef().CollapseAdjacentTextNodes(mDocChangeRange);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
// clean up any empty nodes in the selection
nsresult rv = RemoveEmptyNodes();
NS_ENSURE_SUCCESS(rv, rv);
// attempt to transform any unneeded nbsp's into spaces after doing various operations
if (aAction == EditAction::insertText ||
@@ -525,26 +526,24 @@ HTMLEditRules::AfterEditInner(EditAction
aAction == EditAction::deleteSelection ||
aAction == EditAction::insertBreak ||
aAction == EditAction::htmlPaste ||
aAction == EditAction::loadHTML) {
rv = AdjustWhitespace(selection);
NS_ENSURE_SUCCESS(rv, rv);
// also do this for original selection endpoints.
- NS_ENSURE_STATE(mHTMLEditor);
NS_ENSURE_STATE(mRangeItem->mStartContainer);
NS_ENSURE_STATE(mRangeItem->mEndContainer);
- WSRunObject(mHTMLEditor, mRangeItem->mStartContainer,
+ WSRunObject(&HTMLEditorRef(), mRangeItem->mStartContainer,
mRangeItem->mStartOffset).AdjustWhitespace();
// we only need to handle old selection endpoint if it was different from start
if (mRangeItem->mStartContainer != mRangeItem->mEndContainer ||
mRangeItem->mStartOffset != mRangeItem->mEndOffset) {
- NS_ENSURE_STATE(mHTMLEditor);
- WSRunObject(mHTMLEditor, mRangeItem->mEndContainer,
+ WSRunObject(&HTMLEditorRef(), mRangeItem->mEndContainer,
mRangeItem->mEndOffset).AdjustWhitespace();
}
}
// if we created a new block, make sure selection lands in it
if (mNewBlock) {
rv = PinSelectionToNewBlock(selection);
mNewBlock = nullptr;
@@ -561,36 +560,35 @@ HTMLEditRules::AfterEditInner(EditAction
NS_ENSURE_SUCCESS(rv, rv);
}
// check for any styles which were removed inappropriately
if (aAction == EditAction::insertText ||
aAction == EditAction::insertIMEText ||
aAction == EditAction::deleteSelection ||
IsStyleCachePreservingAction(aAction)) {
- NS_ENSURE_STATE(mHTMLEditor);
- mHTMLEditor->mTypeInState->UpdateSelState(selection);
+ HTMLEditorRef().mTypeInState->UpdateSelState(selection);
rv = ReapplyCachedStyles();
NS_ENSURE_SUCCESS(rv, rv);
ClearCachedStyles();
}
}
- NS_ENSURE_STATE(mHTMLEditor);
-
nsresult rv =
- mHTMLEditor->HandleInlineSpellCheck(
- aAction, *selection,
- mRangeItem->mStartContainer,
- mRangeItem->mStartOffset,
- rangeStartContainer,
- rangeStartOffset,
- rangeEndContainer,
- rangeEndOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ HTMLEditorRef().HandleInlineSpellCheck(
+ aAction, *selection,
+ mRangeItem->mStartContainer,
+ mRangeItem->mStartOffset,
+ rangeStartContainer,
+ rangeStartOffset,
+ rangeEndContainer,
+ rangeEndOffset);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
// detect empty doc
rv = CreateBogusNodeIfNeeded(selection);
NS_ENSURE_SUCCESS(rv, rv);
// adjust selection HINT if needed
if (!mDidExplicitlySetInterline) {
CheckInterlinePosition(*selection);
@@ -1314,23 +1312,21 @@ HTMLEditRules::GetFormatString(nsINode*
}
return NS_OK;
}
void
HTMLEditRules::WillInsert(Selection& aSelection,
bool* aCancel)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
MOZ_ASSERT(aCancel);
TextEditRules::WillInsert(aSelection, aCancel);
- NS_ENSURE_TRUE_VOID(mHTMLEditor);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
// Adjust selection to prevent insertion after a moz-BR. This next only
// works for collapsed selections right now, because selection is a pain to
// work with when not collapsed. (no good way to extend start or end of
// selection), so we ignore those types of selections.
if (!aSelection.IsCollapsed()) {
return;
}
@@ -1344,21 +1340,21 @@ HTMLEditRules::WillInsert(Selection& aSe
EditorRawDOMPoint atStartOfSelection(firstRange->StartRef());
if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
return;
}
MOZ_ASSERT(atStartOfSelection.IsSetAndValid());
// Get prior node
nsCOMPtr<nsIContent> priorNode =
- htmlEditor->GetPreviousEditableHTMLNode(atStartOfSelection);
+ HTMLEditorRef().GetPreviousEditableHTMLNode(atStartOfSelection);
if (priorNode && TextEditUtils::IsMozBR(priorNode)) {
RefPtr<Element> block1 =
- htmlEditor->GetBlock(*atStartOfSelection.GetContainer());
- RefPtr<Element> block2 = htmlEditor->GetBlockNodeParent(priorNode);
+ HTMLEditorRef().GetBlock(*atStartOfSelection.GetContainer());
+ RefPtr<Element> block2 = HTMLEditorRef().GetBlockNodeParent(priorNode);
if (block1 && block1 == block2) {
// If we are here then the selection is right after a mozBR that is in
// the same block as the selection. We need to move the selection start
// to be before the mozBR.
EditorRawDOMPoint point(priorNode);
IgnoredErrorResult error;
aSelection.Collapse(point, error);
@@ -1386,48 +1382,45 @@ nsresult
HTMLEditRules::WillInsertText(EditAction aAction,
Selection* aSelection,
bool* aCancel,
bool* aHandled,
const nsAString* inString,
nsAString* outString,
int32_t aMaxLength)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (NS_WARN_IF(!aSelection) ||
NS_WARN_IF(!aCancel) ||
NS_WARN_IF(!aHandled)) {
return NS_ERROR_NULL_POINTER;
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
// initialize out param
*aCancel = false;
*aHandled = true;
// If the selection isn't collapsed, delete it. Don't delete existing inline
// tags, because we're hopefully going to insert text (bug 787432).
if (!aSelection->IsCollapsed()) {
nsresult rv =
- htmlEditor->DeleteSelectionAsAction(nsIEditor::eNone,
- nsIEditor::eNoStrip);
+ HTMLEditorRef().DeleteSelectionAsAction(nsIEditor::eNone,
+ nsIEditor::eNoStrip);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
WillInsert(*aSelection, aCancel);
// initialize out param
// we want to ignore result of WillInsert()
*aCancel = false;
// we need to get the doc
- nsCOMPtr<nsIDocument> doc = htmlEditor->GetDocument();
+ nsCOMPtr<nsIDocument> doc = HTMLEditorRef().GetDocument();
if (NS_WARN_IF(!doc)) {
return NS_ERROR_FAILURE;
}
// for every property that is set, insert a new inline style node
nsresult rv = CreateStyleForInsertText(*aSelection, *doc);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@@ -1441,43 +1434,44 @@ HTMLEditRules::WillInsertText(EditAction
EditorDOMPoint pointToInsert(firstRange->StartRef());
if (NS_WARN_IF(!pointToInsert.IsSet())) {
return NS_ERROR_FAILURE;
}
MOZ_ASSERT(pointToInsert.IsSetAndValid());
// dont put text in places that can't have it
if (!EditorBase::IsTextNode(pointToInsert.GetContainer()) &&
- !htmlEditor->CanContainTag(*pointToInsert.GetContainer(),
- *nsGkAtoms::textTagName)) {
+ !HTMLEditorRef().CanContainTag(*pointToInsert.GetContainer(),
+ *nsGkAtoms::textTagName)) {
return NS_ERROR_FAILURE;
}
if (aAction == EditAction::insertIMEText) {
// Right now the WSRunObject code bails on empty strings, but IME needs
// the InsertTextWithTransaction() call to still happen since empty strings
// are meaningful there.
// If there is one or more IME selections, its minimum offset should be
// the insertion point.
int32_t IMESelectionOffset =
- htmlEditor->GetIMESelectionStartOffsetIn(pointToInsert.GetContainer());
+ HTMLEditorRef().GetIMESelectionStartOffsetIn(
+ pointToInsert.GetContainer());
if (IMESelectionOffset >= 0) {
pointToInsert.Set(pointToInsert.GetContainer(), IMESelectionOffset);
}
if (inString->IsEmpty()) {
- rv = htmlEditor->InsertTextWithTransaction(
- *doc, *inString, EditorRawDOMPoint(pointToInsert));
+ rv = HTMLEditorRef().InsertTextWithTransaction(
+ *doc, *inString, EditorRawDOMPoint(pointToInsert));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
- WSRunObject wsObj(htmlEditor, pointToInsert);
+ WSRunObject wsObj(&HTMLEditorRef(), pointToInsert);
rv = wsObj.InsertText(*doc, *inString, pointToInsert);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
// aAction == kInsertText
@@ -1491,24 +1485,24 @@ HTMLEditRules::WillInsertText(EditAction
// turn off the edit listener: we know how to
// build the "doc changed range" ourselves, and it's
// must faster to do it once here than to track all
// the changes one at a time.
AutoLockListener lockit(&mListenerEnabled);
// don't change my selection in subtransactions
- AutoTransactionsConserveSelection dontChangeMySelection(htmlEditor);
+ AutoTransactionsConserveSelection dontChangeMySelection(&HTMLEditorRef());
nsAutoString tString(*inString);
const char16_t *unicodeBuf = tString.get();
int32_t pos = 0;
NS_NAMED_LITERAL_STRING(newlineStr, LFSTR);
{
- AutoTrackDOMPoint tracker(htmlEditor->mRangeUpdater, &pointToInsert);
+ AutoTrackDOMPoint tracker(HTMLEditorRef().mRangeUpdater, &pointToInsert);
// for efficiency, break out the pre case separately. This is because
// its a lot cheaper to search the input string for only newlines than
// it is to search for both tabs and newlines.
if (isPRE || IsPlaintextEditor()) {
while (unicodeBuf && pos != -1 &&
pos < static_cast<int32_t>(inString->Length())) {
int32_t oldPos = pos;
@@ -1526,19 +1520,19 @@ HTMLEditRules::WillInsertText(EditAction
pos = tString.Length();
}
nsDependentSubstring subStr(tString, oldPos, subStrLen);
// is it a return?
if (subStr.Equals(newlineStr)) {
RefPtr<Element> brElement =
- htmlEditor->InsertBrElementWithTransaction(*aSelection,
- currentPoint,
- nsIEditor::eNone);
+ HTMLEditorRef().InsertBrElementWithTransaction(*aSelection,
+ currentPoint,
+ nsIEditor::eNone);
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
pos++;
if (brElement->GetNextSibling()) {
pointToInsert.Set(brElement->GetNextSibling());
} else {
pointToInsert.SetToEndOf(currentPoint.GetContainer());
@@ -1550,20 +1544,20 @@ HTMLEditRules::WillInsertText(EditAction
DebugOnly<bool> advanced = currentPoint.AdvanceOffset();
NS_WARNING_ASSERTION(advanced,
"Failed to advance offset after the new <br> element");
NS_WARNING_ASSERTION(currentPoint == pointToInsert,
"Perhaps, <br> element position has been moved to different point "
"by mutation observer");
} else {
EditorRawDOMPoint pointAfterInsertedString;
- rv = htmlEditor->InsertTextWithTransaction(
- *doc, subStr,
- EditorRawDOMPoint(currentPoint),
- &pointAfterInsertedString);
+ rv = HTMLEditorRef().InsertTextWithTransaction(
+ *doc, subStr,
+ EditorRawDOMPoint(currentPoint),
+ &pointAfterInsertedString);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
currentPoint = pointAfterInsertedString;
pointToInsert = pointAfterInsertedString;
}
}
} else {
@@ -1583,17 +1577,17 @@ HTMLEditRules::WillInsertText(EditAction
subStrLen = 1;
}
} else {
subStrLen = tString.Length() - oldPos;
pos = tString.Length();
}
nsDependentSubstring subStr(tString, oldPos, subStrLen);
- WSRunObject wsObj(htmlEditor, currentPoint);
+ WSRunObject wsObj(&HTMLEditorRef(), currentPoint);
// is it a tab?
if (subStr.Equals(tabStr)) {
EditorRawDOMPoint pointAfterInsertedSpaces;
rv = wsObj.InsertText(*doc, spacesStr, currentPoint,
&pointAfterInsertedSpaces);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@@ -1672,45 +1666,42 @@ HTMLEditRules::WillInsertText(EditAction
}
return NS_OK;
}
nsresult
HTMLEditRules::WillLoadHTML(Selection* aSelection,
bool* aCancel)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
NS_ENSURE_TRUE(aSelection && aCancel, NS_ERROR_NULL_POINTER);
*aCancel = false;
// Delete mBogusNode if it exists. If we really need one,
// it will be added during post-processing in AfterEditInner().
if (mBogusNode) {
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_UNEXPECTED;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
- DebugOnly<nsresult> rv = htmlEditor->DeleteNodeWithTransaction(*mBogusNode);
+ DebugOnly<nsresult> rv =
+ HTMLEditorRef().DeleteNodeWithTransaction(*mBogusNode);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"Failed to remove the bogus node");
mBogusNode = nullptr;
}
return NS_OK;
}
bool
HTMLEditRules::CanContainParagraph(Element& aElement) const
{
- if (NS_WARN_IF(!mHTMLEditor)) {
- return false;
- }
-
- if (mHTMLEditor->CanContainTag(aElement, *nsGkAtoms::p)) {
+ MOZ_ASSERT(IsEditorDataAvailable());
+
+ if (HTMLEditorRef().CanContainTag(aElement, *nsGkAtoms::p)) {
return true;
}
// Even if the element cannot have a <p> element as a child, it can contain
// <p> element as a descendant if it's one of the following elements.
if (aElement.IsAnyOfHTMLElements(nsGkAtoms::ol,
nsGkAtoms::ul,
nsGkAtoms::dl,
@@ -1727,27 +1718,27 @@ HTMLEditRules::CanContainParagraph(Eleme
return false;
}
nsresult
HTMLEditRules::WillInsertBreak(Selection& aSelection,
bool* aCancel,
bool* aHandled)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
MOZ_ASSERT(aCancel && aHandled);
*aCancel = false;
*aHandled = false;
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
// If the selection isn't collapsed, delete it.
if (!aSelection.IsCollapsed()) {
nsresult rv =
- htmlEditor->DeleteSelectionAsAction(nsIEditor::eNone, nsIEditor::eStrip);
+ HTMLEditorRef().DeleteSelectionAsAction(nsIEditor::eNone,
+ nsIEditor::eStrip);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
WillInsert(aSelection, aCancel);
// Initialize out param. We want to ignore result of WillInsert().
@@ -1771,36 +1762,36 @@ HTMLEditRules::WillInsertBreak(Selection
EditorDOMPoint atStartOfSelection(firstRange->StartRef());
if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
return NS_ERROR_FAILURE;
}
MOZ_ASSERT(atStartOfSelection.IsSetAndValid());
// Do nothing if the node is read-only
- if (!htmlEditor->IsModifiableNode(atStartOfSelection.GetContainer())) {
+ if (!HTMLEditorRef().IsModifiableNode(atStartOfSelection.GetContainer())) {
*aCancel = true;
return NS_OK;
}
// If the active editing host is an inline element, or if the active editing
// host is the block parent itself and we're configured to use <br> as a
// paragraph separator, just append a <br>.
- nsCOMPtr<Element> host = htmlEditor->GetActiveEditingHost();
+ RefPtr<Element> host = HTMLEditorRef().GetActiveEditingHost();
if (NS_WARN_IF(!host)) {
return NS_ERROR_FAILURE;
}
// Look for the nearest parent block. However, don't return error even if
// there is no block parent here because in such case, i.e., editing host
// is an inline element, we should insert <br> simply.
RefPtr<Element> blockParent =
HTMLEditor::GetBlock(*atStartOfSelection.GetContainer(), host);
- ParagraphSeparator separator = htmlEditor->GetDefaultParagraphSeparator();
+ ParagraphSeparator separator = HTMLEditorRef().GetDefaultParagraphSeparator();
bool insertBRElement;
// If there is no block parent in the editing host, i.e., the editing host
// itself is also a non-block element, we should insert a <br> element.
if (!blockParent) {
// XXX Chromium checks if the CSS box of the editing host is block.
insertBRElement = true;
}
// If only the editing host is block, and the default paragraph separator
@@ -1888,17 +1879,18 @@ HTMLEditRules::WillInsertBreak(Selection
// contains the word "text". The user selects "text" and types return.
// "Text" is deleted leaving an empty block. We want to put in one br to
// make block have a line. Then code further below will put in a second br.)
if (IsEmptyBlockElement(*blockParent, IgnoreSingleBR::eNo)) {
AutoEditorDOMPointChildInvalidator lockOffset(atStartOfSelection);
EditorRawDOMPoint endOfBlockParent;
endOfBlockParent.SetToEndOf(blockParent);
RefPtr<Element> brElement =
- htmlEditor->InsertBrElementWithTransaction(aSelection, endOfBlockParent);
+ HTMLEditorRef().InsertBrElementWithTransaction(aSelection,
+ endOfBlockParent);
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
}
nsCOMPtr<Element> listItem = IsInListItem(blockParent);
if (listItem && listItem != host) {
ReturnInListItem(aSelection, *listItem, *atStartOfSelection.GetContainer(),
@@ -1956,65 +1948,62 @@ HTMLEditRules::WillInsertBreak(Selection
}
return NS_OK;
}
nsresult
HTMLEditRules::InsertBRElement(Selection& aSelection,
const EditorDOMPoint& aPointToBreak)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (NS_WARN_IF(!aPointToBreak.IsSet())) {
return NS_ERROR_INVALID_ARG;
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
bool brElementIsAfterBlock = false;
bool brElementIsBeforeBlock = false;
// First, insert a <br> element.
RefPtr<Element> brElement;
if (IsPlaintextEditor()) {
brElement =
- htmlEditor->InsertBrElementWithTransaction(aSelection, aPointToBreak);
+ HTMLEditorRef().InsertBrElementWithTransaction(aSelection, aPointToBreak);
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
} else {
EditorDOMPoint pointToBreak(aPointToBreak);
- WSRunObject wsObj(htmlEditor, pointToBreak);
+ WSRunObject wsObj(&HTMLEditorRef(), pointToBreak);
int32_t visOffset = 0;
WSType wsType;
nsCOMPtr<nsINode> visNode;
wsObj.PriorVisibleNode(pointToBreak,
address_of(visNode), &visOffset, &wsType);
if (wsType & WSType::block) {
brElementIsAfterBlock = true;
}
wsObj.NextVisibleNode(pointToBreak,
address_of(visNode), &visOffset, &wsType);
if (wsType & WSType::block) {
brElementIsBeforeBlock = true;
}
// If the container of the break is a link, we need to split it and
// insert new <br> between the split links.
nsCOMPtr<nsINode> linkDOMNode;
- if (htmlEditor->IsInLink(pointToBreak.GetContainer(),
- address_of(linkDOMNode))) {
+ if (HTMLEditorRef().IsInLink(pointToBreak.GetContainer(),
+ address_of(linkDOMNode))) {
nsCOMPtr<Element> linkNode = do_QueryInterface(linkDOMNode);
if (NS_WARN_IF(!linkNode)) {
return NS_ERROR_FAILURE;
}
SplitNodeResult splitLinkNodeResult =
- htmlEditor->SplitNodeDeepWithTransaction(
- *linkNode, pointToBreak,
- SplitAtEdges::eDoNotCreateEmptyContainer);
+ HTMLEditorRef().SplitNodeDeepWithTransaction(
+ *linkNode, pointToBreak,
+ SplitAtEdges::eDoNotCreateEmptyContainer);
if (NS_WARN_IF(splitLinkNodeResult.Failed())) {
return splitLinkNodeResult.Rv();
}
pointToBreak = splitLinkNodeResult.SplitPoint();
}
brElement = wsObj.InsertBreak(aSelection, pointToBreak, nsIEditor::eNone);
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
@@ -2043,34 +2032,34 @@ HTMLEditRules::InsertBRElement(Selection
}
return NS_OK;
}
EditorDOMPoint afterBRElement(brElement);
DebugOnly<bool> advanced = afterBRElement.AdvanceOffset();
NS_WARNING_ASSERTION(advanced,
"Failed to advance offset after the new <br> element");
- WSRunObject wsObj(htmlEditor, afterBRElement);
+ WSRunObject wsObj(&HTMLEditorRef(), afterBRElement);
nsCOMPtr<nsINode> maybeSecondBRNode;
int32_t visOffset = 0;
WSType wsType;
wsObj.NextVisibleNode(afterBRElement,
address_of(maybeSecondBRNode), &visOffset, &wsType);
if (wsType == WSType::br) {
// The next thing after the break we inserted is another break. Move the
// second break to be the first break's sibling. This will prevent them
// from being in different inline nodes, which would break
// SetInterlinePosition(). It will also assure that if the user clicks
// away and then clicks back on their new blank line, they will still get
// the style from the line above.
EditorDOMPoint atSecondBRElement(maybeSecondBRNode);
if (brElement->GetNextSibling() != maybeSecondBRNode) {
nsresult rv =
- htmlEditor->MoveNodeWithTransaction(*maybeSecondBRNode->AsContent(),
- afterBRElement);
+ HTMLEditorRef().MoveNodeWithTransaction(*maybeSecondBRNode->AsContent(),
+ afterBRElement);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
}
// SetInterlinePosition(true) means we want the caret to stick to the
// content on the "right". We want the caret to stick to whatever is past
@@ -2097,25 +2086,22 @@ HTMLEditRules::DidInsertBreak(Selection*
{
return NS_OK;
}
nsresult
HTMLEditRules::SplitMailCites(Selection* aSelection,
bool* aHandled)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (NS_WARN_IF(!aSelection) || NS_WARN_IF(!aHandled)) {
return NS_ERROR_INVALID_ARG;
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
EditorRawDOMPoint pointToSplit(EditorBase::GetStartPoint(aSelection));
if (NS_WARN_IF(!pointToSplit.IsSet())) {
return NS_ERROR_FAILURE;
}
RefPtr<Element> citeNode =
GetTopEnclosingMailCite(*pointToSplit.GetContainer());
if (!citeNode) {
@@ -2126,17 +2112,17 @@ HTMLEditRules::SplitMailCites(Selection*
// This does two things for us. It saves us the trouble of having to add
// a break here ourselves to preserve the "blockness" of the inline span
// mailquote (in the inline case), and :
// it means the break won't end up making an empty line that happens to be
// inside a mailquote (in either inline or block case).
// The latter can confuse a user if they click there and start typing,
// because being in the mailquote may affect wrapping behavior, or font
// color, etc.
- WSRunObject wsObj(htmlEditor, pointToSplit);
+ WSRunObject wsObj(&HTMLEditorRef(), pointToSplit);
nsCOMPtr<nsINode> visNode;
int32_t visOffset=0;
WSType wsType;
wsObj.NextVisibleNode(pointToSplit, address_of(visNode), &visOffset, &wsType);
// If selection start point is before a break and it's inside the mailquote,
// let's split it after the visible node.
if (wsType == WSType::br &&
visNode != citeNode && citeNode->Contains(visNode)) {
@@ -2146,19 +2132,19 @@ HTMLEditRules::SplitMailCites(Selection*
"Failed to advance offset to after the visible node");
}
if (NS_WARN_IF(!pointToSplit.GetContainerAsContent())) {
return NS_ERROR_FAILURE;
}
SplitNodeResult splitCiteNodeResult =
- htmlEditor->SplitNodeDeepWithTransaction(
- *citeNode, pointToSplit,
- SplitAtEdges::eDoNotCreateEmptyContainer);
+ HTMLEditorRef().SplitNodeDeepWithTransaction(
+ *citeNode, pointToSplit,
+ SplitAtEdges::eDoNotCreateEmptyContainer);
if (NS_WARN_IF(splitCiteNodeResult.Failed())) {
return splitCiteNodeResult.Rv();
}
pointToSplit.Clear();
// Add an invisible <br> to the end of current cite node (If new left cite
// has not been created, we're at the end of it. Otherwise, we're still at
// the right node) if it was a <span> of style="display: block". This is
@@ -2176,31 +2162,31 @@ HTMLEditRules::SplitMailCites(Selection*
IsFrameOfType(nsIFrame::eBlockFrame)) {
nsCOMPtr<nsINode> lastChild =
previousNodeOfSplitPoint->GetLastChild();
if (lastChild && !lastChild->IsHTMLElement(nsGkAtoms::br)) {
// We ignore the result here.
EditorRawDOMPoint endOfPreviousNodeOfSplitPoint;
endOfPreviousNodeOfSplitPoint.SetToEndOf(previousNodeOfSplitPoint);
RefPtr<Element> invisibleBrElement =
- htmlEditor->InsertBrElementWithTransaction(
- *aSelection,
- endOfPreviousNodeOfSplitPoint);
+ HTMLEditorRef().InsertBrElementWithTransaction(
+ *aSelection,
+ endOfPreviousNodeOfSplitPoint);
NS_WARNING_ASSERTION(invisibleBrElement,
"Failed to create an invisible <br> element");
}
}
// In most cases, <br> should be inserted after current cite. However, if
// left cite hasn't been created because the split point was start of the
// cite node, <br> should be inserted before the current cite.
EditorRawDOMPoint pointToInsertBrNode(splitCiteNodeResult.SplitPoint());
RefPtr<Element> brElement =
- htmlEditor->InsertBrElementWithTransaction(*aSelection,
- pointToInsertBrNode);
+ HTMLEditorRef().InsertBrElementWithTransaction(*aSelection,
+ pointToInsertBrNode);
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
// Now, offset of pointToInsertBrNode is invalid. Let's clear it.
pointToInsertBrNode.Clear();
// Want selection before the break, and on same line.
EditorDOMPoint atBrNode(brElement);
@@ -2216,72 +2202,73 @@ HTMLEditRules::SplitMailCites(Selection*
// We need to examine the content both before the br we just added and also
// just after it. If we don't have another br or block boundary adjacent,
// then we will need a 2nd br added to achieve blank line that user expects.
if (IsInlineNode(*citeNode)) {
// Use DOM point which we tried to collapse to.
EditorRawDOMPoint pointToCreateNewBrNode(atBrNode.GetContainer(),
atBrNode.Offset());
- WSRunObject wsObj(htmlEditor, pointToCreateNewBrNode);
+ WSRunObject wsObj(&HTMLEditorRef(), pointToCreateNewBrNode);
nsCOMPtr<nsINode> visNode;
int32_t visOffset=0;
WSType wsType;
wsObj.PriorVisibleNode(pointToCreateNewBrNode,
address_of(visNode), &visOffset, &wsType);
if (wsType == WSType::normalWS || wsType == WSType::text ||
wsType == WSType::special) {
EditorRawDOMPoint pointAfterNewBrNode(pointToCreateNewBrNode);
DebugOnly<bool> advanced = pointAfterNewBrNode.AdvanceOffset();
NS_WARNING_ASSERTION(advanced,
"Failed to advance offset after the <br> node");
- WSRunObject wsObjAfterBR(htmlEditor, pointAfterNewBrNode);
+ WSRunObject wsObjAfterBR(&HTMLEditorRef(), pointAfterNewBrNode);
wsObjAfterBR.NextVisibleNode(pointAfterNewBrNode,
address_of(visNode), &visOffset, &wsType);
if (wsType == WSType::normalWS || wsType == WSType::text ||
wsType == WSType::special ||
// In case we're at the very end.
wsType == WSType::thisBlock) {
brElement =
- htmlEditor->InsertBrElementWithTransaction(*aSelection,
- pointToCreateNewBrNode);
+ HTMLEditorRef().InsertBrElementWithTransaction(
+ *aSelection, pointToCreateNewBrNode);
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
// Now, those points may be invalid.
pointToCreateNewBrNode.Clear();
pointAfterNewBrNode.Clear();
}
}
}
// delete any empty cites
bool bEmptyCite = false;
if (previousNodeOfSplitPoint) {
nsresult rv =
- htmlEditor->IsEmptyNode(previousNodeOfSplitPoint, &bEmptyCite,
- true, false);
+ HTMLEditorRef().IsEmptyNode(previousNodeOfSplitPoint, &bEmptyCite,
+ true, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (bEmptyCite) {
- rv = htmlEditor->DeleteNodeWithTransaction(*previousNodeOfSplitPoint);
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*previousNodeOfSplitPoint);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
}
if (citeNode) {
- nsresult rv = htmlEditor->IsEmptyNode(citeNode, &bEmptyCite, true, false);
+ nsresult rv =
+ HTMLEditorRef().IsEmptyNode(citeNode, &bEmptyCite, true, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (bEmptyCite) {
- rv = htmlEditor->DeleteNodeWithTransaction(*citeNode);
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*citeNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
}
*aHandled = true;
return NS_OK;
@@ -2290,16 +2277,17 @@ HTMLEditRules::SplitMailCites(Selection*
nsresult
HTMLEditRules::WillDeleteSelection(Selection* aSelection,
nsIEditor::EDirection aAction,
nsIEditor::EStripWrappers aStripWrappers,
bool* aCancel,
bool* aHandled)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
MOZ_ASSERT(aStripWrappers == nsIEditor::eStrip ||
aStripWrappers == nsIEditor::eNoStrip);
if (!aSelection || !aCancel || !aHandled) {
return NS_ERROR_NULL_POINTER;
}
// Initialize out params
*aCancel = false;
@@ -2311,22 +2299,20 @@ HTMLEditRules::WillDeleteSelection(Selec
// If there is only bogus content, cancel the operation
if (mBogusNode) {
*aCancel = true;
return NS_OK;
}
// First check for table selection mode. If so, hand off to table editor.
RefPtr<Element> cell;
- NS_ENSURE_STATE(mHTMLEditor);
nsresult rv =
- mHTMLEditor->GetFirstSelectedCell(nullptr, getter_AddRefs(cell));
+ HTMLEditorRef().GetFirstSelectedCell(nullptr, getter_AddRefs(cell));
if (NS_SUCCEEDED(rv) && cell) {
- NS_ENSURE_STATE(mHTMLEditor);
- rv = mHTMLEditor->DeleteTableCellContents();
+ rv = HTMLEditorRef().DeleteTableCellContents();
*aHandled = true;
return rv;
}
cell = nullptr;
// origCollapsed is used later to determine whether we should join blocks. We
// don't really care about bCollapsed because it will be modified by
// ExtendSelectionForDelete later. TryToJoinBlocksWithTransaction() should
@@ -2342,39 +2328,43 @@ HTMLEditRules::WillDeleteSelection(Selec
NS_ENSURE_STATE(aSelection->GetRangeAt(0));
nsCOMPtr<nsINode> startNode = aSelection->GetRangeAt(0)->GetStartContainer();
int32_t startOffset = aSelection->GetRangeAt(0)->StartOffset();
NS_ENSURE_TRUE(startNode, NS_ERROR_FAILURE);
if (bCollapsed) {
// If we are inside an empty block, delete it.
- NS_ENSURE_STATE(mHTMLEditor);
- nsCOMPtr<Element> host = mHTMLEditor->GetActiveEditingHost();
- NS_ENSURE_TRUE(host, NS_ERROR_FAILURE);
+ RefPtr<Element> host = HTMLEditorRef().GetActiveEditingHost();
+ if (NS_WARN_IF(!host)) {
+ return NS_ERROR_FAILURE;
+ }
rv = CheckForEmptyBlock(startNode, host, aSelection, aAction, aHandled);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
if (*aHandled) {
return NS_OK;
}
// Test for distance between caret and text that will be deleted
rv = CheckBidiLevelForDeletion(aSelection,
EditorRawDOMPoint(startNode, startOffset),
aAction, aCancel);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (*aCancel) {
return NS_OK;
}
- NS_ENSURE_STATE(mHTMLEditor);
- rv = mHTMLEditor->ExtendSelectionForDelete(aSelection, &aAction);
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = HTMLEditorRef().ExtendSelectionForDelete(aSelection, &aAction);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
// We should delete nothing.
if (aAction == nsIEditor::eNone) {
return NS_OK;
}
// ExtendSelectionForDelete() may have changed the selection, update it
NS_ENSURE_STATE(aSelection->GetRangeAt(0));
@@ -2382,35 +2372,34 @@ HTMLEditRules::WillDeleteSelection(Selec
startOffset = aSelection->GetRangeAt(0)->StartOffset();
NS_ENSURE_TRUE(startNode, NS_ERROR_FAILURE);
bCollapsed = aSelection->IsCollapsed();
}
if (bCollapsed) {
// What's in the direction we are deleting?
- NS_ENSURE_STATE(mHTMLEditor);
- WSRunObject wsObj(mHTMLEditor, startNode, startOffset);
+ WSRunObject wsObj(&HTMLEditorRef(), startNode, startOffset);
nsCOMPtr<nsINode> visNode;
int32_t visOffset;
WSType wsType;
// Find next visible node
if (aAction == nsIEditor::eNext) {
wsObj.NextVisibleNode(EditorRawDOMPoint(startNode, startOffset),
address_of(visNode), &visOffset, &wsType);
} else {
wsObj.PriorVisibleNode(EditorRawDOMPoint(startNode, startOffset),
address_of(visNode), &visOffset, &wsType);
}
if (!visNode) {
// Can't find anything to delete!
*aCancel = true;
- // XXX This is the result of mHTMLEditor->GetFirstSelectedCell().
+ // XXX This is the result of HTMLEditorRef().GetFirstSelectedCell().
// The value could be both an error and NS_OK.
return rv;
}
if (wsType == WSType::normalWS) {
// We found some visible ws to delete. Let ws code handle it.
*aHandled = true;
if (aAction == nsIEditor::eNext) {
@@ -2453,28 +2442,26 @@ HTMLEditRules::WillDeleteSelection(Selec
NS_ASSERTION(range->GetStartContainer() == visNode,
"selection start not in visNode");
NS_ASSERTION(range->GetEndContainer() == visNode,
"selection end not in visNode");
so = range->StartOffset();
eo = range->EndOffset();
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_FAILURE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
- rv = WSRunObject::PrepareToDeleteRange(htmlEditor, address_of(visNode),
+ rv = WSRunObject::PrepareToDeleteRange(&HTMLEditorRef(),
+ address_of(visNode),
&so, address_of(visNode), &eo);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
*aHandled = true;
- rv = htmlEditor->DeleteTextWithTransaction(nodeAsText, std::min(so, eo),
- DeprecatedAbs(eo - so));
+ rv = HTMLEditorRef().DeleteTextWithTransaction(nodeAsText,
+ std::min(so, eo),
+ DeprecatedAbs(eo - so));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// XXX When Backspace key is pressed, Chromium removes following empty
// text nodes when removing the last character of the non-empty text
// node. However, Edge never removes empty text nodes even if
// selection is in the following empty text node(s). For now, we
@@ -2498,22 +2485,18 @@ HTMLEditRules::WillDeleteSelection(Selec
return NS_OK;
}
if (wsType == WSType::special || wsType == WSType::br ||
visNode->IsHTMLElement(nsGkAtoms::hr)) {
// Short circuit for invisible breaks. delete them and recurse.
if (visNode->IsHTMLElement(nsGkAtoms::br) &&
- (!mHTMLEditor || !mHTMLEditor->IsVisibleBRElement(visNode))) {
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_FAILURE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
- rv = htmlEditor->DeleteNodeWithTransaction(*visNode);
+ !HTMLEditorRef().IsVisibleBRElement(visNode)) {
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*visNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return WillDeleteSelection(aSelection, aAction, aStripWrappers,
aCancel, aHandled);
}
// Special handling for backspace when positioned after <hr>
@@ -2569,60 +2552,59 @@ HTMLEditRules::WillDeleteSelection(Selec
int32_t otherOffset;
wsObj.NextVisibleNode(EditorRawDOMPoint(startNode, startOffset),
address_of(otherNode),
&otherOffset, &otherWSType);
if (otherWSType == WSType::br) {
// Delete the <br>
- if (NS_WARN_IF(!mHTMLEditor) ||
- NS_WARN_IF(!otherNode->IsContent())) {
+ if (NS_WARN_IF(!otherNode->IsContent())) {
return NS_ERROR_FAILURE;
}
nsIContent* otherContent = otherNode->AsContent();
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
- rv = WSRunObject::PrepareToDeleteNode(htmlEditor, otherContent);
+ rv = WSRunObject::PrepareToDeleteNode(&HTMLEditorRef(),
+ otherContent);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
- rv = htmlEditor->DeleteNodeWithTransaction(*otherContent);
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*otherContent);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
return NS_OK;
}
// Else continue with normal delete code
}
- if (NS_WARN_IF(!mHTMLEditor) ||
- NS_WARN_IF(!visNode->IsContent())) {
+ if (NS_WARN_IF(!visNode->IsContent())) {
return NS_ERROR_FAILURE;
}
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
// Found break or image, or hr.
- rv = WSRunObject::PrepareToDeleteNode(htmlEditor, visNode->AsContent());
+ rv = WSRunObject::PrepareToDeleteNode(&HTMLEditorRef(),
+ visNode->AsContent());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Remember sibling to visnode, if any
- nsCOMPtr<nsIContent> sibling = htmlEditor->GetPriorHTMLSibling(visNode);
+ nsCOMPtr<nsIContent> sibling =
+ HTMLEditorRef().GetPriorHTMLSibling(visNode);
// Delete the node, and join like nodes if appropriate
- rv = htmlEditor->DeleteNodeWithTransaction(*visNode);
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*visNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// We did something, so let's say so.
*aHandled = true;
// Is there a prior node and are they siblings?
nsCOMPtr<nsINode> stepbrother;
if (sibling) {
- stepbrother = htmlEditor->GetNextHTMLSibling(sibling);
+ stepbrother = HTMLEditorRef().GetNextHTMLSibling(sibling);
}
// Are they both text nodes? If so, join them!
if (startNode == stepbrother && startNode->GetAsText() &&
sibling->GetAsText()) {
EditorDOMPoint pt =
JoinNearestEditableNodesWithTransaction(*sibling,
*startNode->AsContent());
if (NS_WARN_IF(!pt.IsSet())) {
@@ -2666,33 +2648,27 @@ HTMLEditRules::WillDeleteSelection(Selec
address_of(otherNode),
&otherOffset, &otherWSType);
}
// First find the adjacent node in the block
nsCOMPtr<nsIContent> leafNode;
nsCOMPtr<nsINode> leftNode, rightNode;
if (aAction == nsIEditor::ePrevious) {
- NS_ENSURE_STATE(mHTMLEditor);
- leafNode = mHTMLEditor->GetLastEditableLeaf(*visNode);
+ leafNode = HTMLEditorRef().GetLastEditableLeaf(*visNode);
leftNode = leafNode;
rightNode = startNode;
} else {
- NS_ENSURE_STATE(mHTMLEditor);
- leafNode = mHTMLEditor->GetFirstEditableLeaf(*visNode);
+ leafNode = HTMLEditorRef().GetFirstEditableLeaf(*visNode);
leftNode = startNode;
rightNode = leafNode;
}
if (otherNode->IsHTMLElement(nsGkAtoms::br)) {
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_FAILURE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
- rv = htmlEditor->DeleteNodeWithTransaction(*otherNode);
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*otherNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// XXX Only in this case, setting "handled" to true only when it
// succeeds?
*aHandled = true;
bDeletedBR = true;
}
@@ -2714,21 +2690,24 @@ HTMLEditRules::WillDeleteSelection(Selec
return NS_OK;
}
// Else we are joining content to block
nsCOMPtr<nsINode> selPointNode = startNode;
int32_t selPointOffset = startOffset;
{
- NS_ENSURE_STATE(mHTMLEditor);
- AutoTrackDOMPoint tracker(mHTMLEditor->mRangeUpdater,
+ AutoTrackDOMPoint tracker(HTMLEditorRef().mRangeUpdater,
address_of(selPointNode), &selPointOffset);
- NS_ENSURE_STATE(leftNode && leftNode->IsContent() &&
- rightNode && rightNode->IsContent());
+ if (NS_WARN_IF(!leftNode) ||
+ NS_WARN_IF(!leftNode->IsContent()) ||
+ NS_WARN_IF(!rightNode) ||
+ NS_WARN_IF(!rightNode->IsContent())) {
+ return NS_ERROR_FAILURE;
+ }
EditActionResult ret =
TryToJoinBlocksWithTransaction(*leftNode->AsContent(),
*rightNode->AsContent());
*aHandled |= ret.Handled();
*aCancel |= ret.Canceled();
if (NS_WARN_IF(ret.Failed())) {
return ret.Rv();
}
@@ -2760,22 +2739,20 @@ HTMLEditRules::WillDeleteSelection(Selec
if (HTMLEditUtils::IsTableElement(visNode)) {
*aCancel = true;
return NS_OK;
}
// First find the relevant nodes
nsCOMPtr<nsINode> leftNode, rightNode;
if (aAction == nsIEditor::ePrevious) {
- NS_ENSURE_STATE(mHTMLEditor);
- leftNode = mHTMLEditor->GetPreviousEditableHTMLNode(*visNode);
+ leftNode = HTMLEditorRef().GetPreviousEditableHTMLNode(*visNode);
rightNode = startNode;
} else {
- NS_ENSURE_STATE(mHTMLEditor);
- rightNode = mHTMLEditor->GetNextEditableHTMLNode(*visNode);
+ rightNode = HTMLEditorRef().GetNextEditableHTMLNode(*visNode);
leftNode = startNode;
}
// Nothing to join
if (!leftNode || !rightNode) {
*aCancel = true;
return NS_OK;
}
@@ -2784,20 +2761,22 @@ HTMLEditRules::WillDeleteSelection(Selec
if (InDifferentTableElements(leftNode, rightNode)) {
*aCancel = true;
return NS_OK;
}
nsCOMPtr<nsINode> selPointNode = startNode;
int32_t selPointOffset = startOffset;
{
- NS_ENSURE_STATE(mHTMLEditor);
- AutoTrackDOMPoint tracker(mHTMLEditor->mRangeUpdater,
+ AutoTrackDOMPoint tracker(HTMLEditorRef().mRangeUpdater,
address_of(selPointNode), &selPointOffset);
- NS_ENSURE_STATE(leftNode->IsContent() && rightNode->IsContent());
+ if (NS_WARN_IF(!leftNode->IsContent()) ||
+ NS_WARN_IF(!rightNode->IsContent())) {
+ return NS_ERROR_FAILURE;
+ }
EditActionResult ret =
TryToJoinBlocksWithTransaction(*leftNode->AsContent(),
*rightNode->AsContent());
// This should claim that trying to join the block means that
// this handles the action because the caller shouldn't do anything
// anymore in this case.
*aHandled = true;
*aCancel |= ret.Canceled();
@@ -2825,40 +2804,37 @@ HTMLEditRules::WillDeleteSelection(Selec
NS_ENSURE_TRUE(startNode, NS_ERROR_FAILURE);
nsCOMPtr<nsINode> endNode = aSelection->GetRangeAt(0)->GetEndContainer();
int32_t endOffset = aSelection->GetRangeAt(0)->EndOffset();
NS_ENSURE_TRUE(endNode, NS_ERROR_FAILURE);
// Figure out if the endpoints are in nodes that can be merged. Adjust
// surrounding whitespace in preparation to delete selection.
if (!IsPlaintextEditor()) {
- NS_ENSURE_STATE(mHTMLEditor);
- AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor);
- rv = WSRunObject::PrepareToDeleteRange(mHTMLEditor,
+ AutoTransactionsConserveSelection dontChangeMySelection(&HTMLEditorRef());
+ rv = WSRunObject::PrepareToDeleteRange(&HTMLEditorRef(),
address_of(startNode), &startOffset,
address_of(endNode), &endOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
{
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_FAILURE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
// Track location of where we are deleting
- AutoTrackDOMPoint startTracker(htmlEditor->mRangeUpdater,
+ AutoTrackDOMPoint startTracker(HTMLEditorRef().mRangeUpdater,
address_of(startNode), &startOffset);
- AutoTrackDOMPoint endTracker(htmlEditor->mRangeUpdater,
+ AutoTrackDOMPoint endTracker(HTMLEditorRef().mRangeUpdater,
address_of(endNode), &endOffset);
// We are handling all ranged deletions directly now.
*aHandled = true;
if (endNode == startNode) {
- rv = htmlEditor->DeleteSelectionWithTransaction(aAction, aStripWrappers);
+ rv = HTMLEditorRef().DeleteSelectionWithTransaction(aAction,
+ aStripWrappers);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else {
// Figure out mailcite ancestors
nsCOMPtr<Element> startCiteNode = GetTopEnclosingMailCite(*startNode);
nsCOMPtr<Element> endCiteNode = GetTopEnclosingMailCite(*endNode);
@@ -2872,43 +2848,44 @@ HTMLEditRules::WillDeleteSelection(Selec
}
// Figure out block parents
nsCOMPtr<Element> leftParent = HTMLEditor::GetBlock(*startNode);
nsCOMPtr<Element> rightParent = HTMLEditor::GetBlock(*endNode);
// Are endpoint block parents the same? Use default deletion
if (leftParent && leftParent == rightParent) {
- NS_ENSURE_STATE(mHTMLEditor);
- htmlEditor->DeleteSelectionWithTransaction(aAction, aStripWrappers);
+ HTMLEditorRef().DeleteSelectionWithTransaction(aAction, aStripWrappers);
} else {
// Deleting across blocks. Are the blocks of same type?
- NS_ENSURE_STATE(leftParent && rightParent);
+ if (NS_WARN_IF(!leftParent) || NS_WARN_IF(!rightParent)) {
+ return NS_ERROR_FAILURE;
+ }
// Are the blocks siblings?
nsCOMPtr<nsINode> leftBlockParent = leftParent->GetParentNode();
nsCOMPtr<nsINode> rightBlockParent = rightParent->GetParentNode();
// MOOSE: this could conceivably screw up a table.. fix me.
if (leftBlockParent == rightBlockParent &&
- htmlEditor->AreNodesSameType(leftParent, rightParent) &&
+ HTMLEditorRef().AreNodesSameType(leftParent, rightParent) &&
// XXX What's special about these three types of block?
(leftParent->IsHTMLElement(nsGkAtoms::p) ||
HTMLEditUtils::IsListItem(leftParent) ||
HTMLEditUtils::IsHeader(*leftParent))) {
// First delete the selection
- rv = htmlEditor->DeleteSelectionWithTransaction(aAction,
- aStripWrappers);
+ rv = HTMLEditorRef().DeleteSelectionWithTransaction(aAction,
+ aStripWrappers);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Join blocks
EditorDOMPoint pt =
- htmlEditor->JoinNodesDeepWithTransaction(*leftParent,
- *rightParent);
+ HTMLEditorRef().JoinNodesDeepWithTransaction(*leftParent,
+ *rightParent);
if (NS_WARN_IF(!pt.IsSet())) {
return NS_ERROR_FAILURE;
}
// Fix up selection
ErrorResult error;
aSelection->Collapse(pt, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
@@ -2922,65 +2899,70 @@ HTMLEditRules::WillDeleteSelection(Selec
AutoRangeArray arrayOfRanges(aSelection);
for (auto& range : arrayOfRanges.mRanges) {
// Build a list of nodes in the range
nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
TrivialFunctor functor;
DOMSubtreeIterator iter;
nsresult rv = iter.Init(*range);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
iter.AppendList(functor, arrayOfNodes);
// Now that we have the list, delete non-table elements
int32_t listCount = arrayOfNodes.Length();
for (int32_t j = 0; j < listCount; j++) {
nsCOMPtr<nsINode> somenode = do_QueryInterface(arrayOfNodes[0]);
- NS_ENSURE_STATE(somenode);
+ if (NS_WARN_IF(!somenode)) {
+ return NS_ERROR_FAILURE;
+ }
DeleteNonTableElements(somenode);
arrayOfNodes.RemoveElementAt(0);
// If something visible is deleted, no need to join. Visible means
// all nodes except non-visible textnodes and breaks.
if (join && origCollapsed) {
if (!somenode->IsContent()) {
join = false;
continue;
}
nsCOMPtr<nsIContent> content = somenode->AsContent();
if (Text* text = content->GetAsText()) {
- join = !htmlEditor->IsInVisibleTextFrames(*text);
+ join = !HTMLEditorRef().IsInVisibleTextFrames(*text);
} else {
join = content->IsHTMLElement(nsGkAtoms::br) &&
- !htmlEditor->IsVisibleBRElement(somenode);
+ !HTMLEditorRef().IsVisibleBRElement(somenode);
}
}
}
}
// Check endpoints for possible text deletion. We can assume that if
// text node is found, we can delete to end or to begining as
// appropriate, since the case where both sel endpoints in same text
// node was already handled (we wouldn't be here)
if (startNode->GetAsText() &&
startNode->Length() > static_cast<uint32_t>(startOffset)) {
// Delete to last character
OwningNonNull<CharacterData> dataNode =
*static_cast<CharacterData*>(startNode.get());
- rv = htmlEditor->DeleteTextWithTransaction(
- dataNode, startOffset,
- startNode->Length() - startOffset);
+ rv = HTMLEditorRef().DeleteTextWithTransaction(
+ dataNode, startOffset,
+ startNode->Length() - startOffset);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
if (endNode->GetAsText() && endOffset) {
// Delete to first character
OwningNonNull<CharacterData> dataNode =
*static_cast<CharacterData*>(endNode.get());
- rv = htmlEditor->DeleteTextWithTransaction(dataNode, 0, endOffset);
+ rv = HTMLEditorRef().DeleteTextWithTransaction(dataNode, 0,
+ endOffset);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
if (join) {
EditActionResult ret =
TryToJoinBlocksWithTransaction(*leftParent, *rightParent);
@@ -2991,19 +2973,19 @@ HTMLEditRules::WillDeleteSelection(Selec
}
}
}
}
}
// We might have left only collapsed whitespace in the start/end nodes
{
- AutoTrackDOMPoint startTracker(mHTMLEditor->mRangeUpdater,
+ AutoTrackDOMPoint startTracker(HTMLEditorRef().mRangeUpdater,
address_of(startNode), &startOffset);
- AutoTrackDOMPoint endTracker(mHTMLEditor->mRangeUpdater,
+ AutoTrackDOMPoint endTracker(HTMLEditorRef().mRangeUpdater,
address_of(endNode), &endOffset);
DeleteNodeIfCollapsedText(*startNode);
DeleteNodeIfCollapsedText(*endNode);
}
// If we're joining blocks: if deleting forward the selection should be
// collapsed to the end of the selection, if deleting backward the selection
@@ -3033,75 +3015,69 @@ HTMLEditRules::WillDeleteSelection(Selec
* 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.
*/
void
HTMLEditRules::DeleteNodeIfCollapsedText(nsINode& aNode)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
Text* text = aNode.GetAsText();
if (!text) {
return;
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return;
- }
-
- if (!mHTMLEditor->IsVisibleTextNode(*text)) {
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
- DebugOnly<nsresult> rv = htmlEditor->DeleteNodeWithTransaction(aNode);
+ if (!HTMLEditorRef().IsVisibleTextNode(*text)) {
+ DebugOnly<nsresult> rv = HTMLEditorRef().DeleteNodeWithTransaction(aNode);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to remove aNode");
}
}
/**
* 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.
*
* @param aSelection The collapsed selection.
*/
nsresult
HTMLEditRules::InsertBRIfNeeded(Selection* aSelection)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (NS_WARN_IF(!aSelection)) {
return NS_ERROR_INVALID_ARG;
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
EditorRawDOMPoint atStartOfSelection(EditorBase::GetStartPoint(aSelection));
if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
return NS_ERROR_FAILURE;
}
// inline elements don't need any br
if (!IsBlockNode(*atStartOfSelection.GetContainer())) {
return NS_OK;
}
// examine selection
- WSRunObject wsObj(htmlEditor, atStartOfSelection);
+ WSRunObject wsObj(&HTMLEditorRef(), atStartOfSelection);
if (((wsObj.mStartReason & WSType::block) ||
(wsObj.mStartReason & WSType::br)) &&
(wsObj.mEndReason & WSType::block)) {
// if we are tucked between block boundaries then insert a br
// first check that we are allowed to
- if (htmlEditor->CanContainTag(*atStartOfSelection.GetContainer(),
- *nsGkAtoms::br)) {
+ if (HTMLEditorRef().CanContainTag(*atStartOfSelection.GetContainer(),
+ *nsGkAtoms::br)) {
RefPtr<Element> brElement =
- htmlEditor->InsertBrElementWithTransaction(*aSelection,
- atStartOfSelection,
- nsIEditor::ePrevious);
+ HTMLEditorRef().InsertBrElementWithTransaction(*aSelection,
+ atStartOfSelection,
+ nsIEditor::ePrevious);
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
}
return NS_OK;
}
@@ -3115,60 +3091,53 @@ HTMLEditRules::InsertBRIfNeeded(Selectio
* @param aAction Which edge to find:
* eNext/eNextWord/eToEndOfLine indicates beginning,
* ePrevious/PreviousWord/eToBeginningOfLine ending.
*/
EditorDOMPoint
HTMLEditRules::GetGoodSelPointForNode(nsINode& aNode,
nsIEditor::EDirection aAction)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
MOZ_ASSERT(aAction == nsIEditor::eNext ||
aAction == nsIEditor::eNextWord ||
aAction == nsIEditor::ePrevious ||
aAction == nsIEditor::ePreviousWord ||
aAction == nsIEditor::eToBeginningOfLine ||
aAction == nsIEditor::eToEndOfLine);
bool isPreviousAction = (aAction == nsIEditor::ePrevious ||
aAction == nsIEditor::ePreviousWord ||
aAction == nsIEditor::eToBeginningOfLine);
- if (NS_WARN_IF(!mHTMLEditor)) {
- return EditorDOMPoint();
- }
- if (aNode.GetAsText() || mHTMLEditor->IsContainer(&aNode) ||
+ if (aNode.GetAsText() || HTMLEditorRef().IsContainer(&aNode) ||
NS_WARN_IF(!aNode.GetParentNode())) {
return EditorDOMPoint(&aNode, isPreviousAction ? aNode.Length() : 0);
}
- if (NS_WARN_IF(!mHTMLEditor) ||
- NS_WARN_IF(!aNode.IsContent())) {
+ if (NS_WARN_IF(!aNode.IsContent())) {
return EditorDOMPoint();
}
EditorDOMPoint ret(&aNode);
if ((!aNode.IsHTMLElement(nsGkAtoms::br) ||
- mHTMLEditor->IsVisibleBRElement(&aNode)) && isPreviousAction) {
+ HTMLEditorRef().IsVisibleBRElement(&aNode)) && isPreviousAction) {
ret.AdvanceOffset();
}
return ret;
}
EditActionResult
HTMLEditRules::TryToJoinBlocksWithTransaction(nsIContent& aLeftNode,
nsIContent& aRightNode)
{
- if (NS_WARN_IF(!mHTMLEditor)) {
- return EditActionIgnored(NS_ERROR_UNEXPECTED);
- }
-
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
- nsCOMPtr<Element> leftBlock = htmlEditor->GetBlock(aLeftNode);
- nsCOMPtr<Element> rightBlock = htmlEditor->GetBlock(aRightNode);
+ MOZ_ASSERT(IsEditorDataAvailable());
+
+ RefPtr<Element> leftBlock = HTMLEditorRef().GetBlock(aLeftNode);
+ RefPtr<Element> rightBlock = HTMLEditorRef().GetBlock(aRightNode);
// Sanity checks
if (NS_WARN_IF(!leftBlock) || NS_WARN_IF(!rightBlock)) {
return EditActionIgnored(NS_ERROR_NULL_POINTER);
}
if (NS_WARN_IF(leftBlock == rightBlock)) {
return EditActionIgnored(NS_ERROR_UNEXPECTED);
}
@@ -3177,23 +3146,23 @@ HTMLEditRules::TryToJoinBlocksWithTransa
HTMLEditUtils::IsTableElement(rightBlock)) {
// Do not try to merge table elements
return EditActionCanceled();
}
// Make sure we don't try to move things into HR's, which look like blocks
// but aren't containers
if (leftBlock->IsHTMLElement(nsGkAtoms::hr)) {
- leftBlock = htmlEditor->GetBlockNodeParent(leftBlock);
+ leftBlock = HTMLEditorRef().GetBlockNodeParent(leftBlock);
if (NS_WARN_IF(!leftBlock)) {
return EditActionIgnored(NS_ERROR_UNEXPECTED);
}
}
if (rightBlock->IsHTMLElement(nsGkAtoms::hr)) {
- rightBlock = htmlEditor->GetBlockNodeParent(rightBlock);
+ rightBlock = HTMLEditorRef().GetBlockNodeParent(rightBlock);
if (NS_WARN_IF(!rightBlock)) {
return EditActionIgnored(NS_ERROR_UNEXPECTED);
}
}
// Bail if both blocks the same
if (leftBlock == rightBlock) {
return EditActionIgnored();
@@ -3226,40 +3195,41 @@ HTMLEditRules::TryToJoinBlocksWithTransa
MOZ_DIAGNOSTIC_ASSERT(!atChildInBlock.IsSet());
leftBlock = leftList;
rightBlock = rightList;
mergeLists = true;
existingList = leftList->NodeInfo()->NameAtom();
}
}
- AutoTransactionsConserveSelection dontChangeMySelection(htmlEditor);
+ AutoTransactionsConserveSelection dontChangeMySelection(&HTMLEditorRef());
// offset below is where you find yourself in rightBlock when you traverse
// upwards from leftBlock
EditorDOMPoint atRightBlockChild;
if (EditorUtils::IsDescendantOf(*leftBlock, *rightBlock,
&atRightBlockChild)) {
// Tricky case. Left block is inside right block. Do ws adjustment. This
// just destroys non-visible ws at boundaries we will be joining.
DebugOnly<bool> advanced = atRightBlockChild.AdvanceOffset();
NS_WARNING_ASSERTION(advanced,
"Failed to advance offset to after child of rightBlock, "
"leftBlock is a descendant of the child");
- nsresult rv = WSRunObject::ScrubBlockBoundary(htmlEditor,
+ nsresult rv = WSRunObject::ScrubBlockBoundary(&HTMLEditorRef(),
WSRunObject::kBlockEnd,
leftBlock);
if (NS_WARN_IF(NS_FAILED(rv))) {
return EditActionIgnored(rv);
}
{
// We can't just track rightBlock because it's an Element.
- AutoTrackDOMPoint tracker(htmlEditor->mRangeUpdater, &atRightBlockChild);
- rv = WSRunObject::ScrubBlockBoundary(htmlEditor,
+ AutoTrackDOMPoint tracker(HTMLEditorRef().mRangeUpdater,
+ &atRightBlockChild);
+ rv = WSRunObject::ScrubBlockBoundary(&HTMLEditorRef(),
WSRunObject::kAfterBlock,
atRightBlockChild.GetContainer(),
atRightBlockChild.Offset());
if (NS_WARN_IF(NS_FAILED(rv))) {
return EditActionIgnored(rv);
}
// XXX AutoTrackDOMPoint instance, tracker, hasn't been destroyed here.
@@ -3304,42 +3274,42 @@ HTMLEditRules::TryToJoinBlocksWithTransa
if (retMoveBlock.Handled()) {
ret.MarkAsHandled();
}
// Now, all children of rightBlock were moved to leftBlock. So,
// atRightBlockChild is now invalid.
atRightBlockChild.Clear();
}
if (brNode &&
- NS_SUCCEEDED(htmlEditor->DeleteNodeWithTransaction(*brNode))) {
+ NS_SUCCEEDED(HTMLEditorRef().DeleteNodeWithTransaction(*brNode))) {
ret.MarkAsHandled();
}
return ret;
}
MOZ_DIAGNOSTIC_ASSERT(!atRightBlockChild.IsSet());
// Offset below is where you find yourself in leftBlock when you traverse
// upwards from rightBlock
EditorDOMPoint leftBlockChild;
if (EditorUtils::IsDescendantOf(*rightBlock, *leftBlock, &leftBlockChild)) {
// Tricky case. Right block is inside left block. Do ws adjustment. This
// just destroys non-visible ws at boundaries we will be joining.
- nsresult rv = WSRunObject::ScrubBlockBoundary(htmlEditor,
+ nsresult rv = WSRunObject::ScrubBlockBoundary(&HTMLEditorRef(),
WSRunObject::kBlockStart,
rightBlock);
if (NS_WARN_IF(NS_FAILED(rv))) {
return EditActionIgnored(rv);
}
{
// We can't just track leftBlock because it's an Element, so track
// something else.
- AutoTrackDOMPoint tracker(htmlEditor->mRangeUpdater, &leftBlockChild);
- rv = WSRunObject::ScrubBlockBoundary(htmlEditor,
+ AutoTrackDOMPoint tracker(HTMLEditorRef().mRangeUpdater, &leftBlockChild);
+ rv = WSRunObject::ScrubBlockBoundary(&HTMLEditorRef(),
WSRunObject::kBeforeBlock,
leftBlock, leftBlockChild.Offset());
if (NS_WARN_IF(NS_FAILED(rv))) {
return EditActionIgnored(rv);
}
// XXX AutoTrackDOMPoint instance, tracker, hasn't been destroyed here.
// Do we really need to do update rightBlock here??
MOZ_DIAGNOSTIC_ASSERT(leftBlock == leftBlockChild.GetContainer());
@@ -3392,27 +3362,27 @@ HTMLEditRules::TryToJoinBlocksWithTransa
// We want to move our content just after the previous visible node.
previousContent.AdvanceOffset();
}
// Because we don't want the moving content to receive the style of the
// previous content, we split the previous content's style.
- nsCOMPtr<Element> editorRoot = htmlEditor->GetEditorRoot();
+ RefPtr<Element> editorRoot = HTMLEditorRef().GetEditorRoot();
if (!editorRoot || &aLeftNode != editorRoot) {
nsCOMPtr<nsIContent> splittedPreviousContent;
nsCOMPtr<nsINode> previousContentParent =
previousContent.GetContainer();
int32_t previousContentOffset = previousContent.Offset();
- rv = htmlEditor->SplitStyleAbovePoint(
- address_of(previousContentParent),
- &previousContentOffset,
- nullptr, nullptr, nullptr,
- getter_AddRefs(splittedPreviousContent));
+ rv = HTMLEditorRef().SplitStyleAbovePoint(
+ address_of(previousContentParent),
+ &previousContentOffset,
+ nullptr, nullptr, nullptr,
+ getter_AddRefs(splittedPreviousContent));
if (NS_WARN_IF(NS_FAILED(rv))) {
return EditActionIgnored(rv);
}
if (splittedPreviousContent) {
previousContent.Set(splittedPreviousContent);
} else {
previousContent.Set(previousContentParent, previousContentOffset);
@@ -3425,33 +3395,33 @@ HTMLEditRules::TryToJoinBlocksWithTransa
ret |= MoveBlock(*previousContent.GetContainerAsElement(), *rightBlock,
previousContent.Offset(), 0);
if (NS_WARN_IF(ret.Failed())) {
return ret;
}
}
if (brNode &&
- NS_SUCCEEDED(htmlEditor->DeleteNodeWithTransaction(*brNode))) {
+ NS_SUCCEEDED(HTMLEditorRef().DeleteNodeWithTransaction(*brNode))) {
ret.MarkAsHandled();
}
return ret;
}
MOZ_DIAGNOSTIC_ASSERT(!atRightBlockChild.IsSet());
MOZ_DIAGNOSTIC_ASSERT(!leftBlockChild.IsSet());
// Normal case. Blocks are siblings, or at least close enough. An example
// of the latter is <p>paragraph</p><ul><li>one<li>two<li>three</ul>. The
// first li and the p are not true siblings, but we still want to join them
// if you backspace from li into p.
// Adjust whitespace at block boundaries
nsresult rv =
- WSRunObject::PrepareToJoinBlocks(htmlEditor, leftBlock, rightBlock);
+ WSRunObject::PrepareToJoinBlocks(&HTMLEditorRef(), leftBlock, rightBlock);
if (NS_WARN_IF(NS_FAILED(rv))) {
return EditActionIgnored(rv);
}
// Do br adjustment.
nsCOMPtr<Element> brNode =
CheckForInvisibleBR(*leftBlock, BRLocation::blockEnd);
EditActionResult ret(NS_OK);
if (mergeLists || leftBlock->NodeInfo()->NameAtom() ==
@@ -3467,17 +3437,17 @@ HTMLEditRules::TryToJoinBlocksWithTransa
} else {
// Nodes are dissimilar types.
ret |= MoveBlock(*leftBlock, *rightBlock, -1, 0);
if (NS_WARN_IF(ret.Failed())) {
return ret;
}
}
if (brNode) {
- rv = htmlEditor->DeleteNodeWithTransaction(*brNode);
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*brNode);
// XXX In other top level if blocks, the result of
// DeleteNodeWithTransaction() is ignored. Why does only this result
// is respected?
if (NS_WARN_IF(NS_FAILED(rv))) {
return ret.SetResult(rv);
}
ret.MarkAsHandled();
}
@@ -3485,43 +3455,38 @@ HTMLEditRules::TryToJoinBlocksWithTransa
}
EditActionResult
HTMLEditRules::MoveBlock(Element& aLeftBlock,
Element& aRightBlock,
int32_t aLeftOffset,
int32_t aRightOffset)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
// GetNodesFromPoint is the workhorse that figures out what we wnat to move.
nsresult rv = GetNodesFromPoint(EditorDOMPoint(&aRightBlock, aRightOffset),
EditAction::makeList, arrayOfNodes,
TouchContent::yes);
if (NS_WARN_IF(NS_FAILED(rv))) {
return EditActionIgnored(rv);
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return EditActionIgnored(NS_ERROR_NOT_AVAILABLE);
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
EditActionResult ret(NS_OK);
for (uint32_t i = 0; i < arrayOfNodes.Length(); i++) {
// get the node to act on
if (IsBlockNode(arrayOfNodes[i])) {
// For block nodes, move their contents only, then delete block.
ret |=
MoveContents(*arrayOfNodes[i]->AsElement(), aLeftBlock, &aLeftOffset);
if (NS_WARN_IF(ret.Failed())) {
return ret;
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return ret.SetResult(NS_ERROR_UNEXPECTED);
- }
- rv = htmlEditor->DeleteNodeWithTransaction(*arrayOfNodes[i]);
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*arrayOfNodes[i]);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"Failed to remove a block node");
ret.MarkAsHandled();
} else {
// Otherwise move the content as is, checking against the DTD.
ret |=
MoveNodeSmart(*arrayOfNodes[i]->AsContent(), aLeftBlock, &aLeftOffset);
}
@@ -3535,37 +3500,32 @@ HTMLEditRules::MoveBlock(Element& aLeftB
return ret;
}
EditActionResult
HTMLEditRules::MoveNodeSmart(nsIContent& aNode,
Element& aDestElement,
int32_t* aInOutDestOffset)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
MOZ_ASSERT(aInOutDestOffset);
- if (NS_WARN_IF(!mHTMLEditor)) {
- return EditActionIgnored(NS_ERROR_UNEXPECTED);
- }
-
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
// Check if this node can go into the destination node
- if (htmlEditor->CanContain(aDestElement, aNode)) {
+ if (HTMLEditorRef().CanContain(aDestElement, aNode)) {
// If it can, move it there.
if (*aInOutDestOffset == -1) {
nsresult rv =
- htmlEditor->MoveNodeToEndWithTransaction(aNode, aDestElement);
+ HTMLEditorRef().MoveNodeToEndWithTransaction(aNode, aDestElement);
if (NS_WARN_IF(NS_FAILED(rv))) {
return EditActionIgnored(rv);
}
} else {
EditorRawDOMPoint pointToInsert(&aDestElement, *aInOutDestOffset);
nsresult rv =
- htmlEditor->MoveNodeWithTransaction(aNode, pointToInsert);
+ HTMLEditorRef().MoveNodeWithTransaction(aNode, pointToInsert);
if (NS_WARN_IF(NS_FAILED(rv))) {
return EditActionIgnored(rv);
}
}
if (*aInOutDestOffset != -1) {
(*aInOutDestOffset)++;
}
// XXX Should we check if the node is actually moved in this case?
@@ -3576,17 +3536,17 @@ HTMLEditRules::MoveNodeSmart(nsIContent&
EditActionResult ret(NS_OK);
if (aNode.IsElement()) {
ret = MoveContents(*aNode.AsElement(), aDestElement, aInOutDestOffset);
if (NS_WARN_IF(ret.Failed())) {
return ret;
}
}
- nsresult rv = htmlEditor->DeleteNodeWithTransaction(aNode);
+ nsresult rv = HTMLEditorRef().DeleteNodeWithTransaction(aNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return ret.SetResult(rv);
}
return ret.MarkAsHandled();
}
EditActionResult
HTMLEditRules::MoveContents(Element& aElement,
@@ -3609,23 +3569,20 @@ HTMLEditRules::MoveContents(Element& aEl
}
return ret;
}
nsresult
HTMLEditRules::DeleteNonTableElements(nsINode* aNode)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
MOZ_ASSERT(aNode);
if (!HTMLEditUtils::IsTableElementButNotTable(aNode)) {
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
- nsresult rv = htmlEditor->DeleteNodeWithTransaction(*aNode);
+ nsresult rv = HTMLEditorRef().DeleteNodeWithTransaction(*aNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
AutoTArray<nsCOMPtr<nsIContent>, 10> childList;
for (nsIContent* child = aNode->GetFirstChild();
@@ -3640,50 +3597,48 @@ HTMLEditRules::DeleteNonTableElements(ns
return NS_OK;
}
nsresult
HTMLEditRules::DidDeleteSelection(Selection* aSelection,
nsIEditor::EDirection aDir,
nsresult aResult)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (!aSelection) {
return NS_ERROR_NULL_POINTER;
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
// find where we are
EditorDOMPoint atStartOfSelection(EditorBase::GetStartPoint(aSelection));
if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
return NS_ERROR_FAILURE;
}
// find any enclosing mailcite
RefPtr<Element> citeNode =
GetTopEnclosingMailCite(*atStartOfSelection.GetContainer());
if (citeNode) {
bool isEmpty = true, seenBR = false;
- htmlEditor->IsEmptyNodeImpl(citeNode, &isEmpty, true, true, false,
- &seenBR);
+ HTMLEditorRef().IsEmptyNodeImpl(citeNode, &isEmpty, true, true, false,
+ &seenBR);
if (isEmpty) {
EditorDOMPoint atCiteNode(citeNode);
{
AutoEditorDOMPointChildInvalidator lockOffset(atCiteNode);
- nsresult rv = htmlEditor->DeleteNodeWithTransaction(*citeNode);
+ nsresult rv = HTMLEditorRef().DeleteNodeWithTransaction(*citeNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
if (atCiteNode.IsSet() && seenBR) {
RefPtr<Element> brElement =
- htmlEditor->InsertBrElementWithTransaction(*aSelection, atCiteNode);
+ HTMLEditorRef().InsertBrElementWithTransaction(*aSelection,
+ atCiteNode);
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
IgnoredErrorResult error;
aSelection->Collapse(EditorRawDOMPoint(brElement), error);
NS_WARNING_ASSERTION(!error.Failed(),
"Failed to collapse selection at the new <br> element");
}
@@ -3698,23 +3653,21 @@ nsresult
HTMLEditRules::WillMakeList(Selection* aSelection,
const nsAString* aListType,
bool aEntireList,
const nsAString* aBulletType,
bool* aCancel,
bool* aHandled,
const nsAString* aItemType)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (!aSelection || !aListType || !aCancel || !aHandled) {
return NS_ERROR_NULL_POINTER;
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
OwningNonNull<nsAtom> listType = NS_Atomize(*aListType);
WillInsert(*aSelection, aCancel);
// initialize out param
// we want to ignore result of WillInsert()
*aCancel = false;
@@ -3736,17 +3689,17 @@ HTMLEditRules::WillMakeList(Selection* a
// block parent, and then further expands to include any ancestors
// whose children are all in the range
*aHandled = true;
nsresult rv = NormalizeSelection(aSelection);
NS_ENSURE_SUCCESS(rv, rv);
- AutoSelectionRestorer selectionRestorer(aSelection, htmlEditor);
+ AutoSelectionRestorer selectionRestorer(aSelection, &HTMLEditorRef());
nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
rv = GetListActionNodes(arrayOfNodes,
aEntireList ? EntireList::yes : EntireList::no);
NS_ENSURE_SUCCESS(rv, rv);
// check if all our nodes are <br>s, or empty inlines
bool bOnlyBreaks = true;
@@ -3760,17 +3713,17 @@ HTMLEditRules::WillMakeList(Selection* a
}
// if no nodes, we make empty list. Ditto if the user tried to make a list
// of some # of breaks.
if (arrayOfNodes.IsEmpty() || bOnlyBreaks) {
// if only breaks, delete them
if (bOnlyBreaks) {
for (auto& node : arrayOfNodes) {
- rv = htmlEditor->DeleteNodeWithTransaction(*node);
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*node);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
}
nsRange* firstRange = aSelection->GetRangeAt(0);
if (NS_WARN_IF(!firstRange)) {
@@ -3778,39 +3731,39 @@ HTMLEditRules::WillMakeList(Selection* a
}
EditorDOMPoint atStartOfSelection(firstRange->StartRef());
if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
return NS_ERROR_FAILURE;
}
// Make sure we can put a list here.
- if (!htmlEditor->CanContainTag(*atStartOfSelection.GetContainer(),
- listType)) {
+ if (!HTMLEditorRef().CanContainTag(*atStartOfSelection.GetContainer(),
+ listType)) {
*aCancel = true;
return NS_OK;
}
SplitNodeResult splitAtSelectionStartResult =
MaybeSplitAncestorsForInsertWithTransaction(listType, atStartOfSelection);
if (NS_WARN_IF(splitAtSelectionStartResult.Failed())) {
return splitAtSelectionStartResult.Rv();
}
RefPtr<Element> theList =
- htmlEditor->CreateNodeWithTransaction(
- *listType,
- splitAtSelectionStartResult.SplitPoint());
+ HTMLEditorRef().CreateNodeWithTransaction(
+ *listType,
+ splitAtSelectionStartResult.SplitPoint());
if (NS_WARN_IF(!theList)) {
return NS_ERROR_FAILURE;
}
EditorRawDOMPoint atFirstListItemToInsertBefore(theList, 0);
RefPtr<Element> theListItem =
- htmlEditor->CreateNodeWithTransaction(*itemType,
- atFirstListItemToInsertBefore);
+ HTMLEditorRef().CreateNodeWithTransaction(*itemType,
+ atFirstListItemToInsertBefore);
if (NS_WARN_IF(!theListItem)) {
return NS_ERROR_FAILURE;
}
// remember our new block for postprocessing
mNewBlock = theListItem;
// put selection in new list item
*aHandled = true;
@@ -3845,43 +3798,47 @@ HTMLEditRules::WillMakeList(Selection* a
// into the same list. respect table cell boundaries when listifying.
if (curList && InDifferentTableElements(curList, curNode)) {
curList = nullptr;
}
// If curNode is a break, delete it, and quit remembering prev list item.
// If an empty inline container, delete it, but still remember the previous
// item.
- if (htmlEditor->IsEditable(curNode) && (TextEditUtils::IsBreak(curNode) ||
- IsEmptyInline(curNode))) {
- rv = htmlEditor->DeleteNodeWithTransaction(*curNode);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (HTMLEditorRef().IsEditable(curNode) &&
+ (TextEditUtils::IsBreak(curNode) || IsEmptyInline(curNode))) {
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*curNode);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
if (TextEditUtils::IsBreak(curNode)) {
prevListItem = nullptr;
}
continue;
}
if (HTMLEditUtils::IsList(curNode)) {
// do we have a curList already?
if (curList && !EditorUtils::IsDescendantOf(*curNode, *curList)) {
// move all of our children into curList. cheezy way to do it: move
// whole list and then RemoveContainerWithTransaction() on the list.
// ConvertListType first: that routine handles converting the list
// item types, if needed.
- rv = htmlEditor->MoveNodeToEndWithTransaction(*curNode, *curList);
+ rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode, *curList);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
newBlock = ConvertListType(curNode->AsElement(), listType, itemType);
if (NS_WARN_IF(!newBlock)) {
return NS_ERROR_FAILURE;
}
- rv = htmlEditor->RemoveBlockContainerWithTransaction(*newBlock);
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = HTMLEditorRef().RemoveBlockContainerWithTransaction(*newBlock);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
} else {
// replace list with new list type
curList = ConvertListType(curNode->AsElement(), listType, itemType);
if (NS_WARN_IF(!curList)) {
return NS_ERROR_FAILURE;
}
}
prevListItem = nullptr;
@@ -3898,106 +3855,110 @@ HTMLEditRules::WillMakeList(Selection* a
// list item is in wrong type of list. if we don't have a curList,
// split the old list and make a new list of correct type.
if (!curList || EditorUtils::IsDescendantOf(*curNode, *curList)) {
if (NS_WARN_IF(!atCurNode.GetContainerAsContent())) {
return NS_ERROR_FAILURE;
}
ErrorResult error;
nsCOMPtr<nsIContent> newLeftNode =
- htmlEditor->SplitNodeWithTransaction(atCurNode, error);
+ HTMLEditorRef().SplitNodeWithTransaction(atCurNode, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
newBlock = newLeftNode ? newLeftNode->AsElement() : nullptr;
EditorRawDOMPoint atParentOfCurNode(atCurNode.GetContainer());
- curList = htmlEditor->CreateNodeWithTransaction(*listType,
- atParentOfCurNode);
+ curList =
+ HTMLEditorRef().CreateNodeWithTransaction(*listType,
+ atParentOfCurNode);
if (NS_WARN_IF(!curList)) {
return NS_ERROR_FAILURE;
}
}
// move list item to new list
- rv = htmlEditor->MoveNodeToEndWithTransaction(*curNode, *curList);
+ rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode, *curList);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// convert list item type if needed
if (!curNode->IsHTMLElement(itemType)) {
newBlock =
- htmlEditor->ReplaceContainerWithTransaction(*curNode->AsElement(),
- *itemType);
+ HTMLEditorRef().ReplaceContainerWithTransaction(
+ *curNode->AsElement(), *itemType);
if (NS_WARN_IF(!newBlock)) {
return NS_ERROR_FAILURE;
}
}
} else {
// item is in right type of list. But we might still have to move it.
// and we might need to convert list item types.
if (!curList) {
curList = atCurNode.GetContainerAsElement();
} else if (atCurNode.GetContainer() != curList) {
// move list item to new list
- rv = htmlEditor->MoveNodeToEndWithTransaction(*curNode, *curList);
+ rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode, *curList);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
if (!curNode->IsHTMLElement(itemType)) {
newBlock =
- htmlEditor->ReplaceContainerWithTransaction(*curNode->AsElement(),
- *itemType);
+ HTMLEditorRef().ReplaceContainerWithTransaction(
+ *curNode->AsElement(), *itemType);
if (NS_WARN_IF(!newBlock)) {
return NS_ERROR_FAILURE;
}
}
}
nsCOMPtr<Element> curElement = do_QueryInterface(curNode);
if (NS_WARN_IF(!curElement)) {
return NS_ERROR_FAILURE;
}
if (aBulletType && !aBulletType->IsEmpty()) {
- rv = htmlEditor->SetAttributeWithTransaction(*curElement,
- *nsGkAtoms::type,
- *aBulletType);
+ rv = HTMLEditorRef().SetAttributeWithTransaction(*curElement,
+ *nsGkAtoms::type,
+ *aBulletType);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else {
- rv = htmlEditor->RemoveAttributeWithTransaction(*curElement,
- *nsGkAtoms::type);
+ rv = HTMLEditorRef().RemoveAttributeWithTransaction(*curElement,
+ *nsGkAtoms::type);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
continue;
}
// if we hit a div clear our prevListItem, insert divs contents
// into our node array, and remove the div
if (curNode->IsHTMLElement(nsGkAtoms::div)) {
prevListItem = nullptr;
int32_t j = i + 1;
GetInnerContent(*curNode, arrayOfNodes, &j);
- rv = htmlEditor->RemoveContainerWithTransaction(*curNode->AsElement());
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = HTMLEditorRef().RemoveContainerWithTransaction(
+ *curNode->AsElement());
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
listCount = arrayOfNodes.Length();
continue;
}
// need to make a list to put things in if we haven't already,
if (!curList) {
SplitNodeResult splitCurNodeResult =
MaybeSplitAncestorsForInsertWithTransaction(listType, atCurNode);
if (NS_WARN_IF(splitCurNodeResult.Failed())) {
return splitCurNodeResult.Rv();
}
curList =
- htmlEditor->CreateNodeWithTransaction(*listType,
- splitCurNodeResult.SplitPoint());
+ HTMLEditorRef().CreateNodeWithTransaction(
+ *listType, splitCurNodeResult.SplitPoint());
if (NS_WARN_IF(!curList)) {
return NS_ERROR_FAILURE;
}
// remember our new block for postprocessing
mNewBlock = curList;
// curList is now the correct thing to put curNode in
prevListItem = nullptr;
@@ -4007,30 +3968,33 @@ HTMLEditRules::WillMakeList(Selection* a
}
// if curNode isn't a list item, we must wrap it in one
nsCOMPtr<Element> listItem;
if (!HTMLEditUtils::IsListItem(curNode)) {
if (IsInlineNode(curNode) && prevListItem) {
// this is a continuation of some inline nodes that belong together in
// the same list item. use prevListItem
- rv = htmlEditor->MoveNodeToEndWithTransaction(*curNode, *prevListItem);
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode,
+ *prevListItem);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
} else {
// don't wrap li around a paragraph. instead replace paragraph with li
if (curNode->IsHTMLElement(nsGkAtoms::p)) {
listItem =
- htmlEditor->ReplaceContainerWithTransaction(*curNode->AsElement(),
- *itemType);
+ HTMLEditorRef().ReplaceContainerWithTransaction(
+ *curNode->AsElement(), *itemType);
if (NS_WARN_IF(!listItem)) {
return NS_ERROR_FAILURE;
}
} else {
listItem =
- htmlEditor->InsertContainerWithTransaction(*curNode, *itemType);
+ HTMLEditorRef().InsertContainerWithTransaction(*curNode, *itemType);
if (NS_WARN_IF(!listItem)) {
return NS_ERROR_FAILURE;
}
}
if (IsInlineNode(curNode)) {
prevListItem = listItem;
} else {
prevListItem = nullptr;
@@ -4038,58 +4002,63 @@ HTMLEditRules::WillMakeList(Selection* a
}
} else {
listItem = curNode->AsElement();
}
if (listItem) {
// if we made a new list item, deal with it: tuck the listItem into the
// end of the active list
- rv = htmlEditor->MoveNodeToEndWithTransaction(*listItem, *curList);
+ rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*listItem, *curList);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
}
return NS_OK;
}
nsresult
HTMLEditRules::WillRemoveList(Selection* aSelection,
bool aOrdered,
bool* aCancel,
bool* aHandled)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (!aSelection || !aCancel || !aHandled) {
return NS_ERROR_NULL_POINTER;
}
// initialize out param
*aCancel = false;
*aHandled = true;
nsresult rv = NormalizeSelection(aSelection);
- NS_ENSURE_SUCCESS(rv, rv);
- NS_ENSURE_STATE(mHTMLEditor);
- AutoSelectionRestorer selectionRestorer(aSelection, mHTMLEditor);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ AutoSelectionRestorer selectionRestorer(aSelection, &HTMLEditorRef());
nsTArray<RefPtr<nsRange>> arrayOfRanges;
GetPromotedRanges(*aSelection, arrayOfRanges, EditAction::makeList);
// use these ranges to contruct a list of nodes to act on.
nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
rv = GetListActionNodes(arrayOfNodes, EntireList::no);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
// Remove all non-editable nodes. Leave them be.
for (int32_t i = arrayOfNodes.Length() - 1; i >= 0; i--) {
OwningNonNull<nsINode> testNode = arrayOfNodes[i];
- NS_ENSURE_STATE(mHTMLEditor);
- if (!mHTMLEditor->IsEditable(testNode)) {
+ if (!HTMLEditorRef().IsEditable(testNode)) {
arrayOfNodes.RemoveElementAt(i);
}
}
// Only act on lists or list items in the array
for (auto& curNode : arrayOfNodes) {
// here's where we actually figure out what to do
if (HTMLEditUtils::IsListItem(curNode)) {
@@ -4097,17 +4066,19 @@ HTMLEditRules::WillRemoveList(Selection*
bool bOutOfList;
do {
rv = PopListItem(*curNode->AsContent(), &bOutOfList);
NS_ENSURE_SUCCESS(rv, rv);
} while (!bOutOfList); // keep popping it out until it's not in a list anymore
} else if (HTMLEditUtils::IsList(curNode)) {
// node is a list, move list items out
rv = RemoveListStructure(*curNode->AsElement());
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
}
return NS_OK;
}
nsresult
HTMLEditRules::WillMakeDefListItem(Selection* aSelection,
const nsAString *aItemType,
@@ -4139,23 +4110,22 @@ HTMLEditRules::WillMakeBasicBlock(Select
nsresult rv = MakeBasicBlock(aSelection, blockType);
Unused << NS_WARN_IF(NS_FAILED(rv));
return rv;
}
nsresult
HTMLEditRules::MakeBasicBlock(Selection& aSelection, nsAtom& blockType)
{
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
+ MOZ_ASSERT(IsEditorDataAvailable());
nsresult rv = NormalizeSelection(&aSelection);
NS_ENSURE_SUCCESS(rv, rv);
- AutoSelectionRestorer selectionRestorer(&aSelection, htmlEditor);
- AutoTransactionsConserveSelection dontChangeMySelection(htmlEditor);
+ AutoSelectionRestorer selectionRestorer(&aSelection, &HTMLEditorRef());
+ AutoTransactionsConserveSelection dontChangeMySelection(&HTMLEditorRef());
// Contruct a list of nodes to act on.
nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
rv = GetNodesFromSelection(aSelection, EditAction::makeBasicBlock,
arrayOfNodes);
NS_ENSURE_SUCCESS(rv, rv);
// If nothing visible in list, make an empty block
@@ -4165,49 +4135,49 @@ HTMLEditRules::MakeBasicBlock(Selection&
return NS_ERROR_FAILURE;
}
EditorDOMPoint pointToInsertBlock(firstRange->StartRef());
if (&blockType == nsGkAtoms::normal ||
&blockType == nsGkAtoms::_empty) {
// We are removing blocks (going to "body text")
RefPtr<Element> curBlock =
- htmlEditor->GetBlock(*pointToInsertBlock.GetContainer());
+ HTMLEditorRef().GetBlock(*pointToInsertBlock.GetContainer());
if (NS_WARN_IF(!curBlock)) {
return NS_ERROR_FAILURE;
}
if (!HTMLEditUtils::IsFormatNode(curBlock)) {
return NS_OK;
}
// If the first editable node after selection is a br, consume it.
// Otherwise it gets pushed into a following block after the split,
// which is visually bad.
nsCOMPtr<nsIContent> brContent =
- htmlEditor->GetNextEditableHTMLNode(pointToInsertBlock);
+ HTMLEditorRef().GetNextEditableHTMLNode(pointToInsertBlock);
if (brContent && brContent->IsHTMLElement(nsGkAtoms::br)) {
AutoEditorDOMPointChildInvalidator lockOffset(pointToInsertBlock);
- rv = htmlEditor->DeleteNodeWithTransaction(*brContent);
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*brContent);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
// Do the splits!
SplitNodeResult splitNodeResult =
- htmlEditor->SplitNodeDeepWithTransaction(
- *curBlock, pointToInsertBlock,
- SplitAtEdges::eDoNotCreateEmptyContainer);
+ HTMLEditorRef().SplitNodeDeepWithTransaction(
+ *curBlock, pointToInsertBlock,
+ SplitAtEdges::eDoNotCreateEmptyContainer);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
EditorRawDOMPoint pointToInsertBrNode(splitNodeResult.SplitPoint());
// Put a <br> element at the split point
brContent =
- htmlEditor->InsertBrElementWithTransaction(aSelection,
- pointToInsertBrNode);
+ HTMLEditorRef().InsertBrElementWithTransaction(aSelection,
+ pointToInsertBrNode);
if (NS_WARN_IF(!brContent)) {
return NS_ERROR_FAILURE;
}
// Put selection at the split point
EditorRawDOMPoint atBrNode(brContent);
ErrorResult error;
aSelection.Collapse(atBrNode, error);
// Don't restore the selection
@@ -4215,45 +4185,45 @@ HTMLEditRules::MakeBasicBlock(Selection&
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
return NS_OK;
}
// We are making a block. Consume a br, if needed.
nsCOMPtr<nsIContent> brNode =
- htmlEditor->GetNextEditableHTMLNodeInBlock(pointToInsertBlock);
+ HTMLEditorRef().GetNextEditableHTMLNodeInBlock(pointToInsertBlock);
if (brNode && brNode->IsHTMLElement(nsGkAtoms::br)) {
AutoEditorDOMPointChildInvalidator lockOffset(pointToInsertBlock);
- rv = htmlEditor->DeleteNodeWithTransaction(*brNode);
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*brNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// We don't need to act on this node any more
arrayOfNodes.RemoveElement(brNode);
}
// Make sure we can put a block here.
SplitNodeResult splitNodeResult =
MaybeSplitAncestorsForInsertWithTransaction(blockType,
pointToInsertBlock);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
RefPtr<Element> block =
- htmlEditor->CreateNodeWithTransaction(blockType,
- splitNodeResult.SplitPoint());
+ HTMLEditorRef().CreateNodeWithTransaction(blockType,
+ splitNodeResult.SplitPoint());
if (NS_WARN_IF(!block)) {
return NS_ERROR_FAILURE;
}
// Remember our new block for postprocessing
mNewBlock = block;
// Delete anything that was in the list of nodes
while (!arrayOfNodes.IsEmpty()) {
OwningNonNull<nsINode> curNode = arrayOfNodes[0];
- rv = htmlEditor->DeleteNodeWithTransaction(*curNode);
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*curNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
arrayOfNodes.RemoveElementAt(0);
}
// Put selection in new block
rv = aSelection.Collapse(block, 0);
// Don't restore the selection
@@ -4297,18 +4267,19 @@ HTMLEditRules::DidMakeBasicBlock(Selecti
return NS_OK;
}
nsresult
HTMLEditRules::WillIndent(Selection* aSelection,
bool* aCancel,
bool* aHandled)
{
- NS_ENSURE_STATE(mHTMLEditor);
- if (mHTMLEditor->IsCSSEnabled()) {
+ MOZ_ASSERT(IsEditorDataAvailable());
+
+ if (HTMLEditorRef().IsCSSEnabled()) {
nsresult rv = WillCSSIndent(aSelection, aCancel, aHandled);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else {
nsresult rv = WillHTMLIndent(aSelection, aCancel, aHandled);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@@ -4317,50 +4288,47 @@ HTMLEditRules::WillIndent(Selection* aSe
return NS_OK;
}
nsresult
HTMLEditRules::WillCSSIndent(Selection* aSelection,
bool* aCancel,
bool* aHandled)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (!aSelection || !aCancel || !aHandled) {
return NS_ERROR_NULL_POINTER;
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
WillInsert(*aSelection, aCancel);
// initialize out param
// we want to ignore result of WillInsert()
*aCancel = false;
*aHandled = true;
nsresult rv = NormalizeSelection(aSelection);
NS_ENSURE_SUCCESS(rv, rv);
- AutoSelectionRestorer selectionRestorer(aSelection, htmlEditor);
+ AutoSelectionRestorer selectionRestorer(aSelection, &HTMLEditorRef());
nsTArray<OwningNonNull<nsRange>> arrayOfRanges;
nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
// short circuit: detect case of collapsed selection inside an <li>.
// just sublist that <li>. This prevents bug 97797.
nsCOMPtr<Element> liNode;
if (aSelection->IsCollapsed()) {
EditorRawDOMPoint selectionStartPoint(
EditorBase::GetStartPoint(aSelection));
if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
return NS_ERROR_FAILURE;
}
Element* block =
- htmlEditor->GetBlock(*selectionStartPoint.GetContainer());
+ HTMLEditorRef().GetBlock(*selectionStartPoint.GetContainer());
if (block && HTMLEditUtils::IsListItem(block)) {
liNode = block;
}
}
if (liNode) {
arrayOfNodes.AppendElement(*liNode);
} else {
@@ -4388,28 +4356,28 @@ HTMLEditRules::WillCSSIndent(Selection*
// make sure we can put a block here
SplitNodeResult splitNodeResult =
MaybeSplitAncestorsForInsertWithTransaction(*nsGkAtoms::div,
atStartOfSelection);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
RefPtr<Element> theBlock =
- htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::div,
- splitNodeResult.SplitPoint());
+ HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::div,
+ splitNodeResult.SplitPoint());
if (NS_WARN_IF(!theBlock)) {
return NS_ERROR_FAILURE;
}
// remember our new block for postprocessing
mNewBlock = theBlock;
ChangeIndentation(*theBlock, Change::plus);
// delete anything that was in the list of nodes
while (!arrayOfNodes.IsEmpty()) {
OwningNonNull<nsINode> curNode = arrayOfNodes[0];
- rv = htmlEditor->DeleteNodeWithTransaction(*curNode);
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*curNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
arrayOfNodes.RemoveElementAt(0);
}
// put selection in new block
*aHandled = true;
EditorRawDOMPoint atStartOfTheBlock(theBlock, 0);
@@ -4430,157 +4398,157 @@ HTMLEditRules::WillCSSIndent(Selection*
for (OwningNonNull<nsINode>& curNode : arrayOfNodes) {
// Here's where we actually figure out what to do.
EditorDOMPoint atCurNode(curNode);
if (NS_WARN_IF(!atCurNode.IsSet())) {
continue;
}
// Ignore all non-editable nodes. Leave them be.
- if (!htmlEditor->IsEditable(curNode)) {
+ if (!HTMLEditorRef().IsEditable(curNode)) {
continue;
}
// some logic for putting list items into nested lists...
if (HTMLEditUtils::IsList(atCurNode.GetContainer())) {
// Check for whether we should join a list that follows curNode.
// We do this if the next element is a list, and the list is of the
// same type (li/ol) as curNode was a part it.
- sibling = htmlEditor->GetNextHTMLSibling(curNode);
+ sibling = HTMLEditorRef().GetNextHTMLSibling(curNode);
if (sibling && HTMLEditUtils::IsList(sibling) &&
atCurNode.GetContainer()->NodeInfo()->NameAtom() ==
sibling->NodeInfo()->NameAtom() &&
atCurNode.GetContainer()->NodeInfo()->NamespaceID() ==
sibling->NodeInfo()->NamespaceID()) {
- rv = htmlEditor->MoveNodeWithTransaction(*curNode->AsContent(),
- EditorRawDOMPoint(sibling, 0));
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = HTMLEditorRef().MoveNodeWithTransaction(
+ *curNode->AsContent(),
+ EditorRawDOMPoint(sibling, 0));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
continue;
}
// Check for whether we should join a list that preceeds curNode.
// We do this if the previous element is a list, and the list is of
// the same type (li/ol) as curNode was a part of.
- sibling = htmlEditor->GetPriorHTMLSibling(curNode);
+ sibling = HTMLEditorRef().GetPriorHTMLSibling(curNode);
if (sibling && HTMLEditUtils::IsList(sibling) &&
atCurNode.GetContainer()->NodeInfo()->NameAtom() ==
sibling->NodeInfo()->NameAtom() &&
atCurNode.GetContainer()->NodeInfo()->NamespaceID() ==
sibling->NodeInfo()->NamespaceID()) {
- rv = htmlEditor->MoveNodeToEndWithTransaction(*curNode->AsContent(),
- *sibling);
+ rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(),
+ *sibling);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
continue;
}
// check to see if curList is still appropriate. Which it is if
// curNode is still right after it in the same list.
sibling = nullptr;
if (curList) {
- sibling = htmlEditor->GetPriorHTMLSibling(curNode);
+ sibling = HTMLEditorRef().GetPriorHTMLSibling(curNode);
}
if (!curList || (sibling && sibling != curList)) {
nsAtom* containerName =
atCurNode.GetContainer()->NodeInfo()->NameAtom();
// Create a new nested list of correct type.
SplitNodeResult splitNodeResult =
MaybeSplitAncestorsForInsertWithTransaction(*containerName,
atCurNode);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
curList =
- htmlEditor->CreateNodeWithTransaction(*containerName,
- splitNodeResult.SplitPoint());
+ HTMLEditorRef().CreateNodeWithTransaction(
+ *containerName, splitNodeResult.SplitPoint());
if (NS_WARN_IF(!curList)) {
return NS_ERROR_FAILURE;
}
// curList is now the correct thing to put curNode in
// remember our new block for postprocessing
mNewBlock = curList;
}
// tuck the node into the end of the active list
- rv = htmlEditor->MoveNodeToEndWithTransaction(*curNode->AsContent(),
- *curList);
+ rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(),
+ *curList);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
continue;
}
// Not a list item.
if (IsBlockNode(*curNode)) {
ChangeIndentation(*curNode->AsElement(), Change::plus);
curQuote = nullptr;
continue;
}
if (!curQuote) {
// First, check that our element can contain a div.
- if (!htmlEditor->CanContainTag(*atCurNode.GetContainer(),
- *nsGkAtoms::div)) {
+ if (!HTMLEditorRef().CanContainTag(*atCurNode.GetContainer(),
+ *nsGkAtoms::div)) {
return NS_OK; // cancelled
}
SplitNodeResult splitNodeResult =
MaybeSplitAncestorsForInsertWithTransaction(*nsGkAtoms::div, atCurNode);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
curQuote =
- htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::div,
- splitNodeResult.SplitPoint());
+ HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::div,
+ splitNodeResult.SplitPoint());
if (NS_WARN_IF(!curQuote)) {
return NS_ERROR_FAILURE;
}
ChangeIndentation(*curQuote, Change::plus);
// remember our new block for postprocessing
mNewBlock = curQuote;
// curQuote is now the correct thing to put curNode in
}
// tuck the node into the end of the active blockquote
- rv = htmlEditor->MoveNodeToEndWithTransaction(*curNode->AsContent(),
- *curQuote);
+ rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(),
+ *curQuote);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
return NS_OK;
}
nsresult
HTMLEditRules::WillHTMLIndent(Selection* aSelection,
bool* aCancel,
bool* aHandled)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (!aSelection || !aCancel || !aHandled) {
return NS_ERROR_NULL_POINTER;
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
WillInsert(*aSelection, aCancel);
// initialize out param
// we want to ignore result of WillInsert()
*aCancel = false;
*aHandled = true;
nsresult rv = NormalizeSelection(aSelection);
NS_ENSURE_SUCCESS(rv, rv);
- AutoSelectionRestorer selectionRestorer(aSelection, htmlEditor);
+ AutoSelectionRestorer selectionRestorer(aSelection, &HTMLEditorRef());
// convert the selection ranges into "promoted" selection ranges:
// this basically just expands the range to include the immediate
// block parent, and then further expands to include any ancestors
// whose children are all in the range
nsTArray<RefPtr<nsRange>> arrayOfRanges;
GetPromotedRanges(*aSelection, arrayOfRanges, EditAction::indent);
@@ -4605,27 +4573,27 @@ HTMLEditRules::WillHTMLIndent(Selection*
// Make sure we can put a block here.
SplitNodeResult splitNodeResult =
MaybeSplitAncestorsForInsertWithTransaction(*nsGkAtoms::blockquote,
atStartOfSelection);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
RefPtr<Element> theBlock =
- htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::blockquote,
- splitNodeResult.SplitPoint());
+ HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::blockquote,
+ splitNodeResult.SplitPoint());
if (NS_WARN_IF(!theBlock)) {
return NS_ERROR_FAILURE;
}
// remember our new block for postprocessing
mNewBlock = theBlock;
// delete anything that was in the list of nodes
while (!arrayOfNodes.IsEmpty()) {
OwningNonNull<nsINode> curNode = arrayOfNodes[0];
- rv = htmlEditor->DeleteNodeWithTransaction(*curNode);
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*curNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
arrayOfNodes.RemoveElementAt(0);
}
// put selection in new block
*aHandled = true;
EditorRawDOMPoint atStartOfTheBlock(theBlock, 0);
@@ -4646,86 +4614,87 @@ HTMLEditRules::WillHTMLIndent(Selection*
for (OwningNonNull<nsINode>& curNode: arrayOfNodes) {
// Here's where we actually figure out what to do.
EditorDOMPoint atCurNode(curNode);
if (NS_WARN_IF(!atCurNode.IsSet())) {
continue;
}
// Ignore all non-editable nodes. Leave them be.
- if (!htmlEditor->IsEditable(curNode)) {
+ if (!HTMLEditorRef().IsEditable(curNode)) {
continue;
}
// some logic for putting list items into nested lists...
if (HTMLEditUtils::IsList(atCurNode.GetContainer())) {
// Check for whether we should join a list that follows curNode.
// We do this if the next element is a list, and the list is of the
// same type (li/ol) as curNode was a part it.
- sibling = htmlEditor->GetNextHTMLSibling(curNode);
+ sibling = HTMLEditorRef().GetNextHTMLSibling(curNode);
if (sibling && HTMLEditUtils::IsList(sibling) &&
atCurNode.GetContainer()->NodeInfo()->NameAtom() ==
sibling->NodeInfo()->NameAtom() &&
atCurNode.GetContainer()->NodeInfo()->NamespaceID() ==
sibling->NodeInfo()->NamespaceID()) {
- rv = htmlEditor->MoveNodeWithTransaction(*curNode->AsContent(),
- EditorRawDOMPoint(sibling, 0));
+ rv = HTMLEditorRef().MoveNodeWithTransaction(
+ *curNode->AsContent(),
+ EditorRawDOMPoint(sibling, 0));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
continue;
}
// Check for whether we should join a list that preceeds curNode.
// We do this if the previous element is a list, and the list is of
// the same type (li/ol) as curNode was a part of.
- sibling = htmlEditor->GetPriorHTMLSibling(curNode);
+ sibling = HTMLEditorRef().GetPriorHTMLSibling(curNode);
if (sibling && HTMLEditUtils::IsList(sibling) &&
atCurNode.GetContainer()->NodeInfo()->NameAtom() ==
sibling->NodeInfo()->NameAtom() &&
atCurNode.GetContainer()->NodeInfo()->NamespaceID() ==
sibling->NodeInfo()->NamespaceID()) {
- rv = htmlEditor->MoveNodeToEndWithTransaction(*curNode->AsContent(),
- *sibling);
+ rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(),
+ *sibling);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
continue;
}
// check to see if curList is still appropriate. Which it is if
// curNode is still right after it in the same list.
sibling = nullptr;
if (curList) {
- sibling = htmlEditor->GetPriorHTMLSibling(curNode);
+ sibling = HTMLEditorRef().GetPriorHTMLSibling(curNode);
}
if (!curList || (sibling && sibling != curList)) {
nsAtom* containerName =
atCurNode.GetContainer()->NodeInfo()->NameAtom();
// Create a new nested list of correct type.
SplitNodeResult splitNodeResult =
MaybeSplitAncestorsForInsertWithTransaction(*containerName,
atCurNode);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
curList =
- htmlEditor->CreateNodeWithTransaction(*containerName,
- splitNodeResult.SplitPoint());
+ HTMLEditorRef().CreateNodeWithTransaction(
+ *containerName, splitNodeResult.SplitPoint());
if (NS_WARN_IF(!curList)) {
return NS_ERROR_FAILURE;
}
// curList is now the correct thing to put curNode in
// remember our new block for postprocessing
mNewBlock = curList;
}
// tuck the node into the end of the active list
- rv = htmlEditor->MoveNodeToEndWithTransaction(*curNode->AsContent(),
- *curList);
+ rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(),
+ *curList);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// forget curQuote, if any
curQuote = nullptr;
continue;
}
@@ -4742,17 +4711,17 @@ HTMLEditRules::WillHTMLIndent(Selection*
if (listItem) {
if (indentedLI == listItem) {
// already indented this list item
continue;
}
// check to see if curList is still appropriate. Which it is if
// curNode is still right after it in the same list.
if (curList) {
- sibling = htmlEditor->GetPriorHTMLSibling(listItem);
+ sibling = HTMLEditorRef().GetPriorHTMLSibling(listItem);
}
if (!curList || (sibling && sibling != curList)) {
EditorDOMPoint atListItem(listItem);
if (NS_WARN_IF(!listItem)) {
return NS_ERROR_FAILURE;
}
nsAtom* containerName =
@@ -4760,24 +4729,24 @@ HTMLEditRules::WillHTMLIndent(Selection*
// Create a new nested list of correct type.
SplitNodeResult splitNodeResult =
MaybeSplitAncestorsForInsertWithTransaction(*containerName,
atListItem);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
curList =
- htmlEditor->CreateNodeWithTransaction(*containerName,
- splitNodeResult.SplitPoint());
+ HTMLEditorRef().CreateNodeWithTransaction(
+ *containerName, splitNodeResult.SplitPoint());
if (NS_WARN_IF(!curList)) {
return NS_ERROR_FAILURE;
}
}
- rv = htmlEditor->MoveNodeToEndWithTransaction(*listItem, *curList);
+ rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*listItem, *curList);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// remember we indented this li
indentedLI = listItem;
continue;
@@ -4788,70 +4757,70 @@ HTMLEditRules::WillHTMLIndent(Selection*
// One reason it might not go in prio blockquote is if we are now
// in a different table cell.
if (curQuote && InDifferentTableElements(curQuote, curNode)) {
curQuote = nullptr;
}
if (!curQuote) {
// First, check that our element can contain a blockquote.
- if (!htmlEditor->CanContainTag(*atCurNode.GetContainer(),
- *nsGkAtoms::blockquote)) {
+ if (!HTMLEditorRef().CanContainTag(*atCurNode.GetContainer(),
+ *nsGkAtoms::blockquote)) {
return NS_OK; // cancelled
}
SplitNodeResult splitNodeResult =
MaybeSplitAncestorsForInsertWithTransaction(*nsGkAtoms::blockquote,
atCurNode);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
curQuote =
- htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::blockquote,
- splitNodeResult.SplitPoint());
+ HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::blockquote,
+ splitNodeResult.SplitPoint());
if (NS_WARN_IF(!curQuote)) {
return NS_ERROR_FAILURE;
}
// remember our new block for postprocessing
mNewBlock = curQuote;
// curQuote is now the correct thing to put curNode in
}
// tuck the node into the end of the active blockquote
- rv = htmlEditor->MoveNodeToEndWithTransaction(*curNode->AsContent(),
- *curQuote);
+ rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(),
+ *curQuote);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// forget curList, if any
curList = nullptr;
}
return NS_OK;
}
nsresult
HTMLEditRules::WillOutdent(Selection& aSelection,
bool* aCancel,
bool* aHandled)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
MOZ_ASSERT(aCancel && aHandled);
*aCancel = false;
*aHandled = true;
nsCOMPtr<nsIContent> rememberedLeftBQ, rememberedRightBQ;
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
- bool useCSS = htmlEditor->IsCSSEnabled();
+
+ bool useCSS = HTMLEditorRef().IsCSSEnabled();
nsresult rv = NormalizeSelection(&aSelection);
NS_ENSURE_SUCCESS(rv, rv);
// Some scoping for selection resetting - we may need to tweak it
{
- AutoSelectionRestorer selectionRestorer(&aSelection, htmlEditor);
+ AutoSelectionRestorer selectionRestorer(&aSelection, &HTMLEditorRef());
// Convert the selection ranges into "promoted" selection ranges: this
// basically just expands the range to include the immediate block parent,
// and then further expands to include any ancestors whose children are all
// in the range
nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
rv = GetNodesFromSelection(aSelection, EditAction::outdent, arrayOfNodes);
NS_ENSURE_SUCCESS(rv, rv);
@@ -4886,18 +4855,18 @@ HTMLEditRules::WillOutdent(Selection& aS
getter_AddRefs(rememberedLeftBQ),
getter_AddRefs(rememberedRightBQ));
NS_ENSURE_SUCCESS(rv, rv);
curBlockQuote = nullptr;
firstBQChild = nullptr;
lastBQChild = nullptr;
curBlockQuoteIsIndentedWithCSS = false;
}
- rv = htmlEditor->RemoveBlockContainerWithTransaction(
- *curNode->AsElement());
+ rv = HTMLEditorRef().RemoveBlockContainerWithTransaction(
+ *curNode->AsElement());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
continue;
}
// Is it a block with a 'margin' property?
if (useCSS && IsBlockNode(curNode)) {
nsAtom& marginProperty = MarginPropertyAtomForIndent(curNode);
@@ -4955,17 +4924,17 @@ HTMLEditRules::WillOutdent(Selection& aS
}
// Are we inside a blockquote?
OwningNonNull<nsINode> n = curNode;
curBlockQuoteIsIndentedWithCSS = false;
// Keep looking up the hierarchy as long as we don't hit the body or the
// active editing host or a table element (other than an entire table)
while (!n->IsHTMLElement(nsGkAtoms::body) &&
- htmlEditor->IsDescendantOfEditorRoot(n) &&
+ HTMLEditorRef().IsDescendantOfEditorRoot(n) &&
(n->IsHTMLElement(nsGkAtoms::table) ||
!HTMLEditUtils::IsTableElement(n))) {
if (!n->GetParentNode()) {
break;
}
n = *n->GetParentNode();
if (n->IsHTMLElement(nsGkAtoms::blockquote)) {
// If so, remember it and the first node we are taking out of it.
@@ -4992,18 +4961,18 @@ HTMLEditRules::WillOutdent(Selection& aS
}
if (!curBlockQuote) {
// Couldn't find enclosing blockquote. Handle list cases.
if (HTMLEditUtils::IsList(curParent)) {
// Move node out of list
if (HTMLEditUtils::IsList(curNode)) {
// Just unwrap this sublist
- rv = htmlEditor->RemoveBlockContainerWithTransaction(
- *curNode->AsElement());
+ rv = HTMLEditorRef().RemoveBlockContainerWithTransaction(
+ *curNode->AsElement());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
// handled list item case above
} else if (HTMLEditUtils::IsList(curNode)) {
// node is a list, but parent is non-list: move list items out
nsCOMPtr<nsIContent> child = curNode->GetLastChild();
@@ -5011,33 +4980,33 @@ HTMLEditRules::WillOutdent(Selection& aS
if (HTMLEditUtils::IsListItem(child)) {
rv = PopListItem(*child);
NS_ENSURE_SUCCESS(rv, rv);
} else if (HTMLEditUtils::IsList(child)) {
// We have an embedded list, so move it out from under the parent
// list. Be sure to put it after the parent list because this
// loop iterates backwards through the parent's list of children.
EditorRawDOMPoint afterCurrentList(curParent, offset + 1);
- rv = htmlEditor->MoveNodeWithTransaction(*child,
- afterCurrentList);
+ rv = HTMLEditorRef().MoveNodeWithTransaction(*child,
+ afterCurrentList);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else {
// Delete any non-list items for now
- rv = htmlEditor->DeleteNodeWithTransaction(*child);
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*child);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
child = curNode->GetLastChild();
}
// Delete the now-empty list
- rv = htmlEditor->RemoveBlockContainerWithTransaction(
- *curNode->AsElement());
+ rv = HTMLEditorRef().RemoveBlockContainerWithTransaction(
+ *curNode->AsElement());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else if (useCSS) {
nsCOMPtr<Element> element;
if (curNode->GetAsText()) {
// We want to outdent the parent of text nodes
element = curNode->GetParentElement();
@@ -5095,57 +5064,58 @@ HTMLEditRules::WillOutdent(Selection& aS
* RemovePartOfBlock() splits aBlock and move aStartChild to aEndChild out of
* aBlock.
*/
nsresult
HTMLEditRules::RemovePartOfBlock(Element& aBlock,
nsIContent& aStartChild,
nsIContent& aEndChild)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
SplitBlock(aBlock, aStartChild, aEndChild);
// Get rid of part of blockquote we are outdenting
-
- NS_ENSURE_STATE(mHTMLEditor);
- nsresult rv = mHTMLEditor->RemoveBlockContainerWithTransaction(aBlock);
- NS_ENSURE_SUCCESS(rv, rv);
-
+ nsresult rv = HTMLEditorRef().RemoveBlockContainerWithTransaction(aBlock);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
return NS_OK;
}
void
HTMLEditRules::SplitBlock(Element& aBlock,
nsIContent& aStartChild,
nsIContent& aEndChild,
nsIContent** aOutLeftNode,
nsIContent** aOutRightNode,
nsIContent** aOutMiddleNode)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
// aStartChild and aEndChild must be exclusive descendants of aBlock
MOZ_ASSERT(EditorUtils::IsDescendantOf(aStartChild, aBlock) &&
EditorUtils::IsDescendantOf(aEndChild, aBlock));
- NS_ENSURE_TRUE_VOID(mHTMLEditor);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
// Split at the start.
SplitNodeResult splitAtStartResult =
- htmlEditor->SplitNodeDeepWithTransaction(
- aBlock, EditorRawDOMPoint(&aStartChild),
- SplitAtEdges::eDoNotCreateEmptyContainer);
+ HTMLEditorRef().SplitNodeDeepWithTransaction(
+ aBlock, EditorRawDOMPoint(&aStartChild),
+ SplitAtEdges::eDoNotCreateEmptyContainer);
NS_WARNING_ASSERTION(splitAtStartResult.Succeeded(),
"Failed to split aBlock at start");
// Split at after the end
EditorRawDOMPoint atAfterEnd(&aEndChild);
DebugOnly<bool> advanced = atAfterEnd.AdvanceOffset();
NS_WARNING_ASSERTION(advanced,
"Failed to advance offset after the end node");
SplitNodeResult splitAtEndResult =
- htmlEditor->SplitNodeDeepWithTransaction(
- aBlock, atAfterEnd,
- SplitAtEdges::eDoNotCreateEmptyContainer);
+ HTMLEditorRef().SplitNodeDeepWithTransaction(
+ aBlock, atAfterEnd,
+ SplitAtEdges::eDoNotCreateEmptyContainer);
NS_WARNING_ASSERTION(splitAtEndResult.Succeeded(),
"Failed to split aBlock at after end");
if (aOutLeftNode) {
NS_IF_ADDREF(*aOutLeftNode = splitAtStartResult.GetPreviousNode());
}
if (aOutRightNode) {
@@ -5164,61 +5134,70 @@ HTMLEditRules::SplitBlock(Element& aBloc
nsresult
HTMLEditRules::OutdentPartOfBlock(Element& aBlock,
nsIContent& aStartChild,
nsIContent& aEndChild,
bool aIsBlockIndentedWithCSS,
nsIContent** aOutLeftNode,
nsIContent** aOutRightNode)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
MOZ_ASSERT(aOutLeftNode && aOutRightNode);
nsCOMPtr<nsIContent> middleNode;
SplitBlock(aBlock, aStartChild, aEndChild, aOutLeftNode, aOutRightNode,
getter_AddRefs(middleNode));
if (NS_WARN_IF(!middleNode) || NS_WARN_IF(!middleNode->IsElement())) {
return NS_ERROR_FAILURE;
}
if (!aIsBlockIndentedWithCSS) {
- NS_ENSURE_STATE(mHTMLEditor);
nsresult rv =
- mHTMLEditor->RemoveBlockContainerWithTransaction(
- *middleNode->AsElement());
- NS_ENSURE_SUCCESS(rv, rv);
- } else if (middleNode->IsElement()) {
+ HTMLEditorRef().RemoveBlockContainerWithTransaction(
+ *middleNode->AsElement());
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
+ }
+
+ if (middleNode->IsElement()) {
// We do nothing if middleNode isn't an element
nsresult rv = ChangeIndentation(*middleNode->AsElement(), Change::minus);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
}
return NS_OK;
}
/**
* ConvertListType() converts list type and list item type.
*/
already_AddRefed<Element>
HTMLEditRules::ConvertListType(Element* aList,
nsAtom* aListType,
nsAtom* aItemType)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
MOZ_ASSERT(aList);
MOZ_ASSERT(aListType);
MOZ_ASSERT(aItemType);
nsCOMPtr<nsINode> child = aList->GetFirstChild();
while (child) {
if (child->IsElement()) {
- dom::Element* element = child->AsElement();
+ Element* element = child->AsElement();
if (HTMLEditUtils::IsListItem(element) &&
!element->IsHTMLElement(aItemType)) {
child =
- mHTMLEditor->ReplaceContainerWithTransaction(*element, *aItemType);
+ HTMLEditorRef().ReplaceContainerWithTransaction(*element, *aItemType);
if (NS_WARN_IF(!child)) {
return nullptr;
}
} else if (HTMLEditUtils::IsList(element) &&
!element->IsHTMLElement(aListType)) {
child = ConvertListType(child->AsElement(), aListType, aItemType);
if (NS_WARN_IF(!child)) {
return nullptr;
@@ -5228,160 +5207,165 @@ HTMLEditRules::ConvertListType(Element*
child = child->GetNextSibling();
}
if (aList->IsHTMLElement(aListType)) {
RefPtr<dom::Element> list = aList;
return list.forget();
}
- return mHTMLEditor->ReplaceContainerWithTransaction(*aList, *aListType);
+ RefPtr<Element> listElement =
+ HTMLEditorRef().ReplaceContainerWithTransaction(*aList, *aListType);
+ NS_WARNING_ASSERTION(listElement != nullptr, "Failed to create list element");
+ return listElement.forget();
}
/**
* CreateStyleForInsertText() takes care of clearing and setting appropriate
* style nodes for text insertion.
*/
nsresult
HTMLEditRules::CreateStyleForInsertText(Selection& aSelection,
nsIDocument& aDoc)
{
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
- MOZ_ASSERT(htmlEditor->mTypeInState);
+ MOZ_ASSERT(IsEditorDataAvailable());
+ MOZ_ASSERT(HTMLEditorRef().mTypeInState);
bool weDidSomething = false;
NS_ENSURE_STATE(aSelection.GetRangeAt(0));
nsCOMPtr<nsINode> node = aSelection.GetRangeAt(0)->GetStartContainer();
int32_t offset = aSelection.GetRangeAt(0)->StartOffset();
nsCOMPtr<Element> rootElement = aDoc.GetRootElement();
NS_ENSURE_STATE(rootElement);
// process clearing any styles first
UniquePtr<PropItem> item =
- Move(htmlEditor->mTypeInState->TakeClearProperty());
+ Move(HTMLEditorRef().mTypeInState->TakeClearProperty());
{
// Transactions may set selection, but we will set selection if necessary.
- AutoTransactionsConserveSelection dontChangeMySelection(htmlEditor);
+ AutoTransactionsConserveSelection dontChangeMySelection(&HTMLEditorRef());
while (item && node != rootElement) {
// XXX If we redesign ClearStyle(), we can use EditorDOMPoint in this
// method.
nsresult rv =
- htmlEditor->ClearStyle(address_of(node), &offset,
- item->tag, item->attr);
- NS_ENSURE_SUCCESS(rv, rv);
- item = Move(htmlEditor->mTypeInState->TakeClearProperty());
+ HTMLEditorRef().ClearStyle(address_of(node), &offset,
+ item->tag, item->attr);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ item = Move(HTMLEditorRef().mTypeInState->TakeClearProperty());
weDidSomething = true;
}
}
// then process setting any styles
- int32_t relFontSize = htmlEditor->mTypeInState->TakeRelativeFontSize();
- item = Move(htmlEditor->mTypeInState->TakeSetProperty());
+ int32_t relFontSize = HTMLEditorRef().mTypeInState->TakeRelativeFontSize();
+ item = Move(HTMLEditorRef().mTypeInState->TakeSetProperty());
if (item || relFontSize) {
// we have at least one style to add; make a new text node to insert style
// nodes above.
if (RefPtr<Text> text = node->GetAsText()) {
// if we are in a text node, split it
SplitNodeResult splitTextNodeResult =
- htmlEditor->SplitNodeDeepWithTransaction(
- *text, EditorRawDOMPoint(text, offset),
- SplitAtEdges::eAllowToCreateEmptyContainer);
+ HTMLEditorRef().SplitNodeDeepWithTransaction(
+ *text, EditorRawDOMPoint(text, offset),
+ SplitAtEdges::eAllowToCreateEmptyContainer);
if (NS_WARN_IF(splitTextNodeResult.Failed())) {
return splitTextNodeResult.Rv();
}
EditorRawDOMPoint splitPoint(splitTextNodeResult.SplitPoint());
node = splitPoint.GetContainer();
offset = splitPoint.Offset();
}
- if (!htmlEditor->IsContainer(node)) {
+ if (!HTMLEditorRef().IsContainer(node)) {
return NS_OK;
}
OwningNonNull<Text> newNode =
EditorBase::CreateTextNode(aDoc, EmptyString());
nsresult rv =
- htmlEditor->InsertNodeWithTransaction(*newNode,
- EditorRawDOMPoint(node, offset));
+ HTMLEditorRef().InsertNodeWithTransaction(
+ *newNode, EditorRawDOMPoint(node, offset));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
node = newNode;
offset = 0;
weDidSomething = true;
if (relFontSize) {
// dir indicated bigger versus smaller. 1 = bigger, -1 = smaller
HTMLEditor::FontSize dir = relFontSize > 0 ?
HTMLEditor::FontSize::incr : HTMLEditor::FontSize::decr;
for (int32_t j = 0; j < DeprecatedAbs(relFontSize); j++) {
- rv = htmlEditor->RelativeFontChangeOnTextNode(dir, newNode, 0, -1);
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = HTMLEditorRef().RelativeFontChangeOnTextNode(dir, newNode, 0, -1);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
}
while (item) {
- rv = htmlEditor->SetInlinePropertyOnNode(*node->AsContent(),
- *item->tag, item->attr,
- item->value);
- NS_ENSURE_SUCCESS(rv, rv);
- item = htmlEditor->mTypeInState->TakeSetProperty();
+ rv = HTMLEditorRef().SetInlinePropertyOnNode(*node->AsContent(),
+ *item->tag, item->attr,
+ item->value);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ item = HTMLEditorRef().mTypeInState->TakeSetProperty();
}
}
if (weDidSomething) {
return aSelection.Collapse(node, offset);
}
return NS_OK;
}
bool
HTMLEditRules::IsEmptyBlockElement(Element& aElement,
IgnoreSingleBR aIgnoreSingleBR)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (NS_WARN_IF(!IsBlockNode(aElement))) {
return false;
}
bool isEmpty = true;
nsresult rv =
- mHTMLEditor->IsEmptyNode(&aElement, &isEmpty,
- aIgnoreSingleBR == IgnoreSingleBR::eYes);
+ HTMLEditorRef().IsEmptyNode(&aElement, &isEmpty,
+ aIgnoreSingleBR == IgnoreSingleBR::eYes);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
return isEmpty;
}
nsresult
HTMLEditRules::WillAlign(Selection& aSelection,
const nsAString& aAlignType,
bool* aCancel,
bool* aHandled)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
MOZ_ASSERT(aCancel && aHandled);
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
WillInsert(aSelection, aCancel);
// Initialize out param. We want to ignore result of WillInsert().
*aCancel = false;
*aHandled = false;
nsresult rv = NormalizeSelection(&aSelection);
NS_ENSURE_SUCCESS(rv, rv);
- AutoSelectionRestorer selectionRestorer(&aSelection, htmlEditor);
+ AutoSelectionRestorer selectionRestorer(&aSelection, &HTMLEditorRef());
// Convert the selection ranges into "promoted" selection ranges: This
// basically just expands the range to include the immediate block parent,
// and then further expands to include any ancestors whose children are all
// in the range
*aHandled = true;
nsTArray<OwningNonNull<nsINode>> nodeArray;
rv = GetNodesFromSelection(aSelection, EditAction::align, nodeArray);
@@ -5442,36 +5426,39 @@ HTMLEditRules::WillAlign(Selection& aSel
atStartOfSelection);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
// Consume a trailing br, if any. This is to keep an alignment from
// creating extra lines, if possible.
nsCOMPtr<nsIContent> brContent =
- htmlEditor->GetNextEditableHTMLNodeInBlock(splitNodeResult.SplitPoint());
+ HTMLEditorRef().GetNextEditableHTMLNodeInBlock(
+ splitNodeResult.SplitPoint());
EditorDOMPoint pointToInsertDiv(splitNodeResult.SplitPoint());
if (brContent && TextEditUtils::IsBreak(brContent)) {
// Making use of html structure... if next node after where we are
// putting our div is not a block, then the br we found is in same block
// we are, so it's safe to consume it.
nsCOMPtr<nsIContent> sibling;
if (pointToInsertDiv.GetChild()) {
- sibling = htmlEditor->GetNextHTMLSibling(pointToInsertDiv.GetChild());
+ sibling =
+ HTMLEditorRef().GetNextHTMLSibling(pointToInsertDiv.GetChild());
}
if (sibling && !IsBlockNode(*sibling)) {
AutoEditorDOMPointChildInvalidator lockOffset(pointToInsertDiv);
- rv = htmlEditor->DeleteNodeWithTransaction(*brContent);
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*brContent);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
}
RefPtr<Element> div =
- htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::div, pointToInsertDiv);
+ HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::div,
+ pointToInsertDiv);
if (NS_WARN_IF(!div)) {
return NS_ERROR_FAILURE;
}
// Remember our new block for postprocessing
mNewBlock = div;
// Set up the alignment on the div, using HTML or CSS
rv = AlignBlock(*div, aAlignType, ContentsOnly::yes);
NS_ENSURE_SUCCESS(rv, rv);
@@ -5497,23 +5484,23 @@ HTMLEditRules::WillAlign(Selection& aSel
nsTArray<bool> transitionList;
MakeTransitionList(nodeArray, transitionList);
// Okay, now go through all the nodes and give them an align attrib or put
// them in a div, or whatever is appropriate. Woohoo!
nsCOMPtr<Element> curDiv;
- bool useCSS = htmlEditor->IsCSSEnabled();
+ bool useCSS = HTMLEditorRef().IsCSSEnabled();
int32_t indexOfTransitionList = -1;
for (OwningNonNull<nsINode>& curNode : nodeArray) {
++indexOfTransitionList;
// Ignore all non-editable nodes. Leave them be.
- if (!htmlEditor->IsEditable(curNode)) {
+ if (!HTMLEditorRef().IsEditable(curNode)) {
continue;
}
// The node is a table element, an hr, a paragraph, a div or a section
// header; in HTML 4, it can directly carry the ALIGN attribute and we
// don't need to nest it, just set the alignment. In CSS, assign the
// corresponding CSS styles in AlignBlock
if (HTMLEditUtils::SupportsAlignAttr(*curNode)) {
@@ -5531,32 +5518,33 @@ HTMLEditRules::WillAlign(Selection& aSel
// Skip insignificant formatting text nodes to prevent unnecessary
// structure splitting!
bool isEmptyTextNode = false;
if (curNode->GetAsText() &&
((HTMLEditUtils::IsTableElement(atCurNode.GetContainer()) &&
!HTMLEditUtils::IsTableCellOrCaption(*atCurNode.GetContainer())) ||
HTMLEditUtils::IsList(atCurNode.GetContainer()) ||
- (NS_SUCCEEDED(htmlEditor->IsEmptyNode(curNode, &isEmptyTextNode)) &&
+ (NS_SUCCEEDED(HTMLEditorRef().IsEmptyNode(curNode,
+ &isEmptyTextNode)) &&
isEmptyTextNode))) {
continue;
}
// If it's a list item, or a list inside a list, forget any "current" div,
// and instead put divs inside the appropriate block (td, li, etc.)
if (HTMLEditUtils::IsListItem(curNode) ||
HTMLEditUtils::IsList(curNode)) {
AutoEditorDOMPointOffsetInvalidator lockChild(atCurNode);
rv = RemoveAlignment(*curNode, aAlignType, true);
NS_ENSURE_SUCCESS(rv, rv);
if (useCSS) {
- htmlEditor->mCSSEditUtils->SetCSSEquivalentToHTMLStyle(
- curNode->AsElement(), nullptr,
- nsGkAtoms::align, &aAlignType, false);
+ HTMLEditorRef().mCSSEditUtils->SetCSSEquivalentToHTMLStyle(
+ curNode->AsElement(), nullptr,
+ nsGkAtoms::align, &aAlignType, false);
curDiv = nullptr;
continue;
}
if (HTMLEditUtils::IsList(atCurNode.GetContainer())) {
// If we don't use CSS, add a contraint to list element: they have to
// be inside another list, i.e., >= second level of nesting
rv = AlignInnerBlocks(*curNode, aAlignType);
NS_ENSURE_SUCCESS(rv, rv);
@@ -5565,58 +5553,60 @@ HTMLEditRules::WillAlign(Selection& aSel
}
// Clear out curDiv so that we don't put nodes after this one into it
}
// Need to make a div to put things in if we haven't already, or if this
// node doesn't go in div we used earlier.
if (!curDiv || transitionList[indexOfTransitionList]) {
// First, check that our element can contain a div.
- if (!htmlEditor->CanContainTag(*atCurNode.GetContainer(),
- *nsGkAtoms::div)) {
+ if (!HTMLEditorRef().CanContainTag(*atCurNode.GetContainer(),
+ *nsGkAtoms::div)) {
// Cancelled
return NS_OK;
}
SplitNodeResult splitNodeResult =
MaybeSplitAncestorsForInsertWithTransaction(*nsGkAtoms::div, atCurNode);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
curDiv =
- htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::div,
- splitNodeResult.SplitPoint());
+ HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::div,
+ splitNodeResult.SplitPoint());
if (NS_WARN_IF(!curDiv)) {
return NS_ERROR_FAILURE;
}
// Remember our new block for postprocessing
mNewBlock = curDiv;
// Set up the alignment on the div
rv = AlignBlock(*curDiv, aAlignType, ContentsOnly::yes);
}
// Tuck the node into the end of the active div
- rv = htmlEditor->MoveNodeToEndWithTransaction(*curNode->AsContent(),
- *curDiv);
+ rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(),
+ *curDiv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
return NS_OK;
}
/**
* AlignInnerBlocks() aligns inside table cells or list items.
*/
nsresult
HTMLEditRules::AlignInnerBlocks(nsINode& aNode,
const nsAString& aAlignType)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
// Gather list of table cells or list items
nsTArray<OwningNonNull<nsINode>> nodeArray;
TableCellAndListItemFunctor functor;
DOMIterator iter(aNode);
iter.AppendList(functor, nodeArray);
// Now that we have the list, align their contents as requested
for (auto& node : nodeArray) {
@@ -5632,122 +5622,122 @@ HTMLEditRules::AlignInnerBlocks(nsINode&
/**
* AlignBlockContents() aligns contents of a block element.
*/
nsresult
HTMLEditRules::AlignBlockContents(nsINode& aNode,
const nsAString& aAlignType)
{
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
- nsCOMPtr<nsIContent> firstChild = htmlEditor->GetFirstEditableChild(aNode);
+ MOZ_ASSERT(IsEditorDataAvailable());
+
+ nsCOMPtr<nsIContent> firstChild =
+ HTMLEditorRef().GetFirstEditableChild(aNode);
if (!firstChild) {
// this cell has no content, nothing to align
return NS_OK;
}
- nsCOMPtr<nsIContent> lastChild = htmlEditor->GetLastEditableChild(aNode);
+ nsCOMPtr<nsIContent> lastChild = HTMLEditorRef().GetLastEditableChild(aNode);
if (firstChild == lastChild && firstChild->IsHTMLElement(nsGkAtoms::div)) {
// the cell already has a div containing all of its content: just
// act on this div.
- return htmlEditor->SetAttributeOrEquivalent(firstChild->AsElement(),
- nsGkAtoms::align,
- aAlignType, false);
+ return HTMLEditorRef().SetAttributeOrEquivalent(firstChild->AsElement(),
+ nsGkAtoms::align,
+ aAlignType, false);
}
// else we need to put in a div, set the alignment, and toss in all the
// children
EditorRawDOMPoint atStartOfNode(&aNode, 0);
RefPtr<Element> divElem =
- htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::div, atStartOfNode);
+ HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::div, atStartOfNode);
if (NS_WARN_IF(!divElem)) {
return NS_ERROR_FAILURE;
}
// set up the alignment on the div
nsresult rv =
- htmlEditor->SetAttributeOrEquivalent(divElem, nsGkAtoms::align,
- aAlignType, false);
+ HTMLEditorRef().SetAttributeOrEquivalent(divElem, nsGkAtoms::align,
+ aAlignType, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// tuck the children into the end of the active div
while (lastChild && (lastChild != divElem)) {
nsresult rv =
- htmlEditor->MoveNodeWithTransaction(*lastChild,
- EditorRawDOMPoint(divElem, 0));
+ HTMLEditorRef().MoveNodeWithTransaction(*lastChild,
+ EditorRawDOMPoint(divElem, 0));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
- lastChild = htmlEditor->GetLastEditableChild(aNode);
+ lastChild = HTMLEditorRef().GetLastEditableChild(aNode);
}
return NS_OK;
}
/**
* CheckForEmptyBlock() is called by WillDeleteSelection() to detect and handle
* case of deleting from inside an empty block.
*/
nsresult
HTMLEditRules::CheckForEmptyBlock(nsINode* aStartNode,
Element* aBodyNode,
Selection* aSelection,
nsIEditor::EDirection aAction,
bool* aHandled)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
// If the editing host is an inline element, bail out early.
if (aBodyNode && IsInlineNode(*aBodyNode)) {
return NS_OK;
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
// If we are inside an empty block, delete it. Note: do NOT delete table
// elements this way.
- RefPtr<Element> block = htmlEditor->GetBlock(*aStartNode);
+ RefPtr<Element> block = HTMLEditorRef().GetBlock(*aStartNode);
bool bIsEmptyNode;
RefPtr<Element> emptyBlock;
if (block && block != aBodyNode) {
// Efficiency hack, avoiding IsEmptyNode() call when in body
- nsresult rv = htmlEditor->IsEmptyNode(block, &bIsEmptyNode, true, false);
- NS_ENSURE_SUCCESS(rv, rv);
+ nsresult rv =
+ HTMLEditorRef().IsEmptyNode(block, &bIsEmptyNode, true, false);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
while (block && bIsEmptyNode && !HTMLEditUtils::IsTableElement(block) &&
block != aBodyNode) {
emptyBlock = block;
- block = htmlEditor->GetBlockNodeParent(emptyBlock);
+ block = HTMLEditorRef().GetBlockNodeParent(emptyBlock);
if (block) {
- rv = htmlEditor->IsEmptyNode(block, &bIsEmptyNode, true, false);
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = HTMLEditorRef().IsEmptyNode(block, &bIsEmptyNode, true, false);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
}
}
if (emptyBlock && emptyBlock->IsEditable()) {
nsCOMPtr<nsINode> blockParent = emptyBlock->GetParentNode();
NS_ENSURE_TRUE(blockParent, NS_ERROR_FAILURE);
if (HTMLEditUtils::IsListItem(emptyBlock)) {
// Are we the first list item in the list?
- if (htmlEditor->IsFirstEditableChild(emptyBlock)) {
+ if (HTMLEditorRef().IsFirstEditableChild(emptyBlock)) {
EditorDOMPoint atBlockParent(blockParent);
if (NS_WARN_IF(!atBlockParent.IsSet())) {
return NS_ERROR_FAILURE;
}
// If we are a sublist, skip the br creation
if (!HTMLEditUtils::IsList(atBlockParent.GetContainer())) {
// Create a br before list
RefPtr<Element> brElement =
- htmlEditor->InsertBrElementWithTransaction(*aSelection,
- atBlockParent);
+ HTMLEditorRef().InsertBrElementWithTransaction(*aSelection,
+ atBlockParent);
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
// Adjust selection to be right before it
ErrorResult error;
aSelection->Collapse(EditorRawDOMPoint(brElement), error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
@@ -5760,17 +5750,17 @@ HTMLEditRules::CheckForEmptyBlock(nsINod
if (aAction == nsIEditor::eNext || aAction == nsIEditor::eNextWord ||
aAction == nsIEditor::eToEndOfLine) {
// Move to the start of the next node, if any
EditorRawDOMPoint afterEmptyBlock(emptyBlock);
DebugOnly<bool> advanced = afterEmptyBlock.AdvanceOffset();
NS_WARNING_ASSERTION(advanced,
"Failed to set selection to the after the empty block");
nsCOMPtr<nsIContent> nextNode =
- htmlEditor->GetNextNode(afterEmptyBlock);
+ HTMLEditorRef().GetNextNode(afterEmptyBlock);
if (nextNode) {
EditorDOMPoint pt = GetGoodSelPointForNode(*nextNode, aAction);
ErrorResult error;
aSelection->Collapse(pt, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
} else {
@@ -5786,17 +5776,17 @@ HTMLEditRules::CheckForEmptyBlock(nsINod
}
}
} else if (aAction == nsIEditor::ePrevious ||
aAction == nsIEditor::ePreviousWord ||
aAction == nsIEditor::eToBeginningOfLine) {
// Move to the end of the previous node
EditorRawDOMPoint atEmptyBlock(emptyBlock);
nsCOMPtr<nsIContent> priorNode =
- htmlEditor->GetPreviousEditableNode(atEmptyBlock);
+ HTMLEditorRef().GetPreviousEditableNode(atEmptyBlock);
if (priorNode) {
EditorDOMPoint pt = GetGoodSelPointForNode(*priorNode, aAction);
nsresult rv = aSelection->Collapse(pt);
NS_ENSURE_SUCCESS(rv, rv);
} else {
EditorRawDOMPoint afterEmptyBlock(emptyBlock);
if (NS_WARN_IF(!afterEmptyBlock.AdvanceOffset())) {
return NS_ERROR_FAILURE;
@@ -5804,36 +5794,38 @@ HTMLEditRules::CheckForEmptyBlock(nsINod
nsresult rv = aSelection->Collapse(afterEmptyBlock);
NS_ENSURE_SUCCESS(rv, rv);
}
} else if (aAction != nsIEditor::eNone) {
MOZ_CRASH("CheckForEmptyBlock doesn't support this action yet");
}
}
*aHandled = true;
- nsresult rv = htmlEditor->DeleteNodeWithTransaction(*emptyBlock);
+ nsresult rv = HTMLEditorRef().DeleteNodeWithTransaction(*emptyBlock);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
return NS_OK;
}
Element*
HTMLEditRules::CheckForInvisibleBR(Element& aBlock,
BRLocation aWhere,
int32_t aOffset)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
nsCOMPtr<nsINode> testNode;
int32_t testOffset = 0;
if (aWhere == BRLocation::blockEnd) {
// No block crossing
nsCOMPtr<nsIContent> rightmostNode =
- mHTMLEditor->GetRightmostChild(&aBlock, true);
+ HTMLEditorRef().GetRightmostChild(&aBlock, true);
if (!rightmostNode) {
return nullptr;
}
testNode = rightmostNode->GetParentNode();
// Since rightmostNode is always the last child, its index is equal to the
// child count, so instead of ComputeIndexOf() we use the faster
@@ -5845,17 +5837,17 @@ HTMLEditRules::CheckForInvisibleBR(Eleme
} else if (aOffset) {
testNode = &aBlock;
// We'll check everything to the left of the input position
testOffset = aOffset;
} else {
return nullptr;
}
- WSRunObject wsTester(mHTMLEditor, testNode, testOffset);
+ WSRunObject wsTester(&HTMLEditorRef(), testNode, testOffset);
if (WSType::br == wsTester.mStartReason) {
return wsTester.mStartReasonNode->AsElement();
}
return nullptr;
}
/**
@@ -5868,19 +5860,20 @@ HTMLEditRules::CheckForInvisibleBR(Eleme
void
HTMLEditRules::GetInnerContent(
nsINode& aNode,
nsTArray<OwningNonNull<nsINode>>& aOutArrayOfNodes,
int32_t* aIndex,
Lists aLists,
Tables aTables)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
MOZ_ASSERT(aIndex);
- for (nsCOMPtr<nsIContent> node = mHTMLEditor->GetFirstEditableChild(aNode);
+ for (nsCOMPtr<nsIContent> node = HTMLEditorRef().GetFirstEditableChild(aNode);
node; node = node->GetNextSibling()) {
if ((aLists == Lists::yes && (HTMLEditUtils::IsList(node) ||
HTMLEditUtils::IsListItem(node))) ||
(aTables == Tables::yes && HTMLEditUtils::IsTableElement(node))) {
GetInnerContent(*node, aOutArrayOfNodes, aIndex, aLists, aTables);
} else {
aOutArrayOfNodes.InsertElementAt(*aIndex, *node);
(*aIndex)++;
@@ -5889,16 +5882,18 @@ HTMLEditRules::GetInnerContent(
}
/**
* Promotes selection to include blocks that have all their children selected.
*/
nsresult
HTMLEditRules::ExpandSelectionForDeletion(Selection& aSelection)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
// Don't need to touch collapsed selections
if (aSelection.IsCollapsed()) {
return NS_OK;
}
// We don't need to mess with cell selections, and we assume multirange
// selections are those.
if (aSelection.RangeCount() != 1) {
@@ -5919,23 +5914,25 @@ HTMLEditRules::ExpandSelectionForDeletio
HTMLEditor::GetBlock(*range->GetCommonAncestor());
NS_ENSURE_STATE(selCommon);
// Set up for loops and cache our root element
nsCOMPtr<nsINode> firstBRParent;
nsCOMPtr<nsINode> unused;
int32_t visOffset = 0, firstBROffset = 0;
WSType wsType;
- nsCOMPtr<Element> root = mHTMLEditor->GetActiveEditingHost();
- NS_ENSURE_TRUE(root, NS_ERROR_FAILURE);
+ RefPtr<Element> root = HTMLEditorRef().GetActiveEditingHost();
+ if (NS_WARN_IF(!root)) {
+ return NS_ERROR_FAILURE;
+ }
// Find previous visible thingy before start of selection
if (selStartNode != selCommon && selStartNode != root) {
while (true) {
- WSRunObject wsObj(mHTMLEditor, selStartNode, selStartOffset);
+ WSRunObject wsObj(&HTMLEditorRef(), selStartNode, selStartOffset);
wsObj.PriorVisibleNode(EditorRawDOMPoint(selStartNode, selStartOffset),
address_of(unused), &visOffset, &wsType);
if (wsType != WSType::thisBlock) {
break;
}
// We want to keep looking up. But stop if we are crossing table
// element boundaries, or if we hit the root.
if (HTMLEditUtils::IsTableElement(wsObj.mStartReasonNode) ||
@@ -5947,21 +5944,21 @@ HTMLEditRules::ExpandSelectionForDeletio
selStartOffset = selStartNode ?
selStartNode->ComputeIndexOf(wsObj.mStartReasonNode) : -1;
}
}
// Find next visible thingy after end of selection
if (selEndNode != selCommon && selEndNode != root) {
for (;;) {
- WSRunObject wsObj(mHTMLEditor, selEndNode, selEndOffset);
+ WSRunObject wsObj(&HTMLEditorRef(), selEndNode, selEndOffset);
wsObj.NextVisibleNode(EditorRawDOMPoint(selEndNode, selEndOffset),
address_of(unused), &visOffset, &wsType);
if (wsType == WSType::br) {
- if (mHTMLEditor->IsVisibleBRElement(wsObj.mEndReasonNode)) {
+ if (HTMLEditorRef().IsVisibleBRElement(wsObj.mEndReasonNode)) {
break;
}
if (!firstBRParent) {
firstBRParent = selEndNode;
firstBROffset = selEndOffset;
}
selEndNode = wsObj.mEndReasonNode->GetParentNode();
selEndOffset = selEndNode
@@ -6027,35 +6024,34 @@ HTMLEditRules::ExpandSelectionForDeletio
* Idea here is to adjust selection endpoint so that they do not cross breaks
* or block boundaries unless something editable beyond that boundary is also
* selected. This adjustment makes it much easier for the various block
* operations to determine what nodes to act on.
*/
nsresult
HTMLEditRules::NormalizeSelection(Selection* inSelection)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
NS_ENSURE_TRUE(inSelection, NS_ERROR_NULL_POINTER);
// don't need to touch collapsed selections
if (inSelection->IsCollapsed()) {
return NS_OK;
}
// we don't need to mess with cell selections, and we assume multirange selections are those.
if (inSelection->RangeCount() != 1) {
return NS_OK;
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_UNEXPECTED;
- }
- RefPtr<HTMLEditor> htmlEditor = mHTMLEditor;
-
RefPtr<nsRange> range = inSelection->GetRangeAt(0);
- NS_ENSURE_TRUE(range, NS_ERROR_NULL_POINTER);
+ if (NS_WARN_IF(!range)) {
+ return NS_ERROR_FAILURE;
+ }
nsCOMPtr<nsINode> startNode = range->GetStartContainer();
if (NS_WARN_IF(!startNode)) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsINode> endNode = range->GetEndContainer();
if (NS_WARN_IF(!endNode)) {
return NS_ERROR_FAILURE;
@@ -6072,39 +6068,40 @@ HTMLEditRules::NormalizeSelection(Select
uint32_t newEndOffset = endOffset;
// some locals we need for whitespace code
nsCOMPtr<nsINode> unused;
int32_t offset = -1;
WSType wsType;
// let the whitespace code do the heavy lifting
- WSRunObject wsEndObj(htmlEditor, endNode, static_cast<int32_t>(endOffset));
+ WSRunObject wsEndObj(&HTMLEditorRef(), endNode,
+ static_cast<int32_t>(endOffset));
// is there any intervening visible whitespace? if so we can't push selection past that,
// it would visibly change maening of users selection
wsEndObj.PriorVisibleNode(EditorRawDOMPoint(endNode, endOffset),
address_of(unused), &offset, &wsType);
if (wsType != WSType::text && wsType != WSType::normalWS) {
// eThisBlock and eOtherBlock conveniently distinquish cases
// of going "down" into a block and "up" out of a block.
if (wsEndObj.mStartReason == WSType::otherBlock) {
// endpoint is just after the close of a block.
nsINode* child =
- htmlEditor->GetRightmostChild(wsEndObj.mStartReasonNode, true);
+ HTMLEditorRef().GetRightmostChild(wsEndObj.mStartReasonNode, true);
if (child) {
int32_t offset = -1;
newEndNode = EditorBase::GetNodeLocation(child, &offset);
// offset *after* child
newEndOffset = static_cast<uint32_t>(offset + 1);
}
// else block is empty - we can leave selection alone here, i think.
} else if (wsEndObj.mStartReason == WSType::thisBlock) {
// endpoint is just after start of this block
EditorRawDOMPoint atEnd(endNode, endChild, endOffset);
- nsINode* child = htmlEditor->GetPreviousEditableHTMLNode(atEnd);
+ nsINode* child = HTMLEditorRef().GetPreviousEditableHTMLNode(atEnd);
if (child) {
int32_t offset = -1;
newEndNode = EditorBase::GetNodeLocation(child, &offset);
// offset *after* child
newEndOffset = static_cast<uint32_t>(offset + 1);
}
// else block is empty - we can leave selection alone here, i think.
} else if (wsEndObj.mStartReason == WSType::br) {
@@ -6113,40 +6110,41 @@ HTMLEditRules::NormalizeSelection(Select
newEndNode =
EditorBase::GetNodeLocation(wsEndObj.mStartReasonNode, &offset);
newEndOffset = static_cast<uint32_t>(offset);;
}
}
// similar dealio for start of range
- WSRunObject wsStartObj(htmlEditor, startNode,
+ WSRunObject wsStartObj(&HTMLEditorRef(), startNode,
static_cast<int32_t>(startOffset));
// is there any intervening visible whitespace? if so we can't push selection past that,
// it would visibly change maening of users selection
wsStartObj.NextVisibleNode(EditorRawDOMPoint(startNode, startOffset),
address_of(unused), &offset, &wsType);
if (wsType != WSType::text && wsType != WSType::normalWS) {
// eThisBlock and eOtherBlock conveniently distinquish cases
// of going "down" into a block and "up" out of a block.
if (wsStartObj.mEndReason == WSType::otherBlock) {
// startpoint is just before the start of a block.
nsINode* child =
- htmlEditor->GetLeftmostChild(wsStartObj.mEndReasonNode, true);
+ HTMLEditorRef().GetLeftmostChild(wsStartObj.mEndReasonNode, true);
if (child) {
int32_t offset = -1;
newStartNode = EditorBase::GetNodeLocation(child, &offset);
newStartOffset = static_cast<uint32_t>(offset);
}
// else block is empty - we can leave selection alone here, i think.
} else if (wsStartObj.mEndReason == WSType::thisBlock) {
// startpoint is just before end of this block
nsINode* child =
- htmlEditor->GetNextEditableHTMLNode(
- EditorRawDOMPoint(startNode, startChild, startOffset));
+ HTMLEditorRef().GetNextEditableHTMLNode(
+ EditorRawDOMPoint(startNode,
+ startChild, startOffset));
if (child) {
int32_t offset = -1;
newStartNode = EditorBase::GetNodeLocation(child, &offset);
newStartOffset = static_cast<uint32_t>(offset);
}
// else block is empty - we can leave selection alone here, i think.
} else if (wsStartObj.mEndReason == WSType::br) {
// startpoint is just before a break. lets adjust it to after it.
@@ -6189,20 +6187,17 @@ HTMLEditRules::NormalizeSelection(Select
* operation really is.
*/
EditorDOMPoint
HTMLEditRules::GetPromotedPoint(RulesEndpoint aWhere,
nsINode& aNode,
int32_t aOffset,
EditAction actionID)
{
- if (NS_WARN_IF(!mHTMLEditor)) {
- return EditorDOMPoint(&aNode, aOffset);
- }
- RefPtr<HTMLEditor> htmlEditor = mHTMLEditor;
+ MOZ_ASSERT(IsEditorDataAvailable());
// we do one thing for text actions, something else entirely for other
// actions
if (actionID == EditAction::insertText ||
actionID == EditAction::insertIMEText ||
actionID == EditAction::insertBreak ||
actionID == EditAction::deleteText) {
bool isSpace, isNBSP;
@@ -6212,23 +6207,25 @@ HTMLEditRules::GetPromotedPoint(RulesEnd
int32_t newOffset = aOffset;
// for text actions, we want to look backwards (or forwards, as
// appropriate) for additional whitespace or nbsp's. We may have to act on
// these later even though they are outside of the initial selection. Even
// if they are in another node!
while (content) {
int32_t offset;
if (aWhere == kStart) {
- htmlEditor->IsPrevCharInNodeWhitespace(content, newOffset,
- &isSpace, &isNBSP,
- getter_AddRefs(temp), &offset);
+ HTMLEditorRef().IsPrevCharInNodeWhitespace(content, newOffset,
+ &isSpace, &isNBSP,
+ getter_AddRefs(temp),
+ &offset);
} else {
- htmlEditor->IsNextCharInNodeWhitespace(content, newOffset,
- &isSpace, &isNBSP,
- getter_AddRefs(temp), &offset);
+ HTMLEditorRef().IsNextCharInNodeWhitespace(content, newOffset,
+ &isSpace, &isNBSP,
+ getter_AddRefs(temp),
+ &offset);
}
if (isSpace || isNBSP) {
content = temp;
newOffset = offset;
} else {
break;
}
}
@@ -6248,30 +6245,30 @@ HTMLEditRules::GetPromotedPoint(RulesEnd
return point;
}
point.Set(point.GetContainer());
}
// look back through any further inline nodes that aren't across a <br>
// from us, and that are enclosed in the same block.
nsCOMPtr<nsINode> priorNode =
- htmlEditor->GetPreviousEditableHTMLNodeInBlock(point);
+ HTMLEditorRef().GetPreviousEditableHTMLNodeInBlock(point);
while (priorNode && priorNode->GetParentNode() &&
- !htmlEditor->IsVisibleBRElement(priorNode) &&
+ !HTMLEditorRef().IsVisibleBRElement(priorNode) &&
!IsBlockNode(*priorNode)) {
point.Set(priorNode);
- priorNode = htmlEditor->GetPreviousEditableHTMLNodeInBlock(point);
+ priorNode = HTMLEditorRef().GetPreviousEditableHTMLNodeInBlock(point);
}
// finding the real start for this point. look up the tree for as long as
// we are the first node in the container, and as long as we haven't hit
// the body node.
nsCOMPtr<nsIContent> nearNode =
- htmlEditor->GetPreviousEditableHTMLNodeInBlock(point);
+ HTMLEditorRef().GetPreviousEditableHTMLNodeInBlock(point);
while (!nearNode &&
!point.IsContainerHTMLElement(nsGkAtoms::body) &&
point.GetContainer()->GetParentNode()) {
// some cutoffs are here: we don't need to also include them in the
// aWhere == kEnd case. as long as they are in one or the other it will
// work. special case for outdent: don't keep looking up if we have
// found a blockquote element to act on
if (actionID == EditAction::outdent &&
@@ -6282,25 +6279,25 @@ HTMLEditRules::GetPromotedPoint(RulesEnd
// Don't walk past the editable section. Note that we need to check
// before walking up to a parent because we need to return the parent
// object, so the parent itself might not be in the editable area, but
// it's OK if we're not performing a block-level action.
bool blockLevelAction = actionID == EditAction::indent ||
actionID == EditAction::outdent ||
actionID == EditAction::align ||
actionID == EditAction::makeBasicBlock;
- if (!htmlEditor->IsDescendantOfEditorRoot(
- point.GetContainer()->GetParentNode()) &&
+ if (!HTMLEditorRef().IsDescendantOfEditorRoot(
+ point.GetContainer()->GetParentNode()) &&
(blockLevelAction ||
- !htmlEditor->IsDescendantOfEditorRoot(point.GetContainer()))) {
+ !HTMLEditorRef().IsDescendantOfEditorRoot(point.GetContainer()))) {
break;
}
point.Set(point.GetContainer());
- nearNode = htmlEditor->GetPreviousEditableHTMLNodeInBlock(point);
+ nearNode = HTMLEditorRef().GetPreviousEditableHTMLNodeInBlock(point);
}
return point;
}
// aWhere == kEnd
// some special casing for text nodes
if (point.IsInTextNode()) {
if (!point.GetContainer()->GetParentNode()) {
@@ -6324,24 +6321,24 @@ HTMLEditRules::GetPromotedPoint(RulesEnd
// inline elements even if it's non-editable. For example, following
// examples with insertParagraph causes different result:
// * <div contenteditable>foo[]<b contenteditable="false">bar</b></div>
// * <div contenteditable>foo[]<b>bar</b></div>
// * <div contenteditable>foo[]<b contenteditable="false">bar</b>baz</div>
// Only in the first case, after the caret position isn't wrapped with
// new <div> element.
nsCOMPtr<nsIContent> nextNode =
- htmlEditor->GetNextEditableHTMLNodeInBlock(point);
+ HTMLEditorRef().GetNextEditableHTMLNodeInBlock(point);
while (nextNode && !IsBlockNode(*nextNode) && nextNode->GetParentNode()) {
point.Set(nextNode);
if (NS_WARN_IF(!point.AdvanceOffset())) {
break;
}
- if (htmlEditor->IsVisibleBRElement(nextNode)) {
+ if (HTMLEditorRef().IsVisibleBRElement(nextNode)) {
break;
}
// Check for newlines in pre-formatted text nodes.
if (EditorBase::IsPreformatted(nextNode) &&
EditorBase::IsTextNode(nextNode)) {
nsAutoString tempString;
nextNode->GetAsText()->GetData(tempString);
@@ -6349,41 +6346,41 @@ HTMLEditRules::GetPromotedPoint(RulesEnd
if (newlinePos >= 0) {
if (static_cast<uint32_t>(newlinePos) + 1 == tempString.Length()) {
// No need for special processing if the newline is at the end.
break;
}
return EditorDOMPoint(nextNode, newlinePos + 1);
}
}
- nextNode = htmlEditor->GetNextEditableHTMLNodeInBlock(point);
+ nextNode = HTMLEditorRef().GetNextEditableHTMLNodeInBlock(point);
}
// finding the real end for this point. look up the tree for as long as we
// are the last node in the container, and as long as we haven't hit the body
// node.
nsCOMPtr<nsIContent> nearNode =
- htmlEditor->GetNextEditableHTMLNodeInBlock(point);
+ HTMLEditorRef().GetNextEditableHTMLNodeInBlock(point);
while (!nearNode &&
!point.IsContainerHTMLElement(nsGkAtoms::body) &&
point.GetContainer()->GetParentNode()) {
// Don't walk past the editable section. Note that we need to check before
// walking up to a parent because we need to return the parent object, so
// the parent itself might not be in the editable area, but it's OK.
- if (!htmlEditor->IsDescendantOfEditorRoot(point.GetContainer()) &&
- !htmlEditor->IsDescendantOfEditorRoot(
- point.GetContainer()->GetParentNode())) {
+ if (!HTMLEditorRef().IsDescendantOfEditorRoot(point.GetContainer()) &&
+ !HTMLEditorRef().IsDescendantOfEditorRoot(
+ point.GetContainer()->GetParentNode())) {
break;
}
point.Set(point.GetContainer());
if (NS_WARN_IF(!point.AdvanceOffset())) {
break;
}
- nearNode = htmlEditor->GetNextEditableHTMLNodeInBlock(point);
+ nearNode = HTMLEditorRef().GetNextEditableHTMLNodeInBlock(point);
}
return point;
}
/**
* GetPromotedRanges() runs all the selection range endpoint through
* GetPromotedPoint().
*/
@@ -6414,41 +6411,42 @@ HTMLEditRules::GetPromotedRanges(Selecti
/**
* PromoteRange() expands a range to include any parents for which all editable
* children are already in range.
*/
void
HTMLEditRules::PromoteRange(nsRange& aRange,
EditAction aOperationType)
{
- NS_ENSURE_TRUE(mHTMLEditor, );
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
+ MOZ_ASSERT(IsEditorDataAvailable());
if (!aRange.IsPositioned()) {
return;
}
nsCOMPtr<nsINode> startNode = aRange.GetStartContainer();
nsCOMPtr<nsINode> endNode = aRange.GetEndContainer();
int32_t startOffset = aRange.StartOffset();
int32_t endOffset = aRange.EndOffset();
// MOOSE major hack:
// GetPromotedPoint doesn't really do the right thing for collapsed ranges
// inside block elements that contain nothing but a solo <br>. It's easier
// to put a workaround here than to revamp GetPromotedPoint. :-(
if (startNode == endNode && startOffset == endOffset) {
- nsCOMPtr<Element> block = htmlEditor->GetBlock(*startNode);
+ RefPtr<Element> block = HTMLEditorRef().GetBlock(*startNode);
if (block) {
bool bIsEmptyNode = false;
- nsCOMPtr<nsIContent> root = htmlEditor->GetActiveEditingHost();
+ nsIContent* host = HTMLEditorRef().GetActiveEditingHost();
+ if (NS_WARN_IF(!host)) {
+ return;
+ }
// Make sure we don't go higher than our root element in the content tree
- NS_ENSURE_TRUE(root, );
- if (!nsContentUtils::ContentIsDescendantOf(root, block)) {
- htmlEditor->IsEmptyNode(block, &bIsEmptyNode, true, false);
+ if (!nsContentUtils::ContentIsDescendantOf(host, block)) {
+ HTMLEditorRef().IsEmptyNode(block, &bIsEmptyNode, true, false);
}
if (bIsEmptyNode) {
startNode = block;
endNode = block;
startOffset = 0;
endOffset = block->Length();
}
}
@@ -6471,26 +6469,26 @@ HTMLEditRules::PromoteRange(nsRange& aRa
// truly enclose the blocks that we will affect.
// Make sure that the new range ends up to be in the editable section.
// XXX Looks like that this check wastes the time. Perhaps, we should
// implement a method which checks both two DOM points in the editor
// root.
EditorDOMPoint startPoint =
GetPromotedPoint(kStart, *startNode, startOffset, aOperationType);
- if (!htmlEditor->IsDescendantOfEditorRoot(
- EditorBase::GetNodeAtRangeOffsetPoint(startPoint))) {
+ if (!HTMLEditorRef().IsDescendantOfEditorRoot(
+ EditorBase::GetNodeAtRangeOffsetPoint(startPoint))) {
return;
}
EditorDOMPoint endPoint =
GetPromotedPoint(kEnd, *endNode, endOffset, aOperationType);
EditorRawDOMPoint lastRawPoint(endPoint);
lastRawPoint.RewindOffset();
- if (!htmlEditor->IsDescendantOfEditorRoot(
- EditorBase::GetNodeAtRangeOffsetPoint(lastRawPoint))) {
+ if (!HTMLEditorRef().IsDescendantOfEditorRoot(
+ EditorBase::GetNodeAtRangeOffsetPoint(lastRawPoint))) {
return;
}
DebugOnly<nsresult> rv = aRange.SetStartAndEnd(startPoint, endPoint);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
class UniqueFunctor final : public BoolDomIterFunctor
@@ -6520,34 +6518,33 @@ private:
*/
nsresult
HTMLEditRules::GetNodesForOperation(
nsTArray<RefPtr<nsRange>>& aArrayOfRanges,
nsTArray<OwningNonNull<nsINode>>& aOutArrayOfNodes,
EditAction aOperationType,
TouchContent aTouchContent)
{
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
+ MOZ_ASSERT(IsEditorDataAvailable());
if (aTouchContent == TouchContent::yes) {
// Split text nodes. This is necessary, since GetPromotedPoint() may return a
// range ending in a text node in case where part of a pre-formatted
// elements needs to be moved.
for (RefPtr<nsRange>& range : aArrayOfRanges) {
EditorDOMPoint atEnd(range->EndRef());
if (NS_WARN_IF(!atEnd.IsSet()) || !atEnd.IsInTextNode()) {
continue;
}
if (!atEnd.IsStartOfContainer() && !atEnd.IsEndOfContainer()) {
// Split the text node.
ErrorResult error;
nsCOMPtr<nsIContent> newLeftNode =
- htmlEditor->SplitNodeWithTransaction(atEnd, error);
+ HTMLEditorRef().SplitNodeWithTransaction(atEnd, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
// Correct the range.
// The new end parent becomes the parent node of the text.
// XXX We want nsRange::SetEnd(const RawRangeBoundary&)
EditorRawDOMPoint atContainerOfSplitNode(atEnd.GetContainer());
@@ -6565,42 +6562,42 @@ HTMLEditRules::GetNodesForOperation(
if (aTouchContent == TouchContent::yes) {
nsTArray<OwningNonNull<RangeItem>> rangeItemArray;
rangeItemArray.AppendElements(aArrayOfRanges.Length());
// First register ranges for special editor gravity
for (auto& rangeItem : rangeItemArray) {
rangeItem = new RangeItem();
rangeItem->StoreRange(aArrayOfRanges[0]);
- htmlEditor->mRangeUpdater.RegisterRangeItem(rangeItem);
+ HTMLEditorRef().mRangeUpdater.RegisterRangeItem(rangeItem);
aArrayOfRanges.RemoveElementAt(0);
}
// Now bust up inlines.
- nsresult rv = NS_OK;
for (auto& item : Reversed(rangeItemArray)) {
- rv = BustUpInlinesAtRangeEndpoints(*item);
+ nsresult rv = BustUpInlinesAtRangeEndpoints(*item);
if (NS_FAILED(rv)) {
break;
}
}
// Then unregister the ranges
for (auto& item : rangeItemArray) {
- htmlEditor->mRangeUpdater.DropRangeItem(item);
+ HTMLEditorRef().mRangeUpdater.DropRangeItem(item);
RefPtr<nsRange> range = item->GetRange();
if (range) {
aArrayOfRanges.AppendElement(range);
}
}
- NS_ENSURE_SUCCESS(rv, rv);
}
// Gather up a list of all the nodes
for (auto& range : aArrayOfRanges) {
DOMSubtreeIterator iter;
nsresult rv = iter.Init(*range);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
if (aOutArrayOfNodes.IsEmpty()) {
iter.AppendList(TrivialFunctor(), aOutArrayOfNodes);
} else {
// We don't want duplicates in aOutArrayOfNodes, so we use an
// iterator/functor that only return nodes that are not already in
// aOutArrayOfNodes.
nsTArray<OwningNonNull<nsINode>> nodes;
iter.AppendList(UniqueFunctor(aOutArrayOfNodes), nodes);
@@ -6618,17 +6615,17 @@ HTMLEditRules::GetNodesForOperation(
aOutArrayOfNodes.RemoveElementAt(i);
GetInnerContent(*node, aOutArrayOfNodes, &j);
}
}
// Empty text node shouldn't be selected if unnecessary
for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) {
if (Text* text = aOutArrayOfNodes[i]->GetAsText()) {
// Don't select empty text except to empty block
- if (!htmlEditor->IsVisibleTextNode(*text)) {
+ if (!HTMLEditorRef().IsVisibleTextNode(*text)) {
aOutArrayOfNodes.RemoveElementAt(i);
}
}
}
}
// Indent/outdent already do something special for list items, but we still
// need to make sure we don't act on table elements
else if (aOperationType == EditAction::outdent ||
@@ -6640,17 +6637,17 @@ HTMLEditRules::GetNodesForOperation(
int32_t j = i;
aOutArrayOfNodes.RemoveElementAt(i);
GetInnerContent(*node, aOutArrayOfNodes, &j);
}
}
}
// Outdent should look inside of divs.
if (aOperationType == EditAction::outdent &&
- !htmlEditor->IsCSSEnabled()) {
+ !HTMLEditorRef().IsCSSEnabled()) {
for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) {
OwningNonNull<nsINode> node = aOutArrayOfNodes[i];
if (node->IsHTMLElement(nsGkAtoms::div)) {
int32_t j = i;
aOutArrayOfNodes.RemoveElementAt(i);
GetInnerContent(*node, aOutArrayOfNodes, &j, Lists::no, Tables::no);
}
}
@@ -6663,20 +6660,22 @@ HTMLEditRules::GetNodesForOperation(
aOperationType == EditAction::makeList ||
aOperationType == EditAction::align ||
aOperationType == EditAction::setAbsolutePosition ||
aOperationType == EditAction::indent ||
aOperationType == EditAction::outdent) {
for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) {
OwningNonNull<nsINode> node = aOutArrayOfNodes[i];
if (aTouchContent == TouchContent::yes && IsInlineNode(node) &&
- htmlEditor->IsContainer(node) && !EditorBase::IsTextNode(node)) {
+ HTMLEditorRef().IsContainer(node) && !EditorBase::IsTextNode(node)) {
nsTArray<OwningNonNull<nsINode>> arrayOfInlines;
nsresult rv = BustUpInlinesAtBRs(*node->AsContent(), arrayOfInlines);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
// Put these nodes in aOutArrayOfNodes, replacing the current node
aOutArrayOfNodes.RemoveElementAt(i);
aOutArrayOfNodes.InsertElementsAt(i, arrayOfInlines);
}
}
}
return NS_OK;
@@ -6694,20 +6693,19 @@ HTMLEditRules::GetChildNodesForOperation
}
nsresult
HTMLEditRules::GetListActionNodes(
nsTArray<OwningNonNull<nsINode>>& aOutArrayOfNodes,
EntireList aEntireList,
TouchContent aTouchContent)
{
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
- RefPtr<Selection> selection = htmlEditor->GetSelection();
+ MOZ_ASSERT(IsEditorDataAvailable());
+
+ RefPtr<Selection> selection = HTMLEditorRef().GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
// Added this in so that ui code can ask to change an entire list, even if
// selection is only in part of it. used by list item dialog.
if (aEntireList == EntireList::yes) {
uint32_t rangeCount = selection->RangeCount();
for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
RefPtr<nsRange> range = selection->GetRangeAt(rangeIdx);
@@ -6723,30 +6721,30 @@ HTMLEditRules::GetListActionNodes(
// the selection spans multiple lists but with no common list parent.
if (!aOutArrayOfNodes.IsEmpty()) {
return NS_OK;
}
}
{
// We don't like other people messing with our selection!
- AutoTransactionsConserveSelection dontChangeMySelection(htmlEditor);
+ AutoTransactionsConserveSelection dontChangeMySelection(&HTMLEditorRef());
// contruct a list of nodes to act on.
nsresult rv = GetNodesFromSelection(*selection, EditAction::makeList,
aOutArrayOfNodes, aTouchContent);
NS_ENSURE_SUCCESS(rv, rv);
}
// Pre-process our list of nodes
for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) {
OwningNonNull<nsINode> testNode = aOutArrayOfNodes[i];
// Remove all non-editable nodes. Leave them be.
- if (!htmlEditor->IsEditable(testNode)) {
+ if (!HTMLEditorRef().IsEditable(testNode)) {
aOutArrayOfNodes.RemoveElementAt(i);
continue;
}
// Scan for table elements and divs. If we find table elements other than
// table, replace it with a list of any editable non-table content.
if (HTMLEditUtils::IsTableElementButNotTable(testNode)) {
int32_t j = i;
@@ -6761,32 +6759,31 @@ HTMLEditRules::GetListActionNodes(
return NS_OK;
}
void
HTMLEditRules::LookInsideDivBQandList(
nsTArray<OwningNonNull<nsINode>>& aNodeArray)
{
- NS_ENSURE_TRUE(mHTMLEditor, );
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
+ MOZ_ASSERT(IsEditorDataAvailable());
// If there is only one node in the array, and it is a list, div, or
// blockquote, then look inside of it until we find inner list or content.
if (aNodeArray.Length() != 1) {
return;
}
OwningNonNull<nsINode> curNode = aNodeArray[0];
while (curNode->IsHTMLElement(nsGkAtoms::div) ||
HTMLEditUtils::IsList(curNode) ||
curNode->IsHTMLElement(nsGkAtoms::blockquote)) {
// Dive as long as there's only one child, and it's a list, div, blockquote
- uint32_t numChildren = htmlEditor->CountEditableChildren(curNode);
+ uint32_t numChildren = HTMLEditorRef().CountEditableChildren(curNode);
if (numChildren != 1) {
break;
}
// Keep diving! XXX One would expect to dive into the one editable node.
nsCOMPtr<nsIContent> child = curNode->GetFirstChild();
if (!child->IsHTMLElement(nsGkAtoms::div) &&
!HTMLEditUtils::IsList(child) &&
@@ -6833,33 +6830,32 @@ HTMLEditRules::GetDefinitionListItemType
}
}
nsresult
HTMLEditRules::GetParagraphFormatNodes(
nsTArray<OwningNonNull<nsINode>>& outArrayOfNodes,
TouchContent aTouchContent)
{
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
- RefPtr<Selection> selection = htmlEditor->GetSelection();
+ MOZ_ASSERT(IsEditorDataAvailable());
+
+ RefPtr<Selection> selection = HTMLEditorRef().GetSelection();
NS_ENSURE_STATE(selection);
// Contruct a list of nodes to act on.
nsresult rv = GetNodesFromSelection(*selection, EditAction::makeBasicBlock,
outArrayOfNodes, aTouchContent);
NS_ENSURE_SUCCESS(rv, rv);
// Pre-process our list of nodes
for (int32_t i = outArrayOfNodes.Length() - 1; i >= 0; i--) {
OwningNonNull<nsINode> testNode = outArrayOfNodes[i];
// Remove all non-editable nodes. Leave them be.
- if (!htmlEditor->IsEditable(testNode)) {
+ if (!HTMLEditorRef().IsEditable(testNode)) {
outArrayOfNodes.RemoveElementAt(i);
continue;
}
// Scan for table elements. If we find table elements other than table,
// replace it with a list of any editable non-table content. Ditto for
// list elements.
if (HTMLEditUtils::IsTableElement(testNode) ||
@@ -6871,82 +6867,66 @@ HTMLEditRules::GetParagraphFormatNodes(
}
}
return NS_OK;
}
nsresult
HTMLEditRules::BustUpInlinesAtRangeEndpoints(RangeItem& item)
{
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
+ MOZ_ASSERT(IsEditorDataAvailable());
bool isCollapsed = item.mStartContainer == item.mEndContainer &&
item.mStartOffset == item.mEndOffset;
nsCOMPtr<nsIContent> endInline = GetHighestInlineParent(*item.mEndContainer);
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_FAILURE;
- }
// XXX Oh, then, if the range is collapsed, we don't need to call
// GetHighestInlineParent(), isn't it?
if (endInline && !isCollapsed) {
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
SplitNodeResult splitEndInlineResult =
- htmlEditor->SplitNodeDeepWithTransaction(
- *endInline,
- EditorRawDOMPoint(item.mEndContainer, item.mEndOffset),
- SplitAtEdges::eDoNotCreateEmptyContainer);
+ HTMLEditorRef().SplitNodeDeepWithTransaction(
+ *endInline,
+ EditorRawDOMPoint(item.mEndContainer, item.mEndOffset),
+ SplitAtEdges::eDoNotCreateEmptyContainer);
if (NS_WARN_IF(splitEndInlineResult.Failed())) {
return splitEndInlineResult.Rv();
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_FAILURE;
- }
EditorRawDOMPoint splitPointAtEnd(splitEndInlineResult.SplitPoint());
item.mEndContainer = splitPointAtEnd.GetContainer();
item.mEndOffset = splitPointAtEnd.Offset();
}
nsCOMPtr<nsIContent> startInline =
GetHighestInlineParent(*item.mStartContainer);
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_FAILURE;
- }
if (startInline) {
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
SplitNodeResult splitStartInlineResult =
- htmlEditor->SplitNodeDeepWithTransaction(
- *startInline,
- EditorRawDOMPoint(item.mStartContainer, item.mStartOffset),
- SplitAtEdges::eDoNotCreateEmptyContainer);
+ HTMLEditorRef().SplitNodeDeepWithTransaction(
+ *startInline,
+ EditorRawDOMPoint(item.mStartContainer,
+ item.mStartOffset),
+ SplitAtEdges::eDoNotCreateEmptyContainer);
if (NS_WARN_IF(splitStartInlineResult.Failed())) {
return splitStartInlineResult.Rv();
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_FAILURE;
- }
EditorRawDOMPoint splitPointAtStart(splitStartInlineResult.SplitPoint());
item.mStartContainer = splitPointAtStart.GetContainer();
item.mStartOffset = splitPointAtStart.Offset();
}
return NS_OK;
}
nsresult
HTMLEditRules::BustUpInlinesAtBRs(
nsIContent& aNode,
nsTArray<OwningNonNull<nsINode>>& aOutArrayOfNodes)
{
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
+ MOZ_ASSERT(IsEditorDataAvailable());
// First build up a list of all the break nodes inside the inline container.
nsTArray<OwningNonNull<nsINode>> arrayOfBreaks;
BRNodeFunctor functor;
DOMIterator iter(aNode);
iter.AppendList(functor, arrayOfBreaks);
// If there aren't any breaks, just put inNode itself in the array
@@ -6958,35 +6938,35 @@ HTMLEditRules::BustUpInlinesAtBRs(
// Else we need to bust up aNode along all the breaks
nsCOMPtr<nsIContent> nextNode = &aNode;
for (OwningNonNull<nsINode>& brNode : arrayOfBreaks) {
EditorRawDOMPoint atBrNode(brNode);
if (NS_WARN_IF(!atBrNode.IsSet())) {
return NS_ERROR_FAILURE;
}
SplitNodeResult splitNodeResult =
- htmlEditor->SplitNodeDeepWithTransaction(
- *nextNode, atBrNode,
- SplitAtEdges::eAllowToCreateEmptyContainer);
+ HTMLEditorRef().SplitNodeDeepWithTransaction(
+ *nextNode, atBrNode,
+ SplitAtEdges::eAllowToCreateEmptyContainer);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
// Put previous node at the split point.
if (splitNodeResult.GetPreviousNode()) {
// Might not be a left node. A break might have been at the very
// beginning of inline container, in which case
// SplitNodeDeepWithTransaction() would not actually split anything.
aOutArrayOfNodes.AppendElement(*splitNodeResult.GetPreviousNode());
}
// Move break outside of container and also put in node list
EditorRawDOMPoint atNextNode(splitNodeResult.GetNextNode());
nsresult rv =
- htmlEditor->MoveNodeWithTransaction(*brNode->AsContent(), atNextNode);
+ HTMLEditorRef().MoveNodeWithTransaction(*brNode->AsContent(), atNextNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
aOutArrayOfNodes.AppendElement(*brNode);
nextNode = splitNodeResult.GetNextNode();
}
@@ -6994,25 +6974,23 @@ HTMLEditRules::BustUpInlinesAtBRs(
aOutArrayOfNodes.AppendElement(*nextNode);
return NS_OK;
}
nsIContent*
HTMLEditRules::GetHighestInlineParent(nsINode& aNode)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (!aNode.IsContent() || IsBlockNode(aNode)) {
return nullptr;
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return nullptr;
- }
-
- Element* host = mHTMLEditor->GetActiveEditingHost();
+ Element* host = HTMLEditorRef().GetActiveEditingHost();
if (NS_WARN_IF(!host)) {
return nullptr;
}
// If aNode is the editing host itself, there is no modifiable inline parent.
if (&aNode == host) {
return nullptr;
}
@@ -7125,126 +7103,129 @@ HTMLEditRules::MakeTransitionList(nsTArr
/**
* 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.
*/
Element*
HTMLEditRules::IsInListItem(nsINode* aNode)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
NS_ENSURE_TRUE(aNode, nullptr);
if (HTMLEditUtils::IsListItem(aNode)) {
return aNode->AsElement();
}
Element* parent = aNode->GetParentElement();
while (parent &&
- mHTMLEditor && mHTMLEditor->IsDescendantOfEditorRoot(parent) &&
+ HTMLEditorRef().IsDescendantOfEditorRoot(parent) &&
!HTMLEditUtils::IsTableElement(parent)) {
if (HTMLEditUtils::IsListItem(parent)) {
return parent;
}
parent = parent->GetParentElement();
}
return nullptr;
}
nsAtom&
HTMLEditRules::DefaultParagraphSeparator()
{
- MOZ_ASSERT(mHTMLEditor);
- if (!mHTMLEditor) {
- return *nsGkAtoms::div;
- }
- return ParagraphSeparatorElement(mHTMLEditor->GetDefaultParagraphSeparator());
+ MOZ_ASSERT(IsEditorDataAvailable());
+ return ParagraphSeparatorElement(
+ HTMLEditorRef().GetDefaultParagraphSeparator());
}
/**
* ReturnInHeader: do the right thing for returns pressed in headers
*/
nsresult
HTMLEditRules::ReturnInHeader(Selection& aSelection,
Element& aHeader,
nsINode& aNode,
int32_t aOffset)
{
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
+ MOZ_ASSERT(IsEditorDataAvailable());
// Remember where the header is
nsCOMPtr<nsINode> headerParent = aHeader.GetParentNode();
int32_t offset = headerParent ? headerParent->ComputeIndexOf(&aHeader) : -1;
// Get ws code to adjust any ws
nsCOMPtr<nsINode> node = &aNode;
- nsresult rv = WSRunObject::PrepareToSplitAcrossBlocks(htmlEditor,
+ nsresult rv = WSRunObject::PrepareToSplitAcrossBlocks(&HTMLEditorRef(),
address_of(node),
&aOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
if (NS_WARN_IF(!node->IsContent())) {
return NS_ERROR_FAILURE;
}
// Split the header
ErrorResult error;
SplitNodeResult splitHeaderResult =
- htmlEditor->SplitNodeDeepWithTransaction(
- aHeader, EditorRawDOMPoint(node, aOffset),
- SplitAtEdges::eAllowToCreateEmptyContainer);
+ HTMLEditorRef().SplitNodeDeepWithTransaction(
+ aHeader, EditorRawDOMPoint(node, aOffset),
+ SplitAtEdges::eAllowToCreateEmptyContainer);
NS_WARNING_ASSERTION(splitHeaderResult.Succeeded(),
"Failed to split aHeader");
// If the previous heading of split point is empty, put a mozbr into it.
- nsCOMPtr<nsIContent> prevItem = htmlEditor->GetPriorHTMLSibling(&aHeader);
+ nsCOMPtr<nsIContent> prevItem = HTMLEditorRef().GetPriorHTMLSibling(&aHeader);
if (prevItem) {
MOZ_DIAGNOSTIC_ASSERT(
HTMLEditUtils::IsHeader(*prevItem));
bool isEmptyNode;
- rv = htmlEditor->IsEmptyNode(prevItem, &isEmptyNode);
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = HTMLEditorRef().IsEmptyNode(prevItem, &isEmptyNode);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
if (isEmptyNode) {
RefPtr<Element> brElement = CreateMozBR(EditorRawDOMPoint(prevItem, 0));
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
}
}
// If the new (righthand) header node is empty, delete it
if (IsEmptyBlockElement(aHeader, IgnoreSingleBR::eYes)) {
- rv = htmlEditor->DeleteNodeWithTransaction(aHeader);
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(aHeader);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Layout tells the caret to blink in a weird place if we don't place a
// break after the header.
nsCOMPtr<nsIContent> sibling;
if (aHeader.GetNextSibling()) {
- sibling = htmlEditor->GetNextHTMLSibling(aHeader.GetNextSibling());
+ sibling = HTMLEditorRef().GetNextHTMLSibling(aHeader.GetNextSibling());
}
if (!sibling || !sibling->IsHTMLElement(nsGkAtoms::br)) {
ClearCachedStyles();
- htmlEditor->mTypeInState->ClearAllProps();
+ HTMLEditorRef().mTypeInState->ClearAllProps();
// Create a paragraph
nsAtom& paraAtom = DefaultParagraphSeparator();
// We want a wrapper element even if we separate with <br>
EditorRawDOMPoint nextToHeader(headerParent, offset + 1);
RefPtr<Element> pNode =
- htmlEditor->CreateNodeWithTransaction(¶Atom == nsGkAtoms::br ?
- *nsGkAtoms::p : paraAtom,
- nextToHeader);
+ HTMLEditorRef().CreateNodeWithTransaction(¶Atom == nsGkAtoms::br ?
+ *nsGkAtoms::p : paraAtom,
+ nextToHeader);
if (NS_WARN_IF(!pNode)) {
return NS_ERROR_FAILURE;
}
// Append a <br> to it
RefPtr<Element> brElement =
- htmlEditor->InsertBrElementWithTransaction(aSelection,
- EditorRawDOMPoint(pNode, 0));
+ HTMLEditorRef().InsertBrElementWithTransaction(
+ aSelection, EditorRawDOMPoint(pNode, 0));
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
// Set selection to before the break
ErrorResult error;
aSelection.Collapse(EditorRawDOMPoint(pNode, 0), error);
if (NS_WARN_IF(error.Failed())) {
@@ -7266,21 +7247,17 @@ HTMLEditRules::ReturnInHeader(Selection&
}
return NS_OK;
}
EditActionResult
HTMLEditRules::ReturnInParagraph(Selection& aSelection,
Element& aParentDivOrP)
{
- if (NS_WARN_IF(!mHTMLEditor)) {
- return EditActionResult(NS_ERROR_NOT_AVAILABLE);
- }
-
- RefPtr<HTMLEditor> htmlEditor = mHTMLEditor;
+ MOZ_ASSERT(IsEditorDataAvailable());
nsRange* firstRange = aSelection.GetRangeAt(0);
if (NS_WARN_IF(!firstRange)) {
return EditActionResult(NS_ERROR_FAILURE);
}
EditorDOMPoint atStartOfSelection(firstRange->StartRef());
if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
@@ -7348,59 +7325,61 @@ HTMLEditRules::ReturnInParagraph(Selecti
if (!nextSibling->IsHTMLElement(nsGkAtoms::br)) {
break;
}
foundBRElement = true;
}
}
}
- bool doesCRCreateNewP = htmlEditor->GetReturnInParagraphCreatesNewParagraph();
+ bool doesCRCreateNewP =
+ HTMLEditorRef().GetReturnInParagraphCreatesNewParagraph();
bool splitAfterNewBR = false;
nsCOMPtr<nsIContent> brContent;
EditorDOMPoint pointToSplitParentDivOrP(atStartOfSelection);
EditorRawDOMPoint pointToInsertBR;
if (doesCRCreateNewP &&
atStartOfSelection.GetContainer() == &aParentDivOrP) {
// We are at the edges of the block, so, we don't need to create new <br>.
brContent = nullptr;
} else if (atStartOfSelection.IsInTextNode()) {
// at beginning of text node?
if (atStartOfSelection.IsStartOfContainer()) {
// is there a BR prior to it?
brContent =
- htmlEditor->GetPriorHTMLSibling(atStartOfSelection.GetContainer());
+ HTMLEditorRef().GetPriorHTMLSibling(atStartOfSelection.GetContainer());
if (!brContent ||
- !htmlEditor->IsVisibleBRElement(brContent) ||
+ !HTMLEditorRef().IsVisibleBRElement(brContent) ||
TextEditUtils::HasMozAttr(brContent)) {
pointToInsertBR.Set(atStartOfSelection.GetContainer());
brContent = nullptr;
}
} else if (atStartOfSelection.IsEndOfContainer()) {
// we're at the end of text node...
// is there a BR after to it?
brContent =
- htmlEditor->GetNextHTMLSibling(atStartOfSelection.GetContainer());
+ HTMLEditorRef().GetNextHTMLSibling(atStartOfSelection.GetContainer());
if (!brContent ||
- !htmlEditor->IsVisibleBRElement(brContent) ||
+ !HTMLEditorRef().IsVisibleBRElement(brContent) ||
TextEditUtils::HasMozAttr(brContent)) {
pointToInsertBR.Set(atStartOfSelection.GetContainer());
DebugOnly<bool> advanced = pointToInsertBR.AdvanceOffset();
NS_WARNING_ASSERTION(advanced,
"Failed to advance offset to after the container of selection start");
brContent = nullptr;
}
} else {
if (doesCRCreateNewP) {
ErrorResult error;
nsCOMPtr<nsIContent> newLeftDivOrP =
- htmlEditor->SplitNodeWithTransaction(pointToSplitParentDivOrP, error);
+ HTMLEditorRef().SplitNodeWithTransaction(pointToSplitParentDivOrP,
+ error);
if (NS_WARN_IF(error.Failed())) {
return EditActionResult(error.StealNSResult());
}
pointToSplitParentDivOrP.SetToEndOf(newLeftDivOrP);
}
// We need to put new <br> after the left node if given node was split
// above.
@@ -7408,46 +7387,45 @@ HTMLEditRules::ReturnInParagraph(Selecti
DebugOnly<bool> advanced = pointToInsertBR.AdvanceOffset();
NS_WARNING_ASSERTION(advanced,
"Failed to advance offset to after the container of selection start");
}
} else {
// not in a text node.
// is there a BR prior to it?
nsCOMPtr<nsIContent> nearNode;
- nearNode =
- htmlEditor->GetPreviousEditableHTMLNode(atStartOfSelection);
- if (!nearNode || !htmlEditor->IsVisibleBRElement(nearNode) ||
+ nearNode = HTMLEditorRef().GetPreviousEditableHTMLNode(atStartOfSelection);
+ if (!nearNode || !HTMLEditorRef().IsVisibleBRElement(nearNode) ||
TextEditUtils::HasMozAttr(nearNode)) {
// is there a BR after it?
- nearNode =
- htmlEditor->GetNextEditableHTMLNode(atStartOfSelection);
- if (!nearNode || !htmlEditor->IsVisibleBRElement(nearNode) ||
+ nearNode = HTMLEditorRef().GetNextEditableHTMLNode(atStartOfSelection);
+ if (!nearNode || !HTMLEditorRef().IsVisibleBRElement(nearNode) ||
TextEditUtils::HasMozAttr(nearNode)) {
pointToInsertBR = atStartOfSelection;
splitAfterNewBR = true;
}
}
if (!pointToInsertBR.IsSet() && TextEditUtils::IsBreak(nearNode)) {
brContent = nearNode;
}
}
if (pointToInsertBR.IsSet()) {
- // Don't modify the DOM tree if mHTMLEditor disappeared.
- if (NS_WARN_IF(!mHTMLEditor)) {
+ // Don't modify the DOM tree if HTMLEditor is destroyed.
+ if (NS_WARN_IF(HTMLEditorRef().Destroyed())) {
return EditActionResult(NS_ERROR_NOT_AVAILABLE);
}
// if CR does not create a new P, default to BR creation
if (NS_WARN_IF(!doesCRCreateNewP)) {
return EditActionResult(NS_OK);
}
brContent =
- htmlEditor->InsertBrElementWithTransaction(aSelection, pointToInsertBR);
+ HTMLEditorRef().InsertBrElementWithTransaction(aSelection,
+ pointToInsertBR);
NS_WARNING_ASSERTION(brContent, "Failed to create a <br> element");
if (splitAfterNewBR) {
// We split the parent after the br we've just inserted.
pointToSplitParentDivOrP.Set(brContent);
DebugOnly<bool> advanced = pointToSplitParentDivOrP.AdvanceOffset();
NS_WARNING_ASSERTION(advanced,
"Failed to advance offset after the new <br>");
}
@@ -7465,76 +7443,76 @@ HTMLEditRules::ReturnInParagraph(Selecti
template<typename PT, typename CT>
nsresult
HTMLEditRules::SplitParagraph(
Selection& aSelection,
Element& aParentDivOrP,
const EditorDOMPointBase<PT, CT>& aStartOfRightNode,
nsIContent* aNextBRNode)
{
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
-
- RefPtr<HTMLEditor> htmlEditor = mHTMLEditor;
+ MOZ_ASSERT(IsEditorDataAvailable());
// split para
// get ws code to adjust any ws
nsCOMPtr<nsINode> selNode = aStartOfRightNode.GetContainer();
int32_t selOffset = aStartOfRightNode.Offset();
nsresult rv =
- WSRunObject::PrepareToSplitAcrossBlocks(htmlEditor,
+ WSRunObject::PrepareToSplitAcrossBlocks(&HTMLEditorRef(),
address_of(selNode), &selOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
if (NS_WARN_IF(!selNode->IsContent())) {
return NS_ERROR_FAILURE;
}
// Split the paragraph.
SplitNodeResult splitDivOrPResult =
- htmlEditor->SplitNodeDeepWithTransaction(
- aParentDivOrP,
- EditorRawDOMPoint(selNode, selOffset),
- SplitAtEdges::eAllowToCreateEmptyContainer);
+ HTMLEditorRef().SplitNodeDeepWithTransaction(
+ aParentDivOrP,
+ EditorRawDOMPoint(selNode, selOffset),
+ SplitAtEdges::eAllowToCreateEmptyContainer);
if (NS_WARN_IF(splitDivOrPResult.Failed())) {
return splitDivOrPResult.Rv();
}
if (NS_WARN_IF(!splitDivOrPResult.DidSplit())) {
return NS_ERROR_FAILURE;
}
// Get rid of the break, if it is visible (otherwise it may be needed to
// prevent an empty p).
- if (aNextBRNode && htmlEditor->IsVisibleBRElement(aNextBRNode)) {
- rv = htmlEditor->DeleteNodeWithTransaction(*aNextBRNode);
+ if (aNextBRNode && HTMLEditorRef().IsVisibleBRElement(aNextBRNode)) {
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*aNextBRNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
// Remove ID attribute on the paragraph from the existing right node.
- rv = htmlEditor->RemoveAttributeWithTransaction(aParentDivOrP,
- *nsGkAtoms::id);
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = HTMLEditorRef().RemoveAttributeWithTransaction(aParentDivOrP,
+ *nsGkAtoms::id);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
// We need to ensure to both paragraphs visible even if they are empty.
// However, moz-<br> element isn't useful in this case because moz-<br>
// elements will be ignored by PlaintextSerializer. Additionally,
// moz-<br> will be exposed as <br> with Element.innerHTML. Therefore,
// we can use normal <br> elements for placeholder in this case.
// Note that Chromium also behaves so.
rv = InsertBRIfNeeded(*splitDivOrPResult.GetPreviousNode());
NS_ENSURE_SUCCESS(rv, rv);
rv = InsertBRIfNeeded(*splitDivOrPResult.GetNextNode());
NS_ENSURE_SUCCESS(rv, rv);
// selection to beginning of right hand para;
// look inside any containers that are up front.
- nsIContent* child = htmlEditor->GetLeftmostChild(&aParentDivOrP, true);
- if (EditorBase::IsTextNode(child) || htmlEditor->IsContainer(child)) {
+ nsIContent* child = HTMLEditorRef().GetLeftmostChild(&aParentDivOrP, true);
+ if (EditorBase::IsTextNode(child) || HTMLEditorRef().IsContainer(child)) {
EditorRawDOMPoint atStartOfChild(child, 0);
ErrorResult error;
aSelection.Collapse(atStartOfChild, error);
if (NS_WARN_IF(error.Failed())) {
error.SuppressException();
}
} else {
EditorRawDOMPoint atChild(child);
@@ -7551,87 +7529,86 @@ HTMLEditRules::SplitParagraph(
* ReturnInListItem: do the right thing for returns pressed in list items
*/
nsresult
HTMLEditRules::ReturnInListItem(Selection& aSelection,
Element& aListItem,
nsINode& aNode,
int32_t aOffset)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
MOZ_ASSERT(HTMLEditUtils::IsListItem(&aListItem));
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
// Get the item parent and the active editing host.
- nsCOMPtr<Element> root = htmlEditor->GetActiveEditingHost();
+ RefPtr<Element> host = HTMLEditorRef().GetActiveEditingHost();
// If we are in an empty item, then we want to pop up out of the list, but
// only if prefs say it's okay and if the parent isn't the active editing
// host.
if (mReturnInEmptyLIKillsList &&
- root != aListItem.GetParentElement() &&
+ host != aListItem.GetParentElement() &&
IsEmptyBlockElement(aListItem, IgnoreSingleBR::eYes)) {
nsCOMPtr<nsIContent> leftListNode = aListItem.GetParent();
// Are we the last list item in the list?
- if (!htmlEditor->IsLastEditableChild(&aListItem)) {
+ if (!HTMLEditorRef().IsLastEditableChild(&aListItem)) {
// We need to split the list!
EditorRawDOMPoint atListItem(&aListItem);
ErrorResult error;
- leftListNode = htmlEditor->SplitNodeWithTransaction(atListItem, error);
+ leftListNode =
+ HTMLEditorRef().SplitNodeWithTransaction(atListItem, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
}
// Are we in a sublist?
EditorRawDOMPoint atNextSiblingOfLeftList(leftListNode);
DebugOnly<bool> advanced = atNextSiblingOfLeftList.AdvanceOffset();
NS_WARNING_ASSERTION(advanced,
"Failed to advance offset after the right list node");
if (HTMLEditUtils::IsList(atNextSiblingOfLeftList.GetContainer())) {
// If so, move item out of this list and into the grandparent list
nsresult rv =
- htmlEditor->MoveNodeWithTransaction(aListItem,
- atNextSiblingOfLeftList);
+ HTMLEditorRef().MoveNodeWithTransaction(aListItem,
+ atNextSiblingOfLeftList);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
ErrorResult error;
aSelection.Collapse(RawRangeBoundary(&aListItem, 0), error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
} else {
// Otherwise kill this item
- nsresult rv = htmlEditor->DeleteNodeWithTransaction(aListItem);
+ nsresult rv = HTMLEditorRef().DeleteNodeWithTransaction(aListItem);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Time to insert a paragraph
nsAtom& paraAtom = DefaultParagraphSeparator();
// We want a wrapper even if we separate with <br>
RefPtr<Element> pNode =
- htmlEditor->CreateNodeWithTransaction(¶Atom == nsGkAtoms::br ?
- *nsGkAtoms::p : paraAtom,
- atNextSiblingOfLeftList);
+ HTMLEditorRef().CreateNodeWithTransaction(¶Atom == nsGkAtoms::br ?
+ *nsGkAtoms::p : paraAtom,
+ atNextSiblingOfLeftList);
if (NS_WARN_IF(!pNode)) {
return NS_ERROR_FAILURE;
}
- RefPtr<Selection> selection = htmlEditor->GetSelection();
+ RefPtr<Selection> selection = HTMLEditorRef().GetSelection();
if (NS_WARN_IF(!selection)) {
return NS_ERROR_FAILURE;
}
// Append a <br> to it
RefPtr<Element> brElement =
- htmlEditor->InsertBrElementWithTransaction(*selection,
- EditorRawDOMPoint(pNode, 0));
+ HTMLEditorRef().InsertBrElementWithTransaction(
+ *selection, EditorRawDOMPoint(pNode, 0));
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
// Set selection to before the break
ErrorResult error;
aSelection.Collapse(EditorRawDOMPoint(pNode, 0), error);
if (NS_WARN_IF(error.Failed())) {
@@ -7640,97 +7617,105 @@ HTMLEditRules::ReturnInListItem(Selectio
}
return NS_OK;
}
// Else we want a new list item at the same list level. Get ws code to
// adjust any ws.
nsCOMPtr<nsINode> selNode = &aNode;
nsresult rv =
- WSRunObject::PrepareToSplitAcrossBlocks(htmlEditor,
+ WSRunObject::PrepareToSplitAcrossBlocks(&HTMLEditorRef(),
address_of(selNode), &aOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
if (NS_WARN_IF(!selNode->IsContent())) {
return NS_ERROR_FAILURE;
}
// Now split the list item.
SplitNodeResult splitListItemResult =
- htmlEditor->SplitNodeDeepWithTransaction(
- aListItem, EditorRawDOMPoint(selNode, aOffset),
- SplitAtEdges::eAllowToCreateEmptyContainer);
+ HTMLEditorRef().SplitNodeDeepWithTransaction(
+ aListItem, EditorRawDOMPoint(selNode, aOffset),
+ SplitAtEdges::eAllowToCreateEmptyContainer);
NS_WARNING_ASSERTION(splitListItemResult.Succeeded(),
"Failed to split the list item");
// Hack: until I can change the damaged doc range code back to being
// extra-inclusive, I have to manually detect certain list items that may be
// left empty.
- nsCOMPtr<nsIContent> prevItem = htmlEditor->GetPriorHTMLSibling(&aListItem);
+ nsCOMPtr<nsIContent> prevItem =
+ HTMLEditorRef().GetPriorHTMLSibling(&aListItem);
if (prevItem && HTMLEditUtils::IsListItem(prevItem)) {
bool isEmptyNode;
- rv = htmlEditor->IsEmptyNode(prevItem, &isEmptyNode);
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = HTMLEditorRef().IsEmptyNode(prevItem, &isEmptyNode);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
if (isEmptyNode) {
RefPtr<Element> brElement = CreateMozBR(EditorRawDOMPoint(prevItem, 0));
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
} else {
- rv = htmlEditor->IsEmptyNode(&aListItem, &isEmptyNode, true);
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = HTMLEditorRef().IsEmptyNode(&aListItem, &isEmptyNode, true);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
if (isEmptyNode) {
RefPtr<nsAtom> nodeAtom = aListItem.NodeInfo()->NameAtom();
if (nodeAtom == nsGkAtoms::dd || nodeAtom == nsGkAtoms::dt) {
nsCOMPtr<nsINode> list = aListItem.GetParentNode();
int32_t itemOffset = list ? list->ComputeIndexOf(&aListItem) : -1;
nsAtom* listAtom = nodeAtom == nsGkAtoms::dt ? nsGkAtoms::dd
: nsGkAtoms::dt;
MOZ_DIAGNOSTIC_ASSERT(itemOffset != -1);
EditorRawDOMPoint atNextListItem(list, aListItem.GetNextSibling(),
itemOffset + 1);
RefPtr<Element> newListItem =
- htmlEditor->CreateNodeWithTransaction(*listAtom, atNextListItem);
+ HTMLEditorRef().CreateNodeWithTransaction(*listAtom,
+ atNextListItem);
if (NS_WARN_IF(!newListItem)) {
return NS_ERROR_FAILURE;
}
- rv = htmlEditor->DeleteNodeWithTransaction(aListItem);
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(aListItem);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
ErrorResult error;
aSelection.Collapse(EditorRawDOMPoint(newListItem, 0), error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
return NS_OK;
}
RefPtr<Element> brElement;
nsresult rv =
- htmlEditor->CopyLastEditableChildStylesWithTransaction(
- *prevItem->AsElement(), aListItem,
- address_of(brElement));
+ HTMLEditorRef().CopyLastEditableChildStylesWithTransaction(
+ *prevItem->AsElement(), aListItem,
+ address_of(brElement));
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_FAILURE;
}
if (brElement) {
EditorRawDOMPoint atBrNode(brElement);
if (NS_WARN_IF(!atBrNode.IsSetAndValid())) {
return NS_ERROR_FAILURE;
}
ErrorResult error;
aSelection.Collapse(atBrNode, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
return NS_OK;
}
} else {
- WSRunObject wsObj(htmlEditor, &aListItem, 0);
+ WSRunObject wsObj(&HTMLEditorRef(), &aListItem, 0);
nsCOMPtr<nsINode> visNode;
int32_t visOffset = 0;
WSType wsType;
wsObj.NextVisibleNode(EditorRawDOMPoint(&aListItem, 0),
address_of(visNode), &visOffset, &wsType);
if (wsType == WSType::special || wsType == WSType::br ||
visNode->IsHTMLElement(nsGkAtoms::hr)) {
EditorRawDOMPoint atVisNode(visNode);
@@ -7761,20 +7746,17 @@ HTMLEditRules::ReturnInListItem(Selectio
}
/**
* MakeBlockquote() puts the list of nodes into one or more blockquotes.
*/
nsresult
HTMLEditRules::MakeBlockquote(nsTArray<OwningNonNull<nsINode>>& aNodeArray)
{
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
+ MOZ_ASSERT(IsEditorDataAvailable());
// The idea here is to put the nodes into a minimal number of blockquotes.
// When the user blockquotes something, they expect one blockquote. That may
// not be possible (for instance, if they have two table cells selected, you
// need two blockquotes inside the cells).
nsCOMPtr<Element> curBlock;
nsCOMPtr<nsINode> prevParent;
@@ -7811,171 +7793,184 @@ HTMLEditRules::MakeBlockquote(nsTArray<O
EditorDOMPoint atCurNode(curNode);
SplitNodeResult splitNodeResult =
MaybeSplitAncestorsForInsertWithTransaction(*nsGkAtoms::blockquote,
atCurNode);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
curBlock =
- htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::blockquote,
- splitNodeResult.SplitPoint());
+ HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::blockquote,
+ splitNodeResult.SplitPoint());
if (NS_WARN_IF(!curBlock)) {
return NS_ERROR_FAILURE;
}
// remember our new block for postprocessing
mNewBlock = curBlock;
// note: doesn't matter if we set mNewBlock multiple times.
}
nsresult rv =
- htmlEditor->MoveNodeToEndWithTransaction(*curNode->AsContent(),
- *curBlock);
+ HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(),
+ *curBlock);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
return NS_OK;
}
/**
* RemoveBlockStyle() makes the nodes have no special block type.
*/
nsresult
HTMLEditRules::RemoveBlockStyle(nsTArray<OwningNonNull<nsINode>>& aNodeArray)
{
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
+ MOZ_ASSERT(IsEditorDataAvailable());
// Intent of this routine is to be used for converting to/from headers,
// paragraphs, pre, and address. Those blocks that pretty much just contain
// inline things...
nsCOMPtr<Element> curBlock;
nsCOMPtr<nsIContent> firstNode, lastNode;
for (auto& curNode : aNodeArray) {
// If curNode is a address, p, header, address, or pre, remove it
if (HTMLEditUtils::IsFormatNode(curNode)) {
// Process any partial progress saved
if (curBlock) {
nsresult rv = RemovePartOfBlock(*curBlock, *firstNode, *lastNode);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
firstNode = lastNode = curBlock = nullptr;
}
- if (!mHTMLEditor->IsEditable(curNode)) {
+ if (!HTMLEditorRef().IsEditable(curNode)) {
continue;
}
// Remove current block
nsresult rv =
- htmlEditor->RemoveBlockContainerWithTransaction(*curNode->AsElement());
- NS_ENSURE_SUCCESS(rv, rv);
+ HTMLEditorRef().RemoveBlockContainerWithTransaction(
+ *curNode->AsElement());
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
} else if (curNode->IsAnyOfHTMLElements(nsGkAtoms::table,
nsGkAtoms::tr,
nsGkAtoms::tbody,
nsGkAtoms::td,
nsGkAtoms::li,
nsGkAtoms::blockquote,
nsGkAtoms::div) ||
HTMLEditUtils::IsList(curNode)) {
// Process any partial progress saved
if (curBlock) {
nsresult rv = RemovePartOfBlock(*curBlock, *firstNode, *lastNode);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
firstNode = lastNode = curBlock = nullptr;
}
- if (!mHTMLEditor->IsEditable(curNode)) {
+ if (!HTMLEditorRef().IsEditable(curNode)) {
continue;
}
// Recursion time
nsTArray<OwningNonNull<nsINode>> childArray;
GetChildNodesForOperation(*curNode, childArray);
nsresult rv = RemoveBlockStyle(childArray);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
} else if (IsInlineNode(curNode)) {
if (curBlock) {
// If so, is this node a descendant?
if (EditorUtils::IsDescendantOf(*curNode, *curBlock)) {
// Then we don't need to do anything different for this node
lastNode = curNode->AsContent();
continue;
}
// Otherwise, we have progressed beyond end of curBlock, so let's
// handle it now. We need to remove the portion of curBlock that
// contains [firstNode - lastNode].
nsresult rv = RemovePartOfBlock(*curBlock, *firstNode, *lastNode);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
firstNode = lastNode = curBlock = nullptr;
// Fall out and handle curNode
}
- curBlock = htmlEditor->GetBlockNodeParent(curNode);
+ curBlock = HTMLEditorRef().GetBlockNodeParent(curNode);
if (!curBlock || !HTMLEditUtils::IsFormatNode(curBlock) ||
- !mHTMLEditor->IsEditable(curBlock)) {
+ !HTMLEditorRef().IsEditable(curBlock)) {
// Not a block kind that we care about.
curBlock = nullptr;
} else {
firstNode = lastNode = curNode->AsContent();
}
} else if (curBlock) {
// Some node that is already sans block style. Skip over it and process
// any partial progress saved.
nsresult rv = RemovePartOfBlock(*curBlock, *firstNode, *lastNode);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
firstNode = lastNode = curBlock = nullptr;
}
}
// Process any partial progress saved
if (curBlock) {
nsresult rv = RemovePartOfBlock(*curBlock, *firstNode, *lastNode);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
firstNode = lastNode = curBlock = nullptr;
}
return NS_OK;
}
/**
* ApplyBlockStyle() does whatever it takes to make the list of nodes into one
* or more blocks of type aBlockTag.
*/
nsresult
HTMLEditRules::ApplyBlockStyle(nsTArray<OwningNonNull<nsINode>>& aNodeArray,
nsAtom& aBlockTag)
{
// Intent of this routine is to be used for converting to/from headers,
// paragraphs, pre, and address. Those blocks that pretty much just contain
// inline things...
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
+ MOZ_ASSERT(IsEditorDataAvailable());
nsCOMPtr<Element> newBlock;
nsCOMPtr<Element> curBlock;
for (auto& curNode : aNodeArray) {
EditorDOMPoint atCurNode(curNode);
// Is it already the right kind of block, or an uneditable block?
if (curNode->IsHTMLElement(&aBlockTag) ||
- (!mHTMLEditor->IsEditable(curNode) && IsBlockNode(curNode))) {
+ (!HTMLEditorRef().IsEditable(curNode) && IsBlockNode(curNode))) {
// Forget any previous block used for previous inline nodes
curBlock = nullptr;
// Do nothing to this block
continue;
}
// If curNode is a address, p, header, address, or pre, replace it with a
// new block of correct type.
// XXX: pre can't hold everything the others can
if (HTMLEditUtils::IsMozDiv(curNode) ||
HTMLEditUtils::IsFormatNode(curNode)) {
// Forget any previous block used for previous inline nodes
curBlock = nullptr;
newBlock =
- htmlEditor->ReplaceContainerAndCloneAttributesWithTransaction(
- *curNode->AsElement(), aBlockTag);
- NS_ENSURE_STATE(newBlock);
+ HTMLEditorRef().ReplaceContainerAndCloneAttributesWithTransaction(
+ *curNode->AsElement(), aBlockTag);
+ if (NS_WARN_IF(!newBlock)) {
+ return NS_ERROR_FAILURE;
+ }
continue;
}
if (HTMLEditUtils::IsTable(curNode) ||
HTMLEditUtils::IsList(curNode) ||
curNode->IsAnyOfHTMLElements(nsGkAtoms::tbody,
nsGkAtoms::tr,
nsGkAtoms::td,
@@ -7984,100 +7979,103 @@ HTMLEditRules::ApplyBlockStyle(nsTArray<
nsGkAtoms::div)) {
// Forget any previous block used for previous inline nodes
curBlock = nullptr;
// Recursion time
nsTArray<OwningNonNull<nsINode>> childArray;
GetChildNodesForOperation(*curNode, childArray);
if (!childArray.IsEmpty()) {
nsresult rv = ApplyBlockStyle(childArray, aBlockTag);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
continue;
}
// Make sure we can put a block here
SplitNodeResult splitNodeResult =
MaybeSplitAncestorsForInsertWithTransaction(aBlockTag, atCurNode);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
RefPtr<Element> theBlock =
- htmlEditor->CreateNodeWithTransaction(aBlockTag,
- splitNodeResult.SplitPoint());
+ HTMLEditorRef().CreateNodeWithTransaction(aBlockTag,
+ splitNodeResult.SplitPoint());
if (NS_WARN_IF(!theBlock)) {
return NS_ERROR_FAILURE;
}
// Remember our new block for postprocessing
mNewBlock = theBlock;
continue;
}
if (curNode->IsHTMLElement(nsGkAtoms::br)) {
// If the node is a break, we honor it by putting further nodes in a new
// parent
if (curBlock) {
// Forget any previous block used for previous inline nodes
curBlock = nullptr;
- nsresult rv = htmlEditor->DeleteNodeWithTransaction(*curNode);
+ nsresult rv = HTMLEditorRef().DeleteNodeWithTransaction(*curNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
continue;
}
// The break is the first (or even only) node we encountered. Create a
// block for it.
SplitNodeResult splitNodeResult =
MaybeSplitAncestorsForInsertWithTransaction(aBlockTag, atCurNode);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
curBlock =
- htmlEditor->CreateNodeWithTransaction(aBlockTag,
- splitNodeResult.SplitPoint());
+ HTMLEditorRef().CreateNodeWithTransaction(aBlockTag,
+ splitNodeResult.SplitPoint());
if (NS_WARN_IF(!curBlock)) {
return NS_ERROR_FAILURE;
}
// Remember our new block for postprocessing
mNewBlock = curBlock;
// Note: doesn't matter if we set mNewBlock multiple times.
nsresult rv =
- htmlEditor->MoveNodeToEndWithTransaction(*curNode->AsContent(),
- *curBlock);
+ HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(),
+ *curBlock);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
continue;
}
if (IsInlineNode(curNode)) {
// If curNode is inline, pull it into curBlock. Note: it's assumed that
// consecutive inline nodes in aNodeArray are actually members of the
// same block parent. This happens to be true now as a side effect of
// how aNodeArray is contructed, but some additional logic should be
// added here if that should change
//
// If curNode is a non editable, drop it if we are going to <pre>.
- if (&aBlockTag == nsGkAtoms::pre && !htmlEditor->IsEditable(curNode)) {
+ if (&aBlockTag == nsGkAtoms::pre &&
+ !HTMLEditorRef().IsEditable(curNode)) {
// Do nothing to this block
continue;
}
// If no curBlock, make one
if (!curBlock) {
AutoEditorDOMPointOffsetInvalidator lockChild(atCurNode);
SplitNodeResult splitNodeResult =
MaybeSplitAncestorsForInsertWithTransaction(aBlockTag, atCurNode);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
curBlock =
- htmlEditor->CreateNodeWithTransaction(aBlockTag,
- splitNodeResult.SplitPoint());
+ HTMLEditorRef().CreateNodeWithTransaction(
+ aBlockTag, splitNodeResult.SplitPoint());
if (NS_WARN_IF(!curBlock)) {
return NS_ERROR_FAILURE;
}
// Remember our new block for postprocessing
mNewBlock = curBlock;
// Note: doesn't matter if we set mNewBlock multiple times.
}
@@ -8086,43 +8084,40 @@ HTMLEditRules::ApplyBlockStyle(nsTArray<
return NS_ERROR_UNEXPECTED;
}
// XXX If curNode is a br, replace it with a return if going to <pre>
// This is a continuation of some inline nodes that belong together in
// the same block item. Use curBlock.
nsresult rv =
- htmlEditor->MoveNodeToEndWithTransaction(*curNode->AsContent(),
- *curBlock);
+ HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(),
+ *curBlock);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
}
return NS_OK;
}
template<typename PT, typename CT>
SplitNodeResult
HTMLEditRules::MaybeSplitAncestorsForInsertWithTransaction(
nsAtom& aTag,
const EditorDOMPointBase<PT, CT>& aStartOfDeepestRightNode)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (NS_WARN_IF(!aStartOfDeepestRightNode.IsSet())) {
return SplitNodeResult(NS_ERROR_INVALID_ARG);
}
MOZ_ASSERT(aStartOfDeepestRightNode.IsSetAndValid());
- if (NS_WARN_IF(!mHTMLEditor)) {
- return SplitNodeResult(NS_ERROR_NOT_AVAILABLE);
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
- RefPtr<Element> host = htmlEditor->GetActiveEditingHost();
+ RefPtr<Element> host = HTMLEditorRef().GetActiveEditingHost();
if (NS_WARN_IF(!host)) {
return SplitNodeResult(NS_ERROR_FAILURE);
}
// The point must be descendant of editing host.
if (NS_WARN_IF(aStartOfDeepestRightNode.GetContainer() != host &&
!EditorUtils::IsDescendantOf(
*aStartOfDeepestRightNode.GetContainer(), *host))) {
@@ -8134,115 +8129,104 @@ HTMLEditRules::MaybeSplitAncestorsForIns
for (; pointToInsert.IsSet();
pointToInsert.Set(pointToInsert.GetContainer())) {
// We cannot split active editing host and its ancestor. So, there is
// no element to contain the specified element.
if (NS_WARN_IF(pointToInsert.GetChild() == host)) {
return SplitNodeResult(NS_ERROR_FAILURE);
}
- if (htmlEditor->CanContainTag(*pointToInsert.GetContainer(), aTag)) {
+ if (HTMLEditorRef().CanContainTag(*pointToInsert.GetContainer(), aTag)) {
// Found an ancestor node which can contain the element.
break;
}
}
MOZ_DIAGNOSTIC_ASSERT(pointToInsert.IsSet());
// If the point itself can contain the tag, we don't need to split any
// ancestor nodes. In this case, we should return the given split point
// as is.
if (pointToInsert.GetContainer() == aStartOfDeepestRightNode.GetContainer()) {
return SplitNodeResult(aStartOfDeepestRightNode);
}
SplitNodeResult splitNodeResult =
- htmlEditor->SplitNodeDeepWithTransaction(
- *pointToInsert.GetChild(),
- aStartOfDeepestRightNode,
- SplitAtEdges::eAllowToCreateEmptyContainer);
+ HTMLEditorRef().SplitNodeDeepWithTransaction(
+ *pointToInsert.GetChild(),
+ aStartOfDeepestRightNode,
+ SplitAtEdges::eAllowToCreateEmptyContainer);
NS_WARNING_ASSERTION(splitNodeResult.Succeeded(),
"Failed to split the node for insert the element");
return splitNodeResult;
}
EditorDOMPoint
HTMLEditRules::JoinNearestEditableNodesWithTransaction(nsIContent& aNodeLeft,
nsIContent& aNodeRight)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
// Caller responsible for left and right node being the same type
nsCOMPtr<nsINode> parent = aNodeLeft.GetParentNode();
if (NS_WARN_IF(!parent)) {
return EditorDOMPoint();
}
int32_t parOffset = parent->ComputeIndexOf(&aNodeLeft);
nsCOMPtr<nsINode> rightParent = aNodeRight.GetParentNode();
// If they don't have the same parent, first move the right node to after the
// left one
if (parent != rightParent) {
- if (NS_WARN_IF(!mHTMLEditor)) {
- return EditorDOMPoint();
- }
nsresult rv =
- mHTMLEditor->MoveNodeWithTransaction(aNodeRight,
- EditorRawDOMPoint(parent,
- parOffset));
+ HTMLEditorRef().MoveNodeWithTransaction(
+ aNodeRight, EditorRawDOMPoint(parent, parOffset));
if (NS_WARN_IF(NS_FAILED(rv))) {
return EditorDOMPoint();
}
}
EditorDOMPoint ret(&aNodeRight, aNodeLeft.Length());
// Separate join rules for differing blocks
if (HTMLEditUtils::IsList(&aNodeLeft) || aNodeLeft.GetAsText()) {
// For lists, merge shallow (wouldn't want to combine list items)
- nsresult rv = mHTMLEditor->JoinNodesWithTransaction(aNodeLeft, aNodeRight);
+ nsresult rv =
+ HTMLEditorRef().JoinNodesWithTransaction(aNodeLeft, aNodeRight);
if (NS_WARN_IF(NS_FAILED(rv))) {
return EditorDOMPoint();
}
return ret;
}
// Remember the last left child, and first right child
- if (NS_WARN_IF(!mHTMLEditor)) {
- return EditorDOMPoint();
- }
- nsCOMPtr<nsIContent> lastLeft = mHTMLEditor->GetLastEditableChild(aNodeLeft);
+ nsCOMPtr<nsIContent> lastLeft =
+ HTMLEditorRef().GetLastEditableChild(aNodeLeft);
if (NS_WARN_IF(!lastLeft)) {
return EditorDOMPoint();
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return EditorDOMPoint();
- }
- nsCOMPtr<nsIContent> firstRight = mHTMLEditor->GetFirstEditableChild(aNodeRight);
+ nsCOMPtr<nsIContent> firstRight =
+ HTMLEditorRef().GetFirstEditableChild(aNodeRight);
if (NS_WARN_IF(!firstRight)) {
return EditorDOMPoint();
}
// For list items, divs, etc., merge smart
- if (NS_WARN_IF(!mHTMLEditor)) {
- return EditorDOMPoint();
- }
- nsresult rv = mHTMLEditor->JoinNodesWithTransaction(aNodeLeft, aNodeRight);
+ nsresult rv = HTMLEditorRef().JoinNodesWithTransaction(aNodeLeft, aNodeRight);
if (NS_WARN_IF(NS_FAILED(rv))) {
return EditorDOMPoint();
}
- if (lastLeft && firstRight && mHTMLEditor &&
- mHTMLEditor->AreNodesSameType(lastLeft, firstRight) &&
- (lastLeft->GetAsText() || !mHTMLEditor ||
+ if (lastLeft && firstRight &&
+ HTMLEditorRef().AreNodesSameType(lastLeft, firstRight) &&
+ (lastLeft->GetAsText() ||
(lastLeft->IsElement() && firstRight->IsElement() &&
CSSEditUtils::ElementsSameStyle(lastLeft->AsElement(),
firstRight->AsElement())))) {
- if (NS_WARN_IF(!mHTMLEditor)) {
- return EditorDOMPoint();
- }
return JoinNearestEditableNodesWithTransaction(*lastLeft, *firstRight);
}
return ret;
}
Element*
HTMLEditRules::GetTopEnclosingMailCite(nsINode& aNode)
{
@@ -8259,85 +8243,84 @@ HTMLEditRules::GetTopEnclosingMailCite(n
}
return ret;
}
nsresult
HTMLEditRules::CacheInlineStyles(nsINode* aNode)
{
- NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
-
- NS_ENSURE_STATE(mHTMLEditor);
+ MOZ_ASSERT(IsEditorDataAvailable());
+
+ if (NS_WARN_IF(!aNode)) {
+ return NS_ERROR_INVALID_ARG;
+ }
nsresult rv = GetInlineStyles(aNode, mCachedStyles);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
nsresult
HTMLEditRules::GetInlineStyles(nsINode* aNode,
StyleCache aStyleCache[SIZE_STYLE_TABLE])
{
+ MOZ_ASSERT(IsEditorDataAvailable());
MOZ_ASSERT(aNode);
- MOZ_ASSERT(mHTMLEditor);
-
- bool useCSS = mHTMLEditor->IsCSSEnabled();
+
+ bool useCSS = HTMLEditorRef().IsCSSEnabled();
for (size_t j = 0; j < SIZE_STYLE_TABLE; ++j) {
// If type-in state is set, don't intervene
bool typeInSet, unused;
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_UNEXPECTED;
- }
- mHTMLEditor->mTypeInState->GetTypingState(typeInSet, unused,
- aStyleCache[j].tag, aStyleCache[j].attr, nullptr);
+ HTMLEditorRef().mTypeInState->GetTypingState(
+ typeInSet, unused, aStyleCache[j].tag,
+ aStyleCache[j].attr, nullptr);
if (typeInSet) {
continue;
}
bool isSet = false;
nsAutoString outValue;
// Don't use CSS for <font size>, we don't support it usefully (bug 780035)
if (!useCSS || (aStyleCache[j].tag == nsGkAtoms::font &&
aStyleCache[j].attr == nsGkAtoms::size)) {
- NS_ENSURE_STATE(mHTMLEditor);
- isSet = mHTMLEditor->IsTextPropertySetByContent(aNode, aStyleCache[j].tag,
- aStyleCache[j].attr,
- nullptr,
- &outValue);
+ isSet =
+ HTMLEditorRef().IsTextPropertySetByContent(aNode, aStyleCache[j].tag,
+ aStyleCache[j].attr,
+ nullptr, &outValue);
} else {
isSet = CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
aNode, aStyleCache[j].tag, aStyleCache[j].attr, outValue,
CSSEditUtils::eComputed);
}
if (isSet) {
aStyleCache[j].mPresent = true;
aStyleCache[j].value.Assign(outValue);
}
}
return NS_OK;
}
nsresult
HTMLEditRules::ReapplyCachedStyles()
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
// The idea here is to examine our cached list of styles and see if any have
// been removed. If so, add typeinstate for them, so that they will be
// reinserted when new content is added.
// remember if we are in css mode
- NS_ENSURE_STATE(mHTMLEditor);
- bool useCSS = mHTMLEditor->IsCSSEnabled();
+ bool useCSS = HTMLEditorRef().IsCSSEnabled();
// get selection point; if it doesn't exist, we have nothing to do
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<Selection> selection = mHTMLEditor->GetSelection();
+ RefPtr<Selection> selection = HTMLEditorRef().GetSelection();
if (!selection) {
// If the document is removed from its parent document during executing an
// editor operation with DOMMutationEvent or something, there may be no
// selection.
return NS_OK;
}
if (!selection->RangeCount()) {
// Nothing to do
@@ -8366,34 +8349,34 @@ HTMLEditRules::ReapplyCachedStyles()
if (useCSS) {
// check computed style first in css case
bAny = CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
selNode, mCachedStyles[i].tag, mCachedStyles[i].attr, curValue,
CSSEditUtils::eComputed);
}
if (!bAny) {
// then check typeinstate and html style
- NS_ENSURE_STATE(mHTMLEditor);
nsresult rv =
- mHTMLEditor->GetInlinePropertyBase(*mCachedStyles[i].tag,
- mCachedStyles[i].attr,
- &(mCachedStyles[i].value),
- &bFirst, &bAny, &bAll,
- &curValue);
- NS_ENSURE_SUCCESS(rv, rv);
+ HTMLEditorRef().GetInlinePropertyBase(*mCachedStyles[i].tag,
+ mCachedStyles[i].attr,
+ &(mCachedStyles[i].value),
+ &bFirst, &bAny, &bAll,
+ &curValue);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
// This style has disappeared through deletion. Let's add the styles to
// mTypeInState when same style isn't applied to the node already.
if ((!bAny || IsStyleCachePreservingAction(mTheAction)) &&
(!styleAtInsertionPoint[i].mPresent ||
styleAtInsertionPoint[i].value != mCachedStyles[i].value)) {
- NS_ENSURE_STATE(mHTMLEditor);
- mHTMLEditor->mTypeInState->SetProp(mCachedStyles[i].tag,
- mCachedStyles[i].attr,
- mCachedStyles[i].value);
+ HTMLEditorRef().mTypeInState->SetProp(mCachedStyles[i].tag,
+ mCachedStyles[i].attr,
+ mCachedStyles[i].value);
}
}
}
return NS_OK;
}
void
@@ -8404,21 +8387,21 @@ HTMLEditRules::ClearCachedStyles()
mCachedStyles[j].mPresent = false;
mCachedStyles[j].value.Truncate();
}
}
void
HTMLEditRules::AdjustSpecialBreaks()
{
- NS_ENSURE_TRUE_VOID(mHTMLEditor);
+ MOZ_ASSERT(IsEditorDataAvailable());
// Gather list of empty nodes
nsTArray<OwningNonNull<nsINode>> nodeArray;
- EmptyEditableFunctor functor(mHTMLEditor);
+ EmptyEditableFunctor functor(&HTMLEditorRef());
DOMIterator iter;
if (NS_WARN_IF(NS_FAILED(iter.Init(*mDocChangeRange)))) {
return;
}
iter.AppendList(functor, nodeArray);
// Put moz-br's into these empty li's and td's
for (auto& node : nodeArray) {
@@ -8433,31 +8416,37 @@ HTMLEditRules::AdjustSpecialBreaks()
return;
}
}
}
nsresult
HTMLEditRules::AdjustWhitespace(Selection* aSelection)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
EditorRawDOMPoint selectionStartPoint(EditorBase::GetStartPoint(aSelection));
if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
return NS_ERROR_FAILURE;
}
// Ask whitespace object to tweak nbsp's
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- return WSRunObject(mHTMLEditor, selectionStartPoint).AdjustWhitespace();
+ nsresult rv =
+ WSRunObject(&HTMLEditorRef(), selectionStartPoint).AdjustWhitespace();
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
}
nsresult
HTMLEditRules::PinSelectionToNewBlock(Selection* aSelection)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
NS_ENSURE_TRUE(aSelection, NS_ERROR_NULL_POINTER);
if (!aSelection->IsCollapsed()) {
return NS_OK;
}
if (NS_WARN_IF(!mNewBlock)) {
return NS_ERROR_NULL_POINTER;
}
@@ -8482,153 +8471,149 @@ HTMLEditRules::PinSelectionToNewBlock(Se
NS_ENSURE_SUCCESS(rv, rv);
if (nodeBefore && nodeAfter) {
return NS_OK; // selection is inside block
}
if (nodeBefore) {
// selection is after block. put at end of block.
- NS_ENSURE_STATE(mHTMLEditor);
- nsCOMPtr<nsINode> tmp = mHTMLEditor->GetLastEditableChild(*mNewBlock);
+ nsCOMPtr<nsINode> tmp = HTMLEditorRef().GetLastEditableChild(*mNewBlock);
if (!tmp) {
tmp = mNewBlock;
}
EditorRawDOMPoint endPoint;
if (EditorBase::IsTextNode(tmp) ||
- mHTMLEditor->IsContainer(tmp)) {
+ HTMLEditorRef().IsContainer(tmp)) {
endPoint.SetToEndOf(tmp);
} else {
endPoint.Set(tmp);
if (NS_WARN_IF(!endPoint.AdvanceOffset())) {
return NS_ERROR_FAILURE;
}
}
return aSelection->Collapse(endPoint);
}
// selection is before block. put at start of block.
- NS_ENSURE_STATE(mHTMLEditor);
- nsCOMPtr<nsINode> tmp = mHTMLEditor->GetFirstEditableChild(*mNewBlock);
+ nsCOMPtr<nsINode> tmp = HTMLEditorRef().GetFirstEditableChild(*mNewBlock);
if (!tmp) {
tmp = mNewBlock;
}
EditorRawDOMPoint atStartOfBlock;
if (EditorBase::IsTextNode(tmp) ||
- mHTMLEditor->IsContainer(tmp)) {
+ HTMLEditorRef().IsContainer(tmp)) {
atStartOfBlock.Set(tmp);
} else {
atStartOfBlock.Set(tmp, 0);
}
return aSelection->Collapse(atStartOfBlock);
}
void
HTMLEditRules::CheckInterlinePosition(Selection& aSelection)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
// If the selection isn't collapsed, do nothing.
if (!aSelection.IsCollapsed()) {
return;
}
- NS_ENSURE_TRUE_VOID(mHTMLEditor);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
// Get the (collapsed) selection location
nsRange* firstRange = aSelection.GetRangeAt(0);
if (NS_WARN_IF(!firstRange)) {
return;
}
EditorDOMPoint atStartOfSelection(firstRange->StartRef());
if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
return;
}
MOZ_ASSERT(atStartOfSelection.IsSetAndValid());
// First, let's check to see if we are after a <br>. We take care of this
// special-case first so that we don't accidentally fall through into one of
// the other conditionals.
nsCOMPtr<nsIContent> node =
- htmlEditor->GetPreviousEditableHTMLNodeInBlock(atStartOfSelection);
+ HTMLEditorRef().GetPreviousEditableHTMLNodeInBlock(atStartOfSelection);
if (node && node->IsHTMLElement(nsGkAtoms::br)) {
aSelection.SetInterlinePosition(true, IgnoreErrors());
return;
}
// Are we after a block? If so try set caret to following content
if (atStartOfSelection.GetChild()) {
- node = htmlEditor->GetPriorHTMLSibling(atStartOfSelection.GetChild());
+ node = HTMLEditorRef().GetPriorHTMLSibling(atStartOfSelection.GetChild());
} else {
node = nullptr;
}
if (node && IsBlockNode(*node)) {
aSelection.SetInterlinePosition(true, IgnoreErrors());
return;
}
// Are we before a block? If so try set caret to prior content
if (atStartOfSelection.GetChild()) {
- node = htmlEditor->GetNextHTMLSibling(atStartOfSelection.GetChild());
+ node = HTMLEditorRef().GetNextHTMLSibling(atStartOfSelection.GetChild());
} else {
node = nullptr;
}
if (node && IsBlockNode(*node)) {
aSelection.SetInterlinePosition(false, IgnoreErrors());
}
}
nsresult
HTMLEditRules::AdjustSelection(Selection* aSelection,
nsIEditor::EDirection aAction)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (NS_WARN_IF(!aSelection)) {
return NS_ERROR_INVALID_ARG;
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
// if the selection isn't collapsed, do nothing.
// moose: one thing to do instead is check for the case of
// only a single break selected, and collapse it. Good thing? Beats me.
if (!aSelection->IsCollapsed()) {
return NS_OK;
}
// get the (collapsed) selection location
EditorDOMPoint point(EditorBase::GetStartPoint(aSelection));
if (NS_WARN_IF(!point.IsSet())) {
return NS_ERROR_FAILURE;
}
// are we in an editable node?
- while (!htmlEditor->IsEditable(point.GetContainer())) {
+ while (!HTMLEditorRef().IsEditable(point.GetContainer())) {
// scan up the tree until we find an editable place to be
point.Set(point.GetContainer());
if (NS_WARN_IF(!point.IsSet())) {
return NS_ERROR_FAILURE;
}
}
// make sure we aren't in an empty block - user will see no cursor. If this
// is happening, put a <br> in the block if allowed.
- RefPtr<Element> theblock = htmlEditor->GetBlock(*point.GetContainer());
-
- if (theblock && htmlEditor->IsEditable(theblock)) {
+ RefPtr<Element> theblock = HTMLEditorRef().GetBlock(*point.GetContainer());
+
+ if (theblock && HTMLEditorRef().IsEditable(theblock)) {
bool bIsEmptyNode;
nsresult rv =
- htmlEditor->IsEmptyNode(theblock, &bIsEmptyNode, false, false);
- NS_ENSURE_SUCCESS(rv, rv);
+ HTMLEditorRef().IsEmptyNode(theblock, &bIsEmptyNode, false, false);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
// check if br can go into the destination node
if (bIsEmptyNode &&
- htmlEditor->CanContainTag(*point.GetContainer(), *nsGkAtoms::br)) {
- Element* rootElement = htmlEditor->GetRoot();
+ HTMLEditorRef().CanContainTag(*point.GetContainer(), *nsGkAtoms::br)) {
+ Element* rootElement = HTMLEditorRef().GetRoot();
if (NS_WARN_IF(!rootElement)) {
return NS_ERROR_FAILURE;
}
if (point.GetContainer() == rootElement) {
// Our root node is completely empty. Don't add a <br> here.
// AfterEditInner() will add one for us when it calls
// CreateBogusNodeIfNeeded()!
return NS_OK;
@@ -8649,24 +8634,24 @@ HTMLEditRules::AdjustSelection(Selection
}
// do we need to insert a special mozBR? We do if we are:
// 1) prior node is in same block where selection is AND
// 2) prior node is a br AND
// 3) that br is not visible
nsCOMPtr<nsIContent> nearNode =
- htmlEditor->GetPreviousEditableHTMLNode(point);
+ HTMLEditorRef().GetPreviousEditableHTMLNode(point);
if (nearNode) {
// is nearNode also a descendant of same block?
- RefPtr<Element> block = htmlEditor->GetBlock(*point.GetContainer());
- RefPtr<Element> nearBlock = htmlEditor->GetBlockNodeParent(nearNode);
+ RefPtr<Element> block = HTMLEditorRef().GetBlock(*point.GetContainer());
+ RefPtr<Element> nearBlock = HTMLEditorRef().GetBlockNodeParent(nearNode);
if (block && block == nearBlock) {
if (nearNode && TextEditUtils::IsBreak(nearNode)) {
- if (!htmlEditor->IsVisibleBRElement(nearNode)) {
+ if (!HTMLEditorRef().IsVisibleBRElement(nearNode)) {
// need to insert special moz BR. Why? Because if we don't
// the user will see no new line for the break. Also, things
// like table cells won't grow in height.
RefPtr<Element> brElement = CreateMozBR(point);
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
point.Set(brElement);
@@ -8674,37 +8659,37 @@ HTMLEditRules::AdjustSelection(Selection
aSelection->SetInterlinePosition(true, IgnoreErrors());
ErrorResult error;
aSelection->Collapse(point, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
} else {
nsCOMPtr<nsIContent> nextNode =
- htmlEditor->GetNextEditableHTMLNodeInBlock(*nearNode);
+ HTMLEditorRef().GetNextEditableHTMLNodeInBlock(*nearNode);
if (nextNode && TextEditUtils::IsMozBR(nextNode)) {
// selection between br and mozbr. make it stick to mozbr
// so that it will be on blank line.
aSelection->SetInterlinePosition(true, IgnoreErrors());
}
}
}
}
}
// we aren't in a textnode: are we adjacent to text or a break or an image?
- nearNode = htmlEditor->GetPreviousEditableHTMLNodeInBlock(point);
+ nearNode = HTMLEditorRef().GetPreviousEditableHTMLNodeInBlock(point);
if (nearNode && (TextEditUtils::IsBreak(nearNode) ||
EditorBase::IsTextNode(nearNode) ||
HTMLEditUtils::IsImage(nearNode) ||
nearNode->IsHTMLElement(nsGkAtoms::hr))) {
// this is a good place for the caret to be
return NS_OK;
}
- nearNode = htmlEditor->GetNextEditableHTMLNodeInBlock(point);
+ nearNode = HTMLEditorRef().GetNextEditableHTMLNodeInBlock(point);
if (nearNode && (TextEditUtils::IsBreak(nearNode) ||
EditorBase::IsTextNode(nearNode) ||
nearNode->IsAnyOfHTMLElements(nsGkAtoms::img,
nsGkAtoms::hr))) {
return NS_OK; // this is a good place for the caret to be
}
// look for a nearby text node.
@@ -8723,53 +8708,52 @@ HTMLEditRules::AdjustSelection(Selection
return NS_OK;
}
template<typename PT, typename CT>
nsIContent*
HTMLEditRules::FindNearEditableNode(const EditorDOMPointBase<PT, CT>& aPoint,
nsIEditor::EDirection aDirection)
{
- if (NS_WARN_IF(!aPoint.IsSet()) ||
- NS_WARN_IF(!mHTMLEditor)) {
+ MOZ_ASSERT(IsEditorDataAvailable());
+
+ if (NS_WARN_IF(!aPoint.IsSet())) {
return nullptr;
}
MOZ_ASSERT(aPoint.IsSetAndValid());
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
nsIContent* nearNode = nullptr;
if (aDirection == nsIEditor::ePrevious) {
- nearNode = htmlEditor->GetPreviousEditableHTMLNode(aPoint);
+ nearNode = HTMLEditorRef().GetPreviousEditableHTMLNode(aPoint);
if (!nearNode) {
return nullptr; // Not illegal.
}
} else {
- nearNode = htmlEditor->GetNextEditableHTMLNode(aPoint);
+ nearNode = HTMLEditorRef().GetNextEditableHTMLNode(aPoint);
if (NS_WARN_IF(!nearNode)) {
// Perhaps, illegal because the node pointed by aPoint isn't editable
// and nobody of previous nodes is editable.
return nullptr;
}
}
// scan in the right direction until we find an eligible text node,
// but don't cross any breaks, images, or table elements.
// XXX This comment sounds odd. |nearNode| may have already crossed breaks
// and/or images.
while (nearNode && !(EditorBase::IsTextNode(nearNode) ||
TextEditUtils::IsBreak(nearNode) ||
HTMLEditUtils::IsImage(nearNode))) {
if (aDirection == nsIEditor::ePrevious) {
- nearNode = htmlEditor->GetPreviousEditableHTMLNode(*nearNode);
+ nearNode = HTMLEditorRef().GetPreviousEditableHTMLNode(*nearNode);
if (NS_WARN_IF(!nearNode)) {
return nullptr;
}
} else {
- nearNode = htmlEditor->GetNextEditableHTMLNode(*nearNode);
+ nearNode = HTMLEditorRef().GetNextEditableHTMLNode(*nearNode);
if (NS_WARN_IF(!nearNode)) {
return nullptr;
}
}
}
// don't cross any table elements
if (InDifferentTableElements(nearNode, aPoint.GetContainer())) {
@@ -8796,18 +8780,17 @@ HTMLEditRules::InDifferentTableElements(
return aNode1 != aNode2;
}
nsresult
HTMLEditRules::RemoveEmptyNodes()
{
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
+ MOZ_ASSERT(IsEditorDataAvailable());
// Some general notes on the algorithm used here: the goal is to examine all
// the nodes in mDocChangeRange, and remove the empty ones. We do this by
// using a content iterator to traverse all the nodes in the range, and
// placing the empty nodes into an array. After finishing the iteration, we
// delete the empty nodes in the array. (They cannot be deleted as we find
// them because that would invalidate the iterator.)
//
@@ -8879,18 +8862,21 @@ HTMLEditRules::RemoveEmptyNodes()
bIsCandidate = true;
}
}
}
if (bIsCandidate) {
// We delete mailcites even if they have a solo br in them. Other
// nodes we require to be empty.
- rv = htmlEditor->IsEmptyNode(node, &bIsEmptyNode, bIsMailCite, true);
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = HTMLEditorRef().IsEmptyNode(node, &bIsEmptyNode,
+ bIsMailCite, true);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
if (bIsEmptyNode) {
if (bIsMailCite) {
// mailcites go on a separate list from other empty nodes
arrayOfEmptyCites.AppendElement(*node);
} else {
arrayOfEmptyNodes.AppendElement(*node);
}
}
@@ -8902,63 +8888,66 @@ HTMLEditRules::RemoveEmptyNodes()
}
}
iter->Next();
}
// now delete the empty nodes
for (OwningNonNull<nsINode>& delNode : arrayOfEmptyNodes) {
- if (htmlEditor->IsModifiableNode(delNode)) {
- rv = htmlEditor->DeleteNodeWithTransaction(*delNode);
+ if (HTMLEditorRef().IsModifiableNode(delNode)) {
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*delNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
}
// Now delete the empty mailcites. This is a separate step because we want
// to pull out any br's and preserve them.
for (OwningNonNull<nsINode>& delNode : arrayOfEmptyCites) {
bool bIsEmptyNode;
- rv = htmlEditor->IsEmptyNode(delNode, &bIsEmptyNode, false, true);
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = HTMLEditorRef().IsEmptyNode(delNode, &bIsEmptyNode, false, true);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
if (!bIsEmptyNode) {
- RefPtr<Selection> selection = htmlEditor->GetSelection();
+ RefPtr<Selection> selection = HTMLEditorRef().GetSelection();
if (NS_WARN_IF(!selection)) {
return NS_ERROR_FAILURE;
}
// We are deleting a cite that has just a br. We want to delete cite,
// but preserve br.
RefPtr<Element> brElement =
- htmlEditor->InsertBrElementWithTransaction(*selection,
- EditorRawDOMPoint(delNode));
+ HTMLEditorRef().InsertBrElementWithTransaction(
+ *selection, EditorRawDOMPoint(delNode));
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
}
- rv = htmlEditor->DeleteNodeWithTransaction(*delNode);
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*delNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
return NS_OK;
}
nsresult
HTMLEditRules::SelectionEndpointInNode(nsINode* aNode,
bool* aResult)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
NS_ENSURE_TRUE(aNode && aResult, NS_ERROR_NULL_POINTER);
*aResult = false;
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<Selection> selection = mHTMLEditor->GetSelection();
+ RefPtr<Selection> selection = HTMLEditorRef().GetSelection();
NS_ENSURE_STATE(selection);
uint32_t rangeCount = selection->RangeCount();
for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
RefPtr<nsRange> range = selection->GetRangeAt(rangeIdx);
nsINode* startContainer = range->GetStartContainer();
if (startContainer) {
if (aNode == startContainer) {
@@ -8989,43 +8978,42 @@ HTMLEditRules::SelectionEndpointInNode(n
}
/**
* IsEmptyInline: Return true if aNode is an empty inline container
*/
bool
HTMLEditRules::IsEmptyInline(nsINode& aNode)
{
- NS_ENSURE_TRUE(mHTMLEditor, false);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
- if (IsInlineNode(aNode) && htmlEditor->IsContainer(&aNode)) {
+ MOZ_ASSERT(IsEditorDataAvailable());
+
+ if (IsInlineNode(aNode) && HTMLEditorRef().IsContainer(&aNode)) {
bool isEmpty = true;
- htmlEditor->IsEmptyNode(&aNode, &isEmpty);
+ HTMLEditorRef().IsEmptyNode(&aNode, &isEmpty);
return isEmpty;
}
return false;
}
bool
HTMLEditRules::ListIsEmptyLine(nsTArray<OwningNonNull<nsINode>>& aArrayOfNodes)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
// We have a list of nodes which we are candidates for being moved into a new
// block. Determine if it's anything more than a blank line. Look for
// editable content above and beyond one single BR.
- NS_ENSURE_TRUE(aArrayOfNodes.Length(), true);
-
- NS_ENSURE_TRUE(mHTMLEditor, false);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
+ if (NS_WARN_IF(!aArrayOfNodes.Length())) {
+ return true;
+ }
int32_t brCount = 0;
-
for (auto& node : aArrayOfNodes) {
- if (!htmlEditor->IsEditable(node)) {
+ if (!HTMLEditorRef().IsEditable(node)) {
continue;
}
if (TextEditUtils::IsBreak(node)) {
// First break doesn't count
if (brCount) {
return false;
}
brCount++;
@@ -9038,60 +9026,52 @@ HTMLEditRules::ListIsEmptyLine(nsTArray<
return true;
}
nsresult
HTMLEditRules::PopListItem(nsIContent& aListItem,
bool* aOutOfList)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
// init out params
if (aOutOfList) {
*aOutOfList = false;
}
nsCOMPtr<nsIContent> kungFuDeathGrip(&aListItem);
Unused << kungFuDeathGrip;
- if (NS_WARN_IF(!mHTMLEditor) ||
- NS_WARN_IF(!aListItem.GetParent()) ||
+ if (NS_WARN_IF(!aListItem.GetParent()) ||
NS_WARN_IF(!aListItem.GetParent()->GetParentNode()) ||
!HTMLEditUtils::IsListItem(&aListItem)) {
return NS_ERROR_FAILURE;
}
// if it's first or last list item, don't need to split the list
// otherwise we do.
- bool bIsFirstListItem = mHTMLEditor->IsFirstEditableChild(&aListItem);
- MOZ_ASSERT(mHTMLEditor);
- bool bIsLastListItem = mHTMLEditor->IsLastEditableChild(&aListItem);
- MOZ_ASSERT(mHTMLEditor);
+ bool bIsFirstListItem = HTMLEditorRef().IsFirstEditableChild(&aListItem);
+ bool bIsLastListItem = HTMLEditorRef().IsLastEditableChild(&aListItem);
nsCOMPtr<nsIContent> leftListNode = aListItem.GetParent();
if (!bIsFirstListItem && !bIsLastListItem) {
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_FAILURE;
- }
-
EditorDOMPoint atListItem(&aListItem);
if (NS_WARN_IF(!atListItem.IsSet())) {
return NS_ERROR_INVALID_ARG;
}
MOZ_ASSERT(atListItem.IsSetAndValid());
// split the list
ErrorResult error;
- leftListNode = mHTMLEditor->SplitNodeWithTransaction(atListItem, error);
+ leftListNode = HTMLEditorRef().SplitNodeWithTransaction(atListItem, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_FAILURE;
- }
}
// In most cases, insert the list item into the new left list node..
EditorDOMPoint pointToInsertListItem(leftListNode);
if (NS_WARN_IF(!pointToInsertListItem.IsSet())) {
return NS_ERROR_FAILURE;
}
MOZ_ASSERT(pointToInsertListItem.IsSetAndValid());
@@ -9101,84 +9081,86 @@ HTMLEditRules::PopListItem(nsIContent& a
// Enter twice at a list item breaks the parent list node.
if (!bIsFirstListItem) {
DebugOnly<bool> advanced = pointToInsertListItem.AdvanceOffset();
NS_WARNING_ASSERTION(advanced,
"Failed to advance offset to right list node");
}
nsresult rv =
- mHTMLEditor->MoveNodeWithTransaction(aListItem, pointToInsertListItem);
+ HTMLEditorRef().MoveNodeWithTransaction(aListItem, pointToInsertListItem);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// unwrap list item contents if they are no longer in a list
if (!HTMLEditUtils::IsList(pointToInsertListItem.GetContainer()) &&
HTMLEditUtils::IsListItem(&aListItem)) {
- NS_ENSURE_STATE(mHTMLEditor);
- rv = mHTMLEditor->RemoveBlockContainerWithTransaction(
- *aListItem.AsElement());
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = HTMLEditorRef().RemoveBlockContainerWithTransaction(
+ *aListItem.AsElement());
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
if (aOutOfList) {
*aOutOfList = true;
}
}
return NS_OK;
}
nsresult
HTMLEditRules::RemoveListStructure(Element& aList)
{
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
+ MOZ_ASSERT(IsEditorDataAvailable());
+
while (aList.GetFirstChild()) {
OwningNonNull<nsIContent> child = *aList.GetFirstChild();
if (HTMLEditUtils::IsListItem(child)) {
bool isOutOfList;
// Keep popping it out until it's not in a list anymore
do {
nsresult rv = PopListItem(child, &isOutOfList);
NS_ENSURE_SUCCESS(rv, rv);
} while (!isOutOfList);
} else if (HTMLEditUtils::IsList(child)) {
nsresult rv = RemoveListStructure(*child->AsElement());
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
} else {
// Delete any non-list items for now
- nsresult rv = htmlEditor->DeleteNodeWithTransaction(*child);
+ nsresult rv = HTMLEditorRef().DeleteNodeWithTransaction(*child);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
}
// Delete the now-empty list
- nsresult rv = htmlEditor->RemoveBlockContainerWithTransaction(aList);
- NS_ENSURE_SUCCESS(rv, rv);
-
+ nsresult rv = HTMLEditorRef().RemoveBlockContainerWithTransaction(aList);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
return NS_OK;
}
// XXX This method is not necessary because even if selection is outside the
// <body> element, the element can be editable.
nsresult
HTMLEditRules::ConfirmSelectionInBody()
{
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
-
- Element* rootElement = mHTMLEditor->GetRoot();
+ MOZ_ASSERT(IsEditorDataAvailable());
+
+ Element* rootElement = HTMLEditorRef().GetRoot();
if (NS_WARN_IF(!rootElement)) {
return NS_ERROR_UNEXPECTED;
}
- Selection* selection = mHTMLEditor->GetSelection();
+ Selection* selection = HTMLEditorRef().GetSelection();
if (NS_WARN_IF(!selection)) {
return NS_ERROR_UNEXPECTED;
}
EditorRawDOMPoint selectionStartPoint(EditorBase::GetStartPoint(selection));
if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
return NS_ERROR_FAILURE;
}
@@ -9214,29 +9196,27 @@ HTMLEditRules::ConfirmSelectionInBody()
}
return NS_OK;
}
nsresult
HTMLEditRules::UpdateDocChangeRange(nsRange* aRange)
{
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
+ MOZ_ASSERT(IsEditorDataAvailable());
// first make sure aRange is in the document. It might not be if
// portions of our editting action involved manipulating nodes
// prior to placing them in the document (e.g., populating a list item
// before placing it in its list)
const RangeBoundary& atStart = aRange->StartRef();
if (NS_WARN_IF(!atStart.IsSet())) {
return NS_ERROR_FAILURE;
}
- if (!mHTMLEditor->IsDescendantOfRoot(atStart.Container())) {
+ if (!HTMLEditorRef().IsDescendantOfRoot(atStart.Container())) {
// just return - we don't need to adjust mDocChangeRange in this case
return NS_OK;
}
if (!mDocChangeRange) {
// clone aRange.
mDocChangeRange = aRange->CloneRange();
} else {
@@ -9287,25 +9267,24 @@ HTMLEditRules::UpdateDocChangeRange(nsRa
}
return NS_OK;
}
nsresult
HTMLEditRules::InsertBRIfNeededInternal(nsINode& aNode,
bool aInsertMozBR)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (!IsBlockNode(aNode)) {
return NS_OK;
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_UNEXPECTED;
- }
bool isEmpty;
- nsresult rv = mHTMLEditor->IsEmptyNode(&aNode, &isEmpty);
+ nsresult rv = HTMLEditorRef().IsEmptyNode(&aNode, &isEmpty);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!isEmpty) {
return NS_OK;
}
RefPtr<Element> brElement =
@@ -9520,156 +9499,162 @@ HTMLEditRules::WillDeleteSelection(Selec
// be an ALIGN attribute (in case we just remove it) or a CENTER
// element (here we have to remove the container and keep its
// children). We break on tables and don't look at their children.
nsresult
HTMLEditRules::RemoveAlignment(nsINode& aNode,
const nsAString& aAlignType,
bool aChildrenOnly)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (EditorBase::IsTextNode(&aNode) || HTMLEditUtils::IsTable(&aNode)) {
return NS_OK;
}
nsCOMPtr<nsINode> child, tmp;
if (aChildrenOnly) {
child = aNode.GetFirstChild();
} else {
child = &aNode;
}
- NS_ENSURE_STATE(mHTMLEditor);
- bool useCSS = mHTMLEditor->IsCSSEnabled();
+
+ bool useCSS = HTMLEditorRef().IsCSSEnabled();
while (child) {
if (aChildrenOnly) {
// get the next sibling right now because we could have to remove child
tmp = child->GetNextSibling();
} else {
tmp = nullptr;
}
if (child->IsHTMLElement(nsGkAtoms::center)) {
// the current node is a CENTER element
// first remove children's alignment
nsresult rv = RemoveAlignment(*child, aAlignType, true);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
// we may have to insert BRs in first and last position of element's children
// if the nodes before/after are not blocks and not BRs
rv = MakeSureElemStartsAndEndsOnCR(*child);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
// now remove the CENTER container
- NS_ENSURE_STATE(mHTMLEditor);
- rv = mHTMLEditor->RemoveContainerWithTransaction(*child->AsElement());
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = HTMLEditorRef().RemoveContainerWithTransaction(*child->AsElement());
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
} else if (IsBlockNode(*child) || child->IsHTMLElement(nsGkAtoms::hr)) {
// the current node is a block element
if (HTMLEditUtils::SupportsAlignAttr(*child)) {
// remove the ALIGN attribute if this element can have it
- NS_ENSURE_STATE(mHTMLEditor);
nsresult rv =
- mHTMLEditor->RemoveAttributeWithTransaction(*child->AsElement(),
- *nsGkAtoms::align);
+ HTMLEditorRef().RemoveAttributeWithTransaction(*child->AsElement(),
+ *nsGkAtoms::align);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
if (useCSS) {
if (child->IsAnyOfHTMLElements(nsGkAtoms::table, nsGkAtoms::hr)) {
- NS_ENSURE_STATE(mHTMLEditor);
nsresult rv =
- mHTMLEditor->SetAttributeOrEquivalent(child->AsElement(),
- nsGkAtoms::align,
- aAlignType, false);
+ HTMLEditorRef().SetAttributeOrEquivalent(child->AsElement(),
+ nsGkAtoms::align,
+ aAlignType, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else {
nsAutoString dummyCssValue;
- NS_ENSURE_STATE(mHTMLEditor);
- nsresult rv = mHTMLEditor->mCSSEditUtils->RemoveCSSInlineStyle(
- *child,
- nsGkAtoms::textAlign,
- dummyCssValue);
+ nsresult rv = HTMLEditorRef().mCSSEditUtils->RemoveCSSInlineStyle(
+ *child,
+ nsGkAtoms::textAlign,
+ dummyCssValue);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
}
if (!child->IsHTMLElement(nsGkAtoms::table)) {
// unless this is a table, look at children
nsresult rv = RemoveAlignment(*child, aAlignType, true);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
}
child = tmp;
}
return NS_OK;
}
// Let's insert a BR as first (resp. last) child of aNode if its
// first (resp. last) child is not a block nor a BR, and if the
// previous (resp. next) sibling is not a block nor a BR
nsresult
HTMLEditRules::MakeSureElemStartsOrEndsOnCR(nsINode& aNode,
bool aStarts)
{
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
- nsINode* child = aStarts ? htmlEditor->GetFirstEditableChild(aNode) :
- htmlEditor->GetLastEditableChild(aNode);
+ MOZ_ASSERT(IsEditorDataAvailable());
+
+ nsINode* child = aStarts ? HTMLEditorRef().GetFirstEditableChild(aNode) :
+ HTMLEditorRef().GetLastEditableChild(aNode);
if (NS_WARN_IF(!child)) {
return NS_OK;
}
bool foundCR = false;
if (IsBlockNode(*child) || child->IsHTMLElement(nsGkAtoms::br)) {
foundCR = true;
} else {
nsINode* sibling =
- aStarts ? htmlEditor->GetPriorHTMLSibling(&aNode) :
- htmlEditor->GetNextHTMLSibling(&aNode);
+ aStarts ? HTMLEditorRef().GetPriorHTMLSibling(&aNode) :
+ HTMLEditorRef().GetNextHTMLSibling(&aNode);
if (sibling) {
if (IsBlockNode(*sibling) || sibling->IsHTMLElement(nsGkAtoms::br)) {
foundCR = true;
}
} else {
foundCR = true;
}
}
if (!foundCR) {
- RefPtr<Selection> selection = htmlEditor->GetSelection();
+ RefPtr<Selection> selection = HTMLEditorRef().GetSelection();
if (NS_WARN_IF(!selection)) {
return NS_ERROR_FAILURE;
}
EditorRawDOMPoint pointToInsert;
if (!aStarts) {
pointToInsert.SetToEndOf(&aNode);
} else {
pointToInsert.Set(&aNode, 0);
}
RefPtr<Element> brElement =
- htmlEditor->InsertBrElementWithTransaction(*selection, pointToInsert);
+ HTMLEditorRef().InsertBrElementWithTransaction(*selection, pointToInsert);
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
}
return NS_OK;
}
nsresult
HTMLEditRules::MakeSureElemStartsAndEndsOnCR(nsINode& aNode)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (NS_WARN_IF(!mHTMLEditor)) {
return NS_ERROR_NOT_AVAILABLE;
}
+
Selection* selection = mHTMLEditor->GetSelection();
if (NS_WARN_IF(!selection)) {
return NS_ERROR_FAILURE;
}
AutoSafeEditorData setData(*this, *mHTMLEditor, *selection);
nsresult rv = MakeSureElemStartsOrEndsOnCR(aNode, false);
@@ -9683,51 +9668,55 @@ HTMLEditRules::MakeSureElemStartsAndEnds
return NS_OK;
}
nsresult
HTMLEditRules::AlignBlock(Element& aElement,
const nsAString& aAlignType,
ContentsOnly aContentsOnly)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (!IsBlockNode(aElement) && !aElement.IsHTMLElement(nsGkAtoms::hr)) {
// We deal only with blocks; early way out
return NS_OK;
}
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
nsresult rv = RemoveAlignment(aElement, aAlignType,
aContentsOnly == ContentsOnly::yes);
- NS_ENSURE_SUCCESS(rv, rv);
- if (htmlEditor->IsCSSEnabled()) {
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ if (HTMLEditorRef().IsCSSEnabled()) {
// Let's use CSS alignment; we use margin-left and margin-right for tables
// and text-align for other block-level elements
- return htmlEditor->SetAttributeOrEquivalent(
- &aElement, nsGkAtoms::align, aAlignType, false);
+ return HTMLEditorRef().SetAttributeOrEquivalent(
+ &aElement, nsGkAtoms::align, aAlignType, false);
}
// HTML case; this code is supposed to be called ONLY if the element
// supports the align attribute but we'll never know...
if (NS_WARN_IF(!HTMLEditUtils::SupportsAlignAttr(aElement))) {
// XXX error?
return NS_OK;
}
- return htmlEditor->SetAttributeOrEquivalent(&aElement, nsGkAtoms::align,
- aAlignType, false);
+ rv = HTMLEditorRef().SetAttributeOrEquivalent(&aElement, nsGkAtoms::align,
+ aAlignType, false);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
}
nsresult
HTMLEditRules::ChangeIndentation(Element& aElement,
Change aChange)
{
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
+ MOZ_ASSERT(IsEditorDataAvailable());
nsAtom& marginProperty = MarginPropertyAtomForIndent(aElement);
nsAutoString value;
CSSEditUtils::GetSpecifiedProperty(aElement, marginProperty, value);
float f;
RefPtr<nsAtom> unit;
CSSEditUtils::ParseLength(value, &f, getter_AddRefs(unit));
if (!f) {
@@ -9755,80 +9744,79 @@ HTMLEditRules::ChangeIndentation(Element
} else if (nsGkAtoms::percentage == unit) {
f += NS_EDITOR_INDENT_INCREMENT_PERCENT * multiplier;
}
if (0 < f) {
nsAutoString newValue;
newValue.AppendFloat(f);
newValue.Append(nsDependentAtomString(unit));
- htmlEditor->mCSSEditUtils->SetCSSProperty(aElement, marginProperty,
- newValue);
+ HTMLEditorRef().mCSSEditUtils->SetCSSProperty(aElement, marginProperty,
+ newValue);
return NS_OK;
}
- htmlEditor->mCSSEditUtils->RemoveCSSProperty(aElement, marginProperty,
- value);
+ HTMLEditorRef().mCSSEditUtils->RemoveCSSProperty(aElement, marginProperty,
+ value);
// Remove unnecessary divs
if (!aElement.IsHTMLElement(nsGkAtoms::div) ||
- &aElement == htmlEditor->GetActiveEditingHost() ||
- !htmlEditor->IsDescendantOfEditorRoot(&aElement) ||
+ &aElement == HTMLEditorRef().GetActiveEditingHost() ||
+ !HTMLEditorRef().IsDescendantOfEditorRoot(&aElement) ||
HTMLEditor::HasAttributes(&aElement)) {
return NS_OK;
}
- nsresult rv = htmlEditor->RemoveContainerWithTransaction(aElement);
- NS_ENSURE_SUCCESS(rv, rv);
-
+ nsresult rv = HTMLEditorRef().RemoveContainerWithTransaction(aElement);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
return NS_OK;
}
nsresult
HTMLEditRules::WillAbsolutePosition(Selection& aSelection,
bool* aCancel,
bool* aHandled)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
MOZ_ASSERT(aCancel && aHandled);
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-
WillInsert(aSelection, aCancel);
// We want to ignore result of WillInsert()
*aCancel = false;
*aHandled = true;
- nsCOMPtr<Element> focusElement = htmlEditor->GetSelectionContainer();
+ RefPtr<Element> focusElement = HTMLEditorRef().GetSelectionContainer();
if (focusElement && HTMLEditUtils::IsImage(focusElement)) {
mNewBlock = focusElement;
return NS_OK;
}
nsresult rv = NormalizeSelection(&aSelection);
NS_ENSURE_SUCCESS(rv, rv);
- AutoSelectionRestorer selectionRestorer(&aSelection, htmlEditor);
+ AutoSelectionRestorer selectionRestorer(&aSelection, &HTMLEditorRef());
// Convert the selection ranges into "promoted" selection ranges: this
// basically just expands the range to include the immediate block parent,
// and then further expands to include any ancestors whose children are all
// in the range.
nsTArray<RefPtr<nsRange>> arrayOfRanges;
GetPromotedRanges(aSelection, arrayOfRanges,
EditAction::setAbsolutePosition);
// Use these ranges to contruct a list of nodes to act on.
nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
rv = GetNodesForOperation(arrayOfRanges, arrayOfNodes,
EditAction::setAbsolutePosition);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
// If nothing visible in list, make an empty block
if (ListIsEmptyLine(arrayOfNodes)) {
nsRange* firstRange = aSelection.GetRangeAt(0);
if (NS_WARN_IF(!firstRange)) {
return NS_ERROR_FAILURE;
}
@@ -9840,27 +9828,27 @@ HTMLEditRules::WillAbsolutePosition(Sele
// Make sure we can put a block here.
SplitNodeResult splitNodeResult =
MaybeSplitAncestorsForInsertWithTransaction(*nsGkAtoms::div,
atStartOfSelection);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
RefPtr<Element> positionedDiv =
- htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::div,
- splitNodeResult.SplitPoint());
+ HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::div,
+ splitNodeResult.SplitPoint());
if (NS_WARN_IF(!positionedDiv)) {
return NS_ERROR_FAILURE;
}
// Remember our new block for postprocessing
mNewBlock = positionedDiv;
// Delete anything that was in the list of nodes
while (!arrayOfNodes.IsEmpty()) {
OwningNonNull<nsINode> curNode = arrayOfNodes[0];
- rv = htmlEditor->DeleteNodeWithTransaction(*curNode);
+ rv = HTMLEditorRef().DeleteNodeWithTransaction(*curNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
arrayOfNodes.RemoveElementAt(0);
}
// Put selection in new block
*aHandled = true;
rv = aSelection.Collapse(positionedDiv, 0);
@@ -9876,62 +9864,62 @@ HTMLEditRules::WillAbsolutePosition(Sele
for (OwningNonNull<nsINode>& curNode : arrayOfNodes) {
// Here's where we actually figure out what to do.
EditorDOMPoint atCurNode(curNode);
if (NS_WARN_IF(!atCurNode.IsSet())) {
return NS_ERROR_FAILURE; // XXX not continue??
}
// Ignore all non-editable nodes. Leave them be.
- if (!htmlEditor->IsEditable(curNode)) {
+ if (!HTMLEditorRef().IsEditable(curNode)) {
continue;
}
nsCOMPtr<nsIContent> sibling;
// Some logic for putting list items into nested lists...
if (HTMLEditUtils::IsList(atCurNode.GetContainer())) {
// Check to see if curList is still appropriate. Which it is if curNode
// is still right after it in the same list.
if (curList) {
- sibling = htmlEditor->GetPriorHTMLSibling(curNode);
+ sibling = HTMLEditorRef().GetPriorHTMLSibling(curNode);
}
if (!curList || (sibling && sibling != curList)) {
nsAtom* containerName =
atCurNode.GetContainer()->NodeInfo()->NameAtom();
// Create a new nested list of correct type.
SplitNodeResult splitNodeResult =
MaybeSplitAncestorsForInsertWithTransaction(*containerName,
atCurNode);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
if (!curPositionedDiv) {
curPositionedDiv =
- htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::div,
- splitNodeResult.SplitPoint());
+ HTMLEditorRef().CreateNodeWithTransaction(
+ *nsGkAtoms::div, splitNodeResult.SplitPoint());
NS_WARNING_ASSERTION(curPositionedDiv,
"Failed to create current positioned div element");
mNewBlock = curPositionedDiv;
}
EditorRawDOMPoint atEndOfCurPositionedDiv;
atEndOfCurPositionedDiv.SetToEndOf(curPositionedDiv);
curList =
- htmlEditor->CreateNodeWithTransaction(*containerName,
- atEndOfCurPositionedDiv);
+ HTMLEditorRef().CreateNodeWithTransaction(*containerName,
+ atEndOfCurPositionedDiv);
if (NS_WARN_IF(!curList)) {
return NS_ERROR_FAILURE;
}
// curList is now the correct thing to put curNode in. Remember our
// new block for postprocessing.
}
// Tuck the node into the end of the active list
- rv = htmlEditor->MoveNodeToEndWithTransaction(*curNode->AsContent(),
- *curList);
+ rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(),
+ *curList);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
continue;
}
// Not a list item, use blockquote? If we are inside a list item, we
// don't want to blockquote, we want to sublist the list item. We may
@@ -9943,17 +9931,17 @@ HTMLEditRules::WillAbsolutePosition(Sele
if (listItem) {
if (indentedLI == listItem) {
// Already indented this list item
continue;
}
// Check to see if curList is still appropriate. Which it is if
// curNode is still right after it in the same list.
if (curList) {
- sibling = htmlEditor->GetPriorHTMLSibling(listItem);
+ sibling = HTMLEditorRef().GetPriorHTMLSibling(listItem);
}
if (!curList || (sibling && sibling != curList)) {
EditorDOMPoint atListItem(listItem);
if (NS_WARN_IF(!atListItem.IsSet())) {
return NS_ERROR_FAILURE;
}
nsAtom* containerName =
@@ -9963,32 +9951,32 @@ HTMLEditRules::WillAbsolutePosition(Sele
MaybeSplitAncestorsForInsertWithTransaction(*containerName,
atListItem);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
if (!curPositionedDiv) {
EditorRawDOMPoint atListItemParent(atListItem.GetContainer());
curPositionedDiv =
- htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::div,
- atListItemParent);
+ HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::div,
+ atListItemParent);
NS_WARNING_ASSERTION(curPositionedDiv,
"Failed to create current positioned div element");
mNewBlock = curPositionedDiv;
}
EditorRawDOMPoint atEndOfCurPositionedDiv;
atEndOfCurPositionedDiv.SetToEndOf(curPositionedDiv);
curList =
- htmlEditor->CreateNodeWithTransaction(*containerName,
- atEndOfCurPositionedDiv);
+ HTMLEditorRef().CreateNodeWithTransaction(*containerName,
+ atEndOfCurPositionedDiv);
if (NS_WARN_IF(!curList)) {
return NS_ERROR_FAILURE;
}
}
- rv = htmlEditor->MoveNodeToEndWithTransaction(*listItem, *curList);
+ rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*listItem, *curList);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Remember we indented this li
indentedLI = listItem;
continue;
}
@@ -10002,112 +9990,120 @@ HTMLEditRules::WillAbsolutePosition(Sele
}
SplitNodeResult splitNodeResult =
MaybeSplitAncestorsForInsertWithTransaction(*nsGkAtoms::div,
atCurNode);
if (NS_WARN_IF(splitNodeResult.Failed())) {
return splitNodeResult.Rv();
}
curPositionedDiv =
- htmlEditor->CreateNodeWithTransaction(*nsGkAtoms::div,
- splitNodeResult.SplitPoint());
+ HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::div,
+ splitNodeResult.SplitPoint());
if (NS_WARN_IF(!curPositionedDiv)) {
return NS_ERROR_FAILURE;
}
// Remember our new block for postprocessing
mNewBlock = curPositionedDiv;
// curPositionedDiv is now the correct thing to put curNode in
}
// Tuck the node into the end of the active blockquote
- rv = htmlEditor->MoveNodeToEndWithTransaction(*curNode->AsContent(),
- *curPositionedDiv);
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(),
+ *curPositionedDiv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
// Forget curList, if any
curList = nullptr;
}
return NS_OK;
}
nsresult
HTMLEditRules::DidAbsolutePosition()
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (!mNewBlock) {
return NS_OK;
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor = mHTMLEditor;
- return htmlEditor->SetPositionToAbsoluteOrStatic(*mNewBlock, true);
+ nsresult rv = HTMLEditorRef().SetPositionToAbsoluteOrStatic(*mNewBlock, true);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
}
nsresult
HTMLEditRules::WillRemoveAbsolutePosition(Selection* aSelection,
bool* aCancel,
- bool* aHandled) {
+ bool* aHandled)
+{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (!aSelection || !aCancel || !aHandled) {
return NS_ERROR_NULL_POINTER;
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor = mHTMLEditor;
-
WillInsert(*aSelection, aCancel);
// initialize out param
// we want to ignore aCancel from WillInsert()
*aCancel = false;
*aHandled = true;
RefPtr<Element> element =
- htmlEditor->GetAbsolutelyPositionedSelectionContainer();
+ HTMLEditorRef().GetAbsolutelyPositionedSelectionContainer();
if (NS_WARN_IF(!element)) {
return NS_ERROR_FAILURE;
}
- AutoSelectionRestorer selectionRestorer(aSelection, htmlEditor);
-
- return htmlEditor->SetPositionToAbsoluteOrStatic(*element, false);
+ AutoSelectionRestorer selectionRestorer(aSelection, &HTMLEditorRef());
+
+ nsresult rv = HTMLEditorRef().SetPositionToAbsoluteOrStatic(*element, false);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
}
nsresult
HTMLEditRules::WillRelativeChangeZIndex(Selection* aSelection,
int32_t aChange,
bool* aCancel,
bool* aHandled)
{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
if (!aSelection || !aCancel || !aHandled) {
return NS_ERROR_NULL_POINTER;
}
- if (NS_WARN_IF(!mHTMLEditor)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- RefPtr<HTMLEditor> htmlEditor = mHTMLEditor;
-
WillInsert(*aSelection, aCancel);
// initialize out param
// we want to ignore aCancel from WillInsert()
*aCancel = false;
*aHandled = true;
RefPtr<Element> element =
- htmlEditor->GetAbsolutelyPositionedSelectionContainer();
+ HTMLEditorRef().GetAbsolutelyPositionedSelectionContainer();
if (NS_WARN_IF(!element)) {
return NS_ERROR_FAILURE;
}
- AutoSelectionRestorer selectionRestorer(aSelection, htmlEditor);
+ AutoSelectionRestorer selectionRestorer(aSelection, &HTMLEditorRef());
int32_t zIndex;
- return htmlEditor->RelativeChangeElementZIndex(*element, aChange, &zIndex);
+ nsresult rv = HTMLEditorRef().RelativeChangeElementZIndex(*element, aChange,
+ &zIndex);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
}
nsresult
HTMLEditRules::DocumentModified()
{
nsContentUtils::AddScriptRunner(
NewRunnableMethod("HTMLEditRules::DocumentModifiedWorker",
this,