Bug 1053779 part 2 - Clean up nsEditor::ReplaceContainer; r=ehsan

This commit is contained in:
Aryeh Gregor 2014-08-13 14:53:33 +03:00
Родитель c5a22b8268
Коммит c9b178f39a
5 изменённых файлов: 79 добавлений и 106 удалений

Просмотреть файл

@ -3256,6 +3256,7 @@ nsHTMLEditRules::WillMakeList(Selection* aSelection,
// here's where we actually figure out what to do
nsCOMPtr<nsIDOMNode> newBlock;
nsCOMPtr<nsIDOMNode> curNode = arrayOfNodes[i];
nsCOMPtr<Element> curNodeAsElement = do_QueryInterface(curNode);
int32_t offset;
curParent = nsEditor::GetNodeLocation(curNode, &offset);
@ -3332,9 +3333,10 @@ nsHTMLEditRules::WillMakeList(Selection* aSelection,
NS_ENSURE_STATE(mHTMLEditor);
if (!mHTMLEditor->NodeIsType(curNode, itemType)) {
NS_ENSURE_STATE(mHTMLEditor);
res = mHTMLEditor->ReplaceContainer(curNode, address_of(newBlock),
nsDependentAtomString(itemType));
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_STATE(curNodeAsElement);
newBlock = dont_AddRef(GetAsDOMNode(
mHTMLEditor->ReplaceContainer(curNodeAsElement, itemType).take()));
NS_ENSURE_STATE(newBlock);
}
} else {
// item is in right type of list. But we might still have to move it.
@ -3350,9 +3352,10 @@ nsHTMLEditRules::WillMakeList(Selection* aSelection,
NS_ENSURE_STATE(mHTMLEditor);
if (!mHTMLEditor->NodeIsType(curNode, itemType)) {
NS_ENSURE_STATE(mHTMLEditor);
res = mHTMLEditor->ReplaceContainer(curNode, address_of(newBlock),
nsDependentAtomString(itemType));
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_STATE(curNodeAsElement);
newBlock = dont_AddRef(GetAsDOMNode(
mHTMLEditor->ReplaceContainer(curNodeAsElement, itemType).take()));
NS_ENSURE_STATE(newBlock);
}
}
nsCOMPtr<nsIDOMElement> curElement = do_QueryInterface(curNode);
@ -3409,14 +3412,16 @@ nsHTMLEditRules::WillMakeList(Selection* aSelection,
// don't wrap li around a paragraph. instead replace paragraph with li
if (nsHTMLEditUtils::IsParagraph(curNode)) {
NS_ENSURE_STATE(mHTMLEditor);
res = mHTMLEditor->ReplaceContainer(curNode, address_of(listItem),
nsDependentAtomString(itemType));
NS_ENSURE_STATE(curNodeAsElement);
listItem = dont_AddRef(GetAsDOMNode(
mHTMLEditor->ReplaceContainer(curNodeAsElement, itemType).take()));
NS_ENSURE_STATE(listItem);
} else {
NS_ENSURE_STATE(mHTMLEditor);
res = mHTMLEditor->InsertContainerAbove(curNode, address_of(listItem),
nsDependentAtomString(itemType));
NS_ENSURE_SUCCESS(res, res);
}
NS_ENSURE_SUCCESS(res, res);
if (IsInlineNode(curNode)) {
prevListItem = listItem;
} else {
@ -4567,7 +4572,7 @@ nsHTMLEditRules::ConvertListType(nsIDOMNode* aList,
MOZ_ASSERT(aItemType);
NS_ENSURE_TRUE(aList && outList, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsINode> list = do_QueryInterface(aList);
nsCOMPtr<Element> list = do_QueryInterface(aList);
NS_ENSURE_STATE(list);
nsCOMPtr<dom::Element> outNode;
@ -4577,7 +4582,7 @@ nsHTMLEditRules::ConvertListType(nsIDOMNode* aList,
}
nsresult
nsHTMLEditRules::ConvertListType(nsINode* aList,
nsHTMLEditRules::ConvertListType(Element* aList,
dom::Element** aOutList,
nsIAtom* aListType,
nsIAtom* aItemType)
@ -4593,17 +4598,13 @@ nsHTMLEditRules::ConvertListType(nsINode* aList,
if (child->IsElement()) {
dom::Element* element = child->AsElement();
if (nsHTMLEditUtils::IsListItem(element) && !element->IsHTML(aItemType)) {
nsCOMPtr<dom::Element> temp;
nsresult rv =
mHTMLEditor->ReplaceContainer(child, getter_AddRefs(temp),
nsDependentAtomString(aItemType));
NS_ENSURE_SUCCESS(rv, rv);
child = temp.forget();
child = mHTMLEditor->ReplaceContainer(element, aItemType);
NS_ENSURE_STATE(child);
} else if (nsHTMLEditUtils::IsList(element) &&
!element->IsHTML(aListType)) {
nsCOMPtr<dom::Element> temp;
nsresult rv =
ConvertListType(child, getter_AddRefs(temp), aListType, aItemType);
nsresult rv = ConvertListType(child->AsElement(), getter_AddRefs(temp),
aListType, aItemType);
NS_ENSURE_SUCCESS(rv, rv);
child = temp.forget();
}
@ -4617,8 +4618,10 @@ nsHTMLEditRules::ConvertListType(nsINode* aList,
return NS_OK;
}
return mHTMLEditor->ReplaceContainer(aList, aOutList,
nsDependentAtomString(aListType));
*aOutList = mHTMLEditor->ReplaceContainer(aList, aListType).take();
NS_ENSURE_STATE(aOutList);
return NS_OK;
}
@ -7328,9 +7331,14 @@ nsHTMLEditRules::ApplyBlockStyle(nsCOMArray<nsIDOMNode>& arrayOfNodes, const nsA
{
curBlock = 0; // forget any previous block used for previous inline nodes
NS_ENSURE_STATE(mHTMLEditor);
res = mHTMLEditor->ReplaceContainer(curNode, address_of(newBlock), *aBlockTag,
nullptr, nullptr, true);
NS_ENSURE_SUCCESS(res, res);
nsCOMPtr<Element> element = do_QueryInterface(curNode);
NS_ENSURE_STATE(element);
newBlock = dont_AddRef(GetAsDOMNode(
mHTMLEditor->ReplaceContainer(element,
nsCOMPtr<nsIAtom>(do_GetAtom(*aBlockTag)),
nullptr, nullptr,
nsEditor::eCloneAttributes).take()));
NS_ENSURE_STATE(newBlock);
}
else if (nsHTMLEditUtils::IsTable(curNode) ||
(curNodeTag.EqualsLiteral("tbody")) ||

Просмотреть файл

@ -231,7 +231,7 @@ protected:
nsCOMPtr<nsIDOMNode>* outList,
nsIAtom* aListType,
nsIAtom* aItemType);
nsresult ConvertListType(nsINode* aList,
nsresult ConvertListType(mozilla::dom::Element* aList,
mozilla::dom::Element** aOutList,
nsIAtom* aListType,
nsIAtom* aItemType);

Просмотреть файл

@ -1942,14 +1942,13 @@ nsHTMLEditor::SplitCellIntoRows(nsIDOMElement *aTable, int32_t aRowIndex, int32_
NS_IMETHODIMP
nsHTMLEditor::SwitchTableCellHeaderType(nsIDOMElement *aSourceCell, nsIDOMElement **aNewCell)
{
NS_ENSURE_TRUE(aSourceCell, NS_ERROR_NULL_POINTER);
nsCOMPtr<Element> sourceCell = do_QueryInterface(aSourceCell);
NS_ENSURE_TRUE(sourceCell, NS_ERROR_NULL_POINTER);
nsAutoEditBatch beginBatching(this);
// Prevent auto insertion of BR in new cell created by ReplaceContainer
nsAutoRules beginRulesSniffing(this, EditAction::insertNode, nsIEditor::eNext);
nsCOMPtr<nsIDOMNode> newNode;
// Save current selection to restore when done
// This is needed so ReplaceContainer can monitor selection
// when replacing nodes
@ -1959,13 +1958,13 @@ nsHTMLEditor::SwitchTableCellHeaderType(nsIDOMElement *aSourceCell, nsIDOMElemen
// Set to the opposite of current type
nsCOMPtr<nsIAtom> atom = nsEditor::GetTag(aSourceCell);
nsString newCellType( (atom == nsEditProperty::td) ? NS_LITERAL_STRING("th") : NS_LITERAL_STRING("td"));
nsIAtom* newCellType = atom == nsEditProperty::td
? nsGkAtoms::th : nsGkAtoms::td;
// This creates new node, moves children, copies attributes (true)
// and manages the selection!
nsresult res = ReplaceContainer(aSourceCell, address_of(newNode),
newCellType, nullptr, nullptr, true);
NS_ENSURE_SUCCESS(res, res);
nsCOMPtr<Element> newNode = ReplaceContainer(sourceCell, newCellType,
nullptr, nullptr, nsEditor::eCloneAttributes);
NS_ENSURE_TRUE(newNode, NS_ERROR_FAILURE);
// Return the new cell

Просмотреть файл

@ -512,15 +512,12 @@ nsEditor::GetIsSelectionEditable(bool *aIsSelectionEditable)
NS_ENSURE_ARG_POINTER(aIsSelectionEditable);
// get current selection
nsCOMPtr<nsISelection> selection;
nsresult res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
// XXX we just check that the anchor node is editable at the moment
// we should check that all nodes in the selection are editable
nsCOMPtr<nsIDOMNode> anchorNode;
selection->GetAnchorNode(getter_AddRefs(anchorNode));
nsCOMPtr<nsINode> anchorNode = selection->GetAnchorNode();
*aIsSelectionEditable = anchorNode && IsEditable(anchorNode);
return NS_OK;
@ -530,7 +527,7 @@ NS_IMETHODIMP
nsEditor::GetIsDocumentEditable(bool *aIsDocumentEditable)
{
NS_ENSURE_ARG_POINTER(aIsDocumentEditable);
nsCOMPtr<nsIDOMDocument> doc = GetDOMDocument();
nsCOMPtr<nsIDocument> doc = GetDocument();
*aIsDocumentEditable = !!doc;
return NS_OK;
@ -555,8 +552,7 @@ nsEditor::GetDOMDocument()
NS_IMETHODIMP
nsEditor::GetDocument(nsIDOMDocument **aDoc)
{
nsCOMPtr<nsIDOMDocument> doc = GetDOMDocument();
doc.forget(aDoc);
*aDoc = GetDOMDocument().take();
return *aDoc ? NS_OK : NS_ERROR_NOT_INITIALIZED;
}
@ -1527,87 +1523,62 @@ nsEditor::DeleteNode(nsINode* aNode)
// to be of type aNodeType. Put inNodes children into outNode.
// Callers responsibility to make sure inNode's children can
// go in outNode.
nsresult
nsEditor::ReplaceContainer(nsIDOMNode *inNode,
nsCOMPtr<nsIDOMNode> *outNode,
const nsAString &aNodeType,
const nsAString *aAttribute,
const nsAString *aValue,
bool aCloneAttributes)
{
NS_ENSURE_TRUE(inNode && outNode, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsINode> node = do_QueryInterface(inNode);
NS_ENSURE_STATE(node);
nsCOMPtr<dom::Element> element;
nsresult rv = ReplaceContainer(node, getter_AddRefs(element), aNodeType,
aAttribute, aValue, aCloneAttributes);
*outNode = element ? element->AsDOMNode() : nullptr;
return rv;
}
nsresult
nsEditor::ReplaceContainer(nsINode* aNode,
dom::Element** outNode,
const nsAString& aNodeType,
const nsAString* aAttribute,
already_AddRefed<Element>
nsEditor::ReplaceContainer(Element* aOldContainer,
nsIAtom* aNodeType,
nsIAtom* aAttribute,
const nsAString* aValue,
bool aCloneAttributes)
ECloneAttributes aCloneAttributes)
{
MOZ_ASSERT(aNode);
MOZ_ASSERT(outNode);
MOZ_ASSERT(aOldContainer && aNodeType);
*outNode = nullptr;
nsCOMPtr<nsIContent> parent = aOldContainer->GetParent();
NS_ENSURE_TRUE(parent, nullptr);
nsCOMPtr<nsIContent> parent = aNode->GetParent();
NS_ENSURE_STATE(parent);
int32_t offset = parent->IndexOf(aNode);
int32_t offset = parent->IndexOf(aOldContainer);
// create new container
*outNode =
CreateHTMLContent(nsCOMPtr<nsIAtom>(do_GetAtom(aNodeType))).take();
NS_ENSURE_STATE(*outNode);
nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(*outNode);
nsIDOMNode* inNode = aNode->AsDOMNode();
nsCOMPtr<Element> ret = CreateHTMLContent(aNodeType);
NS_ENSURE_TRUE(ret, nullptr);
// set attribute if needed
nsresult res;
if (aAttribute && aValue && !aAttribute->IsEmpty()) {
res = elem->SetAttribute(*aAttribute, *aValue);
NS_ENSURE_SUCCESS(res, res);
if (aAttribute && aValue && aAttribute != nsGkAtoms::_empty) {
res = ret->SetAttr(kNameSpaceID_None, aAttribute, *aValue, true);
NS_ENSURE_SUCCESS(res, nullptr);
}
if (aCloneAttributes) {
res = CloneAttributes(elem, inNode);
NS_ENSURE_SUCCESS(res, res);
if (aCloneAttributes == eCloneAttributes) {
res = CloneAttributes(ret->AsDOMNode(), aOldContainer->AsDOMNode());
NS_ENSURE_SUCCESS(res, nullptr);
}
// notify our internal selection state listener
// (Note: A nsAutoSelectionReset object must be created
// before calling this to initialize mRangeUpdater)
nsAutoReplaceContainerSelNotify selStateNotify(mRangeUpdater, inNode, elem);
nsAutoReplaceContainerSelNotify selStateNotify(mRangeUpdater,
aOldContainer->AsDOMNode(), ret->AsDOMNode());
{
nsAutoTxnsConserveSelection conserveSelection(this);
while (aNode->HasChildren()) {
nsCOMPtr<nsIDOMNode> child = aNode->GetFirstChild()->AsDOMNode();
while (aOldContainer->HasChildren()) {
nsCOMPtr<nsIContent> child = aOldContainer->GetFirstChild();
res = DeleteNode(child);
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_SUCCESS(res, nullptr);
res = InsertNode(child, elem, -1);
NS_ENSURE_SUCCESS(res, res);
res = InsertNode(child, ret, -1);
NS_ENSURE_SUCCESS(res, nullptr);
}
}
// insert new container into tree
res = InsertNode(elem, parent->AsDOMNode(), offset);
NS_ENSURE_SUCCESS(res, res);
res = InsertNode(ret, parent, offset);
NS_ENSURE_SUCCESS(res, nullptr);
// delete old container
return DeleteNode(inNode);
res = DeleteNode(aOldContainer);
NS_ENSURE_SUCCESS(res, nullptr);
return ret.forget();
}
///////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -224,18 +224,13 @@ public:
nsresult DeleteNode(nsINode* aNode);
nsresult InsertNode(nsIContent* aContent, nsINode* aParent,
int32_t aPosition);
nsresult ReplaceContainer(nsINode* inNode,
mozilla::dom::Element** outNode,
const nsAString& aNodeType,
const nsAString* aAttribute = nullptr,
enum ECloneAttributes { eDontCloneAttributes, eCloneAttributes };
already_AddRefed<mozilla::dom::Element> ReplaceContainer(
mozilla::dom::Element* aOldContainer,
nsIAtom* aNodeType,
nsIAtom* aAttribute = nullptr,
const nsAString* aValue = nullptr,
bool aCloneAttributes = false);
nsresult ReplaceContainer(nsIDOMNode *inNode,
nsCOMPtr<nsIDOMNode> *outNode,
const nsAString &aNodeType,
const nsAString *aAttribute = nullptr,
const nsAString *aValue = nullptr,
bool aCloneAttributes = false);
ECloneAttributes aCloneAttributes = eDontCloneAttributes);
nsresult RemoveContainer(nsINode* aNode);
nsresult RemoveContainer(nsIDOMNode *inNode);