Bug 1191356 part 6 - Clean up nsHTMLEditRules::WillMakeBasicBlock; r=ehsan

This commit is contained in:
Aryeh Gregor 2016-05-01 17:58:17 +03:00
parent feaa3aff7d
commit 1d5314df0c
2 changed files with 101 additions and 103 deletions

View File

@ -656,7 +656,8 @@ nsHTMLEditRules::WillDoAction(Selection* aSelection,
case EditAction::align:
return WillAlign(*aSelection, *info->alignType, aCancel, aHandled);
case EditAction::makeBasicBlock:
return WillMakeBasicBlock(aSelection, info->blockType, aCancel, aHandled);
return WillMakeBasicBlock(*aSelection, *info->blockType, aCancel,
aHandled);
case EditAction::removeList:
return WillRemoveList(aSelection, info->bOrdered, aCancel, aHandled);
case EditAction::makeDefListItem:
@ -3329,154 +3330,137 @@ nsHTMLEditRules::WillMakeDefListItem(Selection* aSelection,
}
nsresult
nsHTMLEditRules::WillMakeBasicBlock(Selection* aSelection,
const nsAString *aBlockType,
bool *aCancel,
bool *aHandled)
nsHTMLEditRules::WillMakeBasicBlock(Selection& aSelection,
const nsAString& aBlockType,
bool* aCancel,
bool* aHandled)
{
<<<<<<< HEAD
OwningNonNull<nsIAtom> blockType = NS_Atomize(*aBlockType);
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
// initialize out param
=======
MOZ_ASSERT(aCancel && aHandled);
NS_ENSURE_STATE(mHTMLEditor);
nsCOMPtr<nsIEditor> kungFuDeathGrip(mHTMLEditor);
OwningNonNull<nsIAtom> blockType = do_GetAtom(aBlockType);
WillInsert(aSelection, aCancel);
// We want to ignore result of WillInsert()
>>>>>>> Bug 1191356 part 6 - Clean up nsHTMLEditRules::WillMakeBasicBlock
*aCancel = false;
*aHandled = false;
WillInsert(*aSelection, aCancel);
// initialize out param
// we want to ignore result of WillInsert()
*aCancel = false;
nsresult res = NormalizeSelection(aSelection);
nsresult res = NormalizeSelection(&aSelection);
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_STATE(mHTMLEditor);
nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor);
NS_ENSURE_STATE(mHTMLEditor);
nsAutoSelectionReset selectionResetter(&aSelection, mHTMLEditor);
nsAutoTxnsConserveSelection dontSpazMySelection(mHTMLEditor);
*aHandled = true;
nsString tString(*aBlockType);
// contruct a list of nodes to act on.
// Contruct a list of nodes to act on.
nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
res = GetNodesFromSelection(*aSelection, EditAction::makeBasicBlock,
res = GetNodesFromSelection(aSelection, EditAction::makeBasicBlock,
arrayOfNodes);
NS_ENSURE_SUCCESS(res, res);
// Remove all non-editable nodes. Leave them be.
int32_t listCount = arrayOfNodes.Length();
int32_t i;
for (i=listCount-1; i>=0; i--)
{
NS_ENSURE_STATE(mHTMLEditor);
for (int32_t i = arrayOfNodes.Length() - 1; i >= 0; i--) {
if (!mHTMLEditor->IsEditable(arrayOfNodes[i])) {
arrayOfNodes.RemoveElementAt(i);
}
}
// reset list count
listCount = arrayOfNodes.Length();
// If nothing visible in list, make an empty block
if (ListIsEmptyLine(arrayOfNodes)) {
// Get selection location
NS_ENSURE_STATE(aSelection.GetRangeAt(0) &&
aSelection.GetRangeAt(0)->GetStartParent());
OwningNonNull<nsINode> parent =
*aSelection.GetRangeAt(0)->GetStartParent();
int32_t offset = aSelection.GetRangeAt(0)->StartOffset();
// if nothing visible in list, make an empty block
if (ListIsEmptyLine(arrayOfNodes))
{
nsCOMPtr<nsIDOMNode> theBlock;
// get selection location
NS_ENSURE_STATE(aSelection->RangeCount());
nsCOMPtr<nsINode> parent = aSelection->GetRangeAt(0)->GetStartParent();
int32_t offset = aSelection->GetRangeAt(0)->StartOffset();
NS_ENSURE_STATE(parent);
if (tString.EqualsLiteral("normal") ||
tString.IsEmpty() ) // we are removing blocks (going to "body text")
{
NS_ENSURE_STATE(mHTMLEditor);
nsCOMPtr<Element> curBlock = mHTMLEditor->GetBlock(*parent);
NS_ENSURE_TRUE(curBlock, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMNode> curBlockPar =
GetAsDOMNode(curBlock->GetParentNode());
if (nsHTMLEditUtils::IsFormatNode(curBlock))
{
// 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<nsIDOMNode> brNode;
NS_ENSURE_STATE(mHTMLEditor);
res = mHTMLEditor->GetNextHTMLNode(parent->AsDOMNode(), offset,
address_of(brNode));
NS_ENSURE_SUCCESS(res, res);
if (brNode && nsTextEditUtils::IsBreak(brNode))
{
NS_ENSURE_STATE(mHTMLEditor);
if (blockType == nsGkAtoms::normal ||
blockType == nsGkAtoms::_empty) {
// We are removing blocks (going to "body text")
NS_ENSURE_TRUE(mHTMLEditor->GetBlock(parent), NS_ERROR_NULL_POINTER);
OwningNonNull<Element> curBlock = *mHTMLEditor->GetBlock(parent);
if (nsHTMLEditUtils::IsFormatNode(curBlock)) {
// 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> brNode =
mHTMLEditor->GetNextHTMLNode(parent, offset);
if (brNode && brNode->IsHTMLElement(nsGkAtoms::br)) {
res = mHTMLEditor->DeleteNode(brNode);
NS_ENSURE_SUCCESS(res, res);
}
// do the splits!
NS_ENSURE_STATE(mHTMLEditor);
offset = mHTMLEditor->SplitNodeDeep(*curBlock, *parent->AsContent(),
// Do the splits!
offset = mHTMLEditor->SplitNodeDeep(curBlock, *parent->AsContent(),
offset,
nsHTMLEditor::EmptyContainers::no);
NS_ENSURE_STATE(offset != -1);
// put a br at the split point
NS_ENSURE_STATE(mHTMLEditor);
res = mHTMLEditor->CreateBR(curBlockPar, offset, address_of(brNode));
NS_ENSURE_SUCCESS(res, res);
// put selection at the split point
res = aSelection->Collapse(curBlockPar, offset);
selectionResetter.Abort(); // to prevent selection reseter from overriding us.
// Put a br at the split point
brNode = mHTMLEditor->CreateBR(curBlock->GetParentNode(), offset);
NS_ENSURE_STATE(brNode);
// Put selection at the split point
res = aSelection.Collapse(curBlock->GetParentNode(), offset);
// To prevent selection resetter from overriding us.
selectionResetter.Abort();
*aHandled = true;
NS_ENSURE_SUCCESS(res, res);
}
// else nothing to do!
}
else // we are making a block
{
// consume a br, if needed
NS_ENSURE_STATE(mHTMLEditor);
// Else nothing to do!
} else {
// We are making a block. Consume a br, if needed.
nsCOMPtr<nsIContent> brNode =
mHTMLEditor->GetNextHTMLNode(parent, offset, true);
NS_ENSURE_SUCCESS(res, res);
if (brNode && nsTextEditUtils::IsBreak(brNode))
{
NS_ENSURE_STATE(mHTMLEditor);
if (brNode && brNode->IsHTMLElement(nsGkAtoms::br)) {
res = mHTMLEditor->DeleteNode(brNode);
NS_ENSURE_SUCCESS(res, res);
// we don't need to act on this node any more
// We don't need to act on this node any more
arrayOfNodes.RemoveElement(brNode);
}
// make sure we can put a block here
// Make sure we can put a block here
res = SplitAsNeeded(blockType, parent, offset);
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_STATE(mHTMLEditor);
theBlock = dont_AddRef(GetAsDOMNode(
mHTMLEditor->CreateNode(blockType, parent, offset).take()));
NS_ENSURE_STATE(theBlock);
// remember our new block for postprocessing
mNewBlock = theBlock;
// delete anything that was in the list of nodes
nsCOMPtr<Element> block =
mHTMLEditor->CreateNode(blockType, parent, offset);
NS_ENSURE_STATE(block);
// Remember our new block for postprocessing
mNewBlock = block->AsDOMNode();
// Delete anything that was in the list of nodes
while (!arrayOfNodes.IsEmpty()) {
OwningNonNull<nsINode> curNode = arrayOfNodes[0];
NS_ENSURE_STATE(mHTMLEditor);
res = mHTMLEditor->DeleteNode(curNode);
NS_ENSURE_SUCCESS(res, res);
arrayOfNodes.RemoveElementAt(0);
}
// put selection in new block
res = aSelection->Collapse(theBlock,0);
selectionResetter.Abort(); // to prevent selection reseter from overriding us.
// Put selection in new block
res = aSelection.Collapse(block, 0);
// To prevent selection resetter from overriding us.
selectionResetter.Abort();
*aHandled = true;
NS_ENSURE_SUCCESS(res, res);
}
return res;
return NS_OK;
}
else
{
// Ok, now go through all the nodes and make the right kind of blocks,
// or whatever is approriate. Wohoo!
// Note: blockquote is handled a little differently
if (tString.EqualsLiteral("blockquote")) {
res = MakeBlockquote(arrayOfNodes);
} else if (tString.EqualsLiteral("normal") || tString.IsEmpty()) {
res = RemoveBlockStyle(arrayOfNodes);
} else {
res = ApplyBlockStyle(arrayOfNodes, *blockType);
}
return res;
// Okay, now go through all the nodes and make the right kind of blocks, or
// whatever is approriate. Woohoo! Note: blockquote is handled a little
// differently.
if (blockType == nsGkAtoms::blockquote) {
res = MakeBlockquote(arrayOfNodes);
NS_ENSURE_SUCCESS(res, res);
} else if (blockType == nsGkAtoms::normal ||
blockType == nsGkAtoms::_empty) {
res = RemoveBlockStyle(arrayOfNodes);
NS_ENSURE_SUCCESS(res, res);
} else {
res = ApplyBlockStyle(arrayOfNodes, blockType);
NS_ENSURE_SUCCESS(res, res);
}
return res;
return NS_OK;
}
nsresult
@ -6863,6 +6847,18 @@ nsHTMLEditRules::ApplyBlockStyle(nsTArray<OwningNonNull<nsINode>>& aNodeArray,
// SplitAsNeeded: Given a tag name, split inOutParent up to the point where we
// can insert the tag. Adjust inOutParent and inOutOffset to
// point to new location for tag.
nsresult
nsHTMLEditRules::SplitAsNeeded(nsIAtom& aTag,
OwningNonNull<nsINode>& aInOutParent,
int32_t& aInOutOffset)
{
// XXX Is there a better way to do this?
nsCOMPtr<nsINode> parent = aInOutParent.forget();
nsresult res = SplitAsNeeded(aTag, parent, aInOutOffset);
aInOutParent = parent.forget();
return res;
}
nsresult
nsHTMLEditRules::SplitAsNeeded(nsIAtom& aTag,
nsCOMPtr<nsINode>& inOutParent,

View File

@ -178,8 +178,8 @@ protected:
nsresult WillMakeDefListItem(Selection* aSelection,
const nsAString* aBlockType, bool aEntireList,
bool* aCancel, bool* aHandled);
nsresult WillMakeBasicBlock(Selection* aSelection,
const nsAString* aBlockType,
nsresult WillMakeBasicBlock(Selection& aSelection,
const nsAString& aBlockType,
bool* aCancel, bool* aHandled);
nsresult DidMakeBasicBlock(Selection* aSelection, nsRulesInfo* aInfo,
nsresult aResult);
@ -283,6 +283,8 @@ protected:
nsresult ApplyBlockStyle(nsTArray<OwningNonNull<nsINode>>& aNodeArray,
nsIAtom& aBlockTag);
nsresult MakeBlockquote(nsTArray<OwningNonNull<nsINode>>& aNodeArray);
nsresult SplitAsNeeded(nsIAtom& aTag, OwningNonNull<nsINode>& inOutParent,
int32_t& inOutOffset);
nsresult SplitAsNeeded(nsIAtom& aTag, nsCOMPtr<nsINode>& inOutParent,
int32_t& inOutOffset);
nsresult AddTerminatingBR(nsIDOMNode *aBlock);