зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1053779 part 2 - Clean up nsEditor::ReplaceContainer; r=ehsan
This commit is contained in:
Родитель
c5a22b8268
Коммит
c9b178f39a
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче