forked from mirrors/gecko-dev
Bug 1156062 - Back out for now, requested by Masayuki at bug 1191356 comment 23
This commit is contained in:
parent
0baa2aa34f
commit
1840135a82
2 changed files with 84 additions and 58 deletions
|
|
@ -635,7 +635,7 @@ nsHTMLEditRules::WillDoAction(Selection* aSelection,
|
||||||
return WillLoadHTML(aSelection, aCancel);
|
return WillLoadHTML(aSelection, aCancel);
|
||||||
case EditAction::insertBreak:
|
case EditAction::insertBreak:
|
||||||
UndefineCaretBidiLevel(aSelection);
|
UndefineCaretBidiLevel(aSelection);
|
||||||
return WillInsertBreak(*aSelection, aCancel, aHandled);
|
return WillInsertBreak(aSelection, aCancel, aHandled);
|
||||||
case EditAction::deleteSelection:
|
case EditAction::deleteSelection:
|
||||||
return WillDeleteSelection(aSelection, info->collapsedAction,
|
return WillDeleteSelection(aSelection, info->collapsedAction,
|
||||||
info->stripWrappers, aCancel, aHandled);
|
info->stripWrappers, aCancel, aHandled);
|
||||||
|
|
@ -1515,101 +1515,118 @@ nsHTMLEditRules::WillLoadHTML(Selection* aSelection, bool* aCancel)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLEditRules::WillInsertBreak(Selection& aSelection, bool* aCancel,
|
nsHTMLEditRules::WillInsertBreak(Selection* aSelection,
|
||||||
bool* aHandled)
|
bool* aCancel, bool* aHandled)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aCancel && aHandled);
|
if (!aSelection || !aCancel || !aHandled) {
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
}
|
||||||
|
// initialize out params
|
||||||
*aCancel = false;
|
*aCancel = false;
|
||||||
*aHandled = false;
|
*aHandled = false;
|
||||||
|
|
||||||
NS_ENSURE_STATE(mHTMLEditor);
|
// if the selection isn't collapsed, delete it.
|
||||||
nsCOMPtr<nsIEditor> kungFuDeathGrip(mHTMLEditor);
|
nsresult res = NS_OK;
|
||||||
|
if (!aSelection->Collapsed()) {
|
||||||
// If the selection isn't collapsed, delete it.
|
NS_ENSURE_STATE(mHTMLEditor);
|
||||||
nsresult res;
|
|
||||||
if (!aSelection.Collapsed()) {
|
|
||||||
res = mHTMLEditor->DeleteSelection(nsIEditor::eNone, nsIEditor::eStrip);
|
res = mHTMLEditor->DeleteSelection(nsIEditor::eNone, nsIEditor::eStrip);
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
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;
|
*aCancel = false;
|
||||||
|
|
||||||
// Split any mailcites in the way. Should we abort this if we encounter
|
// split any mailcites in the way.
|
||||||
// table cell boundaries?
|
// should we abort this if we encounter table cell boundaries?
|
||||||
if (IsMailEditor()) {
|
if (IsMailEditor()) {
|
||||||
res = SplitMailCites(&aSelection, aHandled);
|
res = SplitMailCites(aSelection, aHandled);
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
NS_ENSURE_SUCCESS(res, res);
|
||||||
if (*aHandled) {
|
if (*aHandled) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Smart splitting rules
|
// smart splitting rules
|
||||||
NS_ENSURE_TRUE(aSelection.GetRangeAt(0) &&
|
nsCOMPtr<nsIDOMNode> node;
|
||||||
aSelection.GetRangeAt(0)->GetStartParent(),
|
int32_t offset;
|
||||||
NS_ERROR_FAILURE);
|
|
||||||
OwningNonNull<nsINode> node = *aSelection.GetRangeAt(0)->GetStartParent();
|
|
||||||
int32_t offset = aSelection.GetRangeAt(0)->StartOffset();
|
|
||||||
|
|
||||||
// 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)) {
|
if (!mHTMLEditor->IsModifiableNode(node)) {
|
||||||
*aCancel = true;
|
*aCancel = true;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Identify the block
|
// identify the block
|
||||||
nsCOMPtr<Element> blockParent = mHTMLEditor->GetBlock(node);
|
nsCOMPtr<nsIDOMNode> blockParent;
|
||||||
|
if (IsBlockNode(node)) {
|
||||||
|
blockParent = node;
|
||||||
|
} else {
|
||||||
|
NS_ENSURE_STATE(mHTMLEditor);
|
||||||
|
blockParent = mHTMLEditor->GetBlockNodeParent(node);
|
||||||
|
}
|
||||||
NS_ENSURE_TRUE(blockParent, NS_ERROR_FAILURE);
|
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.
|
// host is the block parent itself, just append a br.
|
||||||
nsCOMPtr<Element> host = mHTMLEditor->GetActiveEditingHost();
|
NS_ENSURE_STATE(mHTMLEditor);
|
||||||
if (!nsEditorUtils::IsDescendantOf(blockParent, host)) {
|
nsCOMPtr<nsIContent> hostContent = mHTMLEditor->GetActiveEditingHost();
|
||||||
res = StandardBreakImpl(GetAsDOMNode(node), offset, &aSelection);
|
nsCOMPtr<nsIDOMNode> hostNode = do_QueryInterface(hostContent);
|
||||||
|
if (!nsEditorUtils::IsDescendantOf(blockParent, hostNode)) {
|
||||||
|
res = StandardBreakImpl(node, offset, aSelection);
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
NS_ENSURE_SUCCESS(res, res);
|
||||||
*aHandled = true;
|
*aHandled = true;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If block is empty, populate with br. (For example, imagine a div that
|
// if block is empty, populate with br. (for example, imagine a div that
|
||||||
// contains the word "text". The user selects "text" and types return.
|
// 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
|
// "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.)
|
// make block have a line. then code further below will put in a second br.)
|
||||||
bool isEmpty;
|
bool isEmpty;
|
||||||
IsEmptyBlock(GetAsDOMNode(blockParent), &isEmpty);
|
IsEmptyBlock(blockParent, &isEmpty);
|
||||||
if (isEmpty) {
|
if (isEmpty) {
|
||||||
nsCOMPtr<Element> br = mHTMLEditor->CreateBR(blockParent,
|
uint32_t blockLen;
|
||||||
blockParent->Length());
|
NS_ENSURE_STATE(mHTMLEditor);
|
||||||
NS_ENSURE_STATE(br);
|
res = mHTMLEditor->GetLengthOfDOMNode(blockParent, blockLen);
|
||||||
}
|
NS_ENSURE_SUCCESS(res, res);
|
||||||
|
nsCOMPtr<nsIDOMNode> brNode;
|
||||||
nsCOMPtr<Element> listItem = IsInListItem(blockParent);
|
NS_ENSURE_STATE(mHTMLEditor);
|
||||||
if (listItem && listItem != host) {
|
res = mHTMLEditor->CreateBR(blockParent, blockLen, address_of(brNode));
|
||||||
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);
|
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
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)) {
|
if (!(*aHandled)) {
|
||||||
*aHandled = true;
|
*aHandled = true;
|
||||||
return StandardBreakImpl(GetAsDOMNode(node), offset, &aSelection);
|
return StandardBreakImpl(node, offset, aSelection);
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -6320,6 +6337,14 @@ nsHTMLEditRules::MakeTransitionList(nsTArray<OwningNonNull<nsINode>>& aNodeArray
|
||||||
// Also stops on the active editor host (contenteditable).
|
// Also stops on the active editor host (contenteditable).
|
||||||
// Also test if aNode is an li itself.
|
// 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*
|
Element*
|
||||||
nsHTMLEditRules::IsInListItem(nsINode* aNode)
|
nsHTMLEditRules::IsInListItem(nsINode* aNode)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ protected:
|
||||||
nsAString *outString,
|
nsAString *outString,
|
||||||
int32_t aMaxLength);
|
int32_t aMaxLength);
|
||||||
nsresult WillLoadHTML(mozilla::dom::Selection* aSelection, bool* aCancel);
|
nsresult WillLoadHTML(mozilla::dom::Selection* aSelection, bool* aCancel);
|
||||||
nsresult WillInsertBreak(mozilla::dom::Selection& aSelection,
|
nsresult WillInsertBreak(mozilla::dom::Selection* aSelection,
|
||||||
bool* aCancel, bool* aHandled);
|
bool* aCancel, bool* aHandled);
|
||||||
nsresult StandardBreakImpl(nsIDOMNode* aNode, int32_t aOffset,
|
nsresult StandardBreakImpl(nsIDOMNode* aNode, int32_t aOffset,
|
||||||
mozilla::dom::Selection* aSelection);
|
mozilla::dom::Selection* aSelection);
|
||||||
|
|
@ -202,6 +202,7 @@ protected:
|
||||||
nsTArray<mozilla::OwningNonNull<nsINode>>& aOutArrayOfNodes,
|
nsTArray<mozilla::OwningNonNull<nsINode>>& aOutArrayOfNodes,
|
||||||
int32_t* aIndex, Lists aLists = Lists::yes,
|
int32_t* aIndex, Lists aLists = Lists::yes,
|
||||||
Tables aTables = Tables::yes);
|
Tables aTables = Tables::yes);
|
||||||
|
already_AddRefed<nsIDOMNode> IsInListItem(nsIDOMNode* aNode);
|
||||||
mozilla::dom::Element* IsInListItem(nsINode* aNode);
|
mozilla::dom::Element* IsInListItem(nsINode* aNode);
|
||||||
nsresult ReturnInHeader(mozilla::dom::Selection* aSelection,
|
nsresult ReturnInHeader(mozilla::dom::Selection* aSelection,
|
||||||
nsIDOMNode* aHeader, nsIDOMNode* aTextNode,
|
nsIDOMNode* aHeader, nsIDOMNode* aTextNode,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue