author | Masayuki Nakano <masayuki@d-toybox.com> |
Thu, 16 Apr 2020 10:32:26 +0000 | |
changeset 524544 | 6119e9d5fce84f307354d3ed9a3aaf8eca8977de |
parent 524543 | d6a4c108cd4038f7b5516c1b3ff916f5c0d98b17 |
child 524545 | 82550851a0d1355170794a63553de2f40b804892 |
push id | 37321 |
push user | dluca@mozilla.com |
push date | Fri, 17 Apr 2020 09:38:52 +0000 |
treeherder | mozilla-central@24537fed53e6 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | m_kato |
bugs | 1627175 |
milestone | 77.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -1142,25 +1142,26 @@ nsresult EditorBase::CollapseSelectionTo } // get the root element Element* rootElement = GetRoot(); if (NS_WARN_IF(!rootElement)) { return NS_ERROR_NULL_POINTER; } - nsINode* node = rootElement; - nsINode* child = node->GetLastChild(); - while (child && IsContainer(child)) { - node = child; - child = node->GetLastChild(); - } - - uint32_t length = node->Length(); - nsresult rv = SelectionRefPtr()->Collapse(node, static_cast<int32_t>(length)); + nsIContent* lastContent = rootElement; + for (nsIContent* child = lastContent->GetLastChild(); + child && (IsTextEditor() || HTMLEditUtils::IsContainerNode(*child)); + child = child->GetLastChild()) { + lastContent = child; + } + + uint32_t length = lastContent->Length(); + nsresult rv = + SelectionRefPtr()->Collapse(lastContent, static_cast<int32_t>(length)); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Selection::Collapse() failed"); return rv; } NS_IMETHODIMP EditorBase::GetDocumentModified(bool* aOutDocModified) { if (NS_WARN_IF(!aOutDocModified)) { return NS_ERROR_INVALID_ARG; } @@ -4023,20 +4024,16 @@ bool EditorBase::IsDescendantOfEditorRoo nsIContent* root = GetEditorRoot(); if (NS_WARN_IF(!root)) { return false; } return aNode->IsInclusiveDescendantOf(root); } -bool EditorBase::IsContainer(nsINode* aNode) const { - return aNode ? true : false; -} - uint32_t EditorBase::CountEditableChildren(nsINode* aNode) { MOZ_ASSERT(aNode); uint32_t count = 0; EditorType editorType = GetEditorType(); for (nsIContent* child = aNode->GetFirstChild(); child; child = child->GetNextSibling()) { if (EditorUtils::IsEditableContent(*child, editorType)) { ++count;
--- a/editor/libeditor/EditorBase.h +++ b/editor/libeditor/EditorBase.h @@ -2062,21 +2062,16 @@ class EditorBase : public nsIEditor, /** * Returns true if aNode is a descendant of our root node. */ bool IsDescendantOfRoot(nsINode* inNode) const; bool IsDescendantOfEditorRoot(nsINode* aNode) const; /** - * Returns true if aNode is a container. - */ - virtual bool IsContainer(nsINode* aNode) const; - - /** * Counts number of editable child nodes. */ uint32_t CountEditableChildren(nsINode* aNode); /** * Find the deep first and last children. */ nsINode* GetFirstEditableNode(nsINode* aRoot);
--- a/editor/libeditor/HTMLEditSubActionHandler.cpp +++ b/editor/libeditor/HTMLEditSubActionHandler.cpp @@ -3582,17 +3582,17 @@ EditorDOMPoint HTMLEditor::GetGoodCaretP aDirectionAndAmount == nsIEditor::eNextWord || aDirectionAndAmount == nsIEditor::eToEndOfLine); // XXX Why don't we check whether the candidate position is enable or not? // When the result is not editable point, caret will be enclosed in // the non-editable content. // If we can put caret in aContent, return start or end in it. - if (aContent.IsText() || IsContainer(&aContent) || + if (aContent.IsText() || HTMLEditUtils::IsContainerNode(aContent) || NS_WARN_IF(!aContent.GetParentNode())) { return EditorDOMPoint(&aContent, goingForward ? 0 : aContent.Length()); } // If we are going forward, put caret at aContent itself. if (goingForward) { return EditorDOMPoint(&aContent); } @@ -6611,17 +6611,19 @@ nsresult HTMLEditor::CreateStyleForInser if (splitTextNodeResult.Failed()) { NS_WARNING( "EditorBase::SplitNodeDeepWithTransaction(SplitAtEdges::" "eAllowToCreateEmptyContainer) failed"); return splitTextNodeResult.Rv(); } pointToPutCaret = splitTextNodeResult.SplitPoint(); } - if (!IsContainer(pointToPutCaret.GetContainer())) { + if (!pointToPutCaret.IsInContentNode() || + !HTMLEditUtils::IsContainerNode( + *pointToPutCaret.ContainerAsContent())) { return NS_OK; } RefPtr<Text> newEmptyTextNode = CreateTextNode(EmptyString()); if (!newEmptyTextNode) { NS_WARNING("EditorBase::CreateTextNode() failed"); return NS_ERROR_FAILURE; } nsresult rv = InsertNodeWithTransaction(*newEmptyTextNode, pointToPutCaret); @@ -8345,18 +8347,18 @@ nsresult HTMLEditor::MaybeSplitElementsA case EditSubAction::eMergeBlockContents: case EditSubAction::eCreateOrChangeList: case EditSubAction::eSetOrClearAlignment: case EditSubAction::eSetPositionToAbsolute: case EditSubAction::eIndent: case EditSubAction::eOutdent: for (int32_t i = aArrayOfContents.Length() - 1; i >= 0; i--) { OwningNonNull<nsIContent>& content = aArrayOfContents[i]; - if (HTMLEditUtils::IsInlineElement(content) && IsContainer(content) && - !content->IsText()) { + if (HTMLEditUtils::IsInlineElement(content) && + HTMLEditUtils::IsContainerNode(content) && !content->IsText()) { AutoTArray<OwningNonNull<nsIContent>, 24> arrayOfInlineContents; // MOZ_KnownLive because 'aArrayOfContents' is guaranteed to keep it // alive. nsresult rv = SplitElementsAtEveryBRElement(MOZ_KnownLive(content), arrayOfInlineContents); if (NS_FAILED(rv)) { NS_WARNING("HTMLEditor::SplitElementsAtEveryBRElement() failed"); return rv; @@ -9010,17 +9012,17 @@ nsresult HTMLEditor::SplitParagraph( NS_WARNING("HTMLEditor::InsertBRElementIfEmptyBlockElement() failed"); return rv; } } // selection to beginning of right hand para; // look inside any containers that are up front. nsCOMPtr<nsIContent> child = GetLeftmostChild(&aParentDivOrP, true); - if (child && (child->IsText() || IsContainer(child))) { + if (child && (child->IsText() || HTMLEditUtils::IsContainerNode(*child))) { nsresult rv = CollapseSelectionToStartOf(*child); if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) { return NS_ERROR_EDITOR_DESTROYED; } NS_WARNING_ASSERTION( NS_SUCCEEDED(rv), "HTMLEditor::CollapseSelectionToStartOf() failed, but ignored"); } else { @@ -10129,17 +10131,18 @@ nsresult HTMLEditor::EnsureCaretInBlockE if (nodeBefore) { // selection is after block. put at end of block. nsIContent* lastEditableContent = GetLastEditableChild(aElement); if (!lastEditableContent) { lastEditableContent = &aElement; } EditorRawDOMPoint endPoint; - if (lastEditableContent->IsText() || IsContainer(lastEditableContent)) { + if (lastEditableContent->IsText() || + HTMLEditUtils::IsContainerNode(*lastEditableContent)) { endPoint.SetToEndOf(lastEditableContent); } else { endPoint.SetAfter(lastEditableContent); if (NS_WARN_IF(!endPoint.IsSet())) { return NS_ERROR_FAILURE; } } nsresult rv = CollapseSelectionTo(endPoint); @@ -10149,17 +10152,18 @@ nsresult HTMLEditor::EnsureCaretInBlockE } // selection is before block. put at start of block. nsIContent* firstEditableContent = GetFirstEditableChild(aElement); if (!firstEditableContent) { firstEditableContent = &aElement; } EditorRawDOMPoint atStartOfBlock; - if (firstEditableContent->IsText() || IsContainer(firstEditableContent)) { + if (firstEditableContent->IsText() || + HTMLEditUtils::IsContainerNode(*firstEditableContent)) { atStartOfBlock.Set(firstEditableContent); } else { atStartOfBlock.Set(firstEditableContent, 0); } rv = CollapseSelectionTo(atStartOfBlock); NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HTMLEditor::CollapseSelectionTo() failed"); return rv;
--- a/editor/libeditor/HTMLEditUtils.cpp +++ b/editor/libeditor/HTMLEditUtils.cpp @@ -631,21 +631,21 @@ bool HTMLEditUtils::CanNodeContain(nsHTM if (aParentTagId == aChildTagId) { return parent.mCanContainSelf; } const ElementInfo& child = kElements[aChildTagId - 1]; return !!(parent.mCanContainGroups & child.mGroup); } -bool HTMLEditUtils::IsContainer(int32_t aTag) { - NS_ASSERTION(aTag > eHTMLTag_unknown && aTag <= eHTMLTag_userdefined, - "aTag out of range!"); +bool HTMLEditUtils::IsContainerNode(nsHTMLTag aTagId) { + NS_ASSERTION(aTagId > eHTMLTag_unknown && aTagId <= eHTMLTag_userdefined, + "aTagId out of range!"); - return kElements[aTag - 1].mIsContainer; + return kElements[aTagId - 1].mIsContainer; } bool HTMLEditUtils::IsNonListSingleLineContainer(nsINode& aNode) { return aNode.IsAnyOfHTMLElements( nsGkAtoms::address, nsGkAtoms::div, nsGkAtoms::h1, nsGkAtoms::h2, nsGkAtoms::h3, nsGkAtoms::h4, nsGkAtoms::h5, nsGkAtoms::h6, nsGkAtoms::listing, nsGkAtoms::p, nsGkAtoms::pre, nsGkAtoms::xmp); }
--- a/editor/libeditor/HTMLEditUtils.h +++ b/editor/libeditor/HTMLEditUtils.h @@ -92,17 +92,16 @@ class HTMLEditUtils final { static bool IsPre(nsINode* aNode); static bool IsImage(nsINode* aNode); static bool IsLink(nsINode* aNode); static bool IsNamedAnchor(nsINode* aNode); static bool IsMozDiv(nsINode* aNode); static bool IsMailCite(nsINode* aNode); static bool IsFormWidget(nsINode* aNode); static bool SupportsAlignAttr(nsINode& aNode); - static bool IsContainer(int32_t aTag); static bool CanNodeContain(const nsINode& aParent, const nsIContent& aChild) { switch (aParent.NodeType()) { case nsINode::ELEMENT_NODE: case nsINode::DOCUMENT_FRAGMENT_NODE: return HTMLEditUtils::CanNodeContain(*aParent.NodeInfo()->NameAtom(), aChild); } @@ -165,16 +164,32 @@ class HTMLEditUtils final { } // XXX Otherwise, Chromium checks the CSS box is a block, but we don't do it // for now. return false; } /** + * IsContainerNode() returns true if aContent is a container node. + */ + static bool IsContainerNode(const nsIContent& aContent) { + nsHTMLTag tagEnum; + // XXX Should this handle #cdata-section too? + if (aContent.IsText()) { + tagEnum = eHTMLTag_text; + } else { + // XXX Why don't we use nsHTMLTags::AtomTagToId? Are there some + // difference? + tagEnum = nsHTMLTags::StringTagToId(aContent.NodeName()); + } + return HTMLEditUtils::IsContainerNode(tagEnum); + } + + /** * See execCommand spec: * https://w3c.github.io/editing/execCommand.html#non-list-single-line-container * https://w3c.github.io/editing/execCommand.html#single-line-container */ static bool IsNonListSingleLineContainer(nsINode& aNode); static bool IsSingleLineContainer(nsINode& aNode); static EditAction GetEditActionForInsert(const nsAtom& aTagName); @@ -182,16 +197,17 @@ class HTMLEditUtils final { static EditAction GetEditActionForInsert(const Element& aElement); static EditAction GetEditActionForFormatText(const nsAtom& aProperty, const nsAtom* aAttribute, bool aToSetStyle); static EditAction GetEditActionForAlignment(const nsAString& aAlignType); private: static bool CanNodeContain(nsHTMLTag aParentTagId, nsHTMLTag aChildTagId); + static bool IsContainerNode(nsHTMLTag aTagId); }; /** * DefinitionListItemScanner() scans given `<dl>` element's children. * Then, you can check whether `<dt>` and/or `<dd>` elements are in it. */ class MOZ_STACK_CLASS DefinitionListItemScanner final { public:
--- a/editor/libeditor/HTMLEditor.cpp +++ b/editor/libeditor/HTMLEditor.cpp @@ -622,17 +622,19 @@ nsresult HTMLEditor::MaybeCollapseSelect // run. That is, although we are calling a method that is named // "ScanNextVisibleNodeOrBlockBoundary", the node returned might not // be visible/editable! // However, we were given a block that is not a container. Since the // block can not contain anything that's visible, such a block only // makes sense if it is visible by itself, like a <hr>. We want to // place the caret in front of that block. - if (!IsContainer(forwardScanFromPointToPutCaretResult.GetContent())) { + if (!forwardScanFromPointToPutCaretResult.GetContent() || + !HTMLEditUtils::IsContainerNode( + *forwardScanFromPointToPutCaretResult.GetContent())) { pointToPutCaret = forwardScanFromPointToPutCaretResult.RawPointAtContent(); break; } // If the given block does not contain any visible/editable items, we want // to skip it and continue our search. if (IsEmptyNode(*forwardScanFromPointToPutCaretResult.GetContent())) { @@ -805,17 +807,18 @@ NS_IMETHODIMP HTMLEditor::NodeIsBlock(ns *aIsBlock = aNode && aNode->IsContent() && HTMLEditUtils::IsBlockElement(*aNode->AsContent()); return NS_OK; } bool HTMLEditor::IsEmptyInlineNode(nsIContent& aContent) const { MOZ_ASSERT(IsEditActionDataAvailable()); - if (!HTMLEditUtils::IsInlineElement(aContent) || !IsContainer(&aContent)) { + if (!HTMLEditUtils::IsInlineElement(aContent) || + !HTMLEditUtils::IsContainerNode(aContent)) { return false; } return IsEmptyNode(aContent); } /** * GetBlockNodeParent returns enclosing block level ancestor, if any. */ @@ -1219,20 +1222,21 @@ nsresult HTMLEditor::InsertBRElementAtSe void HTMLEditor::CollapseSelectionToDeepestNonTableFirstChild(nsINode* aNode) { MOZ_ASSERT(IsEditActionDataAvailable()); MOZ_ASSERT(aNode); nsCOMPtr<nsINode> node = aNode; - for (nsCOMPtr<nsIContent> child = node->GetFirstChild(); child; + for (nsIContent* child = node->GetFirstChild(); child; child = child->GetFirstChild()) { // Stop if we find a table, don't want to go into nested tables - if (HTMLEditUtils::IsTable(child) || !IsContainer(child)) { + if (HTMLEditUtils::IsTable(child) || + !HTMLEditUtils::IsContainerNode(*child)) { break; } node = child; } DebugOnly<nsresult> rvIgnored = CollapseSelectionToStartOf(*node); NS_WARNING_ASSERTION( NS_SUCCEEDED(rvIgnored), @@ -3758,30 +3762,16 @@ MOZ_CAN_RUN_SCRIPT_BOUNDARY void HTMLEdi return; } NS_WARNING_ASSERTION( NS_SUCCEEDED(rv), "HTMLEditor::OnDocumentModified() failed, but ignored"); } } -bool HTMLEditor::IsContainer(nsINode* aNode) const { - MOZ_ASSERT(aNode); - - int32_t tagEnum; - // XXX Should this handle #cdata-section too? - if (aNode->IsText()) { - tagEnum = eHTMLTag_text; - } else { - tagEnum = nsHTMLTags::StringTagToId(aNode->NodeName()); - } - - return HTMLEditUtils::IsContainer(tagEnum); -} - nsresult HTMLEditor::SelectEntireDocument() { MOZ_ASSERT(IsEditActionDataAvailable()); if (!mInitSucceeded) { return NS_ERROR_NOT_INITIALIZED; } // XXX It's odd to select all of the document body if an contenteditable @@ -4339,17 +4329,18 @@ bool HTMLEditor::IsEmptyNodeImpl(nsINode } // if it's not a text node (handled above) and it's not a container, // then we don't call it empty (it's an <hr>, or <br>, etc.). // Also, if it's an anchor then don't treat it as empty - even though // anchors are containers, named anchors are "empty" but we don't // want to treat them as such. Also, don't call ListItems or table // cells empty if caller desires. Form Widgets not empty. - if (!IsContainer(&aNode) || + if (!aNode.IsContent() || + !HTMLEditUtils::IsContainerNode(*aNode.AsContent()) || (HTMLEditUtils::IsNamedAnchor(&aNode) || HTMLEditUtils::IsFormWidget(&aNode) || (aListOrCellNotEmpty && (HTMLEditUtils::IsListItem(&aNode) || HTMLEditUtils::IsTableCell(&aNode))))) { return false; } // need this for later
--- a/editor/libeditor/HTMLEditor.h +++ b/editor/libeditor/HTMLEditor.h @@ -875,21 +875,16 @@ class HTMLEditor final : public TextEdit * @param aChange [IN] relative change to apply to current z-index of * the element * @param aReturn [OUT] the new z-index of the element */ [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult RelativeChangeElementZIndex( Element& aElement, int32_t aChange, int32_t* aReturn); /** - * Returns true if aNode is a container. - */ - virtual bool IsContainer(nsINode* aNode) const override; - - /** * Join together any adjacent editable text nodes in the range. */ MOZ_CAN_RUN_SCRIPT nsresult CollapseAdjacentTextNodes(nsRange& aRange); /** * IsInVisibleTextFrames() returns true if all text in aText is in visible * text frames. Callers have to guarantee that there is no pending reflow. */
--- a/editor/libeditor/HTMLEditorDataTransfer.cpp +++ b/editor/libeditor/HTMLEditorDataTransfer.cpp @@ -686,17 +686,17 @@ nsresult HTMLEditor::DoInsertHTMLWithCon // node. if (!containerContent) { containerContent = lastInsertedPoint.GetChild(); } // If the container is a text node or a container element except `<table>` // element, put caret a end of it. if (containerContent->IsText() || - (IsContainer(containerContent) && + (HTMLEditUtils::IsContainerNode(*containerContent) && !HTMLEditUtils::IsTable(containerContent))) { pointToPutCaret.SetToEndOf(containerContent); } // Otherwise, i.e., it's an atomic element, `<table>` element or data node, // put caret after it. else { pointToPutCaret.Set(containerContent); DebugOnly<bool> advanced = pointToPutCaret.AdvanceOffset();
--- a/editor/libeditor/HTMLStyleEditor.cpp +++ b/editor/libeditor/HTMLStyleEditor.cpp @@ -884,17 +884,19 @@ EditResult HTMLEditor::ClearStyleAt(cons GetLeftmostChild(splitResult.GetNextNode()); EditorDOMPoint atStartOfNextNode(leftmostChildOfNextNode ? leftmostChildOfNextNode : splitResult.GetNextNode(), 0); RefPtr<HTMLBRElement> brElement; // But don't try to split non-containers like `<br>`, `<hr>` and `<img>` // element. - if (!IsContainer(atStartOfNextNode.GetContainer())) { + if (!atStartOfNextNode.IsInContentNode() || + !HTMLEditUtils::IsContainerNode( + *atStartOfNextNode.ContainerAsContent())) { // If it's a `<br>` element, let's move it into new node later. brElement = HTMLBRElement::FromNode(atStartOfNextNode.GetContainer()); if (!atStartOfNextNode.GetContainerParentAsContent()) { NS_WARNING("atStartOfNextNode was in an orphan node"); return EditResult(NS_ERROR_FAILURE); } atStartOfNextNode.Set(atStartOfNextNode.GetContainerParent(), 0); }
--- a/editor/libeditor/WSRunObject.cpp +++ b/editor/libeditor/WSRunObject.cpp @@ -1094,69 +1094,71 @@ nsIContent* WSRunScanner::GetPreviousWSN MOZ_ASSERT(aStartNode && aBlockParent); if (aStartNode == mEditingHost) { NS_WARNING( "WSRunScanner::GetPreviousWSNodeInner() was called with editing host"); return nullptr; } - nsCOMPtr<nsIContent> priorNode = aStartNode->GetPreviousSibling(); + nsCOMPtr<nsIContent> previousContent = aStartNode->GetPreviousSibling(); OwningNonNull<nsINode> curNode = *aStartNode; - while (!priorNode) { + while (!previousContent) { // We have exhausted nodes in parent of aStartNode. nsCOMPtr<nsINode> curParent = curNode->GetParentNode(); if (!curParent) { NS_WARNING("Reached orphan node while climbing up the DOM tree"); return nullptr; } if (curParent == aBlockParent) { // We have exhausted nodes in the block parent. The convention here is // to return null. return nullptr; } if (curParent == mEditingHost) { NS_WARNING("Reached editing host while climbing up the DOM tree"); return nullptr; } // We have a parent: look for previous sibling - priorNode = curParent->GetPreviousSibling(); + previousContent = curParent->GetPreviousSibling(); curNode = curParent; } - if (!priorNode) { + if (!previousContent) { return nullptr; } // We have a prior node. If it's a block, return it. - if (HTMLEditUtils::IsBlockElement(*priorNode)) { - return priorNode; + if (HTMLEditUtils::IsBlockElement(*previousContent)) { + return previousContent; } - if (mHTMLEditor->IsContainer(priorNode)) { + if (HTMLEditUtils::IsContainerNode(*previousContent)) { // Else if it's a container, get deep rightmost child - nsCOMPtr<nsIContent> child = mHTMLEditor->GetRightmostChild(priorNode); + nsCOMPtr<nsIContent> child = + mHTMLEditor->GetRightmostChild(previousContent); if (child) { return child; } } // Else return the node itself - return priorNode; + return previousContent; } nsIContent* WSRunScanner::GetPreviousWSNode(const EditorDOMPoint& aPoint, nsINode* aBlockParent) const { // Can't really recycle various getnext/prior routines because we // have special needs here. Need to step into inline containers but // not block containers. MOZ_ASSERT(aPoint.IsSet() && aBlockParent); if (aPoint.IsInTextNode()) { return GetPreviousWSNodeInner(aPoint.GetContainer(), aBlockParent); } - if (!mHTMLEditor->IsContainer(aPoint.GetContainer())) { + if (!aPoint.IsInContentNode() || + !HTMLEditUtils::IsContainerNode(*aPoint.ContainerAsContent())) { return GetPreviousWSNodeInner(aPoint.GetContainer(), aBlockParent); } if (!aPoint.Offset()) { if (aPoint.GetContainer() == aBlockParent) { // We are at start of the block. return nullptr; } @@ -1164,133 +1166,135 @@ nsIContent* WSRunScanner::GetPreviousWSN // We are at start of non-block container return GetPreviousWSNodeInner(aPoint.GetContainer(), aBlockParent); } if (NS_WARN_IF(!aPoint.IsInContentNode())) { return nullptr; } - nsCOMPtr<nsIContent> priorNode = aPoint.GetPreviousSiblingOfChild(); - if (NS_WARN_IF(!priorNode)) { + nsCOMPtr<nsIContent> previousContent = aPoint.GetPreviousSiblingOfChild(); + if (NS_WARN_IF(!previousContent)) { return nullptr; } // We have a prior node. If it's a block, return it. - if (HTMLEditUtils::IsBlockElement(*priorNode)) { - return priorNode; + if (HTMLEditUtils::IsBlockElement(*previousContent)) { + return previousContent; } - if (mHTMLEditor->IsContainer(priorNode)) { + if (HTMLEditUtils::IsContainerNode(*previousContent)) { // Else if it's a container, get deep rightmost child - nsCOMPtr<nsIContent> child = mHTMLEditor->GetRightmostChild(priorNode); + nsCOMPtr<nsIContent> child = + mHTMLEditor->GetRightmostChild(previousContent); if (child) { return child; } } // Else return the node itself - return priorNode; + return previousContent; } nsIContent* WSRunScanner::GetNextWSNodeInner(nsINode* aStartNode, nsINode* aBlockParent) const { // Can't really recycle various getnext/prior routines because we have // special needs here. Need to step into inline containers but not block // containers. MOZ_ASSERT(aStartNode && aBlockParent); if (aStartNode == mEditingHost) { NS_WARNING( "WSRunScanner::GetNextWSNodeInner() was called with editing host"); return nullptr; } - nsCOMPtr<nsIContent> nextNode = aStartNode->GetNextSibling(); + nsCOMPtr<nsIContent> nextContent = aStartNode->GetNextSibling(); nsCOMPtr<nsINode> curNode = aStartNode; - while (!nextNode) { + while (!nextContent) { // We have exhausted nodes in parent of aStartNode. nsCOMPtr<nsINode> curParent = curNode->GetParentNode(); if (!curParent) { NS_WARNING("Reached orphan node while climbing up the DOM tree"); return nullptr; } if (curParent == aBlockParent) { // We have exhausted nodes in the block parent. The convention here is // to return null. return nullptr; } if (curParent == mEditingHost) { NS_WARNING("Reached editing host while climbing up the DOM tree"); return nullptr; } // We have a parent: look for next sibling - nextNode = curParent->GetNextSibling(); + nextContent = curParent->GetNextSibling(); curNode = curParent; } - if (!nextNode) { + if (!nextContent) { return nullptr; } // We have a next node. If it's a block, return it. - if (HTMLEditUtils::IsBlockElement(*nextNode)) { - return nextNode; + if (HTMLEditUtils::IsBlockElement(*nextContent)) { + return nextContent; } - if (mHTMLEditor->IsContainer(nextNode)) { + if (HTMLEditUtils::IsContainerNode(*nextContent)) { // Else if it's a container, get deep leftmost child - nsCOMPtr<nsIContent> child = mHTMLEditor->GetLeftmostChild(nextNode); + nsCOMPtr<nsIContent> child = mHTMLEditor->GetLeftmostChild(nextContent); if (child) { return child; } } // Else return the node itself - return nextNode; + return nextContent; } nsIContent* WSRunScanner::GetNextWSNode(const EditorDOMPoint& aPoint, nsINode* aBlockParent) const { // Can't really recycle various getnext/prior routines because we have // special needs here. Need to step into inline containers but not block // containers. MOZ_ASSERT(aPoint.IsSet() && aBlockParent); if (aPoint.IsInTextNode()) { return GetNextWSNodeInner(aPoint.GetContainer(), aBlockParent); } - if (!mHTMLEditor->IsContainer(aPoint.GetContainer())) { + if (!aPoint.IsInContentNode() || + !HTMLEditUtils::IsContainerNode(*aPoint.ContainerAsContent())) { return GetNextWSNodeInner(aPoint.GetContainer(), aBlockParent); } if (NS_WARN_IF(!aPoint.IsInContentNode())) { return nullptr; } - nsCOMPtr<nsIContent> nextNode = aPoint.GetChild(); - if (!nextNode) { + nsCOMPtr<nsIContent> nextContent = aPoint.GetChild(); + if (!nextContent) { if (aPoint.GetContainer() == aBlockParent) { // We are at end of the block. return nullptr; } // We are at end of non-block container return GetNextWSNodeInner(aPoint.GetContainer(), aBlockParent); } // We have a next node. If it's a block, return it. - if (HTMLEditUtils::IsBlockElement(*nextNode)) { - return nextNode; + if (HTMLEditUtils::IsBlockElement(*nextContent)) { + return nextContent; } - if (mHTMLEditor->IsContainer(nextNode)) { + if (HTMLEditUtils::IsContainerNode(*nextContent)) { // else if it's a container, get deep leftmost child - nsCOMPtr<nsIContent> child = mHTMLEditor->GetLeftmostChild(nextNode); + nsCOMPtr<nsIContent> child = mHTMLEditor->GetLeftmostChild(nextContent); if (child) { return child; } } // Else return the node itself - return nextNode; + return nextContent; } nsresult WSRunObject::PrepareToDeleteRangePriv(WSRunObject* aEndObject) { // this routine adjust whitespace before *this* and after aEndObject // in preperation for the two areas to become adjacent after the // intervening content is deleted. It's overly agressive right // now. There might be a block boundary remaining between them after // the deletion, in which case these adjstments are unneeded (though