Bug 1156062 - Back out for now, requested by Masayuki at bug 1191356 comment 23

This commit is contained in:
Aryeh Gregor 2016-04-20 20:45:14 +03:00
parent 0baa2aa34f
commit 1840135a82
2 changed files with 84 additions and 58 deletions

View file

@ -635,7 +635,7 @@ nsHTMLEditRules::WillDoAction(Selection* aSelection,
return WillLoadHTML(aSelection, aCancel);
case EditAction::insertBreak:
UndefineCaretBidiLevel(aSelection);
return WillInsertBreak(*aSelection, aCancel, aHandled);
return WillInsertBreak(aSelection, aCancel, aHandled);
case EditAction::deleteSelection:
return WillDeleteSelection(aSelection, info->collapsedAction,
info->stripWrappers, aCancel, aHandled);
@ -1515,101 +1515,118 @@ nsHTMLEditRules::WillLoadHTML(Selection* aSelection, bool* aCancel)
}
nsresult
nsHTMLEditRules::WillInsertBreak(Selection& aSelection, bool* aCancel,
bool* aHandled)
nsHTMLEditRules::WillInsertBreak(Selection* aSelection,
bool* aCancel, bool* aHandled)
{
MOZ_ASSERT(aCancel && aHandled);
if (!aSelection || !aCancel || !aHandled) {
return NS_ERROR_NULL_POINTER;
}
// initialize out params
*aCancel = false;
*aHandled = false;
NS_ENSURE_STATE(mHTMLEditor);
nsCOMPtr<nsIEditor> kungFuDeathGrip(mHTMLEditor);
// If the selection isn't collapsed, delete it.
nsresult res;
if (!aSelection.Collapsed()) {
// if the selection isn't collapsed, delete it.
nsresult res = NS_OK;
if (!aSelection->Collapsed()) {
NS_ENSURE_STATE(mHTMLEditor);
res = mHTMLEditor->DeleteSelection(nsIEditor::eNone, nsIEditor::eStrip);
NS_ENSURE_SUCCESS(res, res);
}
WillInsert(aSelection, aCancel);
WillInsert(*aSelection, aCancel);
// Initialize out param. We want to ignore result of WillInsert().
// initialize out param
// we want to ignore result of WillInsert()
*aCancel = false;
// Split any mailcites in the way. Should we abort this if we encounter
// table cell boundaries?
// split any mailcites in the way.
// should we abort this if we encounter table cell boundaries?
if (IsMailEditor()) {
res = SplitMailCites(&aSelection, aHandled);
res = SplitMailCites(aSelection, aHandled);
NS_ENSURE_SUCCESS(res, res);
if (*aHandled) {
return NS_OK;
}
}
// Smart splitting rules
NS_ENSURE_TRUE(aSelection.GetRangeAt(0) &&
aSelection.GetRangeAt(0)->GetStartParent(),
NS_ERROR_FAILURE);
OwningNonNull<nsINode> node = *aSelection.GetRangeAt(0)->GetStartParent();
int32_t offset = aSelection.GetRangeAt(0)->StartOffset();
// smart splitting rules
nsCOMPtr<nsIDOMNode> node;
int32_t offset;
// Do nothing if the node is read-only
NS_ENSURE_STATE(mHTMLEditor);
res = mHTMLEditor->GetStartNodeAndOffset(aSelection, getter_AddRefs(node),
&offset);
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
// do nothing if the node is read-only
NS_ENSURE_STATE(mHTMLEditor);
if (!mHTMLEditor->IsModifiableNode(node)) {
*aCancel = true;
return NS_OK;
}
// Identify the block
nsCOMPtr<Element> blockParent = mHTMLEditor->GetBlock(node);
// identify the block
nsCOMPtr<nsIDOMNode> blockParent;
if (IsBlockNode(node)) {
blockParent = node;
} else {
NS_ENSURE_STATE(mHTMLEditor);
blockParent = mHTMLEditor->GetBlockNodeParent(node);
}
NS_ENSURE_TRUE(blockParent, NS_ERROR_FAILURE);
// If the active editing host is an inline element, or if the active editing
// if the active editing host is an inline element, or if the active editing
// host is the block parent itself, just append a br.
nsCOMPtr<Element> host = mHTMLEditor->GetActiveEditingHost();
if (!nsEditorUtils::IsDescendantOf(blockParent, host)) {
res = StandardBreakImpl(GetAsDOMNode(node), offset, &aSelection);
NS_ENSURE_STATE(mHTMLEditor);
nsCOMPtr<nsIContent> hostContent = mHTMLEditor->GetActiveEditingHost();
nsCOMPtr<nsIDOMNode> hostNode = do_QueryInterface(hostContent);
if (!nsEditorUtils::IsDescendantOf(blockParent, hostNode)) {
res = StandardBreakImpl(node, offset, aSelection);
NS_ENSURE_SUCCESS(res, res);
*aHandled = true;
return NS_OK;
}
// If block is empty, populate with br. (For example, imagine a div that
// 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 block is empty, populate with br. (for example, imagine a div that
// 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.)
bool isEmpty;
IsEmptyBlock(GetAsDOMNode(blockParent), &isEmpty);
IsEmptyBlock(blockParent, &isEmpty);
if (isEmpty) {
nsCOMPtr<Element> br = mHTMLEditor->CreateBR(blockParent,
blockParent->Length());
NS_ENSURE_STATE(br);
}
nsCOMPtr<Element> listItem = IsInListItem(blockParent);
if (listItem && listItem != host) {
ReturnInListItem(&aSelection, GetAsDOMNode(listItem), GetAsDOMNode(node),
offset);
*aHandled = true;
return NS_OK;
} else if (nsHTMLEditUtils::IsHeader(*blockParent)) {
// Headers: close (or split) header
ReturnInHeader(&aSelection, GetAsDOMNode(blockParent), GetAsDOMNode(node),
offset);
*aHandled = true;
return NS_OK;
} else if (blockParent->IsHTMLElement(nsGkAtoms::p)) {
// Paragraphs: special rules to look for <br>s
res = ReturnInParagraph(&aSelection, GetAsDOMNode(blockParent),
GetAsDOMNode(node), offset, aCancel, aHandled);
uint32_t blockLen;
NS_ENSURE_STATE(mHTMLEditor);
res = mHTMLEditor->GetLengthOfDOMNode(blockParent, blockLen);
NS_ENSURE_SUCCESS(res, res);
nsCOMPtr<nsIDOMNode> brNode;
NS_ENSURE_STATE(mHTMLEditor);
res = mHTMLEditor->CreateBR(blockParent, blockLen, address_of(brNode));
NS_ENSURE_SUCCESS(res, res);
// Fall through, we may not have handled it in ReturnInParagraph()
}
// If not already handled then do the standard thing
nsCOMPtr<nsIDOMNode> listItem = IsInListItem(blockParent);
if (listItem && listItem != hostNode) {
ReturnInListItem(aSelection, listItem, node, offset);
*aHandled = true;
return NS_OK;
} else if (nsHTMLEditUtils::IsHeader(blockParent)) {
// headers: close (or split) header
ReturnInHeader(aSelection, blockParent, node, offset);
*aHandled = true;
return NS_OK;
} else if (nsHTMLEditUtils::IsParagraph(blockParent)) {
// paragraphs: special rules to look for <br>s
res = ReturnInParagraph(aSelection, blockParent, node, offset,
aCancel, aHandled);
NS_ENSURE_SUCCESS(res, res);
// fall through, we may not have handled it in ReturnInParagraph()
}
// if not already handled then do the standard thing
if (!(*aHandled)) {
*aHandled = true;
return StandardBreakImpl(GetAsDOMNode(node), offset, &aSelection);
return StandardBreakImpl(node, offset, aSelection);
}
return NS_OK;
}
@ -6320,6 +6337,14 @@ nsHTMLEditRules::MakeTransitionList(nsTArray<OwningNonNull<nsINode>>& aNodeArray
// Also stops on the active editor host (contenteditable).
// Also test if aNode is an li itself.
//
already_AddRefed<nsIDOMNode>
nsHTMLEditRules::IsInListItem(nsIDOMNode* aNode)
{
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
nsCOMPtr<nsIDOMNode> retval = do_QueryInterface(IsInListItem(node));
return retval.forget();
}
Element*
nsHTMLEditRules::IsInListItem(nsINode* aNode)
{

View file

@ -134,7 +134,7 @@ protected:
nsAString *outString,
int32_t aMaxLength);
nsresult WillLoadHTML(mozilla::dom::Selection* aSelection, bool* aCancel);
nsresult WillInsertBreak(mozilla::dom::Selection& aSelection,
nsresult WillInsertBreak(mozilla::dom::Selection* aSelection,
bool* aCancel, bool* aHandled);
nsresult StandardBreakImpl(nsIDOMNode* aNode, int32_t aOffset,
mozilla::dom::Selection* aSelection);
@ -202,6 +202,7 @@ protected:
nsTArray<mozilla::OwningNonNull<nsINode>>& aOutArrayOfNodes,
int32_t* aIndex, Lists aLists = Lists::yes,
Tables aTables = Tables::yes);
already_AddRefed<nsIDOMNode> IsInListItem(nsIDOMNode* aNode);
mozilla::dom::Element* IsInListItem(nsINode* aNode);
nsresult ReturnInHeader(mozilla::dom::Selection* aSelection,
nsIDOMNode* aHeader, nsIDOMNode* aTextNode,