Implement switching betweeen TH and TD elements for table editing. b=20973, r=jfrancis, akkana
This commit is contained in:
Родитель
ebf5ec54ff
Коммит
e27221d200
|
@ -1820,7 +1820,8 @@ nsEditor::ReplaceContainer(nsIDOMNode *inNode,
|
|||
nsCOMPtr<nsIDOMNode> *outNode,
|
||||
const nsString &aNodeType,
|
||||
const nsString *aAttribute,
|
||||
const nsString *aValue)
|
||||
const nsString *aValue,
|
||||
PRBool aCloneAttributes)
|
||||
{
|
||||
if (!inNode || !outNode)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
@ -1851,14 +1852,32 @@ nsEditor::ReplaceContainer(nsIDOMNode *inNode,
|
|||
res = elem->SetAttribute(*aAttribute, *aValue);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
if (aCloneAttributes)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode>newNode = do_QueryInterface(elem);
|
||||
res = CloneAttributes(newNode, inNode);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
// notify our internal selection state listener
|
||||
nsAutoReplaceContainerSelNotify selStateNotify(mSavedSel, inNode, *outNode);
|
||||
|
||||
// insert new container into tree
|
||||
res = InsertNode( *outNode, parent, offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// We sometimes insert default <br> (like in a table cell),
|
||||
// so save this to delete later
|
||||
nsCOMPtr<nsIDOMNode> newNodeDefaultChild;
|
||||
nsresult resFirstChild = (*outNode)->GetFirstChild(getter_AddRefs(newNodeDefaultChild));
|
||||
|
||||
// move children into new container
|
||||
|
||||
nsCOMPtr<nsIDOMNode> child;
|
||||
/*
|
||||
// This doesn't work when used with table cells!
|
||||
PRBool bHasMoreChildren;
|
||||
inNode->HasChildNodes(&bHasMoreChildren);
|
||||
nsCOMPtr<nsIDOMNode> child;
|
||||
while (bHasMoreChildren)
|
||||
{
|
||||
inNode->GetLastChild(getter_AddRefs(child));
|
||||
|
@ -1868,14 +1887,35 @@ nsEditor::ReplaceContainer(nsIDOMNode *inNode,
|
|||
if (NS_FAILED(res)) return res;
|
||||
inNode->HasChildNodes(&bHasMoreChildren);
|
||||
}
|
||||
*/
|
||||
// Insert at start of the new node
|
||||
PRInt32 insertIndex = 0;
|
||||
res = inNode->GetFirstChild(getter_AddRefs(child));
|
||||
if (NS_FAILED(res)) return res;
|
||||
while (child)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> nextChild;
|
||||
res = child->GetNextSibling(getter_AddRefs(nextChild));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
res = DeleteNode(child);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
res = InsertNode(child, *outNode, insertIndex);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
child = nextChild;
|
||||
insertIndex++;
|
||||
}
|
||||
// Now that we have some real content in the new node,
|
||||
// delete the default first child
|
||||
// (We must do this AFTER moving the other nodes
|
||||
// because rules would reinsert it if we did it first!)
|
||||
if (NS_SUCCEEDED(resFirstChild) && newNodeDefaultChild)
|
||||
DeleteNode(newNodeDefaultChild);
|
||||
|
||||
// delete old container
|
||||
res = DeleteNode(inNode);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// insert new container into tree
|
||||
res = InsertNode( *outNode, parent, offset);
|
||||
return res;
|
||||
return DeleteNode(inNode);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -318,7 +318,9 @@ public:
|
|||
nsCOMPtr<nsIDOMNode> *outNode,
|
||||
const nsString &aNodeType,
|
||||
const nsString *aAttribute = nsnull,
|
||||
const nsString *aValue = nsnull);
|
||||
const nsString *aValue = nsnull,
|
||||
PRBool aCloneAttributes = PR_FALSE);
|
||||
|
||||
nsresult RemoveContainer(nsIDOMNode *inNode);
|
||||
nsresult InsertContainerAbove(nsIDOMNode *inNode,
|
||||
nsCOMPtr<nsIDOMNode> *outNode,
|
||||
|
|
|
@ -1171,7 +1171,7 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection,
|
|||
// see if we are in an "empty" node.
|
||||
// Note: do NOT delete table elements this way.
|
||||
PRBool bIsEmptyNode;
|
||||
res = IsEmptyNode(node, &bIsEmptyNode, PR_TRUE, PR_FALSE);
|
||||
res = mEditor->IsEmptyNode(node, &bIsEmptyNode, PR_TRUE, PR_FALSE);
|
||||
if (bIsEmptyNode && !mEditor->IsTableElement(node))
|
||||
nodeToDelete = node;
|
||||
else
|
||||
|
@ -1511,7 +1511,7 @@ nsHTMLEditRules::WillMakeList(nsIDOMSelection *aSelection,
|
|||
else if (mEditor->IsInlineNode(curNode) && mEditor->IsContainer(curNode))
|
||||
{
|
||||
PRBool bEmpty;
|
||||
res = IsEmptyNode( curNode, &bEmpty);
|
||||
res = mEditor->IsEmptyNode(curNode, &bEmpty);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (bEmpty)
|
||||
{
|
||||
|
@ -2196,7 +2196,7 @@ nsHTMLEditRules::IsEmptyBlock(nsIDOMNode *aNode,
|
|||
// looks like I forgot to finish this. Wonder what I was going to do?
|
||||
|
||||
if (!nodeToTest) return NS_ERROR_NULL_POINTER;
|
||||
return IsEmptyNode(nodeToTest, outIsEmptyBlock,
|
||||
return mEditor->IsEmptyNode(nodeToTest, outIsEmptyBlock,
|
||||
aMozBRDoesntCount, aListItemsNotEmpty);
|
||||
}
|
||||
|
||||
|
@ -3350,7 +3350,7 @@ nsHTMLEditRules::ReturnInHeader(nsIDOMSelection *aSelection,
|
|||
if (prevItem && nsHTMLEditUtils::IsHeader(prevItem))
|
||||
{
|
||||
PRBool bIsEmptyNode;
|
||||
res = IsEmptyNode(prevItem, &bIsEmptyNode);
|
||||
res = mEditor->IsEmptyNode(prevItem, &bIsEmptyNode);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (bIsEmptyNode)
|
||||
{
|
||||
|
@ -3607,7 +3607,7 @@ nsHTMLEditRules::ReturnInListItem(nsIDOMSelection *aSelection,
|
|||
if (prevItem && nsHTMLEditUtils::IsListItem(prevItem))
|
||||
{
|
||||
PRBool bIsEmptyNode;
|
||||
res = IsEmptyNode(prevItem, &bIsEmptyNode);
|
||||
res = mEditor->IsEmptyNode(prevItem, &bIsEmptyNode);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (bIsEmptyNode)
|
||||
{
|
||||
|
@ -4184,7 +4184,7 @@ nsHTMLEditRules::AdjustSpecialBreaks()
|
|||
if (!node) return NS_ERROR_FAILURE;
|
||||
|
||||
PRBool bIsEmptyNode;
|
||||
res = IsEmptyNode(node, &bIsEmptyNode, PR_FALSE, PR_FALSE);
|
||||
res = mEditor->IsEmptyNode(node, &bIsEmptyNode, PR_FALSE, PR_FALSE);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (bIsEmptyNode
|
||||
&& (nsHTMLEditUtils::IsListItem(node) || mEditor->IsTableCell(node)))
|
||||
|
@ -4551,7 +4551,7 @@ nsHTMLEditRules::RemoveEmptyNodes()
|
|||
if (!node) return NS_ERROR_FAILURE;
|
||||
|
||||
PRBool bIsEmptyNode;
|
||||
res = IsEmptyNode(node, &bIsEmptyNode, PR_FALSE, PR_TRUE);
|
||||
res = mEditor->IsEmptyNode(node, &bIsEmptyNode, PR_FALSE, PR_TRUE);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (bIsEmptyNode && !nsHTMLEditUtils::IsBody(node))
|
||||
{
|
||||
|
@ -4984,7 +4984,7 @@ nsHTMLEditRules::InsertMozBRIfNeeded(nsIDOMNode *aNode)
|
|||
|
||||
PRBool isEmpty;
|
||||
nsCOMPtr<nsIDOMNode> brNode;
|
||||
nsresult res = IsEmptyNode(aNode, &isEmpty);
|
||||
nsresult res = mEditor->IsEmptyNode(aNode, &isEmpty);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (isEmpty)
|
||||
{
|
||||
|
|
|
@ -38,12 +38,15 @@ PRBool
|
|||
nsHTMLEditUtils::IsBody(nsIDOMNode *node)
|
||||
{
|
||||
NS_PRECONDITION(node, "null node passed to nsHTMLEditUtils::IsBody");
|
||||
nsAutoString tag;
|
||||
nsEditor::GetTagString(node,tag);
|
||||
tag.ToLowerCase();
|
||||
if (tag.EqualsWithConversion("body"))
|
||||
if (node)
|
||||
{
|
||||
return PR_TRUE;
|
||||
nsAutoString tag;
|
||||
nsEditor::GetTagString(node,tag);
|
||||
tag.ToLowerCase();
|
||||
if (tag.EqualsWithConversion("body"))
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
|
|
@ -7063,3 +7063,102 @@ nsHTMLEditor::GetLastEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOu
|
|||
return res;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// IsEmptyNode: figure out if aNode is an empty node.
|
||||
// A block can have children and still be considered empty,
|
||||
// if the children are empty or non-editable.
|
||||
//
|
||||
nsresult
|
||||
nsHTMLEditor::IsEmptyNode( nsIDOMNode *aNode,
|
||||
PRBool *outIsEmptyNode,
|
||||
PRBool aMozBRDoesntCount,
|
||||
PRBool aListOrCellNotEmpty)
|
||||
{
|
||||
if (!aNode || !outIsEmptyNode) return NS_ERROR_NULL_POINTER;
|
||||
*outIsEmptyNode = PR_TRUE;
|
||||
|
||||
// effeciency hack - special case if it's a text node
|
||||
if (nsEditor::IsTextNode(aNode))
|
||||
{
|
||||
PRUint32 length = 0;
|
||||
nsCOMPtr<nsIDOMCharacterData>nodeAsText;
|
||||
nodeAsText = do_QueryInterface(aNode);
|
||||
nodeAsText->GetLength(&length);
|
||||
if (length) *outIsEmptyNode = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// if it's not a text node (handled above) and it's not a container,
|
||||
// then we dont call it empty (it's an <hr>, or <br>, etc).
|
||||
// Also, if it's an anchor then dont treat it as empty - even though
|
||||
// anchors are containers, named anchors are "empty" but we don't
|
||||
// want to treat them as such. Also, don't call ListItems or table
|
||||
// cells empty if caller desires.
|
||||
if (!IsContainer(aNode) || nsHTMLEditUtils::IsAnchor(aNode) ||
|
||||
(aListOrCellNotEmpty && nsHTMLEditUtils::IsListItem(aNode)) ||
|
||||
(aListOrCellNotEmpty && nsHTMLEditUtils::IsTableCell(aNode)) )
|
||||
{
|
||||
*outIsEmptyNode = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// iterate over node. if no children, or all children are either
|
||||
// empty text nodes or non-editable, then node qualifies as empty
|
||||
nsCOMPtr<nsIContentIterator> iter;
|
||||
nsCOMPtr<nsIContent> nodeAsContent = do_QueryInterface(aNode);
|
||||
if (!nodeAsContent) return NS_ERROR_FAILURE;
|
||||
nsresult res = nsComponentManager::CreateInstance(kCContentIteratorCID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsIContentIterator),
|
||||
getter_AddRefs(iter));
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = iter->Init(nodeAsContent);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
while (NS_ENUMERATOR_FALSE == iter->IsDone())
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
nsCOMPtr<nsIContent> content;
|
||||
res = iter->CurrentNode(getter_AddRefs(content));
|
||||
if (NS_FAILED(res)) return res;
|
||||
node = do_QueryInterface(content);
|
||||
if (!node) return NS_ERROR_FAILURE;
|
||||
|
||||
// is the node editable and non-empty? if so, return false
|
||||
if (nsEditor::IsEditable(node))
|
||||
{
|
||||
if (nsEditor::IsTextNode(node))
|
||||
{
|
||||
PRUint32 length = 0;
|
||||
nsCOMPtr<nsIDOMCharacterData>nodeAsText;
|
||||
nodeAsText = do_QueryInterface(node);
|
||||
nodeAsText->GetLength(&length);
|
||||
if (length) *outIsEmptyNode = PR_FALSE;
|
||||
}
|
||||
else // an editable, non-text node. we aren't an empty block
|
||||
{
|
||||
// is it the node we are iterating over?
|
||||
if (node.get() == aNode) break;
|
||||
// is it a moz-BR and did the caller ask us not to consider those relevant?
|
||||
if (!(aMozBRDoesntCount && nsHTMLEditUtils::IsMozBR(node)))
|
||||
{
|
||||
// is it an empty node of some sort?
|
||||
PRBool isEmptyNode;
|
||||
res = IsEmptyNode(node, &isEmptyNode, aMozBRDoesntCount, aListOrCellNotEmpty);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!isEmptyNode)
|
||||
{
|
||||
// otherwise it ain't empty
|
||||
*outIsEmptyNode = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res = iter->Next();
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -396,6 +396,8 @@ protected:
|
|||
PRBool AllCellsInRowSelected(nsIDOMElement *aTable, PRInt32 aRowIndex, PRInt32 aNumberOfColumns);
|
||||
PRBool AllCellsInColumnSelected(nsIDOMElement *aTable, PRInt32 aColIndex, PRInt32 aNumberOfRows);
|
||||
|
||||
PRBool IsEmptyCell(nsIDOMElement *aCell);
|
||||
|
||||
// Most insert methods need to get the same basic context data
|
||||
// Any of the pointers may be null if you don't need that datum (for more efficiency)
|
||||
// Input: *aCell is a known cell,
|
||||
|
@ -549,6 +551,9 @@ protected:
|
|||
nsresult IsLastEditableChild( nsIDOMNode *aNode, PRBool *aOutIsLast);
|
||||
nsresult GetFirstEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutFirstChild);
|
||||
nsresult GetLastEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutLastChild);
|
||||
nsresult IsEmptyNode(nsIDOMNode *aNode, PRBool *outIsEmptyBlock,
|
||||
PRBool aMozBRDoesntCount = PR_FALSE,
|
||||
PRBool aListOrCellNotEmpty = PR_FALSE);
|
||||
|
||||
nsresult GetDOMEventReceiver(nsIDOMEventReceiver **aEventReceiver);
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "nsVoidArray.h"
|
||||
|
||||
#include "nsEditorUtils.h"
|
||||
#include "nsHTMLEditUtils.h"
|
||||
|
||||
//#define DEBUG_TABLE 1
|
||||
|
||||
|
@ -120,9 +121,9 @@ nsHTMLEditor::InsertCell(nsIDOMElement *aCell, PRInt32 aRowSpan, PRInt32 aColSpa
|
|||
|
||||
nsCOMPtr<nsIDOMElement> newCell;
|
||||
if (aIsHeader)
|
||||
res = CreateElementWithDefaults(NS_ConvertASCIItoUCS2("th"), getter_AddRefs(newCell));
|
||||
res = CreateElementWithDefaults(NS_LITERAL_STRING("th"), getter_AddRefs(newCell));
|
||||
else
|
||||
res = CreateElementWithDefaults(NS_ConvertASCIItoUCS2("td"), getter_AddRefs(newCell));
|
||||
res = CreateElementWithDefaults(NS_LITERAL_STRING("td"), getter_AddRefs(newCell));
|
||||
|
||||
if(NS_FAILED(res)) return res;
|
||||
if(!newCell) return NS_ERROR_FAILURE;
|
||||
|
@ -137,19 +138,19 @@ nsHTMLEditor::InsertCell(nsIDOMElement *aCell, PRInt32 aRowSpan, PRInt32 aColSpa
|
|||
{
|
||||
nsAutoString newRowSpan(aRowSpan);
|
||||
// Note: Do NOT use editor txt for this
|
||||
newCell->SetAttribute(NS_ConvertASCIItoUCS2("rowspan"), newRowSpan);
|
||||
newCell->SetAttribute(NS_LITERAL_STRING("rowspan"), newRowSpan);
|
||||
}
|
||||
if( aColSpan > 1)
|
||||
{
|
||||
nsAutoString newColSpan(aColSpan);
|
||||
// Note: Do NOT use editor txt for this
|
||||
newCell->SetAttribute(NS_ConvertASCIItoUCS2("colspan"), newColSpan);
|
||||
newCell->SetAttribute(NS_LITERAL_STRING("colspan"), newColSpan);
|
||||
}
|
||||
if(aAfter) cellOffset++;
|
||||
|
||||
//Don't let Rules System change the selection
|
||||
nsAutoTxnsConserveSelection dontChangeSelection(this);
|
||||
return nsEditor::InsertNode(newCell, cellParent, cellOffset);
|
||||
return InsertNode(newCell, cellParent, cellOffset);
|
||||
}
|
||||
|
||||
PRBool IsRowNode(nsCOMPtr<nsIDOMNode> &aNode)
|
||||
|
@ -221,11 +222,11 @@ nsHTMLEditor::InsertTableCell(PRInt32 aNumber, PRBool aAfter)
|
|||
for (i = 0; i < aNumber; i++)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> newCell;
|
||||
res = CreateElementWithDefaults(NS_ConvertASCIItoUCS2("td"), getter_AddRefs(newCell));
|
||||
res = CreateElementWithDefaults(NS_LITERAL_STRING("td"), getter_AddRefs(newCell));
|
||||
if (NS_SUCCEEDED(res) && newCell)
|
||||
{
|
||||
if (aAfter) cellOffset++;
|
||||
res = nsEditor::InsertNode(newCell, cellParent, cellOffset);
|
||||
res = InsertNode(newCell, cellParent, cellOffset);
|
||||
if(NS_FAILED(res)) break;
|
||||
}
|
||||
}
|
||||
|
@ -238,7 +239,7 @@ nsHTMLEditor::GetFirstRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow)
|
|||
aRow = nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> tableElement;
|
||||
nsresult res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), aTableElement, getter_AddRefs(tableElement));
|
||||
nsresult res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), aTableElement, getter_AddRefs(tableElement));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!tableElement) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -303,7 +304,7 @@ nsHTMLEditor::GetNextRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow)
|
|||
aRow = nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> rowElement;
|
||||
nsresult res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("tr"), aTableElement, getter_AddRefs(rowElement));
|
||||
nsresult res = GetElementOrParentByTagName(NS_LITERAL_STRING("tr"), aTableElement, getter_AddRefs(rowElement));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!rowElement) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -498,7 +499,7 @@ nsHTMLEditor::InsertTableRow(PRInt32 aNumber, PRBool aAfter)
|
|||
if (!curCell) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> parentRow;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("tr"), curCell, getter_AddRefs(parentRow));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("tr"), curCell, getter_AddRefs(parentRow));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!parentRow) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -596,7 +597,7 @@ nsHTMLEditor::InsertTableRow(PRInt32 aNumber, PRBool aAfter)
|
|||
{
|
||||
// Create a new row
|
||||
nsCOMPtr<nsIDOMElement> newRow;
|
||||
res = CreateElementWithDefaults(NS_ConvertASCIItoUCS2("tr"), getter_AddRefs(newRow));
|
||||
res = CreateElementWithDefaults(NS_LITERAL_STRING("tr"), getter_AddRefs(newRow));
|
||||
if (NS_SUCCEEDED(res))
|
||||
{
|
||||
if (!newRow) return NS_ERROR_FAILURE;
|
||||
|
@ -604,7 +605,7 @@ nsHTMLEditor::InsertTableRow(PRInt32 aNumber, PRBool aAfter)
|
|||
for (PRInt32 i = 0; i < cellsInRow; i++)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> newCell;
|
||||
res = CreateElementWithDefaults(NS_ConvertASCIItoUCS2("td"), getter_AddRefs(newCell));
|
||||
res = CreateElementWithDefaults(NS_LITERAL_STRING("td"), getter_AddRefs(newCell));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!newCell) return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -615,7 +616,7 @@ nsHTMLEditor::InsertTableRow(PRInt32 aNumber, PRBool aAfter)
|
|||
}
|
||||
// Use transaction system to insert the entire row+cells
|
||||
// (Note that rows are inserted at same childoffset each time)
|
||||
res = nsEditor::InsertNode(newRow, parentOfRow, newRowOffset);
|
||||
res = InsertNode(newRow, parentOfRow, newRowOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
}
|
||||
|
@ -629,7 +630,7 @@ nsHTMLEditor::DeleteTable2(nsCOMPtr<nsIDOMElement> &aTable, nsCOMPtr<nsIDOMSelec
|
|||
{
|
||||
nsCOMPtr<nsIDOMNode> tableParent;
|
||||
PRInt32 tableOffset;
|
||||
if(NS_FAILED(aTable->GetParentNode(getter_AddRefs(tableParent))) || !tableParent)
|
||||
if(!aTable || NS_FAILED(aTable->GetParentNode(getter_AddRefs(tableParent))) || !tableParent)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Save offset we need to restore the selection
|
||||
|
@ -669,7 +670,7 @@ nsHTMLEditor::DeleteTableCell(PRInt32 aNumber)
|
|||
nsCOMPtr<nsIDOMElement> cell;
|
||||
PRInt32 startRowIndex, startColIndex;
|
||||
|
||||
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -689,7 +690,7 @@ nsHTMLEditor::DeleteTableCell(PRInt32 aNumber)
|
|||
if (1 == GetNumberOfCellsInRow(table, startRowIndex))
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> parentRow;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("tr"), cell, getter_AddRefs(parentRow));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("tr"), cell, getter_AddRefs(parentRow));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!parentRow) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -849,7 +850,7 @@ nsHTMLEditor::DeleteTableColumn(PRInt32 aNumber)
|
|||
{
|
||||
// Only 1 cell in row - delete the row
|
||||
nsCOMPtr<nsIDOMElement> parentRow;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("tr"), cell, getter_AddRefs(parentRow));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("tr"), cell, getter_AddRefs(parentRow));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if(!parentRow) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -972,7 +973,7 @@ nsHTMLEditor::DeleteTableRow(PRInt32 aNumber)
|
|||
|
||||
// Delete the row
|
||||
nsCOMPtr<nsIDOMElement> parentRow;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("tr"), cell, getter_AddRefs(parentRow));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("tr"), cell, getter_AddRefs(parentRow));
|
||||
if (NS_SUCCEEDED(res) && parentRow)
|
||||
res = DeleteNode(parentRow);
|
||||
if (NS_FAILED(res))
|
||||
|
@ -992,7 +993,7 @@ nsHTMLEditor::SelectTable()
|
|||
{
|
||||
nsCOMPtr<nsIDOMElement> table;
|
||||
nsresult res = NS_ERROR_FAILURE;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), nsnull, getter_AddRefs(table));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), nsnull, getter_AddRefs(table));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// Don't fail if we didn't find a table
|
||||
if (!table) return NS_OK;
|
||||
|
@ -1011,7 +1012,7 @@ NS_IMETHODIMP
|
|||
nsHTMLEditor::SelectTableCell()
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> cell;
|
||||
nsresult res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("td"), nsnull, getter_AddRefs(cell));
|
||||
nsresult res = GetElementOrParentByTagName(NS_LITERAL_STRING("td"), nsnull, getter_AddRefs(cell));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// Don't fail if we didn't find a table
|
||||
if (!cell) return NS_EDITOR_ELEMENT_NOT_FOUND;
|
||||
|
@ -1032,17 +1033,17 @@ nsHTMLEditor::SelectBlockOfCells(nsIDOMElement *aStartCell, nsIDOMElement *aEndC
|
|||
if (!aStartCell || !aEndCell) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> table;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), aStartCell, getter_AddRefs(table));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), aStartCell, getter_AddRefs(table));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!table) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> endTable;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), aEndCell, getter_AddRefs(endTable));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), aEndCell, getter_AddRefs(endTable));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!endTable) return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -1107,7 +1108,7 @@ nsHTMLEditor::SelectBlockOfCells(nsIDOMElement *aStartCell, nsIDOMElement *aEndC
|
|||
if (!isSelected && cell && row == currentRowIndex && col == currentColIndex)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> cellNode = do_QueryInterface(cell);
|
||||
res = nsEditor::AppendNodeToSelectionAsRange(cellNode);
|
||||
res = AppendNodeToSelectionAsRange(cellNode);
|
||||
if (NS_FAILED(res)) break;
|
||||
}
|
||||
}
|
||||
|
@ -1119,7 +1120,7 @@ NS_IMETHODIMP
|
|||
nsHTMLEditor::SelectAllTableCells()
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> cell;
|
||||
nsresult res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("td"), nsnull, getter_AddRefs(cell));
|
||||
nsresult res = GetElementOrParentByTagName(NS_LITERAL_STRING("td"), nsnull, getter_AddRefs(cell));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// Don't fail if we didn't find a cell
|
||||
|
@ -1131,7 +1132,7 @@ nsHTMLEditor::SelectAllTableCells()
|
|||
|
||||
// Get parent table
|
||||
nsCOMPtr<nsIDOMElement> table;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), cell, getter_AddRefs(table));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), cell, getter_AddRefs(table));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if(!table) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -1140,7 +1141,7 @@ nsHTMLEditor::SelectAllTableCells()
|
|||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -1168,7 +1169,7 @@ nsHTMLEditor::SelectAllTableCells()
|
|||
if (cell && row == currentRowIndex && col == currentColIndex)
|
||||
{
|
||||
cellNode = do_QueryInterface(cell);
|
||||
res = nsEditor::AppendNodeToSelectionAsRange(cellNode);
|
||||
res = AppendNodeToSelectionAsRange(cellNode);
|
||||
if (NS_FAILED(res)) break;
|
||||
cellSelected = PR_TRUE;
|
||||
}
|
||||
|
@ -1178,7 +1179,7 @@ nsHTMLEditor::SelectAllTableCells()
|
|||
if (!cellSelected)
|
||||
{
|
||||
cellNode = do_QueryInterface(startCell);
|
||||
return nsEditor::AppendNodeToSelectionAsRange(cellNode);
|
||||
return AppendNodeToSelectionAsRange(cellNode);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -1187,7 +1188,7 @@ NS_IMETHODIMP
|
|||
nsHTMLEditor::SelectTableRow()
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> cell;
|
||||
nsresult res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("td"), nsnull, getter_AddRefs(cell));
|
||||
nsresult res = GetElementOrParentByTagName(NS_LITERAL_STRING("td"), nsnull, getter_AddRefs(cell));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// Don't fail if we didn't find a cell
|
||||
|
@ -1240,7 +1241,7 @@ nsHTMLEditor::SelectTableRow()
|
|||
if (cell && currentRowIndex == startRowIndex && currentColIndex == col)
|
||||
{
|
||||
cellNode = do_QueryInterface(cell);
|
||||
res = nsEditor::AppendNodeToSelectionAsRange(cellNode);
|
||||
res = AppendNodeToSelectionAsRange(cellNode);
|
||||
if (NS_FAILED(res)) break;
|
||||
cellSelected = PR_TRUE;
|
||||
}
|
||||
|
@ -1249,7 +1250,7 @@ nsHTMLEditor::SelectTableRow()
|
|||
if (!cellSelected)
|
||||
{
|
||||
cellNode = do_QueryInterface(startCell);
|
||||
return nsEditor::AppendNodeToSelectionAsRange(cellNode);
|
||||
return AppendNodeToSelectionAsRange(cellNode);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -1258,7 +1259,7 @@ NS_IMETHODIMP
|
|||
nsHTMLEditor::SelectTableColumn()
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> cell;
|
||||
nsresult res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("td"), nsnull, getter_AddRefs(cell));
|
||||
nsresult res = GetElementOrParentByTagName(NS_LITERAL_STRING("td"), nsnull, getter_AddRefs(cell));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// Don't fail if we didn't find a cell
|
||||
|
@ -1307,7 +1308,7 @@ nsHTMLEditor::SelectTableColumn()
|
|||
if (cell && currentRowIndex == row && currentColIndex == startColIndex)
|
||||
{
|
||||
cellNode = do_QueryInterface(cell);
|
||||
res = nsEditor::AppendNodeToSelectionAsRange(cellNode);
|
||||
res = AppendNodeToSelectionAsRange(cellNode);
|
||||
if (NS_FAILED(res)) break;
|
||||
cellSelected = PR_TRUE;
|
||||
}
|
||||
|
@ -1316,7 +1317,7 @@ nsHTMLEditor::SelectTableColumn()
|
|||
if (!cellSelected)
|
||||
{
|
||||
cellNode = do_QueryInterface(startCell);
|
||||
return nsEditor::AppendNodeToSelectionAsRange(cellNode);
|
||||
return AppendNodeToSelectionAsRange(cellNode);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -1504,33 +1505,26 @@ nsHTMLEditor::SwitchTableCellHeaderType(nsIDOMElement *aSourceCell, nsIDOMElemen
|
|||
{
|
||||
if (!aSourceCell) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> sourceCell = aSourceCell;
|
||||
nsCOMPtr<nsIDOMElement> newCell;
|
||||
nsAutoString tagName;
|
||||
nsEditor::GetTagString(aSourceCell, tagName);
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
nsCOMPtr<nsIDOMNode> sourceNode = do_QueryInterface(aSourceCell);
|
||||
nsCOMPtr<nsIDOMNode> newNode;
|
||||
|
||||
// Set to the opposite of current type
|
||||
PRBool headerType = (tagName == NS_ConvertASCIItoUCS2("td"));
|
||||
|
||||
// Create the new cell, inserting it just before existing cell
|
||||
// Just assume colspan and rowspan = 1 (we'll copy real values with CloneAttributes)
|
||||
nsresult res = InsertCell(aSourceCell, 1, 1, PR_TRUE, headerType, getter_AddRefs(newCell));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!newCell) return res;
|
||||
|
||||
// Copy all of the original attributes to the new cell
|
||||
nsCOMPtr<nsIDOMNode> sourceCellNode = do_QueryInterface(sourceCell);
|
||||
nsCOMPtr<nsIDOMNode> newCellNode = do_QueryInterface(newCell);
|
||||
res = CloneAttributes(newCellNode, sourceCellNode);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// Move all contents from original cell to new cell then delete original (3rd param = PR_TRUE)
|
||||
res = MergeCells(newCell, sourceCell, PR_TRUE);
|
||||
nsAutoString tagName;
|
||||
GetTagString(aSourceCell, tagName);
|
||||
nsString newCellType = (tagName == NS_LITERAL_STRING("td")) ? NS_LITERAL_STRING("th") : NS_LITERAL_STRING("td");
|
||||
|
||||
// This creates new node, moves children, copies attributes (PR_TRUE)
|
||||
// and manages the selection!
|
||||
nsresult res = ReplaceContainer(sourceNode, &newNode, newCellType, nsnull, nsnull, PR_TRUE);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!newNode) return NS_ERROR_FAILURE;
|
||||
|
||||
// Return the new cell
|
||||
if (aNewCell)
|
||||
{
|
||||
*aNewCell = newCell.get();
|
||||
nsCOMPtr<nsIDOMElement> newElement = do_QueryInterface(newNode);
|
||||
*aNewCell = newElement;
|
||||
NS_ADDREF(*aNewCell);
|
||||
}
|
||||
|
||||
|
@ -1826,6 +1820,7 @@ nsHTMLEditor::MergeCells(nsCOMPtr<nsIDOMElement> aTargetCell,
|
|||
|
||||
// Get index of last child in target cell
|
||||
nsCOMPtr<nsIDOMNodeList> childNodes;
|
||||
nsCOMPtr<nsIDOMNode> cellChild;
|
||||
res = targetCell->GetChildNodes(getter_AddRefs(childNodes));
|
||||
// If we fail or don't have children,
|
||||
// we insert at index 0
|
||||
|
@ -1837,10 +1832,20 @@ nsHTMLEditor::MergeCells(nsCOMPtr<nsIDOMElement> aTargetCell,
|
|||
PRUint32 len;
|
||||
res = childNodes->GetLength(&len);
|
||||
if (NS_FAILED(res)) return res;
|
||||
insertIndex = (PRInt32)len;
|
||||
if (len == 1 && IsEmptyCell(aTargetCell))
|
||||
{
|
||||
if (IsEmptyCell(aTargetCell))
|
||||
{
|
||||
// Delete the empty node
|
||||
nsCOMPtr<nsIDOMNode> tempNode;
|
||||
DeleteNode(cellChild);
|
||||
insertIndex = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
insertIndex = (PRInt32)len;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> cellChild;
|
||||
res = cellToMerge->GetFirstChild(getter_AddRefs(cellChild));
|
||||
if (NS_FAILED(res)) return res;
|
||||
while (cellChild)
|
||||
|
@ -1849,10 +1854,10 @@ nsHTMLEditor::MergeCells(nsCOMPtr<nsIDOMElement> aTargetCell,
|
|||
res = cellChild->GetNextSibling(getter_AddRefs(nextChild));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
res = nsEditor::DeleteNode(cellChild);
|
||||
res = DeleteNode(cellChild);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
res = nsEditor::InsertNode(cellChild, targetCell, insertIndex);
|
||||
res = InsertNode(cellChild, targetCell, insertIndex);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
cellChild = nextChild;
|
||||
|
@ -1922,7 +1927,7 @@ nsHTMLEditor::NormalizeTable(nsIDOMElement *aTable)
|
|||
{
|
||||
nsCOMPtr<nsIDOMElement> table;
|
||||
nsresult res = NS_ERROR_FAILURE;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), aTable, getter_AddRefs(table));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), aTable, getter_AddRefs(table));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// Don't fail if we didn't find a table
|
||||
if (!table) return NS_OK;
|
||||
|
@ -2002,7 +2007,7 @@ nsHTMLEditor::GetCellIndexes(nsIDOMElement *aCell, PRInt32 &aRowIndex, PRInt32 &
|
|||
{
|
||||
// Get the selected cell or the cell enclosing the selection anchor
|
||||
nsCOMPtr<nsIDOMElement> cell;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("td"), nsnull, getter_AddRefs(cell));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("td"), nsnull, getter_AddRefs(cell));
|
||||
if (NS_SUCCEEDED(res) && cell)
|
||||
aCell = cell;
|
||||
else
|
||||
|
@ -2030,7 +2035,7 @@ nsHTMLEditor::GetTableLayoutObject(nsIDOMElement* aTable, nsITableLayout **table
|
|||
|
||||
// frames are not ref counted, so don't use an nsCOMPtr
|
||||
nsISupports *layoutObject=nsnull;
|
||||
nsresult res = nsHTMLEditor::GetLayoutObject(aTable, &layoutObject);
|
||||
nsresult res = GetLayoutObject(aTable, &layoutObject);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!layoutObject) return NS_ERROR_FAILURE;
|
||||
return layoutObject->QueryInterface(NS_GET_IID(nsITableLayout),
|
||||
|
@ -2079,7 +2084,7 @@ nsHTMLEditor::GetTableSize(nsIDOMElement *aTable, PRInt32& aRowCount, PRInt32& a
|
|||
aColCount = 0;
|
||||
nsCOMPtr<nsIDOMElement> table;
|
||||
// Get the selected talbe or the table enclosing the selection anchor
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), aTable, getter_AddRefs(table));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), aTable, getter_AddRefs(table));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!table) return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -2114,7 +2119,7 @@ nsHTMLEditor::GetCellDataAt(nsIDOMElement* aTable, PRInt32 aRowIndex, PRInt32 aC
|
|||
{
|
||||
// Get the selected table or the table enclosing the selection anchor
|
||||
nsCOMPtr<nsIDOMElement> table;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), nsnull, getter_AddRefs(table));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), nsnull, getter_AddRefs(table));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (table)
|
||||
aTable = table;
|
||||
|
@ -2181,7 +2186,7 @@ nsHTMLEditor::GetCellContext(nsIDOMSelection **aSelection,
|
|||
if (aColIndex) *aColIndex = 0;
|
||||
|
||||
nsCOMPtr <nsIDOMSelection> selection;
|
||||
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -2202,10 +2207,28 @@ nsHTMLEditor::GetCellContext(nsIDOMSelection **aSelection,
|
|||
// or get the enclosing by a cell
|
||||
if (!cell)
|
||||
{
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("td"), nsnull, getter_AddRefs(cell));
|
||||
// Find a selected or enclosing table element
|
||||
nsCOMPtr<nsIDOMElement> cellOrTableElement;
|
||||
PRInt32 selectedCount;
|
||||
nsAutoString tagName;
|
||||
nsresult res = GetSelectedOrParentTableElement(*getter_AddRefs(cellOrTableElement), tagName, selectedCount);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (tagName == NS_LITERAL_STRING("table"))
|
||||
{
|
||||
// We have a selected table, not a cell
|
||||
if (aTable)
|
||||
{
|
||||
*aTable = cellOrTableElement.get();
|
||||
NS_ADDREF(*aTable);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
// Don't fail if we are not in a cell
|
||||
if (!cell) return NS_EDITOR_ELEMENT_NOT_FOUND;
|
||||
if (tagName != NS_LITERAL_STRING("td"))
|
||||
return NS_EDITOR_ELEMENT_NOT_FOUND;
|
||||
|
||||
// We found a cell
|
||||
cell = cellOrTableElement;
|
||||
}
|
||||
if (aCell)
|
||||
{
|
||||
|
@ -2214,7 +2237,7 @@ nsHTMLEditor::GetCellContext(nsIDOMSelection **aSelection,
|
|||
}
|
||||
|
||||
// Get containing table
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), cell, getter_AddRefs(table));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), cell, getter_AddRefs(table));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// Cell must be in a table, so fail if not found
|
||||
if (!table) return NS_ERROR_FAILURE;
|
||||
|
@ -2261,7 +2284,7 @@ nsHTMLEditor::GetFirstSelectedCell(nsIDOMElement **aCell, nsIDOMRange **aRange)
|
|||
if (aRange) *aRange = nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -2307,7 +2330,7 @@ nsHTMLEditor::GetNextSelectedCell(nsIDOMElement **aCell, nsIDOMRange **aRange)
|
|||
if (aRange) *aRange = nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -2331,7 +2354,7 @@ nsHTMLEditor::GetNextSelectedCell(nsIDOMElement **aCell, nsIDOMRange **aRange)
|
|||
if (!range) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> cellNode;
|
||||
res = nsEditor::GetFirstNodeInRange(range, getter_AddRefs(cellNode));
|
||||
res = GetFirstNodeInRange(range, getter_AddRefs(cellNode));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!cellNode) return NS_ERROR_FAILURE;
|
||||
if (IsTableCell(cellNode))
|
||||
|
@ -2421,7 +2444,7 @@ nsHTMLEditor::SetSelectionAfterTableEdit(nsIDOMElement* aTable, PRInt32 aRow, PR
|
|||
if (!aTable) return res;
|
||||
|
||||
nsCOMPtr<nsIDOMSelection>selection;
|
||||
res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
if (!selection)
|
||||
|
@ -2514,75 +2537,91 @@ nsHTMLEditor::GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsS
|
|||
aSelectedCount = 0;
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_FAILURE;
|
||||
|
||||
nsAutoString tableName; tableName.AssignWithConversion("table");
|
||||
nsAutoString trName; trName.AssignWithConversion("tr");
|
||||
nsAutoString tdName; tdName.AssignWithConversion("td");
|
||||
|
||||
nsCOMPtr<nsIDOMNode> anchorNode;
|
||||
res = selection->GetAnchorNode(getter_AddRefs(anchorNode));
|
||||
if(NS_FAILED(res)) return res;
|
||||
if (!anchorNode) return NS_ERROR_FAILURE;
|
||||
// Try to get the first selected cell
|
||||
nsCOMPtr<nsIDOMElement> tableOrCellElement;
|
||||
res = GetFirstSelectedCell(getter_AddRefs(tableOrCellElement), nsnull);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> tableElement;
|
||||
nsCOMPtr<nsIDOMNode> selectedNode;
|
||||
|
||||
// Get child of anchor node, if exists
|
||||
PRBool hasChildren;
|
||||
anchorNode->HasChildNodes(&hasChildren);
|
||||
|
||||
if (hasChildren)
|
||||
if (tableOrCellElement)
|
||||
{
|
||||
PRInt32 anchorOffset;
|
||||
res = selection->GetAnchorOffset(&anchorOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
selectedNode = nsEditor::GetChildAt(anchorNode, anchorOffset);
|
||||
if (!selectedNode)
|
||||
{
|
||||
selectedNode = anchorNode;
|
||||
// If anchor doesn't have a child, we can't be selecting a table element,
|
||||
// so don't do the following:
|
||||
} else {
|
||||
nsAutoString tag;
|
||||
nsEditor::GetTagString(selectedNode,tag);
|
||||
|
||||
if (tag == tdName)
|
||||
{
|
||||
tableElement = do_QueryInterface(selectedNode);
|
||||
aTagName = tdName;
|
||||
// Each cell is in its own selection range,
|
||||
// so count signals multiple-cell selection
|
||||
res = selection->GetRangeCount(&aSelectedCount);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
else if(tag == tableName)
|
||||
{
|
||||
tableElement = do_QueryInterface(selectedNode);
|
||||
aTagName = tableName;
|
||||
aSelectedCount = 1;
|
||||
}
|
||||
else if(tag == trName)
|
||||
{
|
||||
tableElement = do_QueryInterface(selectedNode);
|
||||
aTagName = trName;
|
||||
aSelectedCount = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!tableElement)
|
||||
{
|
||||
// Didn't find a table element -- find a cell parent
|
||||
res = GetElementOrParentByTagName(tdName, anchorNode, getter_AddRefs(tableElement));
|
||||
if(NS_FAILED(res)) return res;
|
||||
if (tableElement)
|
||||
// Each cell is in its own selection range,
|
||||
// so count signals multiple-cell selection
|
||||
res = selection->GetRangeCount(&aSelectedCount);
|
||||
if (NS_FAILED(res)) return res;
|
||||
aTagName = tdName;
|
||||
}
|
||||
if (tableElement)
|
||||
else
|
||||
{
|
||||
aTableElement = tableElement.get();
|
||||
nsAutoString tableName; tableName.AssignWithConversion("table");
|
||||
nsAutoString trName; trName.AssignWithConversion("tr");
|
||||
|
||||
nsCOMPtr<nsIDOMNode> anchorNode;
|
||||
res = selection->GetAnchorNode(getter_AddRefs(anchorNode));
|
||||
if(NS_FAILED(res)) return res;
|
||||
if (!anchorNode) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> selectedNode;
|
||||
|
||||
// Get child of anchor node, if exists
|
||||
PRBool hasChildren;
|
||||
anchorNode->HasChildNodes(&hasChildren);
|
||||
|
||||
if (hasChildren)
|
||||
{
|
||||
PRInt32 anchorOffset;
|
||||
res = selection->GetAnchorOffset(&anchorOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
selectedNode = GetChildAt(anchorNode, anchorOffset);
|
||||
if (!selectedNode)
|
||||
{
|
||||
selectedNode = anchorNode;
|
||||
// If anchor doesn't have a child, we can't be selecting a table element,
|
||||
// so don't do the following:
|
||||
} else {
|
||||
nsAutoString tag;
|
||||
GetTagString(selectedNode,tag);
|
||||
|
||||
if (tag == tdName)
|
||||
{
|
||||
tableOrCellElement = do_QueryInterface(selectedNode);
|
||||
aTagName = tdName;
|
||||
// Each cell is in its own selection range,
|
||||
// so count signals multiple-cell selection
|
||||
res = selection->GetRangeCount(&aSelectedCount);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
else if(tag == tableName)
|
||||
{
|
||||
tableOrCellElement = do_QueryInterface(selectedNode);
|
||||
aTagName = tableName;
|
||||
aSelectedCount = 1;
|
||||
}
|
||||
else if(tag == trName)
|
||||
{
|
||||
tableOrCellElement = do_QueryInterface(selectedNode);
|
||||
aTagName = trName;
|
||||
aSelectedCount = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!tableOrCellElement)
|
||||
{
|
||||
// Didn't find a table element -- find a cell parent
|
||||
res = GetElementOrParentByTagName(tdName, anchorNode, getter_AddRefs(tableOrCellElement));
|
||||
if(NS_FAILED(res)) return res;
|
||||
if (tableOrCellElement)
|
||||
aTagName = tdName;
|
||||
}
|
||||
}
|
||||
if (tableOrCellElement)
|
||||
{
|
||||
aTableElement = tableOrCellElement.get();
|
||||
NS_ADDREF(aTableElement);
|
||||
}
|
||||
return res;
|
||||
|
@ -2611,7 +2650,7 @@ nsHTMLEditor::GetSelectedCellsType(nsIDOMElement *aElement, PRUint32 &aSelection
|
|||
// (if aElement is null, this uses selection's anchor node)
|
||||
nsCOMPtr<nsIDOMElement> table;
|
||||
|
||||
nsresult res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), aElement, getter_AddRefs(table));
|
||||
nsresult res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), aElement, getter_AddRefs(table));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
PRInt32 rowCount, colCount;
|
||||
|
@ -2742,3 +2781,31 @@ nsHTMLEditor::AllCellsInColumnSelected(nsIDOMElement *aTable, PRInt32 aColIndex,
|
|||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLEditor::IsEmptyCell(nsIDOMElement *aCell)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> cellChild;
|
||||
|
||||
// Check if target only contains empty text node or <br>
|
||||
nsresult res = aCell->GetFirstChild(getter_AddRefs(cellChild));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (cellChild)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> nextChild;
|
||||
res = cellChild->GetNextSibling(getter_AddRefs(nextChild));
|
||||
if (!nextChild)
|
||||
{
|
||||
// We insert a single break into a cell by default
|
||||
// to have some place to locate a cursor -- it is dispensable
|
||||
PRBool isEmpty = nsHTMLEditUtils::IsBreak(cellChild);
|
||||
// Or check if no real content
|
||||
if (!isEmpty)
|
||||
IsEmptyNode(cellChild, &isEmpty, PR_FALSE, PR_FALSE);
|
||||
|
||||
return isEmpty;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -418,7 +418,7 @@ nsTextEditRules::GetTopEnclosingPre(nsIDOMNode *aNode,
|
|||
return res;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsresult
|
||||
nsTextEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
|
@ -487,7 +487,7 @@ nsTextEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel, P
|
|||
|
||||
if (outLeftNode)
|
||||
{
|
||||
res = IsEmptyNode(outLeftNode, &bIsEmptyNode, PR_TRUE, PR_FALSE);
|
||||
res = mEditor->IsEmptyNode(outLeftNode, &bIsEmptyNode, PR_TRUE, PR_FALSE);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (bIsEmptyNode) mEditor->DeleteNode(outLeftNode);
|
||||
}
|
||||
|
@ -501,7 +501,7 @@ nsTextEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel, P
|
|||
mEditor->DeleteNode(firstNode);
|
||||
}
|
||||
|
||||
res = IsEmptyNode(outRightNode, &bIsEmptyNode, PR_TRUE, PR_FALSE);
|
||||
res = mEditor->IsEmptyNode(outRightNode, &bIsEmptyNode, PR_TRUE, PR_FALSE);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (bIsEmptyNode) mEditor->DeleteNode(outRightNode);
|
||||
}
|
||||
|
@ -685,7 +685,7 @@ nsTextEditRules::WillInsertText(PRInt32 aAction,
|
|||
if (isPRE)
|
||||
{
|
||||
char newlineChar = '\n';
|
||||
while (unicodeBuf && (pos != -1) && (pos < outString->Length()))
|
||||
while (unicodeBuf && (pos != -1) && ((PRUint32)pos < outString->Length()))
|
||||
{
|
||||
PRInt32 oldPos = pos;
|
||||
PRInt32 subStrLen;
|
||||
|
@ -723,7 +723,7 @@ nsTextEditRules::WillInsertText(PRInt32 aAction,
|
|||
{
|
||||
char specialChars[] = {'\t','\n',0};
|
||||
nsAutoString tabString; tabString.AssignWithConversion(" ");
|
||||
while (unicodeBuf && (pos != -1) && (pos < outString->Length()))
|
||||
while (unicodeBuf && (pos != -1) && ((PRUint32)pos < outString->Length()))
|
||||
{
|
||||
PRInt32 oldPos = pos;
|
||||
PRInt32 subStrLen;
|
||||
|
@ -1334,106 +1334,6 @@ nsTextEditRules::CreateMozBR(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<ns
|
|||
return res;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// IsEmptyNode: figure out if aNode is an empty node.
|
||||
// A block can have children and still be considered empty,
|
||||
// if the children are empty or non-editable.
|
||||
//
|
||||
nsresult
|
||||
nsTextEditRules::IsEmptyNode( nsIDOMNode *aNode,
|
||||
PRBool *outIsEmptyNode,
|
||||
PRBool aMozBRDoesntCount,
|
||||
PRBool aListItemsNotEmpty)
|
||||
{
|
||||
if (!aNode || !outIsEmptyNode) return NS_ERROR_NULL_POINTER;
|
||||
*outIsEmptyNode = PR_TRUE;
|
||||
|
||||
// effeciency hack - special case if it's a text node
|
||||
if (nsEditor::IsTextNode(aNode))
|
||||
{
|
||||
PRUint32 length = 0;
|
||||
nsCOMPtr<nsIDOMCharacterData>nodeAsText;
|
||||
nodeAsText = do_QueryInterface(aNode);
|
||||
nodeAsText->GetLength(&length);
|
||||
if (length) *outIsEmptyNode = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// if it's not a text node (handled above) and it's not a container,
|
||||
// then we dont call it empty (it's an <hr>, or <br>, etc).
|
||||
// Also, if it's an anchor then dont treat it as empty - even though
|
||||
// anchors are containers, named anchors are "empty" but we don't
|
||||
// want to treat them as such. Also, don't call ListItems or table
|
||||
// cells empty if caller desires.
|
||||
if (!mEditor->IsContainer(aNode) || nsHTMLEditUtils::IsAnchor(aNode) ||
|
||||
(aListItemsNotEmpty && nsHTMLEditUtils::IsListItem(aNode)) ||
|
||||
(aListItemsNotEmpty && nsHTMLEditUtils::IsTableCell(aNode)) )
|
||||
{
|
||||
*outIsEmptyNode = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// iterate over node. if no children, or all children are either
|
||||
// empty text nodes or non-editable, then node qualifies as empty
|
||||
nsCOMPtr<nsIContentIterator> iter;
|
||||
nsCOMPtr<nsIContent> nodeAsContent = do_QueryInterface(aNode);
|
||||
if (!nodeAsContent) return NS_ERROR_FAILURE;
|
||||
nsresult res = nsComponentManager::CreateInstance(kContentIteratorCID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsIContentIterator),
|
||||
getter_AddRefs(iter));
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = iter->Init(nodeAsContent);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
while (NS_ENUMERATOR_FALSE == iter->IsDone())
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
nsCOMPtr<nsIContent> content;
|
||||
res = iter->CurrentNode(getter_AddRefs(content));
|
||||
if (NS_FAILED(res)) return res;
|
||||
node = do_QueryInterface(content);
|
||||
if (!node) return NS_ERROR_FAILURE;
|
||||
|
||||
// is the node editable and non-empty? if so, return false
|
||||
if (mEditor->IsEditable(node))
|
||||
{
|
||||
if (nsEditor::IsTextNode(node))
|
||||
{
|
||||
PRUint32 length = 0;
|
||||
nsCOMPtr<nsIDOMCharacterData>nodeAsText;
|
||||
nodeAsText = do_QueryInterface(node);
|
||||
nodeAsText->GetLength(&length);
|
||||
if (length) *outIsEmptyNode = PR_FALSE;
|
||||
}
|
||||
else // an editable, non-text node. we aren't an empty block
|
||||
{
|
||||
// is it the node we are iterating over?
|
||||
if (node.get() == aNode) break;
|
||||
// is it a moz-BR and did the caller ask us not to consider those relevant?
|
||||
if (!(aMozBRDoesntCount && nsHTMLEditUtils::IsMozBR(node)))
|
||||
{
|
||||
// is it an empty node of some sort?
|
||||
PRBool isEmptyNode;
|
||||
res = IsEmptyNode(node, &isEmptyNode, aMozBRDoesntCount, aListItemsNotEmpty);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!isEmptyNode)
|
||||
{
|
||||
// otherwise it ain't empty
|
||||
*outIsEmptyNode = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res = iter->Next();
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsTextEditRules::DeleteEmptyTextNode(nsIDOMNode *aNode)
|
||||
{
|
||||
|
|
|
@ -161,11 +161,6 @@ protected:
|
|||
|
||||
nsresult CreateMozBR(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outBRNode);
|
||||
|
||||
nsresult IsEmptyNode(nsIDOMNode *aNode,
|
||||
PRBool *outIsEmptyBlock,
|
||||
PRBool aMozBRDoesntCount = PR_FALSE,
|
||||
PRBool aListItemsNotEmpty = PR_FALSE);
|
||||
|
||||
PRBool DeleteEmptyTextNode(nsIDOMNode *aNode);
|
||||
|
||||
nsresult AdjustSelection(nsIDOMSelection *aSelection, nsIEditor::EDirection aDirection);
|
||||
|
|
|
@ -1820,7 +1820,8 @@ nsEditor::ReplaceContainer(nsIDOMNode *inNode,
|
|||
nsCOMPtr<nsIDOMNode> *outNode,
|
||||
const nsString &aNodeType,
|
||||
const nsString *aAttribute,
|
||||
const nsString *aValue)
|
||||
const nsString *aValue,
|
||||
PRBool aCloneAttributes)
|
||||
{
|
||||
if (!inNode || !outNode)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
@ -1851,14 +1852,32 @@ nsEditor::ReplaceContainer(nsIDOMNode *inNode,
|
|||
res = elem->SetAttribute(*aAttribute, *aValue);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
if (aCloneAttributes)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode>newNode = do_QueryInterface(elem);
|
||||
res = CloneAttributes(newNode, inNode);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
// notify our internal selection state listener
|
||||
nsAutoReplaceContainerSelNotify selStateNotify(mSavedSel, inNode, *outNode);
|
||||
|
||||
// insert new container into tree
|
||||
res = InsertNode( *outNode, parent, offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// We sometimes insert default <br> (like in a table cell),
|
||||
// so save this to delete later
|
||||
nsCOMPtr<nsIDOMNode> newNodeDefaultChild;
|
||||
nsresult resFirstChild = (*outNode)->GetFirstChild(getter_AddRefs(newNodeDefaultChild));
|
||||
|
||||
// move children into new container
|
||||
|
||||
nsCOMPtr<nsIDOMNode> child;
|
||||
/*
|
||||
// This doesn't work when used with table cells!
|
||||
PRBool bHasMoreChildren;
|
||||
inNode->HasChildNodes(&bHasMoreChildren);
|
||||
nsCOMPtr<nsIDOMNode> child;
|
||||
while (bHasMoreChildren)
|
||||
{
|
||||
inNode->GetLastChild(getter_AddRefs(child));
|
||||
|
@ -1868,14 +1887,35 @@ nsEditor::ReplaceContainer(nsIDOMNode *inNode,
|
|||
if (NS_FAILED(res)) return res;
|
||||
inNode->HasChildNodes(&bHasMoreChildren);
|
||||
}
|
||||
*/
|
||||
// Insert at start of the new node
|
||||
PRInt32 insertIndex = 0;
|
||||
res = inNode->GetFirstChild(getter_AddRefs(child));
|
||||
if (NS_FAILED(res)) return res;
|
||||
while (child)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> nextChild;
|
||||
res = child->GetNextSibling(getter_AddRefs(nextChild));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
res = DeleteNode(child);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
res = InsertNode(child, *outNode, insertIndex);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
child = nextChild;
|
||||
insertIndex++;
|
||||
}
|
||||
// Now that we have some real content in the new node,
|
||||
// delete the default first child
|
||||
// (We must do this AFTER moving the other nodes
|
||||
// because rules would reinsert it if we did it first!)
|
||||
if (NS_SUCCEEDED(resFirstChild) && newNodeDefaultChild)
|
||||
DeleteNode(newNodeDefaultChild);
|
||||
|
||||
// delete old container
|
||||
res = DeleteNode(inNode);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// insert new container into tree
|
||||
res = InsertNode( *outNode, parent, offset);
|
||||
return res;
|
||||
return DeleteNode(inNode);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -318,7 +318,9 @@ public:
|
|||
nsCOMPtr<nsIDOMNode> *outNode,
|
||||
const nsString &aNodeType,
|
||||
const nsString *aAttribute = nsnull,
|
||||
const nsString *aValue = nsnull);
|
||||
const nsString *aValue = nsnull,
|
||||
PRBool aCloneAttributes = PR_FALSE);
|
||||
|
||||
nsresult RemoveContainer(nsIDOMNode *inNode);
|
||||
nsresult InsertContainerAbove(nsIDOMNode *inNode,
|
||||
nsCOMPtr<nsIDOMNode> *outNode,
|
||||
|
|
|
@ -1171,7 +1171,7 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection,
|
|||
// see if we are in an "empty" node.
|
||||
// Note: do NOT delete table elements this way.
|
||||
PRBool bIsEmptyNode;
|
||||
res = IsEmptyNode(node, &bIsEmptyNode, PR_TRUE, PR_FALSE);
|
||||
res = mEditor->IsEmptyNode(node, &bIsEmptyNode, PR_TRUE, PR_FALSE);
|
||||
if (bIsEmptyNode && !mEditor->IsTableElement(node))
|
||||
nodeToDelete = node;
|
||||
else
|
||||
|
@ -1511,7 +1511,7 @@ nsHTMLEditRules::WillMakeList(nsIDOMSelection *aSelection,
|
|||
else if (mEditor->IsInlineNode(curNode) && mEditor->IsContainer(curNode))
|
||||
{
|
||||
PRBool bEmpty;
|
||||
res = IsEmptyNode( curNode, &bEmpty);
|
||||
res = mEditor->IsEmptyNode(curNode, &bEmpty);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (bEmpty)
|
||||
{
|
||||
|
@ -2196,7 +2196,7 @@ nsHTMLEditRules::IsEmptyBlock(nsIDOMNode *aNode,
|
|||
// looks like I forgot to finish this. Wonder what I was going to do?
|
||||
|
||||
if (!nodeToTest) return NS_ERROR_NULL_POINTER;
|
||||
return IsEmptyNode(nodeToTest, outIsEmptyBlock,
|
||||
return mEditor->IsEmptyNode(nodeToTest, outIsEmptyBlock,
|
||||
aMozBRDoesntCount, aListItemsNotEmpty);
|
||||
}
|
||||
|
||||
|
@ -3350,7 +3350,7 @@ nsHTMLEditRules::ReturnInHeader(nsIDOMSelection *aSelection,
|
|||
if (prevItem && nsHTMLEditUtils::IsHeader(prevItem))
|
||||
{
|
||||
PRBool bIsEmptyNode;
|
||||
res = IsEmptyNode(prevItem, &bIsEmptyNode);
|
||||
res = mEditor->IsEmptyNode(prevItem, &bIsEmptyNode);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (bIsEmptyNode)
|
||||
{
|
||||
|
@ -3607,7 +3607,7 @@ nsHTMLEditRules::ReturnInListItem(nsIDOMSelection *aSelection,
|
|||
if (prevItem && nsHTMLEditUtils::IsListItem(prevItem))
|
||||
{
|
||||
PRBool bIsEmptyNode;
|
||||
res = IsEmptyNode(prevItem, &bIsEmptyNode);
|
||||
res = mEditor->IsEmptyNode(prevItem, &bIsEmptyNode);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (bIsEmptyNode)
|
||||
{
|
||||
|
@ -4184,7 +4184,7 @@ nsHTMLEditRules::AdjustSpecialBreaks()
|
|||
if (!node) return NS_ERROR_FAILURE;
|
||||
|
||||
PRBool bIsEmptyNode;
|
||||
res = IsEmptyNode(node, &bIsEmptyNode, PR_FALSE, PR_FALSE);
|
||||
res = mEditor->IsEmptyNode(node, &bIsEmptyNode, PR_FALSE, PR_FALSE);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (bIsEmptyNode
|
||||
&& (nsHTMLEditUtils::IsListItem(node) || mEditor->IsTableCell(node)))
|
||||
|
@ -4551,7 +4551,7 @@ nsHTMLEditRules::RemoveEmptyNodes()
|
|||
if (!node) return NS_ERROR_FAILURE;
|
||||
|
||||
PRBool bIsEmptyNode;
|
||||
res = IsEmptyNode(node, &bIsEmptyNode, PR_FALSE, PR_TRUE);
|
||||
res = mEditor->IsEmptyNode(node, &bIsEmptyNode, PR_FALSE, PR_TRUE);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (bIsEmptyNode && !nsHTMLEditUtils::IsBody(node))
|
||||
{
|
||||
|
@ -4984,7 +4984,7 @@ nsHTMLEditRules::InsertMozBRIfNeeded(nsIDOMNode *aNode)
|
|||
|
||||
PRBool isEmpty;
|
||||
nsCOMPtr<nsIDOMNode> brNode;
|
||||
nsresult res = IsEmptyNode(aNode, &isEmpty);
|
||||
nsresult res = mEditor->IsEmptyNode(aNode, &isEmpty);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (isEmpty)
|
||||
{
|
||||
|
|
|
@ -38,12 +38,15 @@ PRBool
|
|||
nsHTMLEditUtils::IsBody(nsIDOMNode *node)
|
||||
{
|
||||
NS_PRECONDITION(node, "null node passed to nsHTMLEditUtils::IsBody");
|
||||
nsAutoString tag;
|
||||
nsEditor::GetTagString(node,tag);
|
||||
tag.ToLowerCase();
|
||||
if (tag.EqualsWithConversion("body"))
|
||||
if (node)
|
||||
{
|
||||
return PR_TRUE;
|
||||
nsAutoString tag;
|
||||
nsEditor::GetTagString(node,tag);
|
||||
tag.ToLowerCase();
|
||||
if (tag.EqualsWithConversion("body"))
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
|
|
@ -7063,3 +7063,102 @@ nsHTMLEditor::GetLastEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOu
|
|||
return res;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// IsEmptyNode: figure out if aNode is an empty node.
|
||||
// A block can have children and still be considered empty,
|
||||
// if the children are empty or non-editable.
|
||||
//
|
||||
nsresult
|
||||
nsHTMLEditor::IsEmptyNode( nsIDOMNode *aNode,
|
||||
PRBool *outIsEmptyNode,
|
||||
PRBool aMozBRDoesntCount,
|
||||
PRBool aListOrCellNotEmpty)
|
||||
{
|
||||
if (!aNode || !outIsEmptyNode) return NS_ERROR_NULL_POINTER;
|
||||
*outIsEmptyNode = PR_TRUE;
|
||||
|
||||
// effeciency hack - special case if it's a text node
|
||||
if (nsEditor::IsTextNode(aNode))
|
||||
{
|
||||
PRUint32 length = 0;
|
||||
nsCOMPtr<nsIDOMCharacterData>nodeAsText;
|
||||
nodeAsText = do_QueryInterface(aNode);
|
||||
nodeAsText->GetLength(&length);
|
||||
if (length) *outIsEmptyNode = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// if it's not a text node (handled above) and it's not a container,
|
||||
// then we dont call it empty (it's an <hr>, or <br>, etc).
|
||||
// Also, if it's an anchor then dont treat it as empty - even though
|
||||
// anchors are containers, named anchors are "empty" but we don't
|
||||
// want to treat them as such. Also, don't call ListItems or table
|
||||
// cells empty if caller desires.
|
||||
if (!IsContainer(aNode) || nsHTMLEditUtils::IsAnchor(aNode) ||
|
||||
(aListOrCellNotEmpty && nsHTMLEditUtils::IsListItem(aNode)) ||
|
||||
(aListOrCellNotEmpty && nsHTMLEditUtils::IsTableCell(aNode)) )
|
||||
{
|
||||
*outIsEmptyNode = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// iterate over node. if no children, or all children are either
|
||||
// empty text nodes or non-editable, then node qualifies as empty
|
||||
nsCOMPtr<nsIContentIterator> iter;
|
||||
nsCOMPtr<nsIContent> nodeAsContent = do_QueryInterface(aNode);
|
||||
if (!nodeAsContent) return NS_ERROR_FAILURE;
|
||||
nsresult res = nsComponentManager::CreateInstance(kCContentIteratorCID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsIContentIterator),
|
||||
getter_AddRefs(iter));
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = iter->Init(nodeAsContent);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
while (NS_ENUMERATOR_FALSE == iter->IsDone())
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
nsCOMPtr<nsIContent> content;
|
||||
res = iter->CurrentNode(getter_AddRefs(content));
|
||||
if (NS_FAILED(res)) return res;
|
||||
node = do_QueryInterface(content);
|
||||
if (!node) return NS_ERROR_FAILURE;
|
||||
|
||||
// is the node editable and non-empty? if so, return false
|
||||
if (nsEditor::IsEditable(node))
|
||||
{
|
||||
if (nsEditor::IsTextNode(node))
|
||||
{
|
||||
PRUint32 length = 0;
|
||||
nsCOMPtr<nsIDOMCharacterData>nodeAsText;
|
||||
nodeAsText = do_QueryInterface(node);
|
||||
nodeAsText->GetLength(&length);
|
||||
if (length) *outIsEmptyNode = PR_FALSE;
|
||||
}
|
||||
else // an editable, non-text node. we aren't an empty block
|
||||
{
|
||||
// is it the node we are iterating over?
|
||||
if (node.get() == aNode) break;
|
||||
// is it a moz-BR and did the caller ask us not to consider those relevant?
|
||||
if (!(aMozBRDoesntCount && nsHTMLEditUtils::IsMozBR(node)))
|
||||
{
|
||||
// is it an empty node of some sort?
|
||||
PRBool isEmptyNode;
|
||||
res = IsEmptyNode(node, &isEmptyNode, aMozBRDoesntCount, aListOrCellNotEmpty);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!isEmptyNode)
|
||||
{
|
||||
// otherwise it ain't empty
|
||||
*outIsEmptyNode = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res = iter->Next();
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -396,6 +396,8 @@ protected:
|
|||
PRBool AllCellsInRowSelected(nsIDOMElement *aTable, PRInt32 aRowIndex, PRInt32 aNumberOfColumns);
|
||||
PRBool AllCellsInColumnSelected(nsIDOMElement *aTable, PRInt32 aColIndex, PRInt32 aNumberOfRows);
|
||||
|
||||
PRBool IsEmptyCell(nsIDOMElement *aCell);
|
||||
|
||||
// Most insert methods need to get the same basic context data
|
||||
// Any of the pointers may be null if you don't need that datum (for more efficiency)
|
||||
// Input: *aCell is a known cell,
|
||||
|
@ -549,6 +551,9 @@ protected:
|
|||
nsresult IsLastEditableChild( nsIDOMNode *aNode, PRBool *aOutIsLast);
|
||||
nsresult GetFirstEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutFirstChild);
|
||||
nsresult GetLastEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutLastChild);
|
||||
nsresult IsEmptyNode(nsIDOMNode *aNode, PRBool *outIsEmptyBlock,
|
||||
PRBool aMozBRDoesntCount = PR_FALSE,
|
||||
PRBool aListOrCellNotEmpty = PR_FALSE);
|
||||
|
||||
nsresult GetDOMEventReceiver(nsIDOMEventReceiver **aEventReceiver);
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "nsVoidArray.h"
|
||||
|
||||
#include "nsEditorUtils.h"
|
||||
#include "nsHTMLEditUtils.h"
|
||||
|
||||
//#define DEBUG_TABLE 1
|
||||
|
||||
|
@ -120,9 +121,9 @@ nsHTMLEditor::InsertCell(nsIDOMElement *aCell, PRInt32 aRowSpan, PRInt32 aColSpa
|
|||
|
||||
nsCOMPtr<nsIDOMElement> newCell;
|
||||
if (aIsHeader)
|
||||
res = CreateElementWithDefaults(NS_ConvertASCIItoUCS2("th"), getter_AddRefs(newCell));
|
||||
res = CreateElementWithDefaults(NS_LITERAL_STRING("th"), getter_AddRefs(newCell));
|
||||
else
|
||||
res = CreateElementWithDefaults(NS_ConvertASCIItoUCS2("td"), getter_AddRefs(newCell));
|
||||
res = CreateElementWithDefaults(NS_LITERAL_STRING("td"), getter_AddRefs(newCell));
|
||||
|
||||
if(NS_FAILED(res)) return res;
|
||||
if(!newCell) return NS_ERROR_FAILURE;
|
||||
|
@ -137,19 +138,19 @@ nsHTMLEditor::InsertCell(nsIDOMElement *aCell, PRInt32 aRowSpan, PRInt32 aColSpa
|
|||
{
|
||||
nsAutoString newRowSpan(aRowSpan);
|
||||
// Note: Do NOT use editor txt for this
|
||||
newCell->SetAttribute(NS_ConvertASCIItoUCS2("rowspan"), newRowSpan);
|
||||
newCell->SetAttribute(NS_LITERAL_STRING("rowspan"), newRowSpan);
|
||||
}
|
||||
if( aColSpan > 1)
|
||||
{
|
||||
nsAutoString newColSpan(aColSpan);
|
||||
// Note: Do NOT use editor txt for this
|
||||
newCell->SetAttribute(NS_ConvertASCIItoUCS2("colspan"), newColSpan);
|
||||
newCell->SetAttribute(NS_LITERAL_STRING("colspan"), newColSpan);
|
||||
}
|
||||
if(aAfter) cellOffset++;
|
||||
|
||||
//Don't let Rules System change the selection
|
||||
nsAutoTxnsConserveSelection dontChangeSelection(this);
|
||||
return nsEditor::InsertNode(newCell, cellParent, cellOffset);
|
||||
return InsertNode(newCell, cellParent, cellOffset);
|
||||
}
|
||||
|
||||
PRBool IsRowNode(nsCOMPtr<nsIDOMNode> &aNode)
|
||||
|
@ -221,11 +222,11 @@ nsHTMLEditor::InsertTableCell(PRInt32 aNumber, PRBool aAfter)
|
|||
for (i = 0; i < aNumber; i++)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> newCell;
|
||||
res = CreateElementWithDefaults(NS_ConvertASCIItoUCS2("td"), getter_AddRefs(newCell));
|
||||
res = CreateElementWithDefaults(NS_LITERAL_STRING("td"), getter_AddRefs(newCell));
|
||||
if (NS_SUCCEEDED(res) && newCell)
|
||||
{
|
||||
if (aAfter) cellOffset++;
|
||||
res = nsEditor::InsertNode(newCell, cellParent, cellOffset);
|
||||
res = InsertNode(newCell, cellParent, cellOffset);
|
||||
if(NS_FAILED(res)) break;
|
||||
}
|
||||
}
|
||||
|
@ -238,7 +239,7 @@ nsHTMLEditor::GetFirstRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow)
|
|||
aRow = nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> tableElement;
|
||||
nsresult res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), aTableElement, getter_AddRefs(tableElement));
|
||||
nsresult res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), aTableElement, getter_AddRefs(tableElement));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!tableElement) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -303,7 +304,7 @@ nsHTMLEditor::GetNextRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow)
|
|||
aRow = nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> rowElement;
|
||||
nsresult res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("tr"), aTableElement, getter_AddRefs(rowElement));
|
||||
nsresult res = GetElementOrParentByTagName(NS_LITERAL_STRING("tr"), aTableElement, getter_AddRefs(rowElement));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!rowElement) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -498,7 +499,7 @@ nsHTMLEditor::InsertTableRow(PRInt32 aNumber, PRBool aAfter)
|
|||
if (!curCell) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> parentRow;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("tr"), curCell, getter_AddRefs(parentRow));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("tr"), curCell, getter_AddRefs(parentRow));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!parentRow) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -596,7 +597,7 @@ nsHTMLEditor::InsertTableRow(PRInt32 aNumber, PRBool aAfter)
|
|||
{
|
||||
// Create a new row
|
||||
nsCOMPtr<nsIDOMElement> newRow;
|
||||
res = CreateElementWithDefaults(NS_ConvertASCIItoUCS2("tr"), getter_AddRefs(newRow));
|
||||
res = CreateElementWithDefaults(NS_LITERAL_STRING("tr"), getter_AddRefs(newRow));
|
||||
if (NS_SUCCEEDED(res))
|
||||
{
|
||||
if (!newRow) return NS_ERROR_FAILURE;
|
||||
|
@ -604,7 +605,7 @@ nsHTMLEditor::InsertTableRow(PRInt32 aNumber, PRBool aAfter)
|
|||
for (PRInt32 i = 0; i < cellsInRow; i++)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> newCell;
|
||||
res = CreateElementWithDefaults(NS_ConvertASCIItoUCS2("td"), getter_AddRefs(newCell));
|
||||
res = CreateElementWithDefaults(NS_LITERAL_STRING("td"), getter_AddRefs(newCell));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!newCell) return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -615,7 +616,7 @@ nsHTMLEditor::InsertTableRow(PRInt32 aNumber, PRBool aAfter)
|
|||
}
|
||||
// Use transaction system to insert the entire row+cells
|
||||
// (Note that rows are inserted at same childoffset each time)
|
||||
res = nsEditor::InsertNode(newRow, parentOfRow, newRowOffset);
|
||||
res = InsertNode(newRow, parentOfRow, newRowOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
}
|
||||
|
@ -629,7 +630,7 @@ nsHTMLEditor::DeleteTable2(nsCOMPtr<nsIDOMElement> &aTable, nsCOMPtr<nsIDOMSelec
|
|||
{
|
||||
nsCOMPtr<nsIDOMNode> tableParent;
|
||||
PRInt32 tableOffset;
|
||||
if(NS_FAILED(aTable->GetParentNode(getter_AddRefs(tableParent))) || !tableParent)
|
||||
if(!aTable || NS_FAILED(aTable->GetParentNode(getter_AddRefs(tableParent))) || !tableParent)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Save offset we need to restore the selection
|
||||
|
@ -669,7 +670,7 @@ nsHTMLEditor::DeleteTableCell(PRInt32 aNumber)
|
|||
nsCOMPtr<nsIDOMElement> cell;
|
||||
PRInt32 startRowIndex, startColIndex;
|
||||
|
||||
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -689,7 +690,7 @@ nsHTMLEditor::DeleteTableCell(PRInt32 aNumber)
|
|||
if (1 == GetNumberOfCellsInRow(table, startRowIndex))
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> parentRow;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("tr"), cell, getter_AddRefs(parentRow));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("tr"), cell, getter_AddRefs(parentRow));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!parentRow) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -849,7 +850,7 @@ nsHTMLEditor::DeleteTableColumn(PRInt32 aNumber)
|
|||
{
|
||||
// Only 1 cell in row - delete the row
|
||||
nsCOMPtr<nsIDOMElement> parentRow;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("tr"), cell, getter_AddRefs(parentRow));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("tr"), cell, getter_AddRefs(parentRow));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if(!parentRow) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -972,7 +973,7 @@ nsHTMLEditor::DeleteTableRow(PRInt32 aNumber)
|
|||
|
||||
// Delete the row
|
||||
nsCOMPtr<nsIDOMElement> parentRow;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("tr"), cell, getter_AddRefs(parentRow));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("tr"), cell, getter_AddRefs(parentRow));
|
||||
if (NS_SUCCEEDED(res) && parentRow)
|
||||
res = DeleteNode(parentRow);
|
||||
if (NS_FAILED(res))
|
||||
|
@ -992,7 +993,7 @@ nsHTMLEditor::SelectTable()
|
|||
{
|
||||
nsCOMPtr<nsIDOMElement> table;
|
||||
nsresult res = NS_ERROR_FAILURE;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), nsnull, getter_AddRefs(table));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), nsnull, getter_AddRefs(table));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// Don't fail if we didn't find a table
|
||||
if (!table) return NS_OK;
|
||||
|
@ -1011,7 +1012,7 @@ NS_IMETHODIMP
|
|||
nsHTMLEditor::SelectTableCell()
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> cell;
|
||||
nsresult res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("td"), nsnull, getter_AddRefs(cell));
|
||||
nsresult res = GetElementOrParentByTagName(NS_LITERAL_STRING("td"), nsnull, getter_AddRefs(cell));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// Don't fail if we didn't find a table
|
||||
if (!cell) return NS_EDITOR_ELEMENT_NOT_FOUND;
|
||||
|
@ -1032,17 +1033,17 @@ nsHTMLEditor::SelectBlockOfCells(nsIDOMElement *aStartCell, nsIDOMElement *aEndC
|
|||
if (!aStartCell || !aEndCell) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> table;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), aStartCell, getter_AddRefs(table));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), aStartCell, getter_AddRefs(table));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!table) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> endTable;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), aEndCell, getter_AddRefs(endTable));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), aEndCell, getter_AddRefs(endTable));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!endTable) return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -1107,7 +1108,7 @@ nsHTMLEditor::SelectBlockOfCells(nsIDOMElement *aStartCell, nsIDOMElement *aEndC
|
|||
if (!isSelected && cell && row == currentRowIndex && col == currentColIndex)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> cellNode = do_QueryInterface(cell);
|
||||
res = nsEditor::AppendNodeToSelectionAsRange(cellNode);
|
||||
res = AppendNodeToSelectionAsRange(cellNode);
|
||||
if (NS_FAILED(res)) break;
|
||||
}
|
||||
}
|
||||
|
@ -1119,7 +1120,7 @@ NS_IMETHODIMP
|
|||
nsHTMLEditor::SelectAllTableCells()
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> cell;
|
||||
nsresult res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("td"), nsnull, getter_AddRefs(cell));
|
||||
nsresult res = GetElementOrParentByTagName(NS_LITERAL_STRING("td"), nsnull, getter_AddRefs(cell));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// Don't fail if we didn't find a cell
|
||||
|
@ -1131,7 +1132,7 @@ nsHTMLEditor::SelectAllTableCells()
|
|||
|
||||
// Get parent table
|
||||
nsCOMPtr<nsIDOMElement> table;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), cell, getter_AddRefs(table));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), cell, getter_AddRefs(table));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if(!table) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -1140,7 +1141,7 @@ nsHTMLEditor::SelectAllTableCells()
|
|||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -1168,7 +1169,7 @@ nsHTMLEditor::SelectAllTableCells()
|
|||
if (cell && row == currentRowIndex && col == currentColIndex)
|
||||
{
|
||||
cellNode = do_QueryInterface(cell);
|
||||
res = nsEditor::AppendNodeToSelectionAsRange(cellNode);
|
||||
res = AppendNodeToSelectionAsRange(cellNode);
|
||||
if (NS_FAILED(res)) break;
|
||||
cellSelected = PR_TRUE;
|
||||
}
|
||||
|
@ -1178,7 +1179,7 @@ nsHTMLEditor::SelectAllTableCells()
|
|||
if (!cellSelected)
|
||||
{
|
||||
cellNode = do_QueryInterface(startCell);
|
||||
return nsEditor::AppendNodeToSelectionAsRange(cellNode);
|
||||
return AppendNodeToSelectionAsRange(cellNode);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -1187,7 +1188,7 @@ NS_IMETHODIMP
|
|||
nsHTMLEditor::SelectTableRow()
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> cell;
|
||||
nsresult res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("td"), nsnull, getter_AddRefs(cell));
|
||||
nsresult res = GetElementOrParentByTagName(NS_LITERAL_STRING("td"), nsnull, getter_AddRefs(cell));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// Don't fail if we didn't find a cell
|
||||
|
@ -1240,7 +1241,7 @@ nsHTMLEditor::SelectTableRow()
|
|||
if (cell && currentRowIndex == startRowIndex && currentColIndex == col)
|
||||
{
|
||||
cellNode = do_QueryInterface(cell);
|
||||
res = nsEditor::AppendNodeToSelectionAsRange(cellNode);
|
||||
res = AppendNodeToSelectionAsRange(cellNode);
|
||||
if (NS_FAILED(res)) break;
|
||||
cellSelected = PR_TRUE;
|
||||
}
|
||||
|
@ -1249,7 +1250,7 @@ nsHTMLEditor::SelectTableRow()
|
|||
if (!cellSelected)
|
||||
{
|
||||
cellNode = do_QueryInterface(startCell);
|
||||
return nsEditor::AppendNodeToSelectionAsRange(cellNode);
|
||||
return AppendNodeToSelectionAsRange(cellNode);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -1258,7 +1259,7 @@ NS_IMETHODIMP
|
|||
nsHTMLEditor::SelectTableColumn()
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> cell;
|
||||
nsresult res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("td"), nsnull, getter_AddRefs(cell));
|
||||
nsresult res = GetElementOrParentByTagName(NS_LITERAL_STRING("td"), nsnull, getter_AddRefs(cell));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// Don't fail if we didn't find a cell
|
||||
|
@ -1307,7 +1308,7 @@ nsHTMLEditor::SelectTableColumn()
|
|||
if (cell && currentRowIndex == row && currentColIndex == startColIndex)
|
||||
{
|
||||
cellNode = do_QueryInterface(cell);
|
||||
res = nsEditor::AppendNodeToSelectionAsRange(cellNode);
|
||||
res = AppendNodeToSelectionAsRange(cellNode);
|
||||
if (NS_FAILED(res)) break;
|
||||
cellSelected = PR_TRUE;
|
||||
}
|
||||
|
@ -1316,7 +1317,7 @@ nsHTMLEditor::SelectTableColumn()
|
|||
if (!cellSelected)
|
||||
{
|
||||
cellNode = do_QueryInterface(startCell);
|
||||
return nsEditor::AppendNodeToSelectionAsRange(cellNode);
|
||||
return AppendNodeToSelectionAsRange(cellNode);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -1504,33 +1505,26 @@ nsHTMLEditor::SwitchTableCellHeaderType(nsIDOMElement *aSourceCell, nsIDOMElemen
|
|||
{
|
||||
if (!aSourceCell) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> sourceCell = aSourceCell;
|
||||
nsCOMPtr<nsIDOMElement> newCell;
|
||||
nsAutoString tagName;
|
||||
nsEditor::GetTagString(aSourceCell, tagName);
|
||||
nsAutoEditBatch beginBatching(this);
|
||||
nsCOMPtr<nsIDOMNode> sourceNode = do_QueryInterface(aSourceCell);
|
||||
nsCOMPtr<nsIDOMNode> newNode;
|
||||
|
||||
// Set to the opposite of current type
|
||||
PRBool headerType = (tagName == NS_ConvertASCIItoUCS2("td"));
|
||||
|
||||
// Create the new cell, inserting it just before existing cell
|
||||
// Just assume colspan and rowspan = 1 (we'll copy real values with CloneAttributes)
|
||||
nsresult res = InsertCell(aSourceCell, 1, 1, PR_TRUE, headerType, getter_AddRefs(newCell));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!newCell) return res;
|
||||
|
||||
// Copy all of the original attributes to the new cell
|
||||
nsCOMPtr<nsIDOMNode> sourceCellNode = do_QueryInterface(sourceCell);
|
||||
nsCOMPtr<nsIDOMNode> newCellNode = do_QueryInterface(newCell);
|
||||
res = CloneAttributes(newCellNode, sourceCellNode);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
// Move all contents from original cell to new cell then delete original (3rd param = PR_TRUE)
|
||||
res = MergeCells(newCell, sourceCell, PR_TRUE);
|
||||
nsAutoString tagName;
|
||||
GetTagString(aSourceCell, tagName);
|
||||
nsString newCellType = (tagName == NS_LITERAL_STRING("td")) ? NS_LITERAL_STRING("th") : NS_LITERAL_STRING("td");
|
||||
|
||||
// This creates new node, moves children, copies attributes (PR_TRUE)
|
||||
// and manages the selection!
|
||||
nsresult res = ReplaceContainer(sourceNode, &newNode, newCellType, nsnull, nsnull, PR_TRUE);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!newNode) return NS_ERROR_FAILURE;
|
||||
|
||||
// Return the new cell
|
||||
if (aNewCell)
|
||||
{
|
||||
*aNewCell = newCell.get();
|
||||
nsCOMPtr<nsIDOMElement> newElement = do_QueryInterface(newNode);
|
||||
*aNewCell = newElement;
|
||||
NS_ADDREF(*aNewCell);
|
||||
}
|
||||
|
||||
|
@ -1826,6 +1820,7 @@ nsHTMLEditor::MergeCells(nsCOMPtr<nsIDOMElement> aTargetCell,
|
|||
|
||||
// Get index of last child in target cell
|
||||
nsCOMPtr<nsIDOMNodeList> childNodes;
|
||||
nsCOMPtr<nsIDOMNode> cellChild;
|
||||
res = targetCell->GetChildNodes(getter_AddRefs(childNodes));
|
||||
// If we fail or don't have children,
|
||||
// we insert at index 0
|
||||
|
@ -1837,10 +1832,20 @@ nsHTMLEditor::MergeCells(nsCOMPtr<nsIDOMElement> aTargetCell,
|
|||
PRUint32 len;
|
||||
res = childNodes->GetLength(&len);
|
||||
if (NS_FAILED(res)) return res;
|
||||
insertIndex = (PRInt32)len;
|
||||
if (len == 1 && IsEmptyCell(aTargetCell))
|
||||
{
|
||||
if (IsEmptyCell(aTargetCell))
|
||||
{
|
||||
// Delete the empty node
|
||||
nsCOMPtr<nsIDOMNode> tempNode;
|
||||
DeleteNode(cellChild);
|
||||
insertIndex = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
insertIndex = (PRInt32)len;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> cellChild;
|
||||
res = cellToMerge->GetFirstChild(getter_AddRefs(cellChild));
|
||||
if (NS_FAILED(res)) return res;
|
||||
while (cellChild)
|
||||
|
@ -1849,10 +1854,10 @@ nsHTMLEditor::MergeCells(nsCOMPtr<nsIDOMElement> aTargetCell,
|
|||
res = cellChild->GetNextSibling(getter_AddRefs(nextChild));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
res = nsEditor::DeleteNode(cellChild);
|
||||
res = DeleteNode(cellChild);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
res = nsEditor::InsertNode(cellChild, targetCell, insertIndex);
|
||||
res = InsertNode(cellChild, targetCell, insertIndex);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
cellChild = nextChild;
|
||||
|
@ -1922,7 +1927,7 @@ nsHTMLEditor::NormalizeTable(nsIDOMElement *aTable)
|
|||
{
|
||||
nsCOMPtr<nsIDOMElement> table;
|
||||
nsresult res = NS_ERROR_FAILURE;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), aTable, getter_AddRefs(table));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), aTable, getter_AddRefs(table));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// Don't fail if we didn't find a table
|
||||
if (!table) return NS_OK;
|
||||
|
@ -2002,7 +2007,7 @@ nsHTMLEditor::GetCellIndexes(nsIDOMElement *aCell, PRInt32 &aRowIndex, PRInt32 &
|
|||
{
|
||||
// Get the selected cell or the cell enclosing the selection anchor
|
||||
nsCOMPtr<nsIDOMElement> cell;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("td"), nsnull, getter_AddRefs(cell));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("td"), nsnull, getter_AddRefs(cell));
|
||||
if (NS_SUCCEEDED(res) && cell)
|
||||
aCell = cell;
|
||||
else
|
||||
|
@ -2030,7 +2035,7 @@ nsHTMLEditor::GetTableLayoutObject(nsIDOMElement* aTable, nsITableLayout **table
|
|||
|
||||
// frames are not ref counted, so don't use an nsCOMPtr
|
||||
nsISupports *layoutObject=nsnull;
|
||||
nsresult res = nsHTMLEditor::GetLayoutObject(aTable, &layoutObject);
|
||||
nsresult res = GetLayoutObject(aTable, &layoutObject);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!layoutObject) return NS_ERROR_FAILURE;
|
||||
return layoutObject->QueryInterface(NS_GET_IID(nsITableLayout),
|
||||
|
@ -2079,7 +2084,7 @@ nsHTMLEditor::GetTableSize(nsIDOMElement *aTable, PRInt32& aRowCount, PRInt32& a
|
|||
aColCount = 0;
|
||||
nsCOMPtr<nsIDOMElement> table;
|
||||
// Get the selected talbe or the table enclosing the selection anchor
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), aTable, getter_AddRefs(table));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), aTable, getter_AddRefs(table));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!table) return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -2114,7 +2119,7 @@ nsHTMLEditor::GetCellDataAt(nsIDOMElement* aTable, PRInt32 aRowIndex, PRInt32 aC
|
|||
{
|
||||
// Get the selected table or the table enclosing the selection anchor
|
||||
nsCOMPtr<nsIDOMElement> table;
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), nsnull, getter_AddRefs(table));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), nsnull, getter_AddRefs(table));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (table)
|
||||
aTable = table;
|
||||
|
@ -2181,7 +2186,7 @@ nsHTMLEditor::GetCellContext(nsIDOMSelection **aSelection,
|
|||
if (aColIndex) *aColIndex = 0;
|
||||
|
||||
nsCOMPtr <nsIDOMSelection> selection;
|
||||
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -2202,10 +2207,28 @@ nsHTMLEditor::GetCellContext(nsIDOMSelection **aSelection,
|
|||
// or get the enclosing by a cell
|
||||
if (!cell)
|
||||
{
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("td"), nsnull, getter_AddRefs(cell));
|
||||
// Find a selected or enclosing table element
|
||||
nsCOMPtr<nsIDOMElement> cellOrTableElement;
|
||||
PRInt32 selectedCount;
|
||||
nsAutoString tagName;
|
||||
nsresult res = GetSelectedOrParentTableElement(*getter_AddRefs(cellOrTableElement), tagName, selectedCount);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (tagName == NS_LITERAL_STRING("table"))
|
||||
{
|
||||
// We have a selected table, not a cell
|
||||
if (aTable)
|
||||
{
|
||||
*aTable = cellOrTableElement.get();
|
||||
NS_ADDREF(*aTable);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
// Don't fail if we are not in a cell
|
||||
if (!cell) return NS_EDITOR_ELEMENT_NOT_FOUND;
|
||||
if (tagName != NS_LITERAL_STRING("td"))
|
||||
return NS_EDITOR_ELEMENT_NOT_FOUND;
|
||||
|
||||
// We found a cell
|
||||
cell = cellOrTableElement;
|
||||
}
|
||||
if (aCell)
|
||||
{
|
||||
|
@ -2214,7 +2237,7 @@ nsHTMLEditor::GetCellContext(nsIDOMSelection **aSelection,
|
|||
}
|
||||
|
||||
// Get containing table
|
||||
res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), cell, getter_AddRefs(table));
|
||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), cell, getter_AddRefs(table));
|
||||
if (NS_FAILED(res)) return res;
|
||||
// Cell must be in a table, so fail if not found
|
||||
if (!table) return NS_ERROR_FAILURE;
|
||||
|
@ -2261,7 +2284,7 @@ nsHTMLEditor::GetFirstSelectedCell(nsIDOMElement **aCell, nsIDOMRange **aRange)
|
|||
if (aRange) *aRange = nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -2307,7 +2330,7 @@ nsHTMLEditor::GetNextSelectedCell(nsIDOMElement **aCell, nsIDOMRange **aRange)
|
|||
if (aRange) *aRange = nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -2331,7 +2354,7 @@ nsHTMLEditor::GetNextSelectedCell(nsIDOMElement **aCell, nsIDOMRange **aRange)
|
|||
if (!range) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> cellNode;
|
||||
res = nsEditor::GetFirstNodeInRange(range, getter_AddRefs(cellNode));
|
||||
res = GetFirstNodeInRange(range, getter_AddRefs(cellNode));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!cellNode) return NS_ERROR_FAILURE;
|
||||
if (IsTableCell(cellNode))
|
||||
|
@ -2421,7 +2444,7 @@ nsHTMLEditor::SetSelectionAfterTableEdit(nsIDOMElement* aTable, PRInt32 aRow, PR
|
|||
if (!aTable) return res;
|
||||
|
||||
nsCOMPtr<nsIDOMSelection>selection;
|
||||
res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
if (!selection)
|
||||
|
@ -2514,75 +2537,91 @@ nsHTMLEditor::GetSelectedOrParentTableElement(nsIDOMElement* &aTableElement, nsS
|
|||
aSelectedCount = 0;
|
||||
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
|
||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!selection) return NS_ERROR_FAILURE;
|
||||
|
||||
nsAutoString tableName; tableName.AssignWithConversion("table");
|
||||
nsAutoString trName; trName.AssignWithConversion("tr");
|
||||
nsAutoString tdName; tdName.AssignWithConversion("td");
|
||||
|
||||
nsCOMPtr<nsIDOMNode> anchorNode;
|
||||
res = selection->GetAnchorNode(getter_AddRefs(anchorNode));
|
||||
if(NS_FAILED(res)) return res;
|
||||
if (!anchorNode) return NS_ERROR_FAILURE;
|
||||
// Try to get the first selected cell
|
||||
nsCOMPtr<nsIDOMElement> tableOrCellElement;
|
||||
res = GetFirstSelectedCell(getter_AddRefs(tableOrCellElement), nsnull);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> tableElement;
|
||||
nsCOMPtr<nsIDOMNode> selectedNode;
|
||||
|
||||
// Get child of anchor node, if exists
|
||||
PRBool hasChildren;
|
||||
anchorNode->HasChildNodes(&hasChildren);
|
||||
|
||||
if (hasChildren)
|
||||
if (tableOrCellElement)
|
||||
{
|
||||
PRInt32 anchorOffset;
|
||||
res = selection->GetAnchorOffset(&anchorOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
selectedNode = nsEditor::GetChildAt(anchorNode, anchorOffset);
|
||||
if (!selectedNode)
|
||||
{
|
||||
selectedNode = anchorNode;
|
||||
// If anchor doesn't have a child, we can't be selecting a table element,
|
||||
// so don't do the following:
|
||||
} else {
|
||||
nsAutoString tag;
|
||||
nsEditor::GetTagString(selectedNode,tag);
|
||||
|
||||
if (tag == tdName)
|
||||
{
|
||||
tableElement = do_QueryInterface(selectedNode);
|
||||
aTagName = tdName;
|
||||
// Each cell is in its own selection range,
|
||||
// so count signals multiple-cell selection
|
||||
res = selection->GetRangeCount(&aSelectedCount);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
else if(tag == tableName)
|
||||
{
|
||||
tableElement = do_QueryInterface(selectedNode);
|
||||
aTagName = tableName;
|
||||
aSelectedCount = 1;
|
||||
}
|
||||
else if(tag == trName)
|
||||
{
|
||||
tableElement = do_QueryInterface(selectedNode);
|
||||
aTagName = trName;
|
||||
aSelectedCount = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!tableElement)
|
||||
{
|
||||
// Didn't find a table element -- find a cell parent
|
||||
res = GetElementOrParentByTagName(tdName, anchorNode, getter_AddRefs(tableElement));
|
||||
if(NS_FAILED(res)) return res;
|
||||
if (tableElement)
|
||||
// Each cell is in its own selection range,
|
||||
// so count signals multiple-cell selection
|
||||
res = selection->GetRangeCount(&aSelectedCount);
|
||||
if (NS_FAILED(res)) return res;
|
||||
aTagName = tdName;
|
||||
}
|
||||
if (tableElement)
|
||||
else
|
||||
{
|
||||
aTableElement = tableElement.get();
|
||||
nsAutoString tableName; tableName.AssignWithConversion("table");
|
||||
nsAutoString trName; trName.AssignWithConversion("tr");
|
||||
|
||||
nsCOMPtr<nsIDOMNode> anchorNode;
|
||||
res = selection->GetAnchorNode(getter_AddRefs(anchorNode));
|
||||
if(NS_FAILED(res)) return res;
|
||||
if (!anchorNode) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> selectedNode;
|
||||
|
||||
// Get child of anchor node, if exists
|
||||
PRBool hasChildren;
|
||||
anchorNode->HasChildNodes(&hasChildren);
|
||||
|
||||
if (hasChildren)
|
||||
{
|
||||
PRInt32 anchorOffset;
|
||||
res = selection->GetAnchorOffset(&anchorOffset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
selectedNode = GetChildAt(anchorNode, anchorOffset);
|
||||
if (!selectedNode)
|
||||
{
|
||||
selectedNode = anchorNode;
|
||||
// If anchor doesn't have a child, we can't be selecting a table element,
|
||||
// so don't do the following:
|
||||
} else {
|
||||
nsAutoString tag;
|
||||
GetTagString(selectedNode,tag);
|
||||
|
||||
if (tag == tdName)
|
||||
{
|
||||
tableOrCellElement = do_QueryInterface(selectedNode);
|
||||
aTagName = tdName;
|
||||
// Each cell is in its own selection range,
|
||||
// so count signals multiple-cell selection
|
||||
res = selection->GetRangeCount(&aSelectedCount);
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
else if(tag == tableName)
|
||||
{
|
||||
tableOrCellElement = do_QueryInterface(selectedNode);
|
||||
aTagName = tableName;
|
||||
aSelectedCount = 1;
|
||||
}
|
||||
else if(tag == trName)
|
||||
{
|
||||
tableOrCellElement = do_QueryInterface(selectedNode);
|
||||
aTagName = trName;
|
||||
aSelectedCount = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!tableOrCellElement)
|
||||
{
|
||||
// Didn't find a table element -- find a cell parent
|
||||
res = GetElementOrParentByTagName(tdName, anchorNode, getter_AddRefs(tableOrCellElement));
|
||||
if(NS_FAILED(res)) return res;
|
||||
if (tableOrCellElement)
|
||||
aTagName = tdName;
|
||||
}
|
||||
}
|
||||
if (tableOrCellElement)
|
||||
{
|
||||
aTableElement = tableOrCellElement.get();
|
||||
NS_ADDREF(aTableElement);
|
||||
}
|
||||
return res;
|
||||
|
@ -2611,7 +2650,7 @@ nsHTMLEditor::GetSelectedCellsType(nsIDOMElement *aElement, PRUint32 &aSelection
|
|||
// (if aElement is null, this uses selection's anchor node)
|
||||
nsCOMPtr<nsIDOMElement> table;
|
||||
|
||||
nsresult res = GetElementOrParentByTagName(NS_ConvertASCIItoUCS2("table"), aElement, getter_AddRefs(table));
|
||||
nsresult res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), aElement, getter_AddRefs(table));
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
PRInt32 rowCount, colCount;
|
||||
|
@ -2742,3 +2781,31 @@ nsHTMLEditor::AllCellsInColumnSelected(nsIDOMElement *aTable, PRInt32 aColIndex,
|
|||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLEditor::IsEmptyCell(nsIDOMElement *aCell)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> cellChild;
|
||||
|
||||
// Check if target only contains empty text node or <br>
|
||||
nsresult res = aCell->GetFirstChild(getter_AddRefs(cellChild));
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (cellChild)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> nextChild;
|
||||
res = cellChild->GetNextSibling(getter_AddRefs(nextChild));
|
||||
if (!nextChild)
|
||||
{
|
||||
// We insert a single break into a cell by default
|
||||
// to have some place to locate a cursor -- it is dispensable
|
||||
PRBool isEmpty = nsHTMLEditUtils::IsBreak(cellChild);
|
||||
// Or check if no real content
|
||||
if (!isEmpty)
|
||||
IsEmptyNode(cellChild, &isEmpty, PR_FALSE, PR_FALSE);
|
||||
|
||||
return isEmpty;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -418,7 +418,7 @@ nsTextEditRules::GetTopEnclosingPre(nsIDOMNode *aNode,
|
|||
return res;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsresult
|
||||
nsTextEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel, PRBool *aHandled)
|
||||
{
|
||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||
|
@ -487,7 +487,7 @@ nsTextEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel, P
|
|||
|
||||
if (outLeftNode)
|
||||
{
|
||||
res = IsEmptyNode(outLeftNode, &bIsEmptyNode, PR_TRUE, PR_FALSE);
|
||||
res = mEditor->IsEmptyNode(outLeftNode, &bIsEmptyNode, PR_TRUE, PR_FALSE);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (bIsEmptyNode) mEditor->DeleteNode(outLeftNode);
|
||||
}
|
||||
|
@ -501,7 +501,7 @@ nsTextEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel, P
|
|||
mEditor->DeleteNode(firstNode);
|
||||
}
|
||||
|
||||
res = IsEmptyNode(outRightNode, &bIsEmptyNode, PR_TRUE, PR_FALSE);
|
||||
res = mEditor->IsEmptyNode(outRightNode, &bIsEmptyNode, PR_TRUE, PR_FALSE);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (bIsEmptyNode) mEditor->DeleteNode(outRightNode);
|
||||
}
|
||||
|
@ -685,7 +685,7 @@ nsTextEditRules::WillInsertText(PRInt32 aAction,
|
|||
if (isPRE)
|
||||
{
|
||||
char newlineChar = '\n';
|
||||
while (unicodeBuf && (pos != -1) && (pos < outString->Length()))
|
||||
while (unicodeBuf && (pos != -1) && ((PRUint32)pos < outString->Length()))
|
||||
{
|
||||
PRInt32 oldPos = pos;
|
||||
PRInt32 subStrLen;
|
||||
|
@ -723,7 +723,7 @@ nsTextEditRules::WillInsertText(PRInt32 aAction,
|
|||
{
|
||||
char specialChars[] = {'\t','\n',0};
|
||||
nsAutoString tabString; tabString.AssignWithConversion(" ");
|
||||
while (unicodeBuf && (pos != -1) && (pos < outString->Length()))
|
||||
while (unicodeBuf && (pos != -1) && ((PRUint32)pos < outString->Length()))
|
||||
{
|
||||
PRInt32 oldPos = pos;
|
||||
PRInt32 subStrLen;
|
||||
|
@ -1334,106 +1334,6 @@ nsTextEditRules::CreateMozBR(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<ns
|
|||
return res;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// IsEmptyNode: figure out if aNode is an empty node.
|
||||
// A block can have children and still be considered empty,
|
||||
// if the children are empty or non-editable.
|
||||
//
|
||||
nsresult
|
||||
nsTextEditRules::IsEmptyNode( nsIDOMNode *aNode,
|
||||
PRBool *outIsEmptyNode,
|
||||
PRBool aMozBRDoesntCount,
|
||||
PRBool aListItemsNotEmpty)
|
||||
{
|
||||
if (!aNode || !outIsEmptyNode) return NS_ERROR_NULL_POINTER;
|
||||
*outIsEmptyNode = PR_TRUE;
|
||||
|
||||
// effeciency hack - special case if it's a text node
|
||||
if (nsEditor::IsTextNode(aNode))
|
||||
{
|
||||
PRUint32 length = 0;
|
||||
nsCOMPtr<nsIDOMCharacterData>nodeAsText;
|
||||
nodeAsText = do_QueryInterface(aNode);
|
||||
nodeAsText->GetLength(&length);
|
||||
if (length) *outIsEmptyNode = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// if it's not a text node (handled above) and it's not a container,
|
||||
// then we dont call it empty (it's an <hr>, or <br>, etc).
|
||||
// Also, if it's an anchor then dont treat it as empty - even though
|
||||
// anchors are containers, named anchors are "empty" but we don't
|
||||
// want to treat them as such. Also, don't call ListItems or table
|
||||
// cells empty if caller desires.
|
||||
if (!mEditor->IsContainer(aNode) || nsHTMLEditUtils::IsAnchor(aNode) ||
|
||||
(aListItemsNotEmpty && nsHTMLEditUtils::IsListItem(aNode)) ||
|
||||
(aListItemsNotEmpty && nsHTMLEditUtils::IsTableCell(aNode)) )
|
||||
{
|
||||
*outIsEmptyNode = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// iterate over node. if no children, or all children are either
|
||||
// empty text nodes or non-editable, then node qualifies as empty
|
||||
nsCOMPtr<nsIContentIterator> iter;
|
||||
nsCOMPtr<nsIContent> nodeAsContent = do_QueryInterface(aNode);
|
||||
if (!nodeAsContent) return NS_ERROR_FAILURE;
|
||||
nsresult res = nsComponentManager::CreateInstance(kContentIteratorCID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsIContentIterator),
|
||||
getter_AddRefs(iter));
|
||||
if (NS_FAILED(res)) return res;
|
||||
res = iter->Init(nodeAsContent);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
while (NS_ENUMERATOR_FALSE == iter->IsDone())
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
nsCOMPtr<nsIContent> content;
|
||||
res = iter->CurrentNode(getter_AddRefs(content));
|
||||
if (NS_FAILED(res)) return res;
|
||||
node = do_QueryInterface(content);
|
||||
if (!node) return NS_ERROR_FAILURE;
|
||||
|
||||
// is the node editable and non-empty? if so, return false
|
||||
if (mEditor->IsEditable(node))
|
||||
{
|
||||
if (nsEditor::IsTextNode(node))
|
||||
{
|
||||
PRUint32 length = 0;
|
||||
nsCOMPtr<nsIDOMCharacterData>nodeAsText;
|
||||
nodeAsText = do_QueryInterface(node);
|
||||
nodeAsText->GetLength(&length);
|
||||
if (length) *outIsEmptyNode = PR_FALSE;
|
||||
}
|
||||
else // an editable, non-text node. we aren't an empty block
|
||||
{
|
||||
// is it the node we are iterating over?
|
||||
if (node.get() == aNode) break;
|
||||
// is it a moz-BR and did the caller ask us not to consider those relevant?
|
||||
if (!(aMozBRDoesntCount && nsHTMLEditUtils::IsMozBR(node)))
|
||||
{
|
||||
// is it an empty node of some sort?
|
||||
PRBool isEmptyNode;
|
||||
res = IsEmptyNode(node, &isEmptyNode, aMozBRDoesntCount, aListItemsNotEmpty);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!isEmptyNode)
|
||||
{
|
||||
// otherwise it ain't empty
|
||||
*outIsEmptyNode = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res = iter->Next();
|
||||
if (NS_FAILED(res)) return res;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsTextEditRules::DeleteEmptyTextNode(nsIDOMNode *aNode)
|
||||
{
|
||||
|
|
|
@ -161,11 +161,6 @@ protected:
|
|||
|
||||
nsresult CreateMozBR(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outBRNode);
|
||||
|
||||
nsresult IsEmptyNode(nsIDOMNode *aNode,
|
||||
PRBool *outIsEmptyBlock,
|
||||
PRBool aMozBRDoesntCount = PR_FALSE,
|
||||
PRBool aListItemsNotEmpty = PR_FALSE);
|
||||
|
||||
PRBool DeleteEmptyTextNode(nsIDOMNode *aNode);
|
||||
|
||||
nsresult AdjustSelection(nsIDOMSelection *aSelection, nsIEditor::EDirection aDirection);
|
||||
|
|
Загрузка…
Ссылка в новой задаче